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
@@ -8,150 +8,162 @@ Vtl Token centralized.
8
8
  """
9
9
 
10
10
  # General
11
- PASSIGN = '<-'
12
- ASSIGN = ':='
13
- MEMBERSHIP = '#'
14
- LPAREN = '('
15
- RLPAREN = ')'
16
- COMMA = ','
17
- COLON = ':'
18
- SCOLON = ';'
11
+ PASSIGN = "<-"
12
+ ASSIGN = ":="
13
+ MEMBERSHIP = "#"
14
+ LPAREN = "("
15
+ RLPAREN = ")"
16
+ COMMA = ","
17
+ COLON = ":"
18
+ SCOLON = ";"
19
19
  # Numeric operators.
20
- PLUS = '+'
21
- MINUS = '-'
22
- MULT = '*'
23
- DIV = '/'
24
- MOD = 'mod'
25
- ROUND = 'round'
26
- TRUNC = 'trunc'
27
- CEIL = 'ceil'
28
- FLOOR = 'floor'
29
- ABS = 'abs'
30
- EXP = 'exp'
31
- LN = 'ln'
32
- POWER = 'power'
33
- LOG = 'log'
34
- SQRT = 'sqrt'
20
+ PLUS = "+"
21
+ MINUS = "-"
22
+ MULT = "*"
23
+ DIV = "/"
24
+ MOD = "mod"
25
+ ROUND = "round"
26
+ TRUNC = "trunc"
27
+ CEIL = "ceil"
28
+ FLOOR = "floor"
29
+ ABS = "abs"
30
+ EXP = "exp"
31
+ LN = "ln"
32
+ POWER = "power"
33
+ LOG = "log"
34
+ SQRT = "sqrt"
35
+ RANDOM = "random"
35
36
  # Boolean operators.
36
- AND = 'and'
37
- OR = 'or'
38
- XOR = 'xor'
39
- NOT = 'not'
37
+ AND = "and"
38
+ OR = "or"
39
+ XOR = "xor"
40
+ NOT = "not"
40
41
  # Comparison operators.
41
- EQ = '='
42
- NEQ = '<>'
43
- GT = '>'
44
- GTE = '>='
45
- LT = '<'
46
- LTE = '<='
47
- BETWEEN = 'between'
48
- IN = 'in'
49
- NOT_IN = 'not_in'
50
- CHARSET_MATCH = 'match_characters'
51
- ISNULL = 'isnull'
52
- EXISTS_IN = 'exists_in'
42
+ EQ = "="
43
+ NEQ = "<>"
44
+ GT = ">"
45
+ GTE = ">="
46
+ LT = "<"
47
+ LTE = "<="
48
+ BETWEEN = "between"
49
+ IN = "in"
50
+ NOT_IN = "not_in"
51
+ CHARSET_MATCH = "match_characters"
52
+ ISNULL = "isnull"
53
+ EXISTS_IN = "exists_in"
53
54
  # String operators.
54
- CONCAT = '||'
55
- TRIM = 'trim'
56
- RTRIM = 'rtrim'
57
- LTRIM = 'ltrim'
58
- UCASE = 'upper'
59
- LCASE = 'lower'
60
- SUBSTR = 'substr'
61
- REPLACE = 'replace'
62
- INSTR = 'instr'
63
- LEN = 'length'
55
+ CONCAT = "||"
56
+ TRIM = "trim"
57
+ RTRIM = "rtrim"
58
+ LTRIM = "ltrim"
59
+ UCASE = "upper"
60
+ LCASE = "lower"
61
+ SUBSTR = "substr"
62
+ REPLACE = "replace"
63
+ INSTR = "instr"
64
+ LEN = "length"
64
65
  # Set operators.
65
- UNION = 'union'
66
- INTERSECT = 'intersect'
67
- SETDIFF = 'setdiff'
68
- SYMDIFF = 'symdiff'
66
+ UNION = "union"
67
+ INTERSECT = "intersect"
68
+ SETDIFF = "setdiff"
69
+ SYMDIFF = "symdiff"
69
70
  # Conditional Operators.
70
- IF = 'if'
71
- THEN = 'then'
72
- ELSE = 'else'
73
- NVL = 'nvl'
71
+ IF = "if"
72
+ THEN = "then"
73
+ ELSE = "else"
74
+ CASE = "case"
75
+ NVL = "nvl"
74
76
  # Clause Operators.
75
- FILTER = 'filter'
76
- CALC = 'calc'
77
- AGGREGATE = 'aggr'
78
- KEEP = 'keep'
79
- DROP = 'drop'
80
- RENAME = 'rename'
81
- PIVOT = 'pivot'
82
- UNPIVOT = 'unpivot'
83
- SUBSPACE = 'sub'
77
+ FILTER = "filter"
78
+ CALC = "calc"
79
+ AGGREGATE = "aggr"
80
+ KEEP = "keep"
81
+ DROP = "drop"
82
+ RENAME = "rename"
83
+ PIVOT = "pivot"
84
+ UNPIVOT = "unpivot"
85
+ SUBSPACE = "sub"
84
86
  # Time Operators.
85
- PERIOD_INDICATOR = 'period_indicator'
86
- FILL_TIME_SERIES = 'fill_time_series'
87
- FLOW_TO_STOCK = 'flow_to_stock'
88
- STOCK_TO_FLOW = 'stock_to_flow'
89
- TIMESHIFT = 'timeshift'
90
- TIME_AGG = 'time_agg'
91
- CURRENT_DATE = 'current_date'
87
+ PERIOD_INDICATOR = "period_indicator"
88
+ FILL_TIME_SERIES = "fill_time_series"
89
+ FLOW_TO_STOCK = "flow_to_stock"
90
+ STOCK_TO_FLOW = "stock_to_flow"
91
+ TIMESHIFT = "timeshift"
92
+ TIME_AGG = "time_agg"
93
+ CURRENT_DATE = "current_date"
94
+ DATE_DIFF = "date_diff"
95
+ DATE_ADD = "date_add"
96
+ YEAR = "year"
97
+ MONTH = "month"
98
+ DAYOFMONTH = "dayofmonth"
99
+ DAYOFYEAR = "dayofyear"
100
+ DAYTOYEAR = "daytoyear"
101
+ DAYTOMONTH = "daytomonth"
102
+ YEARTODAY = "yeartoday"
103
+ MONTHTODAY = "monthtoday"
92
104
  # Join Operators.
93
- INNER_JOIN = 'inner_join'
94
- LEFT_JOIN = 'left_join'
95
- CROSS_JOIN = 'cross_join'
96
- FULL_JOIN = 'full_join'
105
+ INNER_JOIN = "inner_join"
106
+ LEFT_JOIN = "left_join"
107
+ CROSS_JOIN = "cross_join"
108
+ FULL_JOIN = "full_join"
97
109
  # Hierarchical aggregation.
98
- HIERARCHY = 'hierarchy'
110
+ HIERARCHY = "hierarchy"
99
111
  # Aggregate and analytic Operators.
100
- COUNT = 'count'
101
- MIN = 'min'
102
- MAX = 'max'
103
- MEDIAN = 'median'
104
- SUM = 'sum'
105
- AVG = 'avg'
106
- STDDEV_POP = 'stddev_pop'
107
- STDDEV_SAMP = 'stddev_samp'
108
- VAR_POP = 'var_pop'
109
- VAR_SAMP = 'var_samp'
110
- FIRST_VALUE = 'first_value'
111
- LAST_VALUE = 'last_value'
112
- LAG = 'lag'
113
- LEAD = 'lead'
114
- RANK = 'rank'
115
- RATIO_TO_REPORT = 'ratio_to_report'
112
+ COUNT = "count"
113
+ MIN = "min"
114
+ MAX = "max"
115
+ MEDIAN = "median"
116
+ SUM = "sum"
117
+ AVG = "avg"
118
+ STDDEV_POP = "stddev_pop"
119
+ STDDEV_SAMP = "stddev_samp"
120
+ VAR_POP = "var_pop"
121
+ VAR_SAMP = "var_samp"
122
+ FIRST_VALUE = "first_value"
123
+ LAST_VALUE = "last_value"
124
+ LAG = "lag"
125
+ LEAD = "lead"
126
+ RANK = "rank"
127
+ RATIO_TO_REPORT = "ratio_to_report"
116
128
  # Data validation Operators.
117
- CHECK_DATAPOINT = 'check_datapoint'
118
- CHECK_HIERARCHY = 'check_hierarchy'
119
- CHECK = 'check'
129
+ CHECK_DATAPOINT = "check_datapoint"
130
+ CHECK_HIERARCHY = "check_hierarchy"
131
+ CHECK = "check"
120
132
  # Role Operators.
121
- IDENTIFIER = 'identifier'
122
- MEASURE = 'measure'
123
- ATTRIBUTE = 'attribute'
124
- VIRAL_ATTRIBUTE = 'viral'
133
+ IDENTIFIER = "identifier"
134
+ MEASURE = "measure"
135
+ ATTRIBUTE = "attribute"
136
+ VIRAL_ATTRIBUTE = "viral"
125
137
  # Other Operators.
126
- TO = 'to'
127
- AS = 'as'
128
- USING = 'using'
129
- OPTIONAL = '_'
130
- HAVING = 'having'
131
- WHEN = 'when'
138
+ TO = "to"
139
+ AS = "as"
140
+ USING = "using"
141
+ OPTIONAL = "_"
142
+ HAVING = "having"
143
+ WHEN = "when"
132
144
  # Helping Tokens
133
- GROUP_BY = 'group by'
134
- GROUP_EXCEPT = 'group except'
135
- GROUP_ALL = 'group all'
136
- CAST = 'cast'
137
- INVALID = 'invalid'
138
- ALL = 'all'
139
- ALL_MEASURES = 'all_measures'
140
- COMPUTED = 'computed'
141
- DATASET = 'dataset'
142
- DATASET_PRIORITY = 'dataset_priority'
143
- RULE = 'rule'
144
- RULE_PRIORITY = 'rule_priority'
145
- NON_NULL = 'non_null'
146
- NON_ZERO = 'non_zero'
147
- PARTIAL_NULL = 'partial_null'
148
- PARTIAL_ZERO = 'partial_zero'
149
- ALWAYS_NULL = 'always_null'
150
- ALWAYS_ZERO = 'always_zero'
151
- APPLY = 'apply'
145
+ GROUP_BY = "group by"
146
+ GROUP_EXCEPT = "group except"
147
+ GROUP_ALL = "group all"
148
+ CAST = "cast"
149
+ INVALID = "invalid"
150
+ ALL = "all"
151
+ ALL_MEASURES = "all_measures"
152
+ COMPUTED = "computed"
153
+ DATASET = "dataset"
154
+ DATASET_PRIORITY = "dataset_priority"
155
+ RULE = "rule"
156
+ RULE_PRIORITY = "rule_priority"
157
+ NON_NULL = "non_null"
158
+ NON_ZERO = "non_zero"
159
+ PARTIAL_NULL = "partial_null"
160
+ PARTIAL_ZERO = "partial_zero"
161
+ ALWAYS_NULL = "always_null"
162
+ ALWAYS_ZERO = "always_zero"
163
+ APPLY = "apply"
152
164
  # Defined operators.
153
- OPERATOR = 'operator'
154
- EVAL = 'eval'
165
+ OPERATOR = "operator"
166
+ EVAL = "eval"
155
167
  # External.
156
168
  SQLITE = '"sqlite"'
157
169
  EXTERNAL = [SQLITE]
@@ -5,6 +5,7 @@ from vtlengine.AST.Grammar.parser import Parser
5
5
 
6
6
  # This class defines a complete generic visitor for a parse tree produced by Parser.
7
7
 
8
+
8
9
  class VtlVisitor(ParseTreeVisitor):
9
10
 
10
11
  # Visit a parse tree produced by Parser#start.
@@ -61,6 +62,10 @@ class VtlVisitor(ParseTreeVisitor):
61
62
  def visitIfExpr(self, ctx: Parser.IfExprContext):
62
63
  return self.visitChildren(ctx)
63
64
 
65
+ # Visit a parse tree produced by Parser#caseExpr.
66
+ def visitCaseExpr(self, ctx: Parser.CaseExprContext):
67
+ return self.visitChildren(ctx)
68
+
64
69
  # Visit a parse tree produced by Parser#clauseExpr.
65
70
  def visitClauseExpr(self, ctx: Parser.ClauseExprContext):
66
71
  return self.visitChildren(ctx)
@@ -89,6 +94,10 @@ class VtlVisitor(ParseTreeVisitor):
89
94
  def visitIfExprComp(self, ctx: Parser.IfExprCompContext):
90
95
  return self.visitChildren(ctx)
91
96
 
97
+ # Visit a parse tree produced by Parser#caseExprComp.
98
+ def visitCaseExprComp(self, ctx: Parser.CaseExprCompContext):
99
+ return self.visitChildren(ctx)
100
+
92
101
  # Visit a parse tree produced by Parser#comparisonExprComp.
93
102
  def visitComparisonExprComp(self, ctx: Parser.ComparisonExprCompContext):
94
103
  return self.visitChildren(ctx)
@@ -146,8 +155,9 @@ class VtlVisitor(ParseTreeVisitor):
146
155
  return self.visitChildren(ctx)
147
156
 
148
157
  # Visit a parse tree produced by Parser#conditionalFunctionsComponents.
149
- def visitConditionalFunctionsComponents(self,
150
- ctx: Parser.ConditionalFunctionsComponentsContext):
158
+ def visitConditionalFunctionsComponents(
159
+ self, ctx: Parser.ConditionalFunctionsComponentsContext
160
+ ):
151
161
  return self.visitChildren(ctx)
152
162
 
153
163
  # Visit a parse tree produced by Parser#aggregateFunctionsComponents.
@@ -335,8 +345,9 @@ class VtlVisitor(ParseTreeVisitor):
335
345
  return self.visitChildren(ctx)
336
346
 
337
347
  # Visit a parse tree produced by Parser#unaryWithOptionalNumericComponent.
338
- def visitUnaryWithOptionalNumericComponent(self,
339
- ctx: Parser.UnaryWithOptionalNumericComponentContext):
348
+ def visitUnaryWithOptionalNumericComponent(
349
+ self, ctx: Parser.UnaryWithOptionalNumericComponentContext
350
+ ):
340
351
  return self.visitChildren(ctx)
341
352
 
342
353
  # Visit a parse tree produced by Parser#binaryNumericComponent.
@@ -396,7 +407,7 @@ class VtlVisitor(ParseTreeVisitor):
396
407
  return self.visitChildren(ctx)
397
408
 
398
409
  # Visit a parse tree produced by Parser#periodAtomComponent.
399
- def visitPeriodAtomComponent(self, ctx: Parser.PeriodAtomComponentContext):
410
+ def visitTimeUnaryAtomComponent(self, ctx: Parser.PeriodAtomComponentContext):
400
411
  return self.visitChildren(ctx)
401
412
 
402
413
  # Visit a parse tree produced by Parser#fillTimeAtomComponent.
vtlengine/AST/__init__.py CHANGED
@@ -6,6 +6,7 @@ Description
6
6
  -----------
7
7
  Basic AST nodes.
8
8
  """
