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,16 +1,33 @@
1
+ import _random
1
2
  import math
2
3
  import operator
4
+ import warnings
3
5
  from decimal import getcontext, Decimal
4
6
  from typing import Any, Optional, Union
5
7
 
6
8
  import vtlengine.Operators as Operator
7
9
  import pandas as pd
8
- from vtlengine.DataTypes import Integer, Number
10
+ from vtlengine.DataTypes import Integer, Number, binary_implicit_promotion
9
11
  from vtlengine.Operators import ALL_MODEL_DATA_TYPES
10
12
 
11
- from vtlengine.AST.Grammar.tokens import ABS, CEIL, DIV, EXP, FLOOR, LN, LOG, MINUS, MOD, MULT, \
12
- PLUS, POWER, \
13
- ROUND, SQRT, TRUNC
13
+ from vtlengine.AST.Grammar.tokens import (
14
+ ABS,
15
+ CEIL,
16
+ DIV,
17
+ EXP,
18
+ FLOOR,
19
+ LN,
20
+ LOG,
21
+ MINUS,
22
+ MOD,
23
+ MULT,
24
+ PLUS,
25
+ POWER,
26
+ ROUND,
27
+ SQRT,
28
+ TRUNC,
29
+ RANDOM,
30
+ )
14
31
  from vtlengine.Exceptions import SemanticError
15
32
  from vtlengine.Model import DataComponent, Dataset, Scalar
16
33
 
@@ -19,6 +36,7 @@ class Unary(Operator.Unary):
19
36
  """
20
37
  Checks that the unary operation is performed with a number.
21
38
  """
39
+
22
40
  type_to_check = Number
23
41
 
24
42
 
@@ -26,6 +44,7 @@ class Binary(Operator.Binary):
26
44
  """
27
45
  Checks that the binary operation is performed with numbers.
28
46
  """
47
+
29
48
  type_to_check = Number
30
49
 
31
50
  @classmethod
@@ -35,7 +54,8 @@ class Binary(Operator.Binary):
35
54
  if isinstance(x, int) and isinstance(y, int):
36
55
  if cls.op == DIV and y == 0:
37
56
  raise SemanticError("2-1-15-6", op=cls.op, value=y)
38
- return cls.py_op(x, y)
57
+ if cls.op == RANDOM:
58
+ return cls.py_op(x, y)
39
59
  x = float(x)
40
60
  y = float(y)
41
61
  # Handles precision to avoid floating point errors
@@ -52,8 +72,9 @@ class Binary(Operator.Binary):
52
72
 
53
73
  class UnPlus(Unary):
54
74
  """
55
- `Plus <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=94&zoom=100,72,142> `_ unary operator
75
+ `Plus <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=94&zoom=100,72,142> `_ unary operator # noqa E501
56
76
  """
77
+
57
78
  op = PLUS
58
79
  py_op = operator.pos
59
80
 
@@ -64,24 +85,27 @@ class UnPlus(Unary):
64
85
 
65
86
  class UnMinus(Unary):
66
87
  """
67
- `Minus <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=95&zoom=100,72,414> `_unary operator
88
+ `Minus <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=95&zoom=100,72,414> `_unary operator # noqa E501
68
89
  """
90
+
69
91
  op = MINUS
70
92
  py_op = operator.neg
71
93
 
72
94
 
73
95
  class AbsoluteValue(Unary):
74
96
  """
75
- `Absolute <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=112&zoom=100,72,801> `_ unary operator
97
+ `Absolute <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=112&zoom=100,72,801> `_ unary operator # noqa E501
76
98
  """
99
+
77
100
  op = ABS
78
101
  py_op = operator.abs
79
102
 
80
103
 
81
104
  class Exponential(Unary):
82
105
  """
83
- `Exponential <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=114&zoom=100,72,94>`_ unary operator
106
+ `Exponential <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=114&zoom=100,72,94>`_ unary operator # noqa E501
84
107
  """
108
+
85
109
  op = EXP
86
110
  py_op = math.exp
87
111
  return_type = Number
@@ -89,9 +113,10 @@ class Exponential(Unary):
89
113
 
