vtlengine 1.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.

Files changed (54) hide show
  1. vtlengine/API/_InternalApi.py +153 -100
  2. vtlengine/API/__init__.py +109 -67
  3. vtlengine/AST/ASTConstructor.py +188 -98
  4. vtlengine/AST/ASTConstructorModules/Expr.py +306 -200
  5. vtlengine/AST/ASTConstructorModules/ExprComponents.py +172 -102
  6. vtlengine/AST/ASTConstructorModules/Terminals.py +158 -95
  7. vtlengine/AST/ASTEncoders.py +1 -1
  8. vtlengine/AST/ASTTemplate.py +8 -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/lexer.py +732 -142
  13. vtlengine/AST/Grammar/parser.py +2188 -826
  14. vtlengine/AST/Grammar/tokens.py +128 -128
  15. vtlengine/AST/VtlVisitor.py +7 -4
  16. vtlengine/AST/__init__.py +22 -11
  17. vtlengine/DataTypes/NumericTypesHandling.py +5 -4
  18. vtlengine/DataTypes/TimeHandling.py +194 -301
  19. vtlengine/DataTypes/__init__.py +304 -218
  20. vtlengine/Exceptions/__init__.py +52 -27
  21. vtlengine/Exceptions/messages.py +134 -62
  22. vtlengine/Interpreter/__init__.py +781 -487
  23. vtlengine/Model/__init__.py +165 -121
  24. vtlengine/Operators/Aggregation.py +156 -95
  25. vtlengine/Operators/Analytic.py +115 -59
  26. vtlengine/Operators/Assignment.py +7 -4
  27. vtlengine/Operators/Boolean.py +27 -32
  28. vtlengine/Operators/CastOperator.py +177 -131
  29. vtlengine/Operators/Clause.py +137 -99
  30. vtlengine/Operators/Comparison.py +148 -117
  31. vtlengine/Operators/Conditional.py +149 -98
  32. vtlengine/Operators/General.py +68 -47
  33. vtlengine/Operators/HROperators.py +91 -72
  34. vtlengine/Operators/Join.py +217 -118
  35. vtlengine/Operators/Numeric.py +89 -44
  36. vtlengine/Operators/RoleSetter.py +16 -15
  37. vtlengine/Operators/Set.py +61 -36
  38. vtlengine/Operators/String.py +213 -139
  39. vtlengine/Operators/Time.py +334 -216
  40. vtlengine/Operators/Validation.py +117 -76
  41. vtlengine/Operators/__init__.py +340 -213
  42. vtlengine/Utils/__init__.py +195 -40
  43. vtlengine/__init__.py +1 -1
  44. vtlengine/files/output/__init__.py +15 -6
  45. vtlengine/files/output/_time_period_representation.py +10 -9
  46. vtlengine/files/parser/__init__.py +77 -52
  47. vtlengine/files/parser/_rfc_dialect.py +6 -5
  48. vtlengine/files/parser/_time_checking.py +46 -37
  49. vtlengine-1.0.1.dist-info/METADATA +236 -0
  50. vtlengine-1.0.1.dist-info/RECORD +58 -0
  51. {vtlengine-1.0.dist-info → vtlengine-1.0.1.dist-info}/WHEEL +1 -1
  52. vtlengine-1.0.dist-info/METADATA +0 -104
  53. vtlengine-1.0.dist-info/RECORD +0 -58
  54. {vtlengine-1.0.dist-info → vtlengine-1.0.1.dist-info}/LICENSE.md +0 -0
@@ -1,20 +1,28 @@
1
1
  import operator
2
- import os
3
2
  import re
4
-
5
3
  from vtlengine.Exceptions import SemanticError
6
4
  from vtlengine.Model import DataComponent, Dataset, Scalar
7
5
 
8
- if os.environ.get("SPARK", False):
9
- import pyspark.pandas as pd
10
- else:
11
- 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
12
11
 
13
12
  from typing import Optional, Any, Union