9
+
9
10
  from dataclasses import dataclass
10
11
  from typing import Any, Dict, List, Optional, Type, Union
11
12
 
@@ -39,9 +40,7 @@ class AST:
39
40
  return f"<{name}({', '.join(out)})>"
40
41
 
41
42
  def toJSON(self):
42
- base = {
43
- 'class_name': self.__class__.__name__
44
- }
43
+ base = {"class_name": self.__class__.__name__}
45
44
  for k in self.__all_annotations().keys():
46
45
  v = self.__getattribute__(k)
47
46
  base[k] = v
@@ -75,6 +74,7 @@ class PersistentAssignment(Assignment):
75
74
  """
76
75
  PersistentAssignment: (left, op, right)
77
76
  """
77
+
78
78
  pass
79
79
 
80
80
 
@@ -85,6 +85,7 @@ class VarID(AST):
85
85
  The Var node is constructed out of ID token.
86
86
  Could be: DATASET or a COMPONENT.
87
87
  """
88
+
88
89
  value: Any
89
90
 
90
91
 
@@ -105,7 +106,8 @@ class UnaryOp(AST):
105
106
  class BinOp(AST):
106
107
  """
107
108
  BinOp: (left, op, right)
108
- op types: "+", "-", "*", "/",MOD, MEMBERSHIP, PIVOT, UNPIVOT, LOG, POWER, CHARSET_MATCH, NVL, MOD
109
+ op types: "+", "-", "*", "/",MOD, MEMBERSHIP, PIVOT, UNPIVOT, LOG,
110
+ POWER, CHARSET_MATCH, NVL, MOD
109
111
  """
110
112
 
111
113
  left: AST
@@ -217,7 +219,7 @@ class Collection(AST):
217
219
  name: str
218
220
  type: str
219
221
  children: List[AST]
220
- kind: str = 'Set'
222
+ kind: str = "Set"
221
223
 
222
224
 
223
225
  @dataclass
@@ -233,9 +235,9 @@ class Windowing(AST):
233
235
  """