90
114
  class NaturalLogarithm(Unary):
91
115
  """
92
- `Natural logarithm <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=115&zoom=100,72,394> `_
116
+ `Natural logarithm <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=115&zoom=100,72,394> `_ # noqa E501
93
117
  unary operator
94
118
  """
119
+
95
120
  op = LN
96
121
  py_op = math.log
97
122
  return_type = Number
@@ -99,9 +124,10 @@ class NaturalLogarithm(Unary):
99
124
 
100
125
  class SquareRoot(Unary):
101
126
  """
102
- `Square Root <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=119&zoom=100,72,556> '_
127
+ `Square Root <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=119&zoom=100,72,556> '_ # noqa E501
103
128
  unary operator
104
129
  """
130
+
105
131
  op = SQRT
106
132
  py_op = math.sqrt
107
133
  return_type = Number
@@ -109,8 +135,9 @@ class SquareRoot(Unary):
109
135
 
110
136
  class Ceil(Unary):
111
137
  """
112
- `Ceilling <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=110&zoom=100,72,94> `_ unary operator
138
+ `Ceilling <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=110&zoom=100,72,94> `_ unary operator # noqa E501
113
139
  """
140
+
114
141
  op = CEIL
115
142
  py_op = math.ceil
116
143
  return_type = Integer
@@ -118,8 +145,9 @@ class Ceil(Unary):
118
145
 
119
146
  class Floor(Unary):
120
147
  """
121
- `Floor <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=111&zoom=100,72,442> `_ unary operator
148
+ `Floor <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=111&zoom=100,72,442> `_ unary operator # noqa E501
122
149
  """
150
+
123
151
  op = FLOOR
124
152
  py_op = math.floor
125
153
  return_type = Integer
@@ -127,8 +155,9 @@ class Floor(Unary):
127
155
 
128
156
  class BinPlus(Binary):
129
157
  """
130
- `Addition <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=96&zoom=100,72,692> `_ binary operator
158
+ `Addition <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=96&zoom=100,72,692> `_ binary operator # noqa E501
131
159
  """
160
+
132
161
  op = PLUS
133
162
  py_op = operator.add
134
163
  type_to_check = Number
@@ -136,8 +165,9 @@ class BinPlus(Binary):
136
165
 
137
166
  class BinMinus(Binary):
138
167
  """
139
- `Subtraction <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=98&zoom=100,72,448> `_ binary operator
168
+ `Subtraction <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=98&zoom=100,72,448> `_ binary operator # noqa E501
140
169
  """
170
+
141
171
  op = MINUS
142
172
  py_op = operator.sub
143
173
  type_to_check = Number
@@ -145,18 +175,20 @@ class BinMinus(Binary):
145
175
 
146
176
  class Mult(Binary):
147
177
  """
148
- `Multiplication <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=100&zoom=100,72,254>`_
178
+ `Multiplication <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=100&zoom=100,72,254>`_ # noqa E501
149
179
  binary operator
150
180
  """
181
+
151
182
  op = MULT
152
183
  py_op = operator.mul
153
184
 
154
185
 
155
186
  class Div(Binary):
156
187
  """
157
- `Division <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=102&zoom=100,72,94>`_
188
+ `Division <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=102&zoom=100,72,94>`_ # noqa E501
158
189
  binary operator
159
190
  """
191
+
160
192
  op = DIV
161
193
  py_op = operator.truediv
162
194
  return_type = Number
@@ -164,8 +196,9 @@ class Div(Binary):
164
196
 
165
197
  class Logarithm(Binary):
166
198
  """
167
- `Logarithm <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=118&zoom=100,72,228>`_ operator
199
+ `Logarithm <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=118&zoom=100,72,228>`_ operator # noqa E501
168
200
  """
201
+
169
202
  op = LOG
170
203
  return_type = Number
171
204
 
@@ -181,16 +214,18 @@ class Logarithm(Binary):
181
214
 
182
215
  class Modulo(Binary):
183
216
  """
184
- `Module <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=104&zoom=100,72,94>`_ operator
217
+ `Module <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=104&zoom=100,72,94>`_ operator # noqa E501
185
218
  """
