-
Notifications
You must be signed in to change notification settings - Fork 131
Expand file tree
/
Copy pathTypeChecker.py
More file actions
101 lines (95 loc) · 5.16 KB
/
TypeChecker.py
File metadata and controls
101 lines (95 loc) · 5.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# All rights reserved.
# This file is part of the STEPCODE project.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the <ORGANIZATION> nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from .ConstructedDataTypes import ENUMERATION, SELECT
from . import BaseType
RAISE_EXCEPTION_IF_TYPE_DOES_NOT_MATCH = True
DEBUG = False
def cast_python_object_to_aggregate(obj, aggregate):
""" This function casts a python object to an aggregate type. For instance:
[1.,2.,3.]-> ARRAY(1,3,REAL)"""
aggregate_lower_bound = aggregate.bound_1()
aggregate_upper_bound = aggregate.bound_2()
if isinstance(obj, list):
for idx in range(aggregate_lower_bound,aggregate_upper_bound+1):
aggregate[idx] = obj[idx-aggregate_lower_bound]
return aggregate
def check_type(instance, expected_type):
""" This function checks whether an object is an instance of a given class
returns False or True
"""
type_match = False #by default, will be set to True if any match
if DEBUG:
print("===")
print("Instance passed: ",instance)
print("Expected type: ", expected_type)
# in the case of an enumeration, we have to check if the instance is in the list
if (isinstance(expected_type,ENUMERATION)):
allowed_ids = expected_type.get_enum_ids()
if instance in allowed_ids:
type_match = True
else:
raise TypeError('Enumeration ids must be %s ( passed %s)'%(allowed_ids,type(instance)))
elif (isinstance(expected_type,SELECT)):
# we check if the instance is of the type of any of the types that are in the SELECT
allowed_types = expected_type.get_allowed_basic_types()
for allowed_type in allowed_types:
if isinstance(instance,allowed_type):
type_match = True
if not type_match:
if RAISE_EXCEPTION_IF_TYPE_DOES_NOT_MATCH:
raise TypeError('Argument type must be %s (you passed %s)'%(allowed_types,type(instance)))
else:
print("WARNING: expected '%s' but passed a '%s', casting from python value to EXPRESS type"%(allowed_types, type(instance)))
return False
elif (isinstance(expected_type, BaseType.Aggregate)):
# first check that they are instance of the same class
if not (isinstance(instance, type(expected_type))):
raise TypeError('Expected %s but passed %s'%(type(expected_type),type(instance)))
# then check that the base type is the same
elif not (instance.get_type() == expected_type.get_type()):
#print instance.get_type()
#print expected_type.get_type()
raise TypeError('Expected %s:%s base type but passed %s:%s base type'%(type(expected_type),expected_type.get_type(),type(instance), instance.get_type()))
# check optional and unique attributes
#elif not (instance._unique == expected_type._unique):
# raise TypeError('Aggregate expects UNIQUE:%s property but passed UNIQUE:%s'%(expected_type._unique, instance._unique))
#elif not (instance._optional == expected_type._optional):
# raise TypeError('Aggregate expects OPTIONAL:%s property but passed OPTIONAL:%s'%(expected_type._optional, instance._optional))
# @TODO: check aggregate bounds
else:
type_match = True
else: # simple data types
type_match = isinstance(instance,expected_type)
if not type_match:
if RAISE_EXCEPTION_IF_TYPE_DOES_NOT_MATCH:
raise TypeError('Argument type must be %s (you passed %s)'%(expected_type,type(instance)))
else:
print("WARNING: expected '%s' but passed a '%s', casting from python value to EXPRESS type"%(expected_type, type(instance)))
return False
return True