234
236
 
235
237
  type_: str
236
- start: int
238
+ start: str
237
239
  start_mode: str
238
- stop: int
240
+ stop: Union[int, str]
239
241
  stop_mode: str
240
242
 
241
243
 
@@ -245,7 +247,7 @@ class OrderBy(AST):
245
247
  order: str
246
248
 
247
249
  def __post_init__(self):
248
- if self.order not in ['asc', 'desc']:
250
+ if self.order not in ["asc", "desc"]:
249
251
  raise ValueError(f"Invalid order: {self.order}")
250
252
 
251
253
 
@@ -254,13 +256,14 @@ class Analytic(AST):
254
256
  """
255
257
  Analytic: (op, operand, partition_by, order_by, params)
256
258
 
257
- op: SUM, AVG, COUNT, MEDIAN, MIN, MAX, STDDEV_POP, STDDEV_SAMP, VAR_POP, VAR_SAMP, FIRST_VALUE, LAST_VALUE, LAG,
258
- LEAD, RATIO_TO_REPORT
259
+ op: SUM, AVG, COUNT, MEDIAN, MIN, MAX, STDDEV_POP, STDDEV_SAMP, VAR_POP, VAR_SAMP,
260
+ FIRST_VALUE, LAST_VALUE, LAG, LEAD, RATIO_TO_REPORT
259
261
 
260
262
  partition_by: List of components.
261
263
  order_by: List of components + mode (ASC, DESC).
262
264
  params: Windowing clause (no need to validate them) or Scalar Item in LAG/LEAD.
263
265
  """