219
+
186
220
  op = MOD
187
221
  py_op = operator.mod
188
222
 
189
223
 
190
224
  class Power(Binary):
191
225
  """
192
- `Power <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=116&zoom=100,72,693>`_ operator
226
+ `Power <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=116&zoom=100,72,693>`_ operator # noqa E501
193
227
  """
228
+
194
229
  op = POWER
195
230
  return_type = Number
196
231
 
@@ -198,26 +233,30 @@ class Power(Binary):
198
233
  def py_op(cls, x: Any, param: Any) -> Any:
199
234
  if pd.isnull(param):
200
235
  return None
201
- return x ** param
236
+ return x**param
202
237
 
203
238
 
204
239
  class Parameterized(Unary):
205
240
  """Parametrized class
206
- Inherits from Unary class, to validate the data type and evaluate if it is the correct one to
207
- perform the operation. Similar to Unary, but in the end, the param validation is added.
241
+ Inherits from Unary class, to validate the data type and evaluate if it is the correct one to
242
+ perform the operation. Similar to Unary, but in the end, the param validation is added.
208
243
  """
209
244
 
210
245
  @classmethod
211
- def validate(cls, operand: Operator.ALL_MODEL_DATA_TYPES,
212
- param: Optional[Union[DataComponent, Scalar]] = None):
246
+ def validate(
247
+ cls,
248
+ operand: Operator.ALL_MODEL_DATA_TYPES,
249
+ param: Optional[Union[DataComponent, Scalar]] = None,
250
+ ) -> Any:
213
251
 
214
252
  if param is not None:
215
253
  if isinstance(param, Dataset):
216
254
  raise SemanticError("1-1-15-8", op=cls.op, comp_type="Dataset")
217
255
  if isinstance(param, DataComponent):
218
256
  if isinstance(operand, Scalar):
219
- raise SemanticError("1-1-15-8", op=cls.op,
220
- comp_type="DataComponent and an Scalar operand")
257
+ raise SemanticError(
258
+ "1-1-15-8", op=cls.op, comp_type="DataComponent and an Scalar operand"
259
+ )
221
260
  cls.validate_type_compatibility(param.data_type)
222
261
  else:
223
262
  cls.validate_scalar_type(param)
@@ -233,17 +272,19 @@ class Parameterized(Unary):
233
272
  return None if pd.isnull(x) else cls.py_op(x, param)
234
273
 
235
274
  @classmethod
236
- def apply_operation_two_series(cls, left_series: pd.Series, right_series: pd.Series) -> Any:
275
+ def apply_operation_two_series(cls, left_series: Any, right_series: Any) -> Any:
237
276
  return left_series.combine(right_series, cls.op_func)
238
277
 
239
278
  @classmethod
240
- def apply_operation_series_scalar(cls, series: pd.Series, param: Any) -> Any:
279
+ def apply_operation_series_scalar(cls, series: Any, param: Any) -> Any:
241
280
  return series.map(lambda x: cls.op_func(x, param))
242
281
 
243
282
  @classmethod
244
- def dataset_evaluation(cls, operand: Dataset, param: Union[DataComponent, Scalar]):
283
+ def dataset_evaluation(
284
+ cls, operand: Dataset, param: Optional[Union[DataComponent, Scalar]] = None
285
+ ) -> Dataset:
245
286
  result = cls.validate(operand, param)
246
- result.data = operand.data.copy()
287
+ result.data = operand.data.copy() if operand.data is not None else pd.DataFrame()
247
288
  for measure_name in result.get_measures_names():
248
289
  try:
249
290
  if isinstance(param, DataComponent):
@@ -251,49 +292,56 @@ class Parameterized(Unary):
251
292
  result.data[measure_name], param.data
252
293
  )
253
294
  else:
254
- param_value = None if param is None else param.value
295
+ param_value = param.value if param is not None else None
255
296
  result.data[measure_name] = cls.apply_operation_series_scalar(
256
297
  result.data[measure_name], param_value
257
298
  )
258
299
  except ValueError:
259
- raise SemanticError("2-1-15-1", op=cls.op, comp_name=measure_name,
260
- dataset_name=operand.name) from None
300
+ raise SemanticError(
301
+ "2-1-15-1", op=cls.op, comp_name=measure_name, dataset_name=operand.name
302
+ ) from None
261
303
  result.data = result.data[result.get_components_names()]
262
304
  return result
263
305
 
264
306
  @classmethod
265
- def component_evaluation(cls, operand: DataComponent, param: Union[DataComponent, Scalar]):
307
+ def component_evaluation(
308
+ cls, operand: DataComponent, param: Optional[Union[DataComponent, Scalar]] = None
309
+ ) -> DataComponent:
266
310
  result = cls.validate(operand, param)
311
+ if operand.data is None:
312
+ operand.data = pd.Series()
267
313
  result.data = operand.data.copy()
268
314
  if isinstance(param, DataComponent):
269
315
  result.data = cls.apply_operation_two_series(operand.data, param.data)
270
316
  else:
271
- param_value = None if param is None else param.value
317
+ param_value = param.value if param is not None else None
272
318
  result.data = cls.apply_operation_series_scalar(operand.data, param_value)
273
319
  return result
274
320
 
275
321
  @classmethod
276
- def scalar_evaluation(cls, operand: Scalar, param: Scalar):
322
+ def scalar_evaluation(cls, operand: Scalar, param: Optional[Any] = None) -> Scalar:
277
323
  result = cls.validate(operand, param)
278
- param_value = None if param is None else param.value
324
+ param_value = param.value if param is not None else None
279
325
  result.value = cls.op_func(operand.value, param_value)
280
326
  return result
281
327
 
282
328
  @classmethod
283
- def evaluate(cls, operand: ALL_MODEL_DATA_TYPES,
284
- param: Optional[Union[DataComponent, Scalar]] = None) -> ALL_MODEL_DATA_TYPES:
329
+ def evaluate(
330
+ cls, operand: ALL_MODEL_DATA_TYPES, param: Optional[Union[DataComponent, Scalar]] = None
331
+ ) -> Union[DataComponent, Dataset, Scalar]:
285
332
  if isinstance(operand, Dataset):
286
333
  return cls.dataset_evaluation(operand, param)
287
- if isinstance(operand, DataComponent):
334
+ elif isinstance(operand, DataComponent):
288
335
  return cls.component_evaluation(operand, param)
289
- if isinstance(operand, Scalar):
336
+ else:
290
337
  return cls.scalar_evaluation(operand, param)
291
338
 
292
339
 
293
340
  class Round(Parameterized):
294
341
  """
295
- `Round <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=106&zoom=100,72,94>`_ operator
342
+ `Round <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=106&zoom=100,72,94>`_ operator # noqa E501
296
343
  """
344
+
297
345
  op = ROUND
298
346
  return_type = Integer
299
347
 
@@ -301,7 +349,7 @@ class Round(Parameterized):
301
349
  def py_op(cls, x: Any, param: Any) -> Any:
302
350
  multiplier = 1.0
303
351
  if not pd.isnull(param):
304
- multiplier = 10 ** param
352
+ multiplier = 10**param
305
353
 
306
354
  if x >= 0.0:
307
355
  rounded_value = math.floor(x * multiplier + 0.5) / multiplier
@@ -316,15 +364,16 @@ class Round(Parameterized):
316
364
 
317
365
  class Trunc(Parameterized):
318
366
  """
319
- `Trunc <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=108&zoom=100,72,94>`_ operator.
367
+ `Trunc <https://sdmx.org/wp-content/uploads/VTL-2.1-Reference-Manual.pdf#page=108&zoom=100,72,94>`_ operator. # noqa E501
320
368
  """
369
+
321
370
  op = TRUNC
322
371
 
323
372
  @classmethod
324
373
  def py_op(cls, x: float, param: Optional[float]) -> Any:
325
374
  multiplier = 1.0
326
375
  if not pd.isnull(param):
327
- multiplier = 10 ** param
376
+ multiplier = 10**param
328
377
 
329
378
  truncated_value = int(x * multiplier) / multiplier
330
379
 
@@ -332,3 +381,37 @@ class Trunc(Parameterized):
332
381
  return truncated_value