14
-
15
- from vtlengine.AST.Grammar.tokens import LEN, CONCAT, UCASE, LCASE, RTRIM, SUBSTR, LTRIM, TRIM, \
16
- REPLACE, INSTR
17
- from vtlengine.DataTypes import Integer, String, ScalarType, check_unary_implicit_promotion
13
+ from vtlengine.AST.Grammar.tokens import (
14
+ LEN,
15
+ CONCAT,
16
+ UCASE,
17
+ LCASE,
18
+ RTRIM,
19
+ SUBSTR,
20
+ LTRIM,
21
+ TRIM,
22
+ REPLACE,
23
+ INSTR,
24
+ )
25
+ from vtlengine.DataTypes import Integer, String, check_unary_implicit_promotion
18
26
  import vtlengine.Operators as Operator
19
27
 
20
28
 
@@ -23,13 +31,14 @@ class Unary(Operator.Unary):
23
31
 
24
32
  @classmethod
25
33
  def op_func(cls, x: Any) -> Any:
34
+
26
35
  x = "" if pd.isnull(x) else str(x)
27
36
  return cls.py_op(x)
28
37
 
29
38
  @classmethod
30
39
  def apply_operation_component(cls, series: Any) -> Any:
31
40
  """Applies the operation to a component"""
32
- return series.map(lambda x: cls.py_op(str(x)), na_action='ignore')
41
+ return series.map(lambda x: cls.py_op(str(x)), na_action="ignore")
33
42
 
34
43
  @classmethod
35
44
  def validate_dataset(cls, dataset: Dataset) -> None:
@@ -38,7 +47,7 @@ class Unary(Operator.Unary):
38
47
  """
39
48
  measures = dataset.get_measures()
40
49
 
41
- if measures is None or len(measures) != 1:
50
+ if len(measures) != 1:
42
51
  raise SemanticError("1-1-18-1", op=cls.op, name=dataset.name)
43
52
 
44
53
 
@@ -109,40 +118,54 @@ class Concatenate(Binary):
109
118
  class Parameterized(Unary):
110
119
 
111
120
  @classmethod
112
- def validate(cls, operand: Operator.ALL_MODEL_DATA_TYPES, param1: Optional[Scalar] = None,
113
- param2: Optional[Scalar] = None):
121
+ def validate(cls, *args: Any) -> Any:
122
+ operand: Operator.ALL_MODEL_DATA_TYPES
123
+ param1: Optional[Scalar]
124
+ param2: Optional[Scalar]
125
+ operand, param1, param2 = (args + (None, None))[:3]
114
126
 
115
127
  if param1 is not None:
116
128
  cls.check_param(param1, 1)
117
129
  if param2 is not None:
118
130
  cls.check_param(param2, 2)
119
-
120
131
  return super().validate(operand)
121
132
 
122
133
  @classmethod
123
- def op_func(cls, x: Union[Dataset, String], param1: Optional[Any],
124
- param2: Optional[Any]) -> Any:
134
+ def op_func(cls, *args: Any) -> Any:
135
+ x: Optional[Any]
136
+ param1: Optional[Any]
137
+ param2: Optional[Any]
138
+ x, param1, param2 = (args + (None, None))[:3]
139
+
125
140
  x = "" if pd.isnull(x) else x
126
141
  return cls.py_op(x, param1, param2)
127
142
 
128
143
  @classmethod
129
- def apply_operation_two_series(cls, left_series: pd.Series, right_series: pd.Series) -> Any:
144
+ def apply_operation_two_series(cls, *args: Any) -> Any:
145
+ left_series, right_series = args
146
+
130
147
  return left_series.combine(right_series, cls.op_func)
131
148
 
132
149
  @classmethod
133
- def apply_operation_series_scalar(cls, series: pd.Series, param1: Any, param2: Any) -> Any:
150
+ def apply_operation_series_scalar(cls, *args: Any) -> Any:
151
+ series, param1, param2 = args
152
+
134
153
  return series.map(lambda x: cls.op_func(x, param1, param2))
135
154
 
136
155
  @classmethod
137
- def dataset_evaluation(cls, operand: Dataset,
138
- param1: Optional[Union[DataComponent, Scalar]],
139
- param2: Optional[Union[DataComponent, Scalar]]):
156
+ def dataset_evaluation(cls, *args: Any) -> Dataset:
157
+ operand: Dataset
158
+ param1: Optional[Union[DataComponent, Scalar]]
159
+ param2: Optional[Union[DataComponent, Scalar]]
160
+ operand, param1, param2 = (args + (None, None))[:3]
161
+
140
162
  result = cls.validate(operand, param1, param2)
141
- result.data = operand.data.copy()
163
+ result.data = operand.data.copy() if operand.data is not None else pd.DataFrame()
142
164
  for measure_name in operand.get_measures_names():
143
165
  if isinstance(param1, DataComponent) or isinstance(param2, DataComponent):
144
- result.data[measure_name] = cls.apply_operation_series(result.data[measure_name],
145
- param1, param2)
166
+ result.data[measure_name] = cls.apply_operation_series(
167
+ result.data[measure_name], param1, param2
168
+ )
146
169
  else:
147
170
  param_value1 = None if param1 is None else param1.value
148
171
  param_value2 = None if param2 is None else param2.value
@@ -152,29 +175,35 @@ class Parameterized(Unary):
152
175
 
153
176
  cols_to_keep = operand.get_identifiers_names() + operand.get_measures_names()
154
177
  result.data = result.data[cols_to_keep]
155
-
156
178
  cls.modify_measure_column(result)
157
179
  return result
158
180
 
159
181
  @classmethod
160
- def component_evaluation(cls, operand: DataComponent,
161
- param1: Optional[Union[DataComponent, Scalar]],
162
- param2: Optional[Union[DataComponent, Scalar]]):
182
+ def component_evaluation(cls, *args: Any) -> DataComponent:
183
+ operand: DataComponent
184
+ param1: Optional[Union[DataComponent, Scalar]]
185
+ param2: Optional[Union[DataComponent, Scalar]]
186
+ operand, param1, param2 = (args + (None, None))[:3]
187
+
163
188
  result = cls.validate(operand, param1, param2)
164
- result.data = operand.data.copy()
189
+ result.data = operand.data.copy() if operand.data is not None else pd.Series()
165
190
  if isinstance(param1, DataComponent) or isinstance(param2, DataComponent):
166
191
  result.data = cls.apply_operation_series(result.data, param1, param2)
167
192
  else:
168
193
  param_value1 = None if param1 is None else param1.value
169
194
  param_value2 = None if param2 is None else param2.value
170
- result.data = cls.apply_operation_series_scalar(operand.data, param_value1,
171
- param_value2)
195
+ result.data = cls.apply_operation_series_scalar(
196
+ operand.data, param_value1, param_value2
197
+ )
172
198
  return result
173
199
 
174
200
  @classmethod
175
- def scalar_evaluation(cls, operand: Scalar,
176
- param1: Optional[Union[DataComponent, Scalar]],
177
- param2: Optional[Union[DataComponent, Scalar]]):
201
+ def scalar_evaluation(cls, *args: Any) -> Scalar:
202
+ operand: Scalar
203
+ param1: Optional[Scalar]
204
+ param2: Optional[Scalar]
205
+ operand, param1, param2 = (args + (None, None))[:3]
206
+
178
207
  result = cls.validate(operand, param1, param2)
179
208
  param_value1 = None if param1 is None else param1.value
180
209
  param_value2 = None if param2 is None else param2.value
@@ -182,27 +211,34 @@ class Parameterized(Unary):
182
211
  return result
183
212
 
184
213
  @classmethod
185
- def evaluate(cls, operand: Operator.ALL_MODEL_DATA_TYPES,
186
- param1: Optional[Union[DataComponent, Scalar]] = None,
187
- param2: Optional[
188
- Union[DataComponent, Scalar]] = None) -> Operator.ALL_MODEL_DATA_TYPES:
214
+ def evaluate(cls, *args: Any) -> Union[Dataset, DataComponent, Scalar]:
215
+ param1: Optional[Union[DataComponent, Scalar]]
216
+ param2: Optional[Union[DataComponent, Scalar]]
217
+ operand, param1, param2 = (args + (None, None))[:3]
218
+
189
219
  if isinstance(operand, Dataset):
190
220
  return cls.dataset_evaluation(operand, param1, param2)
191
221
  if isinstance(operand, DataComponent):
192
222
  return cls.component_evaluation(operand, param1, param2)
193
- if isinstance(operand, Scalar):
194
- return cls.scalar_evaluation(operand, param1, param2)
223
+ return cls.scalar_evaluation(operand, param1, param2)
195
224
 
196
225
  @classmethod
197
- def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int):
226
+ def check_param(cls, *args: Any) -> None:
198
227
  raise Exception("Method should be implemented by inheritors")
199
228
 
200
229
  @classmethod
201
- def check_param_value(cls, param: Optional[Union[int, str]], position: int):
230
+ def check_param_value(cls, *args: Any) -> None:
202
231
  raise Exception("Method should be implemented by inheritors")
203
232
 
204
233
  @classmethod
205
- def generate_series_from_param(cls, param: Optional[Union[DataComponent, Scalar]], length: int):
234
+ def generate_series_from_param(cls, *args: Any) -> Any:
235
+ param: Optional[Union[DataComponent, Scalar]] = None
236
+ length: int
237
+ if len(args) == 2:
238
+ param, length = args
239
+ else:
240
+ length = args[0]
241
+
206
242
  if param is None:
207
243
  return pd.Series(index=range(length), dtype=object)
208
244
  if isinstance(param, Scalar):
@@ -210,18 +246,14 @@ class Parameterized(Unary):
210
246
  return param.data
211
247
 
212
248
  @classmethod
213
- def apply_operation_series(cls,
214
- data: pd.Series,
215
- param1: Optional[Union[DataComponent, Scalar]],
216
- param2: Optional[Union[DataComponent, Scalar]]):
249
+ def apply_operation_series(cls, *args: Any) -> Any:
250
+ param1: Optional[Union[DataComponent, Scalar]]
251
+ param2: Optional[Union[DataComponent, Scalar]]
252
+ data, param1, param2 = (args + (None, None))[:3]
253
+
217
254
  param1_data = cls.generate_series_from_param(param1, len(data))
218
255
  param2_data = cls.generate_series_from_param(param2, len(data))
219
-
220
- df = pd.DataFrame([
221
- data,
222
- param1_data,
223
- param2_data
224
- ]).T
256
+ df = pd.DataFrame([data, param1_data, param2_data]).T
225
257
  n1, n2, n3 = df.columns
226
258
  return df.apply(lambda x: cls.op_func(x[n1], x[n2], x[n3]), axis=1)
227
259
 
@@ -231,12 +263,12 @@ class Substr(Parameterized):
231
263
  return_type = String
232
264
 
233
265
  @classmethod
234
- def validate_params(cls, params: Optional[Any]):
266
+ def validate_params(cls, params: Any) -> None:
235
267
  if len(params) != 2:
236
268
  raise SemanticError("1-1-18-7", op=cls.op, number=len(params), expected=2)
237
269
 
238
270
  @classmethod
239
- def py_op(cls, x: str, param1: Optional[Any], param2: Optional[Any]) -> Any:
271
+ def py_op(cls, x: str, param1: Any, param2: Any) -> Any:
240
272
  x = str(x)
241
273
  param1 = None if pd.isnull(param1) else int(param1)
242
274
  param2 = None if pd.isnull(param2) else int(param2)
@@ -251,16 +283,16 @@ class Substr(Parameterized):
251
283
  if param2 is None or (param1 + param2) > len(x):
252
284
  param2 = len(x)
253
285
  else:
254
- param2 = (param1 + param2)
286
+ param2 = param1 + param2
255
287
  return x[param1:param2]
256
288
 
257
289
  @classmethod
258
- def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int):
290
+ def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int) -> None:
259
291
  if not param:
260
292
  return
261
293
  if position not in (1, 2):
262
294
  raise SemanticError("1-1-18-3", op=cls.op, pos=position)
263
- data_type: ScalarType = param.data_type
295
+ data_type: Any = param.data_type
264
296
 
265
297
  if not check_unary_implicit_promotion(data_type, Integer):
266
298
  raise SemanticError("1-1-18-4", op=cls.op, param_type=cls.op, correct_type="Integer")
@@ -272,11 +304,12 @@ class Substr(Parameterized):
272
304
  cls.check_param_value(param.value, position)
273
305
 
274
306
  @classmethod
275
- def check_param_value(cls, param: Optional[Union[int, str]], position: int):
276
- if not pd.isnull(param) and not param >= 1 and position == 1:
277
- raise SemanticError("1-1-18-4", op=cls.op, param_type="Start", correct_type=">= 1")
278
- elif not pd.isnull(param) and not param >= 0 and position == 2:
279
- raise SemanticError("1-1-18-4", op=cls.op, param_type="Length", correct_type=">= 0")
307
+ def check_param_value(cls, param: Optional[Any], position: int) -> None:
308
+ if param is not None:
309
+ if not pd.isnull(param) and not param >= 1 and position == 1:
310
+ raise SemanticError("1-1-18-4", op=cls.op, param_type="Start", correct_type=">= 1")
311
+ elif not pd.isnull(param) and not param >= 0 and position == 2:
312
+ raise SemanticError("1-1-18-4", op=cls.op, param_type="Length", correct_type=">= 0")
280
313
 
281
314
 
282
315
  class Replace(Parameterized):
@@ -288,23 +321,25 @@ class Replace(Parameterized):
288
321
  if pd.isnull(param1):
289
322
  return ""
290
323
  elif pd.isnull(param2):
291
- param2 = ''
324
+ param2 = ""
292
325
  x = str(x)
293
- return x.replace(param1, param2)
326
+ if param1 is not None and param2 is not None:
327
+ return x.replace(param1, param2)
328
+ return x
294
329
 
295
330
  @classmethod
296
- def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int):
331
+ def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int) -> None:
297
332
  if not param:
298
333
  return
299
334
  if position not in (1, 2):
300
335
  raise SemanticError("1-1-18-3", op=cls.op, pos=position)
301
- data_type: ScalarType = param.data_type
336
+ data_type: Any = param.data_type
302
337
 
303
338
  if not check_unary_implicit_promotion(data_type, String):
304
339
  raise SemanticError("1-1-18-4", op=cls.op, param_type=cls.op, correct_type="String")
305
340
 
306
341
  @classmethod
307
- def validate_params(cls, params: Optional[Any]):
342
+ def validate_params(cls, params: Any) -> None:
308
343
  if len(params) != 2:
309
344
  raise SemanticError("1-1-18-7", op=cls.op, number=len(params), expected=2)
310
345
 
@@ -314,13 +349,19 @@ class Instr(Parameterized):
314
349
  return_type = Integer
315
350
 
316
351
  @classmethod
317
- def validate(cls, operand: Operator.ALL_MODEL_DATA_TYPES,
318
- param1: Optional[Scalar] = None,
319
- param2: Optional[Scalar] = None,
320
- param3: Optional[Scalar] = None):
352
+ def validate(
353
+ cls,
354
+ operand: Operator.ALL_MODEL_DATA_TYPES,
355
+ param1: Optional[Operator.ALL_MODEL_DATA_TYPES] = None,
356
+ param2: Optional[Operator.ALL_MODEL_DATA_TYPES] = None,
357
+ param3: Optional[Operator.ALL_MODEL_DATA_TYPES] = None,
358
+ ) -> Any:
321
359
 
322
- if isinstance(param1, Dataset) or isinstance(param2, Dataset) or isinstance(param3,
323
- Dataset):
360
+ if (
361
+ isinstance(param1, Dataset)
362
+ or isinstance(param2, Dataset)
363
+ or isinstance(param3, Dataset)
364
+ ):
324
365
  raise SemanticError("1-1-18-10", op=cls.op)
325
366
  if param1 is not None:
326
367
  cls.check_param(param1, 1)
@@ -332,30 +373,33 @@ class Instr(Parameterized):
332
373
  return super().validate(operand)
333
374
 
334
375
  @classmethod
335
- def validate_params(cls, params: Optional[Any]):
376
+ def validate_params(cls, params: Any) -> None:
336
377
  if len(params) != 2:
337
378
  raise SemanticError("1-1-18-7", op=cls.op, number=len(params), expected=2)
338
379
 
339
380
  @classmethod
340
- def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int):
381
+ def check_param(cls, param: Optional[Union[DataComponent, Scalar]], position: int) -> None:
341
382
  if not param:
342
383
  return
343
384
  if position not in (1, 2, 3):
344
385
  raise SemanticError("1-1-18-9", op=cls.op)
345
- data_type: ScalarType = param.data_type
386
+ data_type: Any = param.data_type
346
387
 
347
388
  if position == 1:
348
389
  if not check_unary_implicit_promotion(data_type, String):
349
- raise SemanticError("1-1-18-4", op=cls.op, param_type="Pattern",
350
- correct_type="String")
390
+ raise SemanticError(
391
+ "1-1-18-4", op=cls.op, param_type="Pattern", correct_type="String"
392
+ )
351
393
  elif position == 2:
352
394
  if not check_unary_implicit_promotion(data_type, Integer):
353
- raise SemanticError("1-1-18-4", op=cls.op, param_type="Start",
354
- correct_type="Integer")
395
+ raise SemanticError(
396
+ "1-1-18-4", op=cls.op, param_type="Start", correct_type="Integer"
397
+ )
355
398
  else:
356
399
  if not check_unary_implicit_promotion(data_type, Integer):
357
- raise SemanticError("1-1-18-4", op=cls.op, param_type="Occurrence",
358
- correct_type="Integer")
400
+ raise SemanticError(
401
+ "1-1-18-4", op=cls.op, param_type="Occurrence", correct_type="Integer"
402
+ )
359
403
  if isinstance(param, DataComponent):
360
404
  if param.data is not None:
361
405
  param.data.map(lambda x: cls.check_param_value(x, position))
@@ -363,53 +407,58 @@ class Instr(Parameterized):
363
407
  cls.check_param_value(param.value, position)
364
408
 
365
409
  @classmethod
366
- def check_param_value(cls, param: Optional[Union[int, str]], position: int):
410
+ def check_param_value(cls, param: Any, position: int) -> None:
367
411
  if position == 2:
368
412
  if not pd.isnull(param) and param < 1:
369
413
  raise SemanticError("1-1-18-4", op=cls.op, param_type="Start", correct_type=">= 1")
370
414
  elif position == 3:
371
415
  if not pd.isnull(param) and param < 1:
372
- raise SemanticError("1-1-18-4", op=cls.op, param_type="Occurrence",
373
- correct_type=">= 1")
416
+ raise SemanticError(
417
+ "1-1-18-4", op=cls.op, param_type="Occurrence", correct_type=">= 1"
418
+ )
374
419
 
375
420
  @classmethod
376
- def apply_operation_series_scalar(cls, series: pd.Series, param1: Any, param2: Any,
377
- param3: Any) -> Any:
421
+ def apply_operation_series_scalar(
422
+ cls, series: Any, param1: Any, param2: Any, param3: Any
423
+ ) -> Any:
378
424
  return series.map(lambda x: cls.op_func(x, param1, param2, param3))
379
425
 
380
426
  @classmethod
381
- def apply_operation_series(cls,
382
- data: pd.Series,
383
- param1: Optional[Union[DataComponent, Scalar]],
384
- param2: Optional[Union[DataComponent, Scalar]],
385
- param3: Optional[Union[DataComponent, Scalar]],
386
- ):
427
+ def apply_operation_series(
428
+ cls,
429
+ data: Any,
430
+ param1: Optional[Union[DataComponent, Scalar]],
431
+ param2: Optional[Union[DataComponent, Scalar]],
432
+ param3: Optional[Union[DataComponent, Scalar]],
433
+ ) -> Any:
387
434
  param1_data = cls.generate_series_from_param(param1, len(data))
388
435
  param2_data = cls.generate_series_from_param(param2, len(data))
389
436
  param3_data = cls.generate_series_from_param(param3, len(data))
390
437
 
391
- df = pd.DataFrame([
392
- data,
393
- param1_data,
394
- param2_data,
395
- param3_data
396
- ]).T
438
+ df = pd.DataFrame([data, param1_data, param2_data, param3_data]).T
397
439
  n1, n2, n3, n4 = df.columns
398
440
  return df.apply(lambda x: cls.op_func(x[n1], x[n2], x[n3], x[n4]), axis=1)
399
441
 
400
442
  @classmethod
401
- def dataset_evaluation(cls, operand: Dataset,
402
- param1: Optional[Union[DataComponent, Scalar]],
403
- param2: Optional[Union[DataComponent, Scalar]],
404
- param3: Optional[Union[DataComponent, Scalar]]):
443
+ def dataset_evaluation( # type: ignore[override]
444
+ cls,
445
+ operand: Dataset,
446
+ param1: Optional[Union[DataComponent, Scalar]],
447
+ param2: Optional[Union[DataComponent, Scalar]],
448
+ param3: Optional[Union[DataComponent, Scalar]],
449
+ ) -> Dataset:
405
450
  result = cls.validate(operand, param1, param2, param3)
406
- result.data = operand.data.copy()
451
+ result.data = operand.data.copy() if operand.data is not None else pd.DataFrame()
407
452
  for measure_name in operand.get_measures_names():
408
- if isinstance(param1, DataComponent) or isinstance(param2, DataComponent) or isinstance(
409
- param3,
410
- DataComponent):
411
- result.data[measure_name] = cls.apply_operation_series(operand.data[measure_name],
412
- param1, param2, param3)
453
+ if (
454
+ isinstance(param1, DataComponent)
455
+ or isinstance(param2, DataComponent)
456
+ or isinstance(param3, DataComponent)
457
+ ):
458
+ if operand.data is not None:
459
+ result.data[measure_name] = cls.apply_operation_series(
460
+ operand.data[measure_name], param1, param2, param3
461
+ )
413
462
  else:
414
463
  param_value1 = None if param1 is None else param1.value
415
464
  param_value2 = None if param2 is None else param2.value
@@ -423,28 +472,38 @@ class Instr(Parameterized):
423
472
  return result
424
473
 
425
474
  @classmethod
426
- def component_evaluation(cls, operand: DataComponent,
427
- param1: Optional[Union[DataComponent, Scalar]],
428
- param2: Optional[Union[DataComponent, Scalar]],
429
- param3: Optional[Union[DataComponent, Scalar]]):
475
+ def component_evaluation( # type: ignore[override]
476
+ cls,
477
+ operand: DataComponent,
478
+ param1: Optional[Union[DataComponent, Scalar]],
479
+ param2: Optional[Union[DataComponent, Scalar]],
480
+ param3: Optional[Union[DataComponent, Scalar]],
481
+ ) -> DataComponent:
430
482
  result = cls.validate(operand, param1, param2, param3)
431
- result.data = operand.data.copy()
432
- if isinstance(param1, DataComponent) or isinstance(param2, DataComponent) or isinstance(
433
- param3, DataComponent):
483
+ result.data = operand.data.copy() if operand.data is not None else pd.Series()
484
+ if (
485
+ isinstance(param1, DataComponent)
486
+ or isinstance(param2, DataComponent)
487
+ or isinstance(param3, DataComponent)
488
+ ):
434
489
  result.data = cls.apply_operation_series(operand.data, param1, param2, param3)
435
490
  else:
436
491
  param_value1 = None if param1 is None else param1.value
437
492
  param_value2 = None if param2 is None else param2.value
438
493
  param_value3 = None if param3 is None else param3.value
439
- result.data = cls.apply_operation_series_scalar(operand.data, param_value1,
440
- param_value2, param_value3)
494
+ result.data = cls.apply_operation_series_scalar(
495
+ operand.data, param_value1, param_value2, param_value3
496
+ )
441
497
  return result
442
498
 
443
499
  @classmethod
444
- def scalar_evaluation(cls, operand: Scalar,
445
- param1: Optional[Union[DataComponent, Scalar]],
446
- param2: Optional[Union[DataComponent, Scalar]],
447
- param3: Optional[Union[DataComponent, Scalar]]):
500
+ def scalar_evaluation( # type: ignore[override]
501
+ cls,
502
+ operand: Scalar,
503
+ param1: Optional[Scalar],
504
+ param2: Optional[Scalar],
505
+ param3: Optional[Scalar],
506
+ ) -> Scalar:
448
507
  result = cls.validate(operand, param1, param2, param3)
449
508
  param_value1 = None if param1 is None else param1.value
450
509
  param_value2 = None if param2 is None else param2.value
@@ -453,11 +512,13 @@ class Instr(Parameterized):
453
512
  return result
454
513
 
455
514
  @classmethod
456
- def evaluate(cls, operand: Operator.ALL_MODEL_DATA_TYPES,
457
- param1: Optional[Union[DataComponent, Scalar]] = None,
458
- param2: Optional[Union[DataComponent, Scalar]] = None,
459
- param3: Optional[
460
- Union[DataComponent, Scalar]] = None) -> Operator.ALL_MODEL_DATA_TYPES:
515
+ def evaluate(
516
+ cls,
517
+ operand: Operator.ALL_MODEL_DATA_TYPES,
518
+ param1: Optional[Any] = None,
519
+ param2: Optional[Any] = None,
520
+ param3: Optional[Any] = None,
521
+ ) -> Any:
461
522
  if isinstance(operand, Dataset):
462
523
  return cls.dataset_evaluation(operand, param1, param2, param3)
463
524
  if isinstance(operand, DataComponent):
@@ -466,33 +527,46 @@ class Instr(Parameterized):
466
527
  return cls.scalar_evaluation(operand, param1, param2, param3)
467
528
 
468
529
  @classmethod
469
- def op_func(cls, x: str, param1: Optional[Any], param2: Optional[Any],
470
- param3: Optional[Any]) -> Any:
530
+ def op_func( # type: ignore[override]
531
+ cls,
532
+ x: Any,
533
+ param1: Optional[Any],
534
+ param2: Optional[Any],
535
+ param3: Optional[Any],
536
+ ) -> Any:
537
+
471
538
  if pd.isnull(x):
472
539
  return None
473
540
  return cls.py_op(x, param1, param2, param3)
474
541
 
475
542
  @classmethod
476
- def py_op(cls, str_value: str, str_to_find: Optional[str], start: Optional[int],
477
- occurrence: Optional[int]) -> Any:
543
+ def py_op(
544
+ cls,
545
+ str_value: str,
546
+ str_to_find: Optional[str],
547
+ start: Optional[int],
548
+ occurrence: Optional[int],
549
+ ) -> Any:
478
550
  str_value = str(str_value)
479
551
  if not pd.isnull(start):
480
- if isinstance(start, int) or start.is_integer():
552
+ if isinstance(start, int) or isinstance(start, float):
481
553
  start = int(start - 1)
482
554
  else:
483
555
  # OPERATORS_STRINGOPERATORS.92
484
- raise SemanticError("1-1-18-4", op=cls.op, param_type="Start",
485
- correct_type="Integer")
556
+ raise SemanticError(
557
+ "1-1-18-4", op=cls.op, param_type="Start", correct_type="Integer"
558
+ )
486
559
  else:
487
560
  start = 0
488
561
 
489
562
  if not pd.isnull(occurrence):
490
- if isinstance(occurrence, int) or occurrence.is_integer():
563
+ if isinstance(occurrence, int) or isinstance(occurrence, float):
491
564
  occurrence = int(occurrence - 1)
492
565
  else:
493
566
  # OPERATORS_STRINGOPERATORS.93
494
- raise SemanticError("1-1-18-4", op=cls.op, param_type="Occurrence",
495
- correct_type="Integer")
567
+ raise SemanticError(
568
+ "1-1-18-4", op=cls.op, param_type="Occurrence", correct_type="Integer"
569
+ )
496
570
  else:
497
571
  occurrence = 0
498
572
  if pd.isnull(str_to_find):