266
+
264
267
  op: str
265
268
  operand: Optional[AST]
266
269
  window: Optional[Windowing] = None
@@ -307,6 +310,7 @@ class Aggregation(AST):
307
310
 
308
311
  grouping types: 'group by', 'group except', 'group all'.
309
312
  """
313
+
310
314
  op: str
311
315
  operand: Optional[AST] = None
312
316
  grouping_op: Optional[str] = None
@@ -334,11 +338,31 @@ class If(AST):
334
338
  """
335
339
  If: (condition, thenOp, elseOp)
336
340
  """
341
+
337
342
  condition: AST
338
343
  thenOp: AST
339
344
  elseOp: AST
340
345
 
341
346
 
347
+ class CaseObj:
348
+ condition: AST
349
+ thenOp: AST
350
+
351
+ def __init__(self, condition: AST, thenOp: AST):
352
+ self.condition = condition
353
+ self.thenOp = thenOp
354
+
355
+
356
+ @dataclass
357
+ class Case(AST):
358
+ """
359
+ Case: (condition, thenOp, elseOp)
360
+ """
361
+
362
+ cases: List[CaseObj]
363
+ elseOp: AST
364
+
365
+
342
366
  @dataclass
343
367
  class Validation(AST):
344
368
  """
@@ -358,6 +382,7 @@ class ComponentType(AST):
358
382
  """
359
383
  ComponentType: (data_type, role)
360
384
  """
