vtlengine 1.0.0__py3-none-any.whl → 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of vtlengine might be problematic. Click here for more details.
- vtlengine/API/_InternalApi.py +153 -100
- vtlengine/API/__init__.py +109 -67
- vtlengine/AST/ASTConstructor.py +188 -98
- vtlengine/AST/ASTConstructorModules/Expr.py +306 -200
- vtlengine/AST/ASTConstructorModules/ExprComponents.py +172 -102
- vtlengine/AST/ASTConstructorModules/Terminals.py +158 -95
- vtlengine/AST/ASTEncoders.py +1 -1
- vtlengine/AST/ASTTemplate.py +8 -9
- vtlengine/AST/ASTVisitor.py +8 -12
- vtlengine/AST/DAG/__init__.py +43 -35
- vtlengine/AST/DAG/_words.py +4 -4
- vtlengine/AST/Grammar/lexer.py +732 -142
- vtlengine/AST/Grammar/parser.py +2188 -826
- vtlengine/AST/Grammar/tokens.py +128 -128
- vtlengine/AST/VtlVisitor.py +7 -4
- vtlengine/AST/__init__.py +22 -11
- vtlengine/DataTypes/NumericTypesHandling.py +5 -4
- vtlengine/DataTypes/TimeHandling.py +194 -301
- vtlengine/DataTypes/__init__.py +304 -218
- vtlengine/Exceptions/__init__.py +52 -27
- vtlengine/Exceptions/messages.py +134 -62
- vtlengine/Interpreter/__init__.py +781 -487
- vtlengine/Model/__init__.py +165 -121
- vtlengine/Operators/Aggregation.py +156 -95
- vtlengine/Operators/Analytic.py +115 -59
- vtlengine/Operators/Assignment.py +7 -4
- vtlengine/Operators/Boolean.py +27 -32
- vtlengine/Operators/CastOperator.py +177 -131
- vtlengine/Operators/Clause.py +137 -99
- vtlengine/Operators/Comparison.py +148 -117
- vtlengine/Operators/Conditional.py +149 -98
- vtlengine/Operators/General.py +68 -47
- vtlengine/Operators/HROperators.py +91 -72
- vtlengine/Operators/Join.py +217 -118
- vtlengine/Operators/Numeric.py +89 -44
- vtlengine/Operators/RoleSetter.py +16 -15
- vtlengine/Operators/Set.py +61 -36
- vtlengine/Operators/String.py +213 -139
- vtlengine/Operators/Time.py +334 -216
- vtlengine/Operators/Validation.py +117 -76
- vtlengine/Operators/__init__.py +340 -213
- vtlengine/Utils/__init__.py +195 -40
- vtlengine/__init__.py +1 -1
- vtlengine/files/output/__init__.py +15 -6
- vtlengine/files/output/_time_period_representation.py +10 -9
- vtlengine/files/parser/__init__.py +77 -52
- vtlengine/files/parser/_rfc_dialect.py +6 -5
- vtlengine/files/parser/_time_checking.py +46 -37
- vtlengine-1.0.1.dist-info/METADATA +236 -0
- vtlengine-1.0.1.dist-info/RECORD +58 -0
- {vtlengine-1.0.dist-info → vtlengine-1.0.1.dist-info}/WHEEL +1 -1
- vtlengine-1.0.dist-info/METADATA +0 -104
- vtlengine-1.0.dist-info/RECORD +0 -58
- {vtlengine-1.0.dist-info → vtlengine-1.0.1.dist-info}/LICENSE.md +0 -0
vtlengine/DataTypes/__init__.py
CHANGED
|
@@ -1,151 +1,171 @@
|
|
|
1
|
-
from typing import Any, Type
|
|
2
|
-
|
|
1
|
+
from typing import Any, Optional, Type, Dict, Set, Union
|
|
3
2
|
import pandas as pd
|
|
4
3
|
|
|
5
4
|
from vtlengine.DataTypes.TimeHandling import str_period_to_date, check_max_date, date_to_period_str
|
|
6
5
|
from vtlengine.Exceptions import SemanticError
|
|
7
6
|
|
|
8
|
-
DTYPE_MAPPING = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
DTYPE_MAPPING: Dict[str, str] = {
|
|
8
|
+
"String": "string",
|
|
9
|
+
"Number": "float64",
|
|
10
|
+
"Integer": "int64",
|
|
11
|
+
"TimeInterval": "string",
|
|
12
|
+
"Date": "string",
|
|
13
|
+
"TimePeriod": "string",
|
|
14
|
+
"Duration": "string",
|
|
15
|
+
"Boolean": "object",
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
CAST_MAPPING = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
CAST_MAPPING: Dict[str, type] = {
|
|
19
|
+
"String": str,
|
|
20
|
+
"Number": float,
|
|
21
|
+
"Integer": int,
|
|
22
|
+
"TimeInterval": str,
|
|
23
|
+
"Date": str,
|
|
24
|
+
"TimePeriod": str,
|
|
25
|
+
"Duration": str,
|
|
26
|
+
"Boolean": bool,
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
|
|
31
30
|
class ScalarType:
|
|
32
|
-
"""
|
|
33
|
-
"""
|
|
31
|
+
""" """
|
|
34
32
|
|
|
35
|
-
default = None
|
|
33
|
+
default: Optional[Union[str, "ScalarType"]] = None
|
|
34
|
+
|
|
35
|
+
def __name__(self) -> Any:
|
|
36
|
+
return self.__class__.__name__
|
|
36
37
|
|
|
37
|
-
def
|
|
38
|
-
return
|
|
38
|
+
def __str__(self) -> str:
|
|
39
|
+
return SCALAR_TYPES_CLASS_REVERSE[self.__class__]
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
__repr__ = __str__
|
|
42
|
+
|
|
43
|
+
def strictly_same_class(self, obj: "ScalarType") -> bool:
|
|
41
44
|
if not isinstance(obj, ScalarType):
|
|
42
45
|
raise Exception("Not use strictly_same_class")
|
|
43
46
|
return self.__class__ == obj.__class__
|
|
44
47
|
|
|
45
|
-
def __eq__(self, other):
|
|
48
|
+
def __eq__(self, other: Any) -> bool:
|
|
46
49
|
return self.__class__.__name__ == other.__class__.__name__
|
|
47
50
|
|
|
48
|
-
def __ne__(self, other):
|
|
51
|
+
def __ne__(self, other: Any) -> bool:
|
|
49
52
|
return not self.__eq__(other)
|
|
50
53
|
|
|
51
|
-
def instance_is_included(self, set_:
|
|
54
|
+
def instance_is_included(self, set_: Set[Any]) -> bool:
|
|
52
55
|
return self.__class__ in set_
|
|
53
56
|
|
|
54
57
|
@classmethod
|
|
55
|
-
def is_included(cls, set_:
|
|
58
|
+
def is_included(cls, set_: Set[Any]) -> bool:
|
|
56
59
|
return cls in set_
|
|
57
60
|
|
|
58
61
|
@classmethod
|
|
59
|
-
def promotion_changed_type(cls, promoted:
|
|
62
|
+
def promotion_changed_type(cls, promoted: Any) -> bool:
|
|
60
63
|
return not issubclass(cls, promoted)
|
|
61
64
|
|
|
62
65
|
@classmethod
|
|
63
|
-
def implicit_cast(cls, value, from_type:
|
|
66
|
+
def implicit_cast(cls, value: Any, from_type: Any) -> Any:
|
|
64
67
|
raise Exception("Method should be implemented by inheritors")
|
|
65
68
|
|
|
66
69
|
@classmethod
|
|
67
|
-
def explicit_cast(cls, value, from_type:
|
|
70
|
+
def explicit_cast(cls, value: Any, from_type: Any) -> Any:
|
|
68
71
|
raise Exception("Method should be implemented by inheritors")
|
|
69
72
|
|
|
70
73
|
@classmethod
|
|
71
|
-
def is_subtype(cls, obj:
|
|
74
|
+
def is_subtype(cls, obj: Any) -> bool:
|
|
72
75
|
return issubclass(cls, obj)
|
|
73
76
|
|
|
74
|
-
|
|
77
|
+
@classmethod
|
|
78
|
+
def is_null_type(cls) -> bool:
|
|
75
79
|
return False
|
|
76
80
|
|
|
77
81
|
@classmethod
|
|
78
|
-
def check_type(cls, value):
|
|
79
|
-
if isinstance(value, CAST_MAPPING[cls.__name__]):
|
|
82
|
+
def check_type(cls, value: Any) -> bool:
|
|
83
|
+
if isinstance(value, CAST_MAPPING[cls.__name__]): # type: ignore[index]
|
|
80
84
|
return True
|
|
81
|
-
|
|
82
85
|
raise Exception(f"Value {value} is not a {cls.__name__}")
|
|
83
86
|
|
|
84
87
|
@classmethod
|
|
85
|
-
def cast(cls, value):
|
|
88
|
+
def cast(cls, value: Any) -> Any:
|
|
86
89
|
if pd.isnull(value):
|
|
87
90
|
return None
|
|
88
|
-
|
|
91
|
+
class_name: str = cls.__name__.__str__()
|
|
92
|
+
return CAST_MAPPING[class_name](value)
|
|
89
93
|
|
|
90
94
|
@classmethod
|
|
91
95
|
def dtype(cls) -> str:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
__str__ = __repr__
|
|
96
|
+
class_name: str = cls.__name__.__str__()
|
|
97
|
+
return DTYPE_MAPPING[class_name]
|
|
95
98
|
|
|
96
99
|
|
|
97
100
|
class String(ScalarType):
|
|
98
|
-
"""
|
|
101
|
+
""" """
|
|
99
102
|
|
|
100
|
-
"""
|
|
101
103
|
default = ""
|
|
102
104
|
|
|
103
105
|
@classmethod
|
|
104
|
-
def implicit_cast(cls, value, from_type:
|
|
106
|
+
def implicit_cast(cls, value: Any, from_type: Any) -> str:
|
|
105
107
|
# if pd.isna(value):
|
|
106
108
|
# return cls.default
|
|
107
|
-
if from_type in {
|
|
108
|
-
|
|
109
|
+
if from_type in {
|
|
110
|
+
Number,
|
|
111
|
+
Integer,
|
|
112
|
+
Boolean,
|
|
113
|
+
String,
|
|
114
|
+
Date,
|
|
115
|
+
TimePeriod,
|
|
116
|
+
TimeInterval,
|
|
117
|
+
Duration,
|
|
118
|
+
}:
|
|
109
119
|
return str(value)
|
|
110
120
|
|
|
111
|
-
raise SemanticError(
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
raise SemanticError(
|
|
122
|
+
"2-1-5-1",
|
|
123
|
+
value=value,
|
|
124
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
125
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
126
|
+
)
|
|
114
127
|
|
|
115
128
|
@classmethod
|
|
116
|
-
def explicit_cast(cls, value, from_type:
|
|
129
|
+
def explicit_cast(cls, value: Any, from_type: Any) -> str:
|
|
117
130
|
if from_type in {TimePeriod, Date, String}:
|
|
118
131
|
return str(value)
|
|
119
132
|
|
|
120
|
-
raise SemanticError(
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
raise SemanticError(
|
|
134
|
+
"2-1-5-1",
|
|
135
|
+
value=value,
|
|
136
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
137
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
138
|
+
)
|
|
123
139
|
|
|
124
140
|
|
|
125
141
|
class Number(ScalarType):
|
|
126
|
-
"""
|
|
127
|
-
"""
|
|
142
|
+
""" """
|
|
128
143
|
|
|
129
|
-
def __eq__(self, other):
|
|
130
|
-
return (
|
|
131
|
-
|
|
144
|
+
def __eq__(self, other: Any) -> bool:
|
|
145
|
+
return (
|
|
146
|
+
self.__class__.__name__ == other.__class__.__name__
|
|
147
|
+
or other.__class__.__name__ == Integer.__name__
|
|
148
|
+
)
|
|
132
149
|
|
|
133
|
-
def __ne__(self, other):
|
|
150
|
+
def __ne__(self, other: Any) -> bool:
|
|
134
151
|
return not self.__eq__(other)
|
|
135
152
|
|
|
136
153
|
@classmethod
|
|
137
|
-
def implicit_cast(cls, value, from_type:
|
|
154
|
+
def implicit_cast(cls, value: Any, from_type: Any) -> float:
|
|
138
155
|
# if pd.isna(value):
|
|
139
156
|
# return cls.default
|
|
140
157
|
if from_type in {Integer, Number}:
|
|
141
158
|
return float(value)
|
|
142
159
|
|
|
143
|
-
raise SemanticError(
|
|
144
|
-
|
|
145
|
-
|
|
160
|
+
raise SemanticError(
|
|
161
|
+
"2-1-5-1",
|
|
162
|
+
value=value,
|
|
163
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
164
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
165
|
+
)
|
|
146
166
|
|
|
147
167
|
@classmethod
|
|
148
|
-
def explicit_cast(cls, value, from_type:
|
|
168
|
+
def explicit_cast(cls, value: Any, from_type: Any) -> float:
|
|
149
169
|
if from_type in {Boolean}:
|
|
150
170
|
if value:
|
|
151
171
|
return 1.0
|
|
@@ -157,12 +177,15 @@ class Number(ScalarType):
|
|
|
157
177
|
except ValueError:
|
|
158
178
|
pass
|
|
159
179
|
|
|
160
|
-
raise SemanticError(
|
|
161
|
-
|
|
162
|
-
|
|
180
|
+
raise SemanticError(
|
|
181
|
+
"2-1-5-1",
|
|
182
|
+
value=value,
|
|
183
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
184
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
185
|
+
)
|
|
163
186
|
|
|
164
187
|
@classmethod
|
|
165
|
-
def cast(cls, value):
|
|
188
|
+
def cast(cls, value: Any) -> Optional[float]:
|
|
166
189
|
if pd.isnull(value):
|
|
167
190
|
return None
|
|
168
191
|
if isinstance(value, str):
|
|
@@ -174,18 +197,19 @@ class Number(ScalarType):
|
|
|
174
197
|
|
|
175
198
|
|
|
176
199
|
class Integer(Number):
|
|
177
|
-
"""
|
|
178
|
-
"""
|
|
200
|
+
""" """
|
|
179
201
|
|
|
180
|
-
def __eq__(self, other):
|
|
181
|
-
return (
|
|
182
|
-
|
|
202
|
+
def __eq__(self, other: Any) -> bool:
|
|
203
|
+
return (
|
|
204
|
+
self.__class__.__name__ == other.__class__.__name__
|
|
205
|
+
or other.__class__.__name__ == Number.__name__
|
|
206
|
+
)
|
|
183
207
|
|
|
184
|
-
def __ne__(self, other):
|
|
208
|
+
def __ne__(self, other: Any) -> bool:
|
|
185
209
|
return not self.__eq__(other)
|
|
186
210
|
|
|
187
211
|
@classmethod
|
|
188
|
-
def implicit_cast(cls, value, from_type:
|
|
212
|
+
def implicit_cast(cls, value: Any, from_type: Any) -> int:
|
|
189
213
|
if from_type.__name__ == "Integer":
|
|
190
214
|
return value
|
|
191
215
|
|
|
@@ -193,16 +217,22 @@ class Integer(Number):
|
|
|
193
217
|
if value.is_integer():
|
|
194
218
|
return int(value)
|
|
195
219
|
else:
|
|
196
|
-
raise SemanticError(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
220
|
+
raise SemanticError(
|
|
221
|
+
"2-1-5-1",
|
|
222
|
+
value=value,
|
|
223
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
224
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
raise SemanticError(
|
|
228
|
+
"2-1-5-1",
|
|
229
|
+
value=value,
|
|
230
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
231
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
232
|
+
)
|
|
203
233
|
|
|
204
234
|
@classmethod
|
|
205
|
-
def explicit_cast(cls, value, from_type:
|
|
235
|
+
def explicit_cast(cls, value: Any, from_type: Any) -> int:
|
|
206
236
|
if from_type in {Boolean}:
|
|
207
237
|
if value:
|
|
208
238
|
return 1
|
|
@@ -211,21 +241,30 @@ class Integer(Number):
|
|
|
211
241
|
if from_type in {Number, String}:
|
|
212
242
|
try:
|
|
213
243
|
if float(value) - int(value) != 0:
|
|
214
|
-
raise SemanticError(
|
|
215
|
-
|
|
216
|
-
|
|
244
|
+
raise SemanticError(
|
|
245
|
+
"2-1-5-1",
|
|
246
|
+
value=value,
|
|
247
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
248
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
249
|
+
)
|
|
217
250
|
except ValueError:
|
|
218
|
-
raise SemanticError(
|
|
219
|
-
|
|
220
|
-
|
|
251
|
+
raise SemanticError(
|
|
252
|
+
"2-1-5-1",
|
|
253
|
+
value=value,
|
|
254
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
255
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
256
|
+
)
|
|
221
257
|
return int(value)
|
|
222
258
|
|
|
223
|
-
raise SemanticError(
|
|
224
|
-
|
|
225
|
-
|
|
259
|
+
raise SemanticError(
|
|
260
|
+
"2-1-5-1",
|
|
261
|
+
value=value,
|
|
262
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
263
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
264
|
+
)
|
|
226
265
|
|
|
227
266
|
@classmethod
|
|
228
|
-
def cast(cls, value):
|
|
267
|
+
def cast(cls, value: Any) -> Optional[int]:
|
|
229
268
|
if pd.isnull(value):
|
|
230
269
|
return None
|
|
231
270
|
if isinstance(value, float):
|
|
@@ -243,13 +282,12 @@ class Integer(Number):
|
|
|
243
282
|
|
|
244
283
|
|
|
245
284
|
class TimeInterval(ScalarType):
|
|
246
|
-
"""
|
|
285
|
+
""" """
|
|
247
286
|
|
|
248
|
-
"""
|
|
249
287
|
default = None
|
|
250
288
|
|
|
251
289
|
@classmethod
|
|
252
|
-
def implicit_cast(cls, value, from_type:
|
|
290
|
+
def implicit_cast(cls, value: Any, from_type: Any) -> Any:
|
|
253
291
|
# TODO: Remove String, only for compatibility with previous engine
|
|
254
292
|
if from_type in {TimeInterval, String}:
|
|
255
293
|
return value
|
|
@@ -263,107 +301,133 @@ class TimeInterval(ScalarType):
|
|
|
263
301
|
end_value = str_period_to_date(value, start=False).isoformat()
|
|
264
302
|
return f"{init_value}/{end_value}"
|
|
265
303
|
|
|
266
|
-
raise SemanticError(
|
|
267
|
-
|
|
268
|
-
|
|
304
|
+
raise SemanticError(
|
|
305
|
+
"2-1-5-1",
|
|
306
|
+
value=value,
|
|
307
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
308
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
309
|
+
)
|
|
269
310
|
|
|
270
311
|
@classmethod
|
|
271
|
-
def explicit_cast(cls, value, from_type:
|
|
312
|
+
def explicit_cast(cls, value: Any, from_type: Any) -> Any:
|
|
272
313
|
|
|
273
|
-
raise SemanticError(
|
|
274
|
-
|
|
275
|
-
|
|
314
|
+
raise SemanticError(
|
|
315
|
+
"2-1-5-1",
|
|
316
|
+
value=value,
|
|
317
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
318
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
319
|
+
)
|
|
276
320
|
|
|
277
321
|
|
|
278
322
|
class Date(TimeInterval):
|
|
279
|
-
"""
|
|
323
|
+
""" """
|
|
280
324
|
|
|
281
|
-
"""
|
|
282
325
|
default = None
|
|
283
326
|
|
|
284
327
|
@classmethod
|
|
285
|
-
def implicit_cast(cls, value, from_type:
|
|
328
|
+
def implicit_cast(cls, value: Any, from_type: Any) -> Any:
|
|
286
329
|
# TODO: Remove String, only for compatibility with previous engine
|
|
287
330
|
if from_type in {Date, String}:
|
|
288
331
|
return value
|
|
289
332
|
|
|
290
|
-
raise SemanticError(
|
|
291
|
-
|
|
292
|
-
|
|
333
|
+
raise SemanticError(
|
|
334
|
+
"2-1-5-1",
|
|
335
|
+
value=value,
|
|
336
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
337
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
338
|
+
)
|
|
293
339
|
|
|
294
340
|
@classmethod
|
|
295
|
-
def explicit_cast(cls, value, from_type:
|
|
341
|
+
def explicit_cast(cls, value: Any, from_type: Any) -> Any:
|
|
296
342
|
# TODO: Remove String, only for compatibility with previous engine
|
|
297
343
|
if from_type == String:
|
|
298
344
|
return value
|
|
299
345
|
|
|
300
|
-
raise SemanticError(
|
|
301
|
-
|
|
302
|
-
|
|
346
|
+
raise SemanticError(
|
|
347
|
+
"2-1-5-1",
|
|
348
|
+
value=value,
|
|
349
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
350
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
351
|
+
)
|
|
303
352
|
|
|
304
353
|
|
|
305
354
|
class TimePeriod(TimeInterval):
|
|
306
|
-
"""
|
|
355
|
+
""" """
|
|
307
356
|
|
|
308
|
-
"""
|
|
309
357
|
default = None
|
|
310
358
|
|
|
311
359
|
@classmethod
|
|
312
|
-
def implicit_cast(cls, value, from_type:
|
|
360
|
+
def implicit_cast(cls, value: Any, from_type: Any) -> Any:
|
|
313
361
|
# TODO: Remove String, only for compatibility with previous engine
|
|
314
362
|
if from_type in {TimePeriod, String}:
|
|
315
363
|
return value
|
|
316
364
|
|
|
317
|
-
raise SemanticError(
|
|
318
|
-
|
|
319
|
-
|
|
365
|
+
raise SemanticError(
|
|
366
|
+
"2-1-5-1",
|
|
367
|
+
value=value,
|
|
368
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
369
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
370
|
+
)
|
|
320
371
|
|
|
321
372
|
@classmethod
|
|
322
|
-
def explicit_cast(cls, value, from_type:
|
|
373
|
+
def explicit_cast(cls, value: Any, from_type: Any) -> Any:
|
|
323
374
|
if from_type in {Date}:
|
|
324
375
|
try:
|
|
325
376
|
period_str = date_to_period_str(value, "D")
|
|
326
377
|
except ValueError:
|
|
327
|
-
raise SemanticError(
|
|
328
|
-
|
|
329
|
-
|
|
378
|
+
raise SemanticError(
|
|
379
|
+
"2-1-5-1",
|
|
380
|
+
value=value,
|
|
381
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
382
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
383
|
+
)
|
|
330
384
|
return period_str
|
|
331
385
|
# TODO: Remove String, only for compatibility with previous engine
|
|
332
386
|
elif from_type == String:
|
|
333
387
|
return value
|
|
334
388
|
|
|
335
|
-
raise SemanticError(
|
|
336
|
-
|
|
337
|
-
|
|
389
|
+
raise SemanticError(
|
|
390
|
+
"2-1-5-1",
|
|
391
|
+
value=value,
|
|
392
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
393
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
394
|
+
)
|
|
338
395
|
|
|
339
396
|
|
|
340
397
|
class Duration(ScalarType):
|
|
341
398
|
|
|
342
399
|
@classmethod
|
|
343
|
-
def implicit_cast(cls, value, from_type:
|
|
400
|
+
def implicit_cast(cls, value: Any, from_type: Any) -> str:
|
|
344
401
|
if from_type in {Duration, String}:
|
|
345
402
|
return value
|
|
346
403
|
|
|
347
|
-
raise SemanticError(
|
|
348
|
-
|
|
349
|
-
|
|
404
|
+
raise SemanticError(
|
|
405
|
+
"2-1-5-1",
|
|
406
|
+
value=value,
|
|
407
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
408
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
409
|
+
)
|
|
350
410
|
|
|
351
411
|
@classmethod
|
|
352
|
-
def explicit_cast(cls, value, from_type:
|
|
412
|
+
def explicit_cast(cls, value: Any, from_type: Any) -> Any:
|
|
353
413
|
if from_type == String:
|
|
354
414
|
return value
|
|
355
415
|
|
|
356
|
-
raise SemanticError(
|
|
357
|
-
|
|
358
|
-
|
|
416
|
+
raise SemanticError(
|
|
417
|
+
"2-1-5-1",
|
|
418
|
+
value=value,
|
|
419
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
420
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
421
|
+
)
|
|
359
422
|
|
|
360
423
|
|
|
361
424
|
class Boolean(ScalarType):
|
|
362
|
-
"""
|
|
363
|
-
|
|
425
|
+
""" """
|
|
426
|
+
|
|
364
427
|
default = None
|
|
365
428
|
|
|
366
|
-
|
|
429
|
+
@classmethod
|
|
430
|
+
def cast(cls, value: Any) -> Optional[bool]:
|
|
367
431
|
if pd.isnull(value):
|
|
368
432
|
return None
|
|
369
433
|
if isinstance(value, str):
|
|
@@ -392,86 +456,95 @@ class Boolean(ScalarType):
|
|
|
392
456
|
return value
|
|
393
457
|
|
|
394
458
|
@classmethod
|
|
395
|
-
def implicit_cast(cls, value, from_type:
|
|
459
|
+
def implicit_cast(cls, value: Any, from_type: Any) -> bool:
|
|
396
460
|
if from_type in {Boolean}:
|
|
397
461
|
return value
|
|
398
462
|
|
|
399
|
-
raise SemanticError(
|
|
400
|
-
|
|
401
|
-
|
|
463
|
+
raise SemanticError(
|
|
464
|
+
"2-1-5-1",
|
|
465
|
+
value=value,
|
|
466
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
467
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
468
|
+
)
|
|
402
469
|
|
|
403
470
|
@classmethod
|
|
404
|
-
def explicit_cast(cls, value, from_type:
|
|
471
|
+
def explicit_cast(cls, value: Any, from_type: Any) -> bool:
|
|
405
472
|
if from_type in {Number, Integer}:
|
|
406
473
|
if value in {0, 0.0}:
|
|
407
474
|
return False
|
|
408
475
|
return True
|
|
409
476
|
|
|
410
|
-
raise SemanticError(
|
|
411
|
-
|
|
412
|
-
|
|
477
|
+
raise SemanticError(
|
|
478
|
+
"2-1-5-1",
|
|
479
|
+
value=value,
|
|
480
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
|
|
481
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[cls],
|
|
482
|
+
)
|
|
413
483
|
|
|
414
484
|
|
|
415
485
|
class Null(ScalarType):
|
|
416
|
-
"""
|
|
417
|
-
"""
|
|
486
|
+
""" """
|
|
418
487
|
|
|
419
|
-
|
|
488
|
+
@classmethod
|
|
489
|
+
def is_null_type(cls) -> bool:
|
|
420
490
|
return True
|
|
421
491
|
|
|
422
|
-
|
|
492
|
+
@classmethod
|
|
493
|
+
def check_type(cls, value: Any) -> bool:
|
|
423
494
|
return True
|
|
424
495
|
|
|
425
|
-
|
|
496
|
+
@classmethod
|
|
497
|
+
def cast(cls, value: Any) -> None:
|
|
426
498
|
return None
|
|
427
499
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
500
|
+
@classmethod
|
|
501
|
+
def dtype(cls) -> str:
|
|
502
|
+
return "string"
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
SCALAR_TYPES: Dict[str, Type[ScalarType]] = {
|
|
506
|
+
"String": String,
|
|
507
|
+
"Number": Number,
|
|
508
|
+
"Integer": Integer,
|
|
509
|
+
"Time": TimeInterval,
|
|
510
|
+
"Date": Date,
|
|
511
|
+
"Time_Period": TimePeriod,
|
|
512
|
+
"Duration": Duration,
|
|
513
|
+
"Boolean": Boolean,
|
|
441
514
|
}
|
|
442
515
|
|
|
443
|
-
SCALAR_TYPES_CLASS_REVERSE = {
|
|
444
|
-
String:
|
|
445
|
-
Number:
|
|
446
|
-
Integer:
|
|
447
|
-
TimeInterval:
|
|
448
|
-
Date:
|
|
449
|
-
TimePeriod:
|
|
450
|
-
Duration:
|
|
451
|
-
Boolean:
|
|
516
|
+
SCALAR_TYPES_CLASS_REVERSE: Dict[Type[ScalarType], str] = {
|
|
517
|
+
String: "String",
|
|
518
|
+
Number: "Number",
|
|
519
|
+
Integer: "Integer",
|
|
520
|
+
TimeInterval: "Time",
|
|
521
|
+
Date: "Date",
|
|
522
|
+
TimePeriod: "Time_Period",
|
|
523
|
+
Duration: "Duration",
|
|
524
|
+
Boolean: "Boolean",
|
|
452
525
|
}
|
|
453
526
|
|
|
454
|
-
BASIC_TYPES = {
|
|
527
|
+
BASIC_TYPES: Dict[type, Type[ScalarType]] = {
|
|
455
528
|
str: String,
|
|
456
529
|
int: Integer,
|
|
457
530
|
float: Number,
|
|
458
531
|
bool: Boolean,
|
|
459
|
-
type(None): Null
|
|
532
|
+
type(None): Null,
|
|
460
533
|
}
|
|
461
534
|
|
|
462
|
-
COMP_NAME_MAPPING = {
|
|
463
|
-
String:
|
|
464
|
-
Number:
|
|
465
|
-
Integer:
|
|
466
|
-
TimeInterval:
|
|
467
|
-
TimePeriod:
|
|
468
|
-
Date:
|
|
469
|
-
Duration:
|
|
470
|
-
Boolean:
|
|
471
|
-
Null:
|
|
535
|
+
COMP_NAME_MAPPING: Dict[Type[ScalarType], str] = {
|
|
536
|
+
String: "str_var",
|
|
537
|
+
Number: "num_var",
|
|
538
|
+
Integer: "int_var",
|
|
539
|
+
TimeInterval: "time_var",
|
|
540
|
+
TimePeriod: "time_period_var",
|
|
541
|
+
Date: "date_var",
|
|
542
|
+
Duration: "duration_var",
|
|
543
|
+
Boolean: "bool_var",
|
|
544
|
+
Null: "null_var",
|
|
472
545
|
}
|
|
473
546
|
|
|
474
|
-
IMPLICIT_TYPE_PROMOTION_MAPPING = {
|
|
547
|
+
IMPLICIT_TYPE_PROMOTION_MAPPING: Dict[Type[ScalarType], Any] = {
|
|
475
548
|
# TODO: Remove Time types, only for compatibility with previous engine
|
|
476
549
|
String: {String, Boolean, TimePeriod},
|
|
477
550
|
Number: {String, Number, Integer},
|
|
@@ -482,11 +555,11 @@ IMPLICIT_TYPE_PROMOTION_MAPPING = {
|
|
|
482
555
|
TimePeriod: {TimeInterval, TimePeriod},
|
|
483
556
|
Duration: {Duration},
|
|
484
557
|
Boolean: {String, Boolean},
|
|
485
|
-
Null: {String, Number, Integer, TimeInterval, Date, TimePeriod, Duration, Boolean, Null}
|
|
558
|
+
Null: {String, Number, Integer, TimeInterval, Date, TimePeriod, Duration, Boolean, Null},
|
|
486
559
|
}
|
|
487
560
|
|
|
488
561
|
# TODO: Implicit are valid as cast without mask
|
|
489
|
-
EXPLICIT_WITHOUT_MASK_TYPE_PROMOTION_MAPPING = {
|
|
562
|
+
EXPLICIT_WITHOUT_MASK_TYPE_PROMOTION_MAPPING: Dict[Type[ScalarType], Any] = {
|
|
490
563
|
# TODO: Remove time types, only for compatibility with previous engine
|
|
491
564
|
String: {Integer, String, Date, TimePeriod, TimeInterval, Duration, Number},
|
|
492
565
|
Number: {Integer, Boolean, String, Number},
|
|
@@ -497,10 +570,10 @@ EXPLICIT_WITHOUT_MASK_TYPE_PROMOTION_MAPPING = {
|
|
|
497
570
|
TimePeriod: {TimePeriod, String},
|
|
498
571
|
Duration: {Duration, String},
|
|
499
572
|
Boolean: {Integer, Number, String, Boolean},
|
|
500
|
-
Null: {String, Number, Integer, TimeInterval, Date, TimePeriod, Duration, Boolean, Null}
|
|
573
|
+
Null: {String, Number, Integer, TimeInterval, Date, TimePeriod, Duration, Boolean, Null},
|
|
501
574
|
}
|
|
502
575
|
|
|
503
|
-
EXPLICIT_WITH_MASK_TYPE_PROMOTION_MAPPING = {
|
|
576
|
+
EXPLICIT_WITH_MASK_TYPE_PROMOTION_MAPPING: Dict[Type[ScalarType], Any] = {
|
|
504
577
|
String: {Number, TimeInterval, Date, TimePeriod, Duration},
|
|
505
578
|
Number: {},
|
|
506
579
|
Integer: {},
|
|
@@ -509,14 +582,16 @@ EXPLICIT_WITH_MASK_TYPE_PROMOTION_MAPPING = {
|
|
|
509
582
|
TimePeriod: {Date},
|
|
510
583
|
Duration: {String},
|
|
511
584
|
Boolean: {},
|
|
512
|
-
Null: {String, Number, Integer, TimeInterval, Date, TimePeriod, Duration, Boolean, Null}
|
|
585
|
+
Null: {String, Number, Integer, TimeInterval, Date, TimePeriod, Duration, Boolean, Null},
|
|
513
586
|
}
|
|
514
587
|
|
|
515
588
|
|
|
516
|
-
def binary_implicit_promotion(
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
589
|
+
def binary_implicit_promotion(
|
|
590
|
+
left_type: Type[ScalarType],
|
|
591
|
+
right_type: Type[ScalarType],
|
|
592
|
+
type_to_check: Optional[Type[ScalarType]] = None,
|
|
593
|
+
return_type: Optional[Type[ScalarType]] = None,
|
|
594
|
+
) -> Type[ScalarType]:
|
|
520
595
|
"""
|
|
521
596
|
Validates the compatibility between the types of the operands and the operator
|
|
522
597
|
(implicit type promotion : check_binary_implicit_type_promotion)
|
|
@@ -539,28 +614,33 @@ def binary_implicit_promotion(left_type: ScalarType,
|
|
|
539
614
|
if right_type.is_included(left_implicities):
|
|
540
615
|
return right_type
|
|
541
616
|
return type_to_check
|
|
542
|
-
raise SemanticError(
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
617
|
+
raise SemanticError(
|
|
618
|
+
code="1-1-1-2",
|
|
619
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[left_type],
|
|
620
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[right_type],
|
|
621
|
+
type_check=SCALAR_TYPES_CLASS_REVERSE[type_to_check],
|
|
622
|
+
)
|
|
623
|
+
# raise Exception(f"Implicit cast not allowed from
|
|
624
|
+
# {left_type} and {right_type} to {type_to_check}")
|
|
625
|
+
|
|
626
|
+
if return_type and (
|
|
627
|
+
left_type.is_included(right_implicities) or right_type.is_included(left_implicities)
|
|
628
|
+
):
|
|
550
629
|
return return_type
|
|
551
630
|
if left_type.is_included(right_implicities):
|
|
552
631
|
return left_type
|
|
553
632
|
if right_type.is_included(left_implicities):
|
|
554
633
|
return right_type
|
|
555
634
|
|
|
556
|
-
raise SemanticError(
|
|
557
|
-
|
|
558
|
-
|
|
635
|
+
raise SemanticError(
|
|
636
|
+
code="1-1-1-1",
|
|
637
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[left_type],
|
|
638
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[right_type],
|
|
639
|
+
)
|
|
559
640
|
|
|
560
641
|
|
|
561
642
|
def check_binary_implicit_promotion(
|
|
562
|
-
|
|
563
|
-
type_to_check: ScalarType = None, return_type: ScalarType = None
|
|
643
|
+
left: Type[ScalarType], right: Any, type_to_check: Any = None, return_type: Any = None
|
|
564
644
|
) -> bool:
|
|
565
645
|
"""
|
|
566
646
|
Validates the compatibility between the types of the operands and the operator
|
|
@@ -580,8 +660,10 @@ def check_binary_implicit_promotion(
|
|
|
580
660
|
|
|
581
661
|
|
|
582
662
|
def unary_implicit_promotion(
|
|
583
|
-
|
|
584
|
-
|
|
663
|
+
operand_type: Type[ScalarType],
|
|
664
|
+
type_to_check: Optional[Type[ScalarType]] = None,
|
|
665
|
+
return_type: Optional[Type[ScalarType]] = None,
|
|
666
|
+
) -> Type[ScalarType]:
|
|
585
667
|
"""
|
|
586
668
|
Validates the compatibility between the type of the operand and the operator
|
|
587
669
|
param operand: The operand
|
|
@@ -592,20 +674,24 @@ def unary_implicit_promotion(
|
|
|
592
674
|
operand_implicities = IMPLICIT_TYPE_PROMOTION_MAPPING[operand_type]
|
|
593
675
|
if type_to_check:
|
|
594
676
|
if not type_to_check.is_included(operand_implicities):
|
|
595
|
-
raise SemanticError(
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
677
|
+
raise SemanticError(
|
|
678
|
+
code="1-1-1-1",
|
|
679
|
+
type_1=SCALAR_TYPES_CLASS_REVERSE[operand_type],
|
|
680
|
+
type_2=SCALAR_TYPES_CLASS_REVERSE[type_to_check],
|
|
681
|
+
)
|
|
599
682
|
if return_type:
|
|
600
683
|
return return_type
|
|
601
|
-
if (
|
|
602
|
-
|
|
684
|
+
if (
|
|
685
|
+
type_to_check
|
|
686
|
+
and not issubclass(operand_type, type_to_check)
|
|
687
|
+
and not issubclass(type_to_check, operand_type)
|
|
688
|
+
):
|
|
603
689
|
return type_to_check
|
|
604
690
|
return operand_type
|
|
605
691
|
|
|
606
692
|
|
|
607
693
|
def check_unary_implicit_promotion(
|
|
608
|
-
|
|
694
|
+
operand_type: Type[ScalarType], type_to_check: Any = None, return_type: Any = None
|
|
609
695
|
) -> bool:
|
|
610
696
|
"""
|
|
611
697
|
Validates the compatibility between the type of the operand and the operator
|