333
382
 
334
383
  return int(truncated_value)
384
+
385
+
386
+ class PseudoRandom(_random.Random):
387
+
388
+ def __init__(self, seed: Union[int, float]) -> None:
389
+ super().__init__()
390
+ self.seed(seed)
391
+
392
+
393
+ class Random(Parameterized):
394
+
395
+ op = RANDOM
396
+ return_type = Number
397
+
398
+ @classmethod
399
+ def validate(cls, seed: Any, index: Any = None) -> Any:
400
+ if index.data_type != Integer:
401
+ index.data_type = binary_implicit_promotion(index.data_type, Integer)
402
+ if index.value < 0:
403
+ raise SemanticError("2-1-15-2", op=cls.op, value=index)
404
+ if index.value > 10000:
405
+ warnings.warn("Random: The value of 'index' is very big. This can affect "
406
+ "performance.", UserWarning)
407
+ return super().validate(seed, index)
408
+
409
+ @classmethod
410
+ def py_op(cls,
411
+ seed: Union[int, float],
412
+ index: int
413
+ ) -> float:
414
+ instance: PseudoRandom = PseudoRandom(seed)
415
+ for _ in range(index):
416
+ instance.random()
417
+ return instance.random().__round__(6)
@@ -1,43 +1,42 @@
1
- import os
2
1
  from copy import copy
2
+ from typing import Any, Union
3
3
 
4
4
  from vtlengine.Exceptions import SemanticError
5
5
 
6
- if os.environ.get("SPARK", False):
7
- import pyspark.pandas as pd
8
- else:
9
- import pandas as pd
6
+ # if os.environ.get("SPARK", False):
7
+ # import pyspark.pandas as pd
8
+ # else:
9
+ # import pandas as pd
10
+ import pandas as pd
10
11
 
11
12
  from vtlengine.Model import DataComponent, Role, Scalar
12
13
  from vtlengine.Operators import Unary
13
14
 
14
- ALLOWED_MODEL_TYPES = [DataComponent, Scalar]
15
+ ALLOWED_MODEL_TYPES = Union[DataComponent, Scalar]
15
16
 
16
17
 
17
18
  class RoleSetter(Unary):
18
- role = None
19
+ role: Role
19
20
 
20
21
  @classmethod
21
- def validate(cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0):
22
+ def validate(cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0) -> DataComponent:
22
23
  if isinstance(operand, Scalar):
23
-
24
24
  nullable = True
25
25
  if cls.role == Role.IDENTIFIER or operand.value is not None:
26
26
  nullable = False
27
-
28
27
  return DataComponent(
29
28
  name=operand.name,
30
29
  data_type=operand.data_type,
31
30
  role=cls.role,
32
31
  nullable=nullable,
33
- data=None
32
+ data=None,
34
33
  )
35
34
  operand.role = cls.role
36
35
  return copy(operand)
37
36
 
38
37
  @classmethod
39
- def evaluate(cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0):
40
- if isinstance(operand, DataComponent):
38
+ def evaluate(cls, operand: Any, data_size: int = 0) -> DataComponent:
39
+ if isinstance(operand, DataComponent) and operand.data is not None:
41
40
  if not operand.nullable and any(operand.data.isnull()):
42
41
  raise SemanticError("1-1-1-16")
43
42
  result = cls.validate(operand, data_size)
@@ -52,14 +51,16 @@ class Identifier(RoleSetter):
52
51
  role = Role.IDENTIFIER
53
52
 
54
53
  @classmethod
55
- def validate(cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0):
54
+ def validate(cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0) -> DataComponent:
56
55
  result = super().validate(operand)
57
56
  if result.nullable:
58
57
  raise SemanticError("1-1-1-16")
59
58
  return result
60
59
 
61
60
  @classmethod
62
- def evaluate(cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0):
61
+ def evaluate( # type: ignore[override]
62
+ cls, operand: ALLOWED_MODEL_TYPES, data_size: int = 0
63
+ ) -> DataComponent:
63
64
  if isinstance(operand, Scalar):
64
65
  if operand.value is None:
65
66
  raise SemanticError("1-1-1-16")