vtlengine 1.0__py3-none-any.whl → 1.0.2__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.

Files changed (56) hide show
  1. vtlengine/API/_InternalApi.py +159 -102
  2. vtlengine/API/__init__.py +110 -68
  3. vtlengine/AST/ASTConstructor.py +188 -98
  4. vtlengine/AST/ASTConstructorModules/Expr.py +402 -205
  5. vtlengine/AST/ASTConstructorModules/ExprComponents.py +248 -104
  6. vtlengine/AST/ASTConstructorModules/Terminals.py +158 -95
  7. vtlengine/AST/ASTEncoders.py +1 -1
  8. vtlengine/AST/ASTTemplate.py +24 -9
  9. vtlengine/AST/ASTVisitor.py +8 -12
  10. vtlengine/AST/DAG/__init__.py +43 -35
  11. vtlengine/AST/DAG/_words.py +4 -4
  12. vtlengine/AST/Grammar/Vtl.g4 +49 -20
  13. vtlengine/AST/Grammar/VtlTokens.g4 +13 -1
  14. vtlengine/AST/Grammar/lexer.py +2012 -1312
  15. vtlengine/AST/Grammar/parser.py +7524 -4343
  16. vtlengine/AST/Grammar/tokens.py +140 -128
  17. vtlengine/AST/VtlVisitor.py +16 -5
  18. vtlengine/AST/__init__.py +41 -11
  19. vtlengine/DataTypes/NumericTypesHandling.py +5 -4
  20. vtlengine/DataTypes/TimeHandling.py +196 -301
  21. vtlengine/DataTypes/__init__.py +304 -218
  22. vtlengine/Exceptions/__init__.py +96 -27
  23. vtlengine/Exceptions/messages.py +149 -69
  24. vtlengine/Interpreter/__init__.py +817 -497
  25. vtlengine/Model/__init__.py +172 -121
  26. vtlengine/Operators/Aggregation.py +156 -95
  27. vtlengine/Operators/Analytic.py +167 -79
  28. vtlengine/Operators/Assignment.py +7 -4
  29. vtlengine/Operators/Boolean.py +27 -32
  30. vtlengine/Operators/CastOperator.py +177 -131
  31. vtlengine/Operators/Clause.py +137 -99
  32. vtlengine/Operators/Comparison.py +148 -117
  33. vtlengine/Operators/Conditional.py +290 -98
  34. vtlengine/Operators/General.py +68 -47
  35. vtlengine/Operators/HROperators.py +91 -72
  36. vtlengine/Operators/Join.py +217 -118
  37. vtlengine/Operators/Numeric.py +129 -46
  38. vtlengine/Operators/RoleSetter.py +16 -15
  39. vtlengine/Operators/Set.py +61 -36
  40. vtlengine/Operators/String.py +213 -139
  41. vtlengine/Operators/Time.py +467 -215
  42. vtlengine/Operators/Validation.py +117 -76
  43. vtlengine/Operators/__init__.py +340 -213
  44. vtlengine/Utils/__init__.py +232 -41
  45. vtlengine/__init__.py +1 -1
  46. vtlengine/files/output/__init__.py +15 -6
  47. vtlengine/files/output/_time_period_representation.py +10 -9
  48. vtlengine/files/parser/__init__.py +79 -52
  49. vtlengine/files/parser/_rfc_dialect.py +6 -5
  50. vtlengine/files/parser/_time_checking.py +48 -37
  51. vtlengine-1.0.2.dist-info/METADATA +245 -0
  52. vtlengine-1.0.2.dist-info/RECORD +58 -0
  53. {vtlengine-1.0.dist-info → vtlengine-1.0.2.dist-info}/WHEEL +1 -1
  54. vtlengine-1.0.dist-info/METADATA +0 -104
  55. vtlengine-1.0.dist-info/RECORD +0 -58
  56. {vtlengine-1.0.dist-info → vtlengine-1.0.2.dist-info}/LICENSE.md +0 -0
@@ -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
- 'String': 'string',
10
- 'Number': 'float64',
11
- 'Integer': 'int64',
12
- 'TimeInterval': 'string',
13
- 'Date': 'string',
14
- 'TimePeriod': 'string',
15
- 'Duration': 'string',
16
- 'Boolean': 'object',
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
- 'String': str,
21
- 'Number': float,
22
- 'Integer': int,
23
- 'TimeInterval': str,
24
- 'Date': str,
25
- 'TimePeriod': str,
26
- 'Duration': str,
27
- 'Boolean': bool,
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 __repr__(self) -> str:
38
- return f"{self.__class__.__name__}"
38
+ def __str__(self) -> str:
39
+ return SCALAR_TYPES_CLASS_REVERSE[self.__class__]
39
40
 
40
- def strictly_same_class(self, obj) -> bool:
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_: set) -> bool:
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_: set) -> bool:
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: Type['ScalarType']) -> bool:
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: Type['ScalarType']) -> Any:
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: Type['ScalarType']) -> Any:
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: Type["ScalarType"]) -> bool:
74
+ def is_subtype(cls, obj: Any) -> bool:
72
75
  return issubclass(cls, obj)
73
76
 
