vtlengine 1.0.2__py3-none-any.whl → 1.0.3__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 (46) hide show
  1. vtlengine/API/_InternalApi.py +12 -5
  2. vtlengine/API/__init__.py +8 -8
  3. vtlengine/AST/ASTConstructor.py +23 -43
  4. vtlengine/AST/ASTConstructorModules/Expr.py +69 -84
  5. vtlengine/AST/ASTConstructorModules/ExprComponents.py +47 -57
  6. vtlengine/AST/ASTConstructorModules/Terminals.py +28 -39
  7. vtlengine/AST/ASTTemplate.py +0 -1
  8. vtlengine/AST/DAG/__init__.py +12 -15
  9. vtlengine/AST/Grammar/tokens.py +2 -2
  10. vtlengine/AST/VtlVisitor.py +0 -1
  11. vtlengine/AST/__init__.py +2 -3
  12. vtlengine/DataTypes/TimeHandling.py +10 -7
  13. vtlengine/DataTypes/__init__.py +17 -24
  14. vtlengine/Exceptions/__init__.py +3 -5
  15. vtlengine/Exceptions/messages.py +68 -56
  16. vtlengine/Interpreter/__init__.py +82 -103
  17. vtlengine/Model/__init__.py +10 -12
  18. vtlengine/Operators/Aggregation.py +14 -14
  19. vtlengine/Operators/Analytic.py +3 -10
  20. vtlengine/Operators/Assignment.py +2 -3
  21. vtlengine/Operators/Boolean.py +5 -7
  22. vtlengine/Operators/CastOperator.py +12 -13
  23. vtlengine/Operators/Clause.py +11 -13
  24. vtlengine/Operators/Comparison.py +31 -17
  25. vtlengine/Operators/Conditional.py +48 -49
  26. vtlengine/Operators/General.py +4 -4
  27. vtlengine/Operators/HROperators.py +41 -34
  28. vtlengine/Operators/Join.py +18 -22
  29. vtlengine/Operators/Numeric.py +44 -45
  30. vtlengine/Operators/RoleSetter.py +6 -8
  31. vtlengine/Operators/Set.py +7 -12
  32. vtlengine/Operators/String.py +19 -27
  33. vtlengine/Operators/Time.py +298 -109
  34. vtlengine/Operators/Validation.py +4 -7
  35. vtlengine/Operators/__init__.py +38 -41
  36. vtlengine/Utils/__init__.py +133 -114
  37. vtlengine/__init__.py +1 -1
  38. vtlengine/files/output/__init__.py +2 -2
  39. vtlengine/files/output/_time_period_representation.py +0 -1
  40. vtlengine/files/parser/__init__.py +16 -18
  41. vtlengine/files/parser/_time_checking.py +1 -2
  42. {vtlengine-1.0.2.dist-info → vtlengine-1.0.3.dist-info}/METADATA +5 -2
  43. vtlengine-1.0.3.dist-info/RECORD +58 -0
  44. vtlengine-1.0.2.dist-info/RECORD +0 -58
  45. {vtlengine-1.0.2.dist-info → vtlengine-1.0.3.dist-info}/LICENSE.md +0 -0
  46. {vtlengine-1.0.2.dist-info → vtlengine-1.0.3.dist-info}/WHEEL +0 -0
@@ -1,23 +1,23 @@
1
1
  from antlr4.tree.Tree import TerminalNodeImpl
2
2
 
3
3
  from vtlengine.AST import (
4
+ ID,
4
5
  Aggregation,
5
- If,
6
+ Analytic,
6
7
  BinOp,
7
- UnaryOp,
8
- ID,
9
- ParamOp,
10
- MulOp,
8
+ Case,
9
+ CaseObj,
11
10
  Constant,
11
+ EvalOp,
12
+ Identifier,
13
+ If,
14
+ MulOp,
12
15
  ParamConstant,
16
+ ParamOp,
13
17
  TimeAggregation,
14
- Identifier,
15
- EvalOp,
16
- VarID,
17
- Analytic,
18
18
  UDOCall,
19
- Case,
20
- CaseObj,
19
+ UnaryOp,
20
+ VarID,
21
21
  )
