vtlengine 1.2.0__tar.gz → 1.2.1__tar.gz
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.
- {vtlengine-1.2.0 → vtlengine-1.2.1}/PKG-INFO +1 -1
- {vtlengine-1.2.0 → vtlengine-1.2.1}/pyproject.toml +5 -5
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Interpreter/__init__.py +13 -4
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Aggregation.py +2 -2
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Conditional.py +15 -13
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Join.py +5 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Utils/__Virtual_Assets.py +2 -2
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/__init__.py +1 -1
- {vtlengine-1.2.0 → vtlengine-1.2.1}/LICENSE.md +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/README.md +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/API/_InternalApi.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/API/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/API/data/schema/json_schema_2.1.json +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTComment.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTConstructor.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTConstructorModules/Expr.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTConstructorModules/ExprComponents.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTConstructorModules/Terminals.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTConstructorModules/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTDataExchange.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTEncoders.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTString.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTTemplate.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTVisitor.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/DAG/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/DAG/_words.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/Grammar/Vtl.g4 +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/Grammar/VtlTokens.g4 +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/Grammar/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/Grammar/lexer.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/Grammar/parser.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/Grammar/tokens.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/VtlVisitor.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/DataTypes/TimeHandling.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/DataTypes/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Exceptions/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Exceptions/messages.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Model/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Analytic.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Assignment.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Boolean.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/CastOperator.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Clause.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Comparison.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/General.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/HROperators.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Numeric.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/RoleSetter.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Set.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/String.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Time.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/Validation.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Operators/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/Utils/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/__extras_check.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/files/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/files/output/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/files/output/_time_period_representation.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/files/parser/__init__.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/files/parser/_rfc_dialect.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/files/parser/_time_checking.py +0 -0
- {vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "vtlengine"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.1"
|
|
4
4
|
description = "Run and Validate VTL Scripts"
|
|
5
5
|
license = "AGPL-3.0"
|
|
6
6
|
readme = "README.md"
|
|
@@ -55,10 +55,10 @@ pytest = "^8.4"
|
|
|
55
55
|
pytest-cov = "^6.2.1"
|
|
56
56
|
pytest-xdist = "^3.8.0"
|
|
57
57
|
line-profiler-pycharm = "^1.2.0"
|
|
58
|
-
mypy = "1.
|
|
58
|
+
mypy = "1.17.1"
|
|
59
59
|
pandas-stubs = "2.2.2.240807"
|
|
60
|
-
ruff = "^0.12.
|
|
61
|
-
types-jsonschema = "4.
|
|
60
|
+
ruff = "^0.12.7"
|
|
61
|
+
types-jsonschema = "4.25.0.20250720"
|
|
62
62
|
|
|
63
63
|
[tool.poetry.group.docs.dependencies]
|
|
64
64
|
sphinx = "^7.4.7"
|
|
@@ -77,7 +77,7 @@ lint.select = [
|
|
|
77
77
|
lint.ignore = ["B023", "B028", "B904", "C403", "D100", "D101", "D102", "D103", "D104", "D105",
|
|
78
78
|
"D107", "D200", "D201", "D202", "D203", "D205", "D209", "D212", "D213", "D301",
|
|
79
79
|
"D400", "D401", "D404", "D411", "D413", "D415", "D419", "E203", "S608"]
|
|
80
|
-
lint.exclude = ["*/Grammar/*"]
|
|
80
|
+
lint.exclude = ["*/Grammar/*", "*/main.py"]
|
|
81
81
|
|
|
82
82
|
[tool.ruff.lint.per-file-ignores]
|
|
83
83
|
"tests/*" = ["S101", "PT006", "PT012", "PT013", "E501", "W605"]
|
|
@@ -591,16 +591,25 @@ class InterpreterAnalyzer(ASTTemplate):
|
|
|
591
591
|
else:
|
|
592
592
|
operand_comp = self.visit(node.operand)
|
|
593
593
|
component_name = operand_comp.name
|
|
594
|
+
id_names = self.regular_aggregation_dataset.get_identifiers_names()
|
|
594
595
|
measure_names = self.regular_aggregation_dataset.get_measures_names()
|
|
596
|
+
attribute_names = self.regular_aggregation_dataset.get_attributes_names()
|
|
595
597
|
dataset_components = self.regular_aggregation_dataset.components.copy()
|
|
596
|
-
for name in measure_names:
|
|
597
|
-
|
|
598
|
-
|
|
598
|
+
for name in measure_names + attribute_names:
|
|
599
|
+
dataset_components.pop(name)
|
|
600
|
+
|
|
601
|
+
dataset_components[operand_comp.name] = Component(
|
|
602
|
+
name=operand_comp.name,
|
|
603
|
+
data_type=operand_comp.data_type,
|
|
604
|
+
role=operand_comp.role,
|
|
605
|
+
nullable=operand_comp.nullable,
|
|
606
|
+
)
|
|
599
607
|
|
|
600
608
|
if self.only_semantic or self.regular_aggregation_dataset.data is None:
|
|
601
609
|
data = None
|
|
602
610
|
else:
|
|
603
|
-
data = self.regular_aggregation_dataset.data[
|
|
611
|
+
data = self.regular_aggregation_dataset.data[id_names].copy()
|
|
612
|
+
data[operand_comp.name] = operand_comp.data
|
|
604
613
|
|
|
605
614
|
operand = Dataset(
|
|
606
615
|
name=self.regular_aggregation_dataset.name,
|
|
@@ -103,12 +103,12 @@ class Aggregation(Operator.Unary):
|
|
|
103
103
|
elif measure.data_type == Duration:
|
|
104
104
|
if mode == "input":
|
|
105
105
|
data[measure.name] = data[measure.name].map(
|
|
106
|
-
lambda x: PERIOD_IND_MAPPING[x],
|
|
106
|
+
lambda x: PERIOD_IND_MAPPING[x],
|
|
107
107
|
na_action="ignore",
|
|
108
108
|
)
|
|
109
109
|
else:
|
|
110
110
|
data[measure.name] = data[measure.name].map(
|
|
111
|
-
lambda x: PERIOD_IND_MAPPING_REVERSE[x],
|
|
111
|
+
lambda x: PERIOD_IND_MAPPING_REVERSE[x],
|
|
112
112
|
na_action="ignore",
|
|
113
113
|
)
|
|
114
114
|
elif measure.data_type == Boolean:
|
|
@@ -157,15 +157,19 @@ class If(Operator):
|
|
|
157
157
|
op=cls.op,
|
|
158
158
|
type=SCALAR_TYPES_CLASS_REVERSE[condition.data_type],
|
|
159
159
|
)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
nullable
|
|
167
|
-
if isinstance(right, DataComponent):
|
|
168
|
-
nullable
|
|
160
|
+
|
|
161
|
+
if (
|
|
162
|
+
isinstance(left, Scalar)
|
|
163
|
+
and isinstance(right, Scalar)
|
|
164
|
+
and (left.data_type == Null or right.data_type == Null)
|
|
165
|
+
):
|
|
166
|
+
nullable = True
|
|
167
|
+
if isinstance(left, DataComponent) and isinstance(right, DataComponent):
|
|
168
|
+
nullable = left.nullable or right.nullable
|
|
169
|
+
elif isinstance(left, DataComponent):
|
|
170
|
+
nullable = left.nullable or right.data_type == Null
|
|
171
|
+
elif isinstance(right, DataComponent):
|
|
172
|
+
nullable = left.data_type == Null or right.nullable
|
|
169
173
|
return DataComponent(
|
|
170
174
|
name=comp_name,
|
|
171
175
|
data=None,
|
|
@@ -433,11 +437,9 @@ class Case(Operator):
|
|
|
433
437
|
raise SemanticError("2-1-9-4", op=cls.op, name=condition.name)
|
|
434
438
|
|
|
435
439
|
nullable = any(
|
|
436
|
-
(
|
|
437
|
-
for
|
|
440
|
+
(op.nullable if isinstance(op, DataComponent) else op.data_type == Null)
|
|
441
|
+
for op in ops
|
|
438
442
|
)
|
|
439
|
-
nullable |= any(condition.nullable for condition in conditions)
|
|
440
|
-
|
|
441
443
|
data_type = ops[0].data_type
|
|
442
444
|
for op in ops[1:]:
|
|
443
445
|
data_type = binary_implicit_promotion(data_type, op.data_type)
|
|
@@ -9,6 +9,7 @@ from typing import Any, Dict, List, Optional
|
|
|
9
9
|
import pandas as pd
|
|
10
10
|
|
|
11
11
|
from vtlengine.AST import BinOp
|
|
12
|
+
from vtlengine.AST.Grammar.tokens import CROSS_JOIN, FULL_JOIN, INNER_JOIN, LEFT_JOIN
|
|
12
13
|
from vtlengine.DataTypes import binary_implicit_promotion
|
|
13
14
|
from vtlengine.Exceptions import SemanticError
|
|
14
15
|
from vtlengine.Model import Component, Dataset, Role
|
|
@@ -276,6 +277,7 @@ class Join(Operator):
|
|
|
276
277
|
|
|
277
278
|
|
|
278
279
|
class InnerJoin(Join):
|
|
280
|
+
op = INNER_JOIN
|
|
279
281
|
how = "inner"
|
|
280
282
|
|
|
281
283
|
@classmethod
|
|
@@ -296,10 +298,12 @@ class InnerJoin(Join):
|
|
|
296
298
|
|
|
297
299
|
|
|
298
300
|
class LeftJoin(Join):
|
|
301
|
+
op = LEFT_JOIN
|
|
299
302
|
how = "left"
|
|
300
303
|
|
|
301
304
|
|
|
302
305
|
class FullJoin(Join):
|
|
306
|
+
op = FULL_JOIN
|
|
303
307
|
how = "outer"
|
|
304
308
|
|
|
305
309
|
@classmethod
|
|
@@ -320,6 +324,7 @@ class FullJoin(Join):
|
|
|
320
324
|
|
|
321
325
|
|
|
322
326
|
class CrossJoin(Join):
|
|
327
|
+
op = CROSS_JOIN
|
|
323
328
|
how = "cross"
|
|
324
329
|
|
|
325
330
|
@classmethod
|
|
@@ -24,11 +24,11 @@ class VirtualCounter:
|
|
|
24
24
|
@classmethod
|
|
25
25
|
def _new_ds_name(cls) -> str:
|
|
26
26
|
cls.dataset_count += 1
|
|
27
|
-
name = f"
|
|
27
|
+
name = f"__VDS_{copy(cls.dataset_count)}__"
|
|
28
28
|
return name
|
|
29
29
|
|
|
30
30
|
@classmethod
|
|
31
31
|
def _new_dc_name(cls) -> str:
|
|
32
32
|
cls.component_count += 1
|
|
33
|
-
name = f"
|
|
33
|
+
name = f"__VDC_{copy(cls.component_count)}__"
|
|
34
34
|
return name
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/AST/ASTConstructorModules/ExprComponents.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vtlengine-1.2.0 → vtlengine-1.2.1}/src/vtlengine/files/output/_time_period_representation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|