74
- def is_null_type(self) -> bool:
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
- return CAST_MAPPING[cls.__name__](value)
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
- return DTYPE_MAPPING[cls.__name__]
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: Type['ScalarType']) -> str:
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 {Number, Integer, Boolean, String, Date, TimePeriod, TimeInterval,
108
- Duration}:
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("2-1-5-1", value=value,
112
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
113
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> str:
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("2-1-5-1", value=value,
121
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
122
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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 (self.__class__.__name__ == other.__class__.__name__ or
131
- other.__class__.__name__ == Integer.__name__)
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: Type['ScalarType']) -> float:
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("2-1-5-1", value=value,
144
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
145
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> float:
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("2-1-5-1", value=value,
161
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
162
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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 (self.__class__.__name__ == other.__class__.__name__ or
182
- other.__class__.__name__ == Number.__name__)
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: Type['ScalarType']) -> int:
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("2-1-5-1", value=value,
197
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
198
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
199
-
200
- raise SemanticError("2-1-5-1", value=value,
201
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
202
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> int:
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("2-1-5-1", value=value,
215
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
216
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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("2-1-5-1", value=value,
219
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
220
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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("2-1-5-1", value=value,
224
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
225
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> Any:
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("2-1-5-1", value=value,
267
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
268
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> Any:
312
+ def explicit_cast(cls, value: Any, from_type: Any) -> Any:
272
313
 
273
- raise SemanticError("2-1-5-1", value=value,
274
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
275
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> Any:
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("2-1-5-1", value=value,
291
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
292
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> Any:
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("2-1-5-1", value=value,
301
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
302
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> Any:
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("2-1-5-1", value=value,
318
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
319
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> Any:
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("2-1-5-1", value=value,
328
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
329
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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("2-1-5-1", value=value,
336
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
337
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> str:
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("2-1-5-1", value=value,
348
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
349
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> Any:
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("2-1-5-1", value=value,
357
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
358
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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
- def cast(self, value):
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: Type['ScalarType']) -> bool:
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("2-1-5-1", value=value,
400
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
401
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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: Type['ScalarType']) -> bool:
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("2-1-5-1", value=value,
411
- type_1=SCALAR_TYPES_CLASS_REVERSE[from_type],
412
- type_2=SCALAR_TYPES_CLASS_REVERSE[cls])
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
- def is_null_type(self) -> bool:
488
+ @classmethod
489
+ def is_null_type(cls) -> bool:
420
490
  return True
421
491
 
422
- def check_type(self, value):
492
+ @classmethod
493
+ def check_type(cls, value: Any) -> bool:
423
494
  return True
424
495
 
425
- def cast(self, value):
496
+ @classmethod
497
+ def cast(cls, value: Any) -> None:
426
498
  return None
427
499
 
428
- def dtype(self):
429
- return 'string'
430
-
431
-
432
- SCALAR_TYPES = {
433
- 'String': String,
434
- 'Number': Number,
435
- 'Integer': Integer,
436
- 'Time': TimeInterval,
437
- 'Date': Date,
438
- 'Time_Period': TimePeriod,
439
- 'Duration': Duration,
440
- 'Boolean': Boolean,
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: 'String',
445
- Number: 'Number',
446
- Integer: 'Integer',
447
- TimeInterval: 'Time',
448
- Date: 'Date',
449
- TimePeriod: 'Time_Period',
450
- Duration: 'Duration',
451
- Boolean: '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: 'str_var',
464
- Number: 'num_var',
465
- Integer: 'int_var',
466
- TimeInterval: 'time_var',
467
- TimePeriod: 'time_period_var',
468
- Date: 'date_var',
469
- Duration: 'duration_var',
470
- Boolean: 'bool_var',
471
- Null: 'null_var'
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(left_type: ScalarType,
517
- right_type: ScalarType,
518
- type_to_check: ScalarType = None,
519
- return_type: ScalarType = None) -> ScalarType:
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(code="1-1-1-2",
543
- type_1=SCALAR_TYPES_CLASS_REVERSE[left_type],
544
- type_2=SCALAR_TYPES_CLASS_REVERSE[right_type],
545
- type_check=SCALAR_TYPES_CLASS_REVERSE[type_to_check])
546
- # raise Exception(f"Implicit cast not allowed from {left_type} and {right_type} to {type_to_check}")
547
-
548
- if return_type and (left_type.is_included(
549
- right_implicities) or right_type.is_included(left_implicities)):
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(code="1-1-1-1",
557
- type_1=SCALAR_TYPES_CLASS_REVERSE[left_type],
558
- type_2=SCALAR_TYPES_CLASS_REVERSE[right_type])
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
- left: ScalarType, right: ScalarType,
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
- operand_type: ScalarType, type_to_check: ScalarType = None, return_type: ScalarType = None
584
- ) -> ScalarType:
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(code="1-1-1-1",
596
- type_1=SCALAR_TYPES_CLASS_REVERSE[operand_type],
597
- type_2=SCALAR_TYPES_CLASS_REVERSE[type_to_check])
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 (type_to_check and not issubclass(operand_type, type_to_check)
602
- and not issubclass(type_to_check, operand_type)):
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
- operand_type: ScalarType, type_to_check: ScalarType = None, return_type: ScalarType = None
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