22
22
  from vtlengine.AST.ASTConstructorModules.Terminals import Terminals
23
23
  from vtlengine.AST.Grammar.parser import Parser
@@ -36,20 +36,20 @@ class ExprComp(VtlVisitor):
36
36
  def visitExprComponent(self, ctx: Parser.ExprComponentContext):
37
37
  """
38
38
  exprComponent:
39
- LPAREN exprComponent RPAREN # parenthesisExprComp # noqa E501
40
- | functionsComponents # functionsExpressionComp # noqa E501
41
- | op=(PLUS|MINUS|NOT) right=exprComponent # unaryExprComp # noqa E501
42
- | left=exprComponent op=(MUL|DIV) right=exprComponent # arithmeticExprComp # noqa E501
43
- | left=exprComponent op=(PLUS|MINUS|CONCAT) right=exprComponent # arithmeticExprOrConcatComp # noqa E501
44
- | left=exprComponent comparisonOperand right=exprComponent # comparisonExprComp # noqa E501
45
- | left=exprComponent op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExprComp # noqa E501
46
- | left=exprComponent op=AND right=exprComponent # booleanExprComp # noqa E501
47
- | left=exprComponent op=(OR|XOR) right=exprComponent # booleanExprComp # noqa E501
48
- | IF conditionalExpr=exprComponent THEN thenExpr=exprComponent ELSE elseExpr=exprComponent # ifExprComp # noqa E501
49
- | constant # constantExprComp # noqa E501
50
- | componentID # compId # noqa E501
39
+ LPAREN exprComponent RPAREN # parenthesisExprComp
40
+ | functionsComponents # functionsExpressionComp
41
+ | op=(PLUS|MINUS|NOT) right=exprComponent # unaryExprComp
42
+ | left=exprComponent op=(MUL|DIV) right=exprComponent # arithmeticExprComp
43
+ | left=exprComponent op=(PLUS|MINUS|CONCAT) right=exprComponent # arithmeticExprOrConcatComp
44
+ | left=exprComponent comparisonOperand right=exprComponent # comparisonExprComp
45
+ | left=exprComponent op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExprComp
46
+ | left=exprComponent op=AND right=exprComponent # booleanExprComp
47
+ | left=exprComponent op=(OR|XOR) right=exprComponent # booleanExprComp
48
+ | IF conditionalExpr=exprComponent THEN thenExpr=exprComponent ELSE elseExpr=exprComponent # ifExprComp
49
+ | constant # constantExprComp
50
+ | componentID # compId
51
51
  ;
52
- """
52
+ """ # noqa E501
53
53
  ctx_list = list(ctx.getChildren())
54
54
  c = ctx_list[0]
55
55
 
@@ -279,8 +279,8 @@ class ExprComp(VtlVisitor):
279
279
 
280
280
  def visitCallComponent(self, ctx: Parser.CallComponentContext):
281
281
  """
282
- callFunction: operatorID LPAREN (parameterComponent (COMMA parameterComponent)*)? RPAREN # callComponent # noqa E501
283
- """
282
+ callFunction: operatorID LPAREN (parameterComponent (COMMA parameterComponent)*)? RPAREN # callComponent
283
+ """ # noqa E501
284
284
  ctx_list = list(ctx.getChildren())
285
285
  c = ctx_list[0]
286
286
 
@@ -295,8 +295,8 @@ class ExprComp(VtlVisitor):
295
295
 
296
296
  def visitEvalAtomComponent(self, ctx: Parser.EvalAtomComponentContext):