385
+
361
386
  name: str
362
387
  data_type: Optional[Type[ScalarType]] = None
363
388
  role: Optional[Role] = None
@@ -400,8 +425,9 @@ class Argument(AST):
400
425
  """
401
426
  Argument: (name, type_, default)
402
427
  """
428
+
403
429
  name: str
404
- type_: ScalarType
430
+ type_: Type[ScalarType]
405
431
  default: Optional[AST]
406
432
 
407
433
 
@@ -423,6 +449,7 @@ class DefIdentifier(AST):
423
449
  """
424
450
  DefIdentifier: (value, kind)
425
451
  """
452
+
426
453
  value: str
427
454
  kind: str
428
455
 
@@ -432,6 +459,7 @@ class DPRIdentifier(AST):
432
459
  """
433
460
  DefIdentifier: (value, kind, alias)
434
461
  """
462
+
435
463
  value: str
436
464
  kind: str
437
465
  alias: Optional[str] = None
@@ -444,6 +472,7 @@ class HRBinOp(AST):
444
472
  HRBinOp: (left, op, right)
445
473
  op types: '+','-', '=', '>', '<', '>=', '<='.
446
474
  """
475
+
447
476
  left: DefIdentifier
448
477
  op: str
449
478
  right: DefIdentifier
@@ -529,4 +558,5 @@ class NoOp(AST):
529
558
  """