297
297
  """
298
- | EVAL LPAREN routineName LPAREN (componentID|scalarItem)? (COMMA (componentID|scalarItem))* RPAREN (LANGUAGE STRING_CONSTANT)? (RETURNS outputParameterTypeComponent)? RPAREN # evalAtomComponent # noqa E501
299
- """
298
+ | EVAL LPAREN routineName LPAREN (componentID|scalarItem)? (COMMA (componentID|scalarItem))* RPAREN (LANGUAGE STRING_CONSTANT)? (RETURNS outputParameterTypeComponent)? RPAREN # evalAtomComponent
299
+ """ # noqa E501
300
300
  ctx_list = list(ctx.getChildren())
301
301
 
302
302
  routine_name = Terminals().visitRoutineName(ctx_list[2])
@@ -346,8 +346,8 @@ class ExprComp(VtlVisitor):
346
346
 
347
347
  def visitCastExprComponent(self, ctx: Parser.CastExprComponentContext):
348
348
  """
349
- | CAST LPAREN exprComponent COMMA (basicScalarType|valueDomainName) (COMMA STRING_CONSTANT)? RPAREN # castExprComponent # noqa E501
350
- """
349
+ | CAST LPAREN exprComponent COMMA (basicScalarType|valueDomainName) (COMMA STRING_CONSTANT)? RPAREN # castExprComponent
350
+ """ # noqa E501
351
351
  ctx_list = list(ctx.getChildren())
352
352
  c = ctx_list[0]
353
353
 
@@ -579,24 +579,19 @@ class ExprComp(VtlVisitor):
579
579
  elif isinstance(ctx, Parser.CurrentDateAtomComponentContext):
580
580
  return self.visitCurrentDateAtomComponent(ctx)
581
581
  elif isinstance(ctx, Parser.DateDiffAtomComponentContext):
582
- return self.visitDateAddAtomComponentContext(ctx)
582
+ return self.visitDateDiffAtomComponent(ctx)
583
583
  elif isinstance(ctx, Parser.DateAddAtomComponentContext):
584
584
  return self.visitDateAddAtomComponentContext(ctx)
585
- elif isinstance(ctx, Parser.YearAtomComponentContext):
586
- return self.visitTimeUnaryAtomComponent(ctx)
587
- elif isinstance(ctx, Parser.MonthAtomComponentContext):
588
- return self.visitTimeUnaryAtomComponent(ctx)
589
- elif isinstance(ctx, Parser.DayOfMonthAtomComponentContext):
590
- return self.visitTimeUnaryAtomComponent(ctx)
591
- elif isinstance(ctx, Parser.DayOfYearAtomComponentContext):
592
- return self.visitTimeUnaryAtomComponent(ctx)
593
- elif isinstance(ctx, Parser.DayToYearAtomComponentContext):
594
- return self.visitTimeUnaryAtomComponent(ctx)
595
- elif isinstance(ctx, Parser.DayToMonthAtomComponentContext):
596
- return self.visitTimeUnaryAtomComponent(ctx)
597
- elif isinstance(ctx, Parser.YearToDayAtomComponentContext):
598
- return self.visitTimeUnaryAtomComponent(ctx)
599
- elif isinstance(ctx, Parser.MonthToDayAtomComponentContext):
585
+ elif (isinstance(ctx, (
586
+ Parser.YearAtomComponentContext,
587
+ Parser.MonthAtomComponentContext,
588
+ Parser.DayOfMonthAtomComponentContext,
589
+ Parser.DayOfYearAtomComponentContext,
590
+ Parser.DayToYearAtomComponentContext,
591
+ Parser.DayToMonthAtomComponentContext,
592
+ Parser.YearToDayAtomComponentContext,
593
+ Parser.MonthToDayAtomComponentContext
594
+ ))):
600
595
  return self.visitTimeUnaryAtomComponent(ctx)
601
596
  else:
602
597
  raise NotImplementedError
@@ -653,9 +648,9 @@ class ExprComp(VtlVisitor):
653
648
 
654
649
  def visitTimeAggAtomComponent(self, ctx: Parser.TimeAggAtomComponentContext):
655
650
  """
656
- TIME_AGG LPAREN periodIndTo=STRING_CONSTANT (COMMA periodIndFrom=(STRING_CONSTANT| OPTIONAL ))? # noqa E501
657
- (COMMA op=optionalExprComponent)? (COMMA (FIRST|LAST))? RPAREN # timeAggAtomComponent; # noqa E501
658
- """
651
+ TIME_AGG LPAREN periodIndTo=STRING_CONSTANT (COMMA periodIndFrom=(STRING_CONSTANT| OPTIONAL ))?
652
+ (COMMA op=optionalExprComponent)? (COMMA (FIRST|LAST))? RPAREN # timeAggAtomComponent;
653
+ """ # noqa E501
659
654
  ctx_list = list(ctx.getChildren())
660
655
  c = ctx_list[0]
661
656
 
@@ -674,10 +669,7 @@ class ExprComp(VtlVisitor):
674
669
  and str_.getSymbol().type in [Parser.FIRST, Parser.LAST]
675
670
  ]
676
671
 
677
- if len(conf) == 0:
678
- conf = None
679
- else:
680
- conf = conf[0]
672
+ conf = None if len(conf) == 0 else conf[0]
681
673
 
682
674
  if ctx.op is not None:
683
675
  operand_node = self.visitOptionalExprComponent(ctx.op)
@@ -706,7 +698,7 @@ class ExprComp(VtlVisitor):
706
698
 
707
699
  op = c.getSymbol().text
708
700
  left_node = self.visitExprComponent(ctx_list[2])
709
- right_node = Constant("INTEGER_CONSTANT", int(ctx_list[4].getSymbol().text))
701
+ right_node = self.visitExprComponent(ctx_list[4])
710
702
 
711
703
  return BinOp(left=left_node, op=op, right=right_node)
712
704
 
@@ -889,9 +881,7 @@ class ExprComp(VtlVisitor):
889
881
  elif isinstance(c, Parser.OrderByClauseContext):
890
882
  order_by = Terminals().visitOrderByClause(c)
891
883
  continue
892
- elif isinstance(c, Parser.SignedIntegerContext) or isinstance(
893
- c, Parser.ScalarItemContext
894
- ):
884
+ elif isinstance(c, (Parser.SignedIntegerContext, Parser.ScalarItemContext)):
895
885
  if params is None:
896
886
  params = []
897
887
  if isinstance(c, Parser.SignedIntegerContext):
@@ -1,13 +1,3 @@
1
- from vtlengine.DataTypes import (
2
- Boolean,
3
- Date,
4
- Duration,
5
- Integer,
6
- Number,
7
- String,
8
- TimeInterval,
9
- TimePeriod,
10
- )
11
1
  from antlr4.tree.Tree import TerminalNodeImpl
12
2
 
13
3
  from vtlengine.AST import (
@@ -24,6 +14,16 @@ from vtlengine.AST import (
24
14
  )
25
15
  from vtlengine.AST.Grammar.parser import Parser
26
16
  from vtlengine.AST.VtlVisitor import VtlVisitor
17
+ from vtlengine.DataTypes import (
18
+ Boolean,
19
+ Date,
20
+ Duration,
21
+ Integer,
22
+ Number,
23
+ String,
24
+ TimeInterval,
25
+ TimePeriod,
26
+ )
27
27
  from vtlengine.Model import Component, Dataset, Role, Scalar
28
28
 
29
29
 
@@ -377,21 +377,21 @@ class Terminals(VtlVisitor):
377
377
 
378
378
  def visitDpRuleset(self, ctx: Parser.DpRulesetContext):
379
379
  """
380
- DATAPOINT # dataPoint # noqa E501
381
- | DATAPOINT_ON_VD (GLPAREN valueDomainName (MUL valueDomainName)* GRPAREN )? # dataPointVd # noqa E501
382
- | DATAPOINT_ON_VAR (GLPAREN varID (MUL varID)* GRPAREN )? # dataPointVar # noqa E501
380
+ DATAPOINT # dataPoint
381
+ | DATAPOINT_ON_VD (GLPAREN valueDomainName (MUL valueDomainName)* GRPAREN )? # dataPointVd
382
+ | DATAPOINT_ON_VAR (GLPAREN varID (MUL varID)* GRPAREN )? # dataPointVar
383
383
  ;