530
559
  NoOp: ()
531
560
  """
561
+
532
562
  pass
@@ -1,8 +1,9 @@
1
1
  import operator
2
2
  from decimal import Decimal
3
+ from typing import Union
3
4
 
4
5
 
5
- def decimal_add(a, b):
6
+ def decimal_add(a: Union[float, int], b: Union[float, int]) -> float:
6
7
  """
7
8
  Adds two numbers, if they are floats, converts them to Decimal and then to float
8
9
  :param a: first number
@@ -16,21 +17,21 @@ def decimal_add(a, b):
16
17
  return operator.add(a, b)
17
18
 
18
19
 
19
- def decimal_sub(a, b):
20
+ def decimal_sub(a: Union[float, int], b: Union[float, int]) -> float:
20
21
  if isinstance(a, float) and isinstance(b, float):
21
22
  decimal_value = Decimal(a) - Decimal(b)
22
23
  return float(decimal_value)
23
24
  return operator.sub(a, b)
24
25
 
25
26
 
26
- def decimal_mul(a, b):
27
+ def decimal_mul(a: Union[float, int], b: Union[float, int]) -> float:
27
28
  if isinstance(a, float) and isinstance(b, float):
28
29
  decimal_value = Decimal(a) * Decimal(b)
29
30
  return float(decimal_value)
30
31
  return operator.mul(a, b)
31
32
 
32
33
 
33
- def decimal_div(a, b):
34
+ def decimal_div(a: Union[float, int], b: Union[float, int]) -> float:
34
35
  if isinstance(a, float) and isinstance(b, float):
35
36
  decimal_value = Decimal(a) / Decimal(b)
36
37
  return float(decimal_value)