384
- """
384
+ """ # noqa E501
385
385
  # AST_ASTCONSTRUCTOR.54
386
386
  raise NotImplementedError
387
387
 
388
388
  def visitHrRuleset(self, ctx: Parser.HrRulesetContext):
389
389
  """
390
- hrRuleset: HIERARCHICAL # hrRulesetType # noqa E501
391
- | HIERARCHICAL_ON_VD ( GLPAREN vdName=IDENTIFIER (LPAREN valueDomainName (MUL valueDomainName)* RPAREN)? GRPAREN )? # hrRulesetVdType # noqa E501
392
- | HIERARCHICAL_ON_VAR ( GLPAREN varName=varID (LPAREN varID (MUL varID)* RPAREN)? GRPAREN )? # hrRulesetVarType # noqa E501
390
+ hrRuleset: HIERARCHICAL # hrRulesetType
391
+ | HIERARCHICAL_ON_VD ( GLPAREN vdName=IDENTIFIER (LPAREN valueDomainName (MUL valueDomainName)* RPAREN)? GRPAREN )? # hrRulesetVdType
392
+ | HIERARCHICAL_ON_VAR ( GLPAREN varName=varID (LPAREN varID (MUL varID)* RPAREN)? GRPAREN )? # hrRulesetVarType
393
393
  ;
394
- """
394
+ """ # noqa E501
395
395
  # AST_ASTCONSTRUCTOR.55
396
396
  raise NotImplementedError
397
397
 
@@ -407,15 +407,9 @@ class Terminals(VtlVisitor):
407
407
  for constraint in ctx_list
408
408
  if isinstance(constraint, Parser.ScalarTypeContext)
409
409
  ]
410
- if len(data_type) > 0:
411
- data_type = data_type[0]
412
- else:
413
- data_type = String()
410
+ data_type = data_type[0] if len(data_type) > 0 else String()
414
411
 
415
- if role_node == Role.IDENTIFIER:
416
- nullable = False
417
- else:
418
- nullable = True
412
+ nullable = role_node != Role.IDENTIFIER
419
413
 
420
414
  return Component(name="Component", data_type=data_type, role=role_node, nullable=nullable)
421
415
 
@@ -503,7 +497,7 @@ class Terminals(VtlVisitor):
503
497
  def visitScalarWithCast(self, ctx: Parser.ScalarWithCastContext):
504
498
  """
505
499
  | CAST LPAREN constant COMMA (basicScalarType) (COMMA STRING_CONSTANT)? RPAREN #scalarWithCast # noqa E501
506
- """
500
+ """ # noqa E501
507
501
  ctx_list = list(ctx.getChildren())
508
502
  c = ctx_list[0]
509
503
 
@@ -513,10 +507,7 @@ class Terminals(VtlVisitor):
513
507
  const_node = self.visitConstant(ctx_list[2])
514
508
  basic_scalar_type = [self.visitBasicScalarType(ctx_list[4])]
515
509
 
516
- if len(ctx_list) > 6:
517
- param_node = [ParamConstant("PARAM_CAST", ctx_list[6])]
518
- else:
519
- param_node = []
510
+ param_node = [ParamConstant("PARAM_CAST", ctx_list[6])] if len(ctx_list) > 6 else []
520
511
 
521
512
  if len(basic_scalar_type) == 1:
522
513
  children_nodes = [const_node, basic_scalar_type[0]]
@@ -681,14 +672,12 @@ class Terminals(VtlVisitor):
681
672
  first = num_rows_1 # unbounded (default value)
682
673
  second = num_rows_2 # current data point (default value)
683
674
 
684
- if mode_2 == "preceding":
685
- if (
686
- mode_1 == "preceding" and num_rows_1 == -1 and num_rows_2 == -1
687
- ): # preceding and preceding (error)
688
- raise Exception(
689
- f"Cannot have 2 preceding clauses with unbounded in analytic clause, "
690
- f"line {ctx_list[3].start.line}"
691
- )
675
+ if (mode_2 == "preceding" and mode_1 == "preceding" and num_rows_1 == -1
676
+ and num_rows_2 == -1): # preceding and preceding (error)
677
+ raise Exception(
678
+ f"Cannot have 2 preceding clauses with unbounded in analytic clause, "
679
+ f"line {ctx_list[3].start.line}"
680
+ )
692
681
 
693
682
  if (
694
683
  mode_1 == "following" and num_rows_1 == -1 and num_rows_2 == -1
@@ -10,7 +10,6 @@ Template to start a new visitor for the AST.
10
10
  from typing import Any
11
11
 
12
12
  import vtlengine.AST as AST
13
-
14
13
  from vtlengine.AST.ASTVisitor import NodeVisitor
15
14
 
16
15
 
@@ -15,24 +15,24 @@ import networkx as nx
15
15
 
16
16
  from vtlengine.AST import (
17
17
  AST,
18
- BinOp,
19
- VarID,
20
18
  Aggregation,
21
19
  Analytic,
22
- JoinOp,
23
- ParamOp,
24
- Operator,
25
- Identifier,
20
+ Assignment,
21
+ BinOp,
26
22
  DefIdentifier,
27
- Start,
23
+ DPRuleset,
28
24
  HRuleset,
29
- RegularAggregation,
25
+ Identifier,
26
+ JoinOp,
27
+ Operator,
28
+ ParamOp,
30
29
  PersistentAssignment,
31
- Assignment,
32
- DPRuleset,
30
+ RegularAggregation,
31
+ Start,
32
+ VarID,
33
33
  )
34
34
  from vtlengine.AST.ASTTemplate import ASTTemplate
35
- from vtlengine.AST.DAG._words import INSERT, DELETE, OUTPUTS, PERSISTENT, INPUTS, GLOBAL
35
+ from vtlengine.AST.DAG._words import DELETE, GLOBAL, INPUTS, INSERT, OUTPUTS, PERSISTENT
36
36
  from vtlengine.AST.Grammar.tokens import AS, MEMBERSHIP, TO
37
37
  from vtlengine.Exceptions import SemanticError
38
38
 
@@ -313,10 +313,7 @@ class DAGAnalyzer(ASTTemplate):
313
313
  self.visit(node.left)
314
314
  self.isDataset = False
315
315
  self.visit(node.right)
316
- elif node.op == AS:
317
- self.visit(node.left)
318
- self.alias.append(node.right.value)
319
- elif node.op == TO:
316
+ elif node.op == AS or node.op == TO:
320
317
  self.visit(node.left)
321
318
  self.alias.append(node.right.value)
322
319
  else:
@@ -91,8 +91,8 @@ STOCK_TO_FLOW = "stock_to_flow"
91
91
  TIMESHIFT = "timeshift"
92
92
  TIME_AGG = "time_agg"
93
93
  CURRENT_DATE = "current_date"
94
- DATE_DIFF = "date_diff"
95
- DATE_ADD = "date_add"
94
+ DATEDIFF = "datediff"
95
+ DATE_ADD = "dateadd"
96
96
  YEAR = "year"
97
97
  MONTH = "month"
98
98
  DAYOFMONTH = "dayofmonth"
@@ -2,7 +2,6 @@ from antlr4 import ParseTreeVisitor
2
2
 
3
3
  from vtlengine.AST.Grammar.parser import Parser
4
4
 
5
-
6
5
  # This class defines a complete generic visitor for a parse tree produced by Parser.
7
6
 
8
7
 
vtlengine/AST/__init__.py CHANGED
@@ -11,7 +11,6 @@ from dataclasses import dataclass
11
11
  from typing import Any, Dict, List, Optional, Type, Union
12
12
 
13
13
  from vtlengine.DataTypes import ScalarType
14
-
15
14
  from vtlengine.Model import Role
16
15
 
17
16
 
@@ -33,7 +32,7 @@ class AST:
33
32
  """Returns a human-friendly description."""
34
33
  out = []
35
34
  name = self.__class__.__name__
36
- for k in self.__all_annotations().keys():
35
+ for k in self.__all_annotations():
37
36
  v = self.__getattribute__(k)
38
37
  if v:
39
38
  out.append(f"{k}={str(v)}")
@@ -41,7 +40,7 @@ class AST:
41
40
 
42
41
  def toJSON(self):
43
42
  base = {"class_name": self.__class__.__name__}
44
- for k in self.__all_annotations().keys():
43
+ for k in self.__all_annotations():
45
44
  v = self.__getattribute__(k)
46
45
  base[k] = v
47
46
  return base
@@ -1,8 +1,9 @@
1
1
  import calendar
2
2
  import copy
3
3
  import operator
4
- from datetime import date, datetime as dt
5
- from typing import Union, Optional, Any, Dict
4
+ from datetime import date
5
+ from datetime import datetime as dt
6
+ from typing import Any, Dict, Optional, Union
6
7
 
7
8
  import pandas as pd
8
9
 
@@ -31,9 +32,11 @@ def date_to_period(date_value: date, period_indicator: str) -> Any:
31
32
  return TimePeriodHandler(f"{date_value.year}D{date_value.timetuple().tm_yday}")
32
33
 
33
34
 
34
- def period_to_date(
35
- year: int, period_indicator: str, period_number: int, start: bool = False
36
- ) -> date:
35
+ def period_to_date(year: int,
36
+ period_indicator: str,
37
+ period_number: int,
38
+ start: bool = False
39
+ ) -> date:
37
40
  if period_indicator == "A":
38
41
  return date(year, 1, 1) if start else date(year, 12, 31)
39
42
  periods = {
@@ -209,7 +212,7 @@ class TimePeriodHandler:
209
212
  raise SemanticError(
210
213
  "2-1-19-7",
211
214
  periods=PeriodDuration.periods[self.period_indicator],
212
- period_inidcator=self.period_indicator,
215
+ period_indicator=self.period_indicator,
213
216
  )
214
217
  # raise ValueError(f'Period Number must be between 1 and '
215
218
  # f'{PeriodDuration.periods[self.period_indicator]} '
@@ -483,7 +486,7 @@ def check_max_date(str_: Optional[str]) -> Optional[str]:
483
486
 
484
487
  # Format 2010-01-01. Prevent passthrough of other ISO 8601 formats.
485
488
  if len(str_) != 10 or str_[7] != "-":
486
- raise SemanticError("2-1-19-8", date=str)
489
+ raise SemanticError("2-1-19-8", date=str_)
487
490
  # raise ValueError(f"Invalid date format, must be YYYY-MM-DD: {str_}")
488
491
 
489
492
  result = date.fromisoformat(str_)
@@ -1,7 +1,8 @@
1
- from typing import Any, Optional, Type, Dict, Set, Union
1
+ from typing import Any, Dict, Optional, Set, Type, Union
2
+
2
3
  import pandas as pd
3
4
 
4
- from vtlengine.DataTypes.TimeHandling import str_period_to_date, check_max_date, date_to_period_str
5
+ from vtlengine.DataTypes.TimeHandling import check_max_date, date_to_period_str, str_period_to_date
5
6
  from vtlengine.Exceptions import SemanticError
6
7
 
7
8
  DTYPE_MAPPING: Dict[str, str] = {
@@ -310,7 +311,8 @@ class TimeInterval(ScalarType):
310
311
 
311
312
  @classmethod
312
313
  def explicit_cast(cls, value: Any, from_type: Any) -> Any:
313
-
314
+ if from_type == String:
315
+ return value # check_time(value). TODO: resolve this to avoid a circular import.
314
316
  raise SemanticError(
315
317
  "2-1-5-1",
316
318
  value=value,
@@ -328,7 +330,7 @@ class Date(TimeInterval):
328
330
  def implicit_cast(cls, value: Any, from_type: Any) -> Any:
329
331
  # TODO: Remove String, only for compatibility with previous engine
330
332
  if from_type in {Date, String}:
331
- return value
333
+ return check_max_date(value)
332
334
 
333
335
  raise SemanticError(
334
336
  "2-1-5-1",
@@ -341,7 +343,7 @@ class Date(TimeInterval):
341
343
  def explicit_cast(cls, value: Any, from_type: Any) -> Any:
342
344
  # TODO: Remove String, only for compatibility with previous engine
343
345
  if from_type == String:
344
- return value
346
+ return check_max_date(value)
345
347
 
346
348
  raise SemanticError(
347
349
  "2-1-5-1",
@@ -384,7 +386,7 @@ class TimePeriod(TimeInterval):
384
386
  return period_str
385
387
  # TODO: Remove String, only for compatibility with previous engine
386
388
  elif from_type == String:
387
- return value
389
+ return value # check_time_period(value) TODO: resolve this to avoid a circular import.
388
390
 
389
391
  raise SemanticError(
390
392
  "2-1-5-1",
@@ -442,15 +444,9 @@ class Boolean(ScalarType):
442
444
  else:
443
445
  return None
444
446
  if isinstance(value, int):
445
- if value != 0:
446
- return True
447
- else:
448
- return False
447
+ return value != 0
449
448
  if isinstance(value, float):
450
- if value != 0.0:
451
- return True
452
- else:
453
- return False
449
+ return value != 0.0
454
450
  if isinstance(value, bool):
455
451
  return value
456
452
  return value
@@ -470,9 +466,7 @@ class Boolean(ScalarType):
470
466
  @classmethod
471
467
  def explicit_cast(cls, value: Any, from_type: Any) -> bool:
472
468
  if from_type in {Number, Integer}:
473
- if value in {0, 0.0}:
474
- return False
475
- return True
469
+ return value not in {0}
476
470
 
477
471
  raise SemanticError(
478
472
  "2-1-5-1",
@@ -672,13 +666,12 @@ def unary_implicit_promotion(
672
666
  return: The resulting type of the operation, after the implicit type promotion
673
667
  """
674
668
  operand_implicities = IMPLICIT_TYPE_PROMOTION_MAPPING[operand_type]
675
- if type_to_check:
676
- if not type_to_check.is_included(operand_implicities):
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
- )
669
+ if type_to_check and not type_to_check.is_included(operand_implicities):
670
+ raise SemanticError(
671
+ code="1-1-1-1",
672
+ type_1=SCALAR_TYPES_CLASS_REVERSE[operand_type],
673
+ type_2=SCALAR_TYPES_CLASS_REVERSE[type_to_check],
674
+ )
682
675
  if return_type:
683
676
  return return_type
684
677
  if (
@@ -7,7 +7,8 @@ Description
7
7
  All exceptions exposed by the Vtl engine.
8
8
  """
9
9
 
10
- from typing import Optional, Any, List
10
+ from typing import Any, List, Optional
11
+
11
12
  from vtlengine.Exceptions.messages import centralised_messages
12
13
 
13
14
  dataset_output = None
@@ -165,10 +166,7 @@ def key_distance(key: str, objetive: str) -> int:
165
166
 
166
167
  for i in range(1, len(key) + 1):
167
168
  for j in range(1, len(objetive) + 1):
168
- if key[i - 1] == objetive[j - 1]:
169
- cost = 0
170
- else:
171
- cost = 1
169
+ cost = 0 if key[i - 1] == objetive[j - 1] else 1
172
170
  dp[i][j] = min(dp[i - 1][j] + 1,
173
171
  dp[i][j - 1] + 1,
174
172
  dp[i - 1][j - 1] + cost)