pydpm_xl 0.2.0__py3-none-any.whl → 0.2.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.
py_dpm/__init__.py CHANGED
@@ -41,7 +41,7 @@ Available packages:
41
41
  - pydpm.api: Main APIs for migration, syntax, and semantic analysis
42
42
  """
43
43
 
44
- __version__ = "0.2.0"
44
+ __version__ = "0.2.2"
45
45
  __author__ = "MeaningfulData S.L."
46
46
  __email__ = "info@meaningfuldata.eu"
47
47
  __license__ = "GPL-3.0-or-later"
@@ -10,7 +10,7 @@ Also provides enrichment functionality to create engine-ready ASTs with framewor
10
10
  """
11
11
 
12
12
  from datetime import datetime
13
- from typing import Dict, Any, Optional
13
+ from typing import Dict, Any, Any, Optional
14
14
  from py_dpm.dpm_xl.utils.serialization import ASTToJSONVisitor
15
15
 
16
16
 
@@ -23,8 +23,8 @@ def generate_complete_ast(
23
23
  """
24
24
  Generate complete AST with all data fields, exactly like json_scripts examples.
25
25
 
26
- This function replicates the exact same process used to generate the reference
27
- JSON files in json_scripts/, ensuring complete data field population.
26
+ This function replicates the process used to generate the reference JSON files,
27
+ using the new SemanticAPI to perform full semantic validation and operand checking.
28
28
 
29
29
  Args:
30
30
  expression: DPM-XL expression string
@@ -34,25 +34,18 @@ def generate_complete_ast(
34
34
  If None, uses all available data (release-agnostic).
35
35
 
36
36
  Returns:
37
- dict: {
38
- 'success': bool,
39
- 'ast': dict, # Complete AST with data fields
40
- 'context': dict, # Context from WITH clause
41
- 'error': str, # Error if failed
42
- 'data_populated': bool # Whether data fields were populated
43
- }
37
+ dict with keys:
38
+ success, ast, context, error, data_populated, semantic_result
44
39
  """
45
40
  try:
46
41
  # Import here to avoid circular imports
47
- from py_dpm.api import API
42
+ from py_dpm.api.dpm_xl.semantic import SemanticAPI
48
43
  from py_dpm.dpm.utils import get_engine
49
44
 
50
- # Initialize database connection if provided
45
+ # Initialize database connection if explicitly provided, to surface connection errors early
51
46
  if connection_url or database_path:
52
47
  try:
53
- engine = get_engine(
54
- database_path=database_path, connection_url=connection_url
55
- )
48
+ get_engine(database_path=database_path, connection_url=connection_url)
56
49
  except Exception as e:
57
50
  return {
58
51
  "success": False,
@@ -62,194 +55,79 @@ def generate_complete_ast(
62
55
  "data_populated": False,
63
56
  }
64
57
 
65
- # Use the legacy API which does complete semantic validation
66
- # This is the same API used to generate the original JSON files
67
- api = API(database_path=database_path, connection_url=connection_url)
68
-
69
- # Perform complete semantic validation with operand checking
70
- # This should populate all data fields on VarID nodes
71
- semantic_result = api.semantic_validation(expression, release_id=release_id)
72
-
73
- # Force data population if semantic validation completed successfully
74
- if hasattr(api, "AST") and api.AST and semantic_result:
75
- try:
76
- from py_dpm.dpm_xl.ast.operands import OperandsChecking
77
- from py_dpm.dpm.utils import get_session
78
-
79
- session = get_session()
80
-
81
- # Extract the expression AST
82
- def get_inner_ast(ast_obj):
83
- if hasattr(ast_obj, "children") and len(ast_obj.children) > 0:
84
- child = ast_obj.children[0]
85
- if hasattr(child, "expression"):
86
- return child.expression
87
- else:
88
- return child
89
- return ast_obj
90
-
91
- inner_ast = get_inner_ast(api.AST)
92
-
93
- # Run operand checking to populate data fields
94
- oc = OperandsChecking(
95
- session=session,
96
- expression=expression,
97
- ast=inner_ast,
98
- release_id=release_id,
99
- )
100
-
101
- # Apply the data from operand checker to VarID nodes
102
- if hasattr(oc, "data") and oc.data is not None:
103
-
104
- # Apply data to VarID nodes in the AST
105
- def apply_data_to_varids(node):
106
- if (
107
- hasattr(node, "__class__")
108
- and node.__class__.__name__ == "VarID"
109
- ):
110
- table = getattr(node, "table", None)
111
- rows = getattr(node, "rows", None)
112
- cols = getattr(node, "cols", None)
113
-
114
- if table and table in oc.operands:
115
- # Filter data for this specific VarID
116
- # Start with table filter
117
- filter_mask = oc.data["table_code"] == table
118
-
119
- # Add row filter only if rows is not None and doesn't contain wildcards
120
- # IMPORTANT: If rows contains '*', include all rows (don't filter)
121
- if rows is not None and "*" not in rows:
122
- filter_mask = filter_mask & (
123
- oc.data["row_code"].isin(rows)
124
- )
125
-
126
- # Add column filter only if cols is not None and doesn't contain wildcards
127
- # IMPORTANT: If cols contains '*', include all columns (don't filter)
128
- if cols is not None and "*" not in cols:
129
- filter_mask = filter_mask & (
130
- oc.data["column_code"].isin(cols)
131
- )
132
-
133
- filtered_data = oc.data[filter_mask]
134
-
135
- if not filtered_data.empty:
136
- # IMPORTANT: Remove wildcard entries (NULL column/row/sheet codes)
137
- # when specific entries exist for the same dimension
138
- # The database contains both wildcard entries (column_code=NULL for c*)
139
- # and specific entries (column_code='0010'). When we query with wildcards,
140
- # we want only the specific entries.
141
-
142
- # Remove rows where column_code is NULL if there are non-NULL column_code entries
143
- if filtered_data["column_code"].notna().any():
144
- filtered_data = filtered_data[
145
- filtered_data["column_code"].notna()
146
- ]
147
-
148
- # Remove rows where row_code is NULL if there are non-NULL row_code entries
149
- if filtered_data["row_code"].notna().any():
150
- filtered_data = filtered_data[
151
- filtered_data["row_code"].notna()
152
- ]
153
-
154
- # Remove rows where sheet_code is NULL if there are non-NULL sheet_code entries
155
- if filtered_data["sheet_code"].notna().any():
156
- filtered_data = filtered_data[
157
- filtered_data["sheet_code"].notna()
158
- ]
159
-
160
- # IMPORTANT: After filtering, remove any remaining duplicates
161
- # based on (row_code, column_code, sheet_code) combination
162
- filtered_data = filtered_data.drop_duplicates(
163
- subset=[
164
- "row_code",
165
- "column_code",
166
- "sheet_code",
167
- ],
168
- keep="first",
169
- )
170
-
171
- # Set the data attribute on the VarID node
172
- if not filtered_data.empty:
173
- node.data = filtered_data
174
-
175
- # Recursively apply to child nodes
176
- for attr_name in [
177
- "children",
178
- "left",
179
- "right",
180
- "operand",
181
- "operands",
182
- "expression",
183
- "condition",
184
- "then_expr",
185
- "else_expr",
186
- ]:
187
- if hasattr(node, attr_name):
188
- attr_value = getattr(node, attr_name)
189
- if isinstance(attr_value, list):
190
- for item in attr_value:
191
- if hasattr(item, "__class__"):
192
- apply_data_to_varids(item)
193
- elif attr_value and hasattr(attr_value, "__class__"):
194
- apply_data_to_varids(attr_value)
195
-
196
- # Apply data to all VarID nodes in the AST
197
- apply_data_to_varids(inner_ast)
58
+ # Use the modern SemanticAPI which performs full semantic validation and operand checking
59
+ semantic_api = SemanticAPI(
60
+ database_path=database_path, connection_url=connection_url
61
+ )
198
62
 
199
- except Exception as e:
200
- # Silently continue if data population fails
201
- pass
202
-
203
- if hasattr(api, "AST") and api.AST is not None:
204
- # Extract components exactly like batch_validator does
205
- def extract_components(ast_obj):
206
- if hasattr(ast_obj, "children") and len(ast_obj.children) > 0:
207
- child = ast_obj.children[0]
208
- if hasattr(child, "expression"):
209
- return child.expression, child.partial_selection
210
- else:
211
- return child, None
212
- return ast_obj, None
213
-
214
- actual_ast, context = extract_components(api.AST)
215
-
216
- # Convert to JSON exactly like batch_validator does
217
- visitor = ASTToJSONVisitor(context)
218
- ast_dict = visitor.visit(actual_ast)
219
-
220
- # Check if data fields were populated
221
- data_populated = _check_data_fields_populated(ast_dict)
222
-
223
- # Serialize context
224
- context_dict = None
225
- if context:
226
- context_dict = {
227
- "table": getattr(context, "table", None),
228
- "rows": getattr(context, "rows", None),
229
- "columns": getattr(context, "cols", None),
230
- "sheets": getattr(context, "sheets", None),
231
- "default": getattr(context, "default", None),
232
- "interval": getattr(context, "interval", None),
233
- }
63
+ semantic_result = semantic_api.validate_expression(
64
+ expression, release_id=release_id
65
+ )
234
66
 
67
+ # If semantic validation failed, return structured error
68
+ if not semantic_result.is_valid:
235
69
  return {
236
- "success": True,
237
- "ast": ast_dict,
238
- "context": context_dict,
239
- "error": None,
240
- "data_populated": data_populated,
70
+ "success": False,
71
+ "ast": None,
72
+ "context": None,
73
+ "error": semantic_result.error_message,
74
+ "data_populated": False,
241
75
  "semantic_result": semantic_result,
242
76
  }
243
77
 
244
- else:
78
+ ast_root = getattr(semantic_api, "ast", None)
79
+
80
+ if ast_root is None:
245
81
  return {
246
82
  "success": False,
247
83
  "ast": None,
248
84
  "context": None,
249
85
  "error": "Semantic validation did not generate AST",
250
86
  "data_populated": False,
87
+ "semantic_result": semantic_result,
88
+ }
89
+
90
+ # Extract components exactly like batch_validator does
91
+ def extract_components(ast_obj):
92
+ if hasattr(ast_obj, "children") and len(ast_obj.children) > 0:
93
+ child = ast_obj.children[0]
94
+ if hasattr(child, "expression"):
95
+ return child.expression, child.partial_selection
96
+ else:
97
+ return child, None
98
+ return ast_obj, None
99
+
100
+ actual_ast, context = extract_components(ast_root)
101
+
102
+ # Convert to JSON using the ASTToJSONVisitor, which uses VarID.data populated
103
+ # during semantic validation / operand checking.
104
+ visitor = ASTToJSONVisitor(context)
105
+ ast_dict = visitor.visit(actual_ast)
106
+
107
+ # Check if data fields were populated
108
+ data_populated = _check_data_fields_populated(ast_dict)
109
+
110
+ # Serialize context
111
+ context_dict = None
112
+ if context:
113
+ context_dict = {
114
+ "table": getattr(context, "table", None),
115
+ "rows": getattr(context, "rows", None),
116
+ "columns": getattr(context, "cols", None),
117
+ "sheets": getattr(context, "sheets", None),
118
+ "default": getattr(context, "default", None),
119
+ "interval": getattr(context, "interval", None),
251
120
  }
252
121
 
122
+ return {
123
+ "success": True,
124
+ "ast": ast_dict,
125
+ "context": context_dict,
126
+ "error": None,
127
+ "data_populated": data_populated,
128
+ "semantic_result": semantic_result,
129
+ }
130
+
253
131
  except Exception as e:
254
132
  return {
255
133
  "success": False,
@@ -56,6 +56,8 @@ class SemanticAPI:
56
56
  """
57
57
  self.database_path = database_path
58
58
  self.connection_url = connection_url
59
+ # Store last parsed AST for consumers that need it (e.g. complete AST generation)
60
+ self.ast = None
59
61
 
60
62
  if connection_url:
61
63
  # Create isolated engine and session for the provided connection URL
@@ -141,6 +143,8 @@ class SemanticAPI:
141
143
 
142
144
  # Generate AST
143
145
  ast = self.visitor.visit(parse_tree)
146
+ # Expose AST on the instance for downstream consumers
147
+ self.ast = ast
144
148
 
145
149
  # Perform semantic analysis
146
150
  oc = OperandsChecking(
py_dpm/cli/main.py CHANGED
@@ -6,7 +6,7 @@ import os
6
6
  import sys
7
7
  import pandas as pd
8
8
 
9
- from py_dpm.api import SemanticAPI
9
+ from py_dpm.api import SemanticAPI, SyntaxAPI
10
10
  from py_dpm.api.dpm_xl.semantic import SemanticValidationResult
11
11
  from py_dpm.api.dpm.operation_scopes import OperationScopesAPI
12
12
  from py_dpm.dpm.migration import run_migration
@@ -147,9 +147,11 @@ def syntax(expression: str):
147
147
  """Perform syntactic analysis on a DPM expression."""
148
148
 
149
149
  status = 0
150
- api = API()
150
+ api = SyntaxAPI()
151
151
  try:
152
- api.syntax_validation(expression)
152
+ result = api.validate_expression(expression)
153
+ if not result.is_valid:
154
+ raise SyntaxError(result.error_message or "Syntax errors detected")
153
155
  message_formatted = Text("Syntax OK", style="bold green")
154
156
  except SyntaxError as e:
155
157
  message = str(e)
@@ -74,7 +74,12 @@ class TableQuery:
74
74
  subq.c.table_code.isnot(None)
75
75
  )
76
76
 
77
- q = filter_by_release(q, release_id, subq.c.start_release, subq.c.end_release)
77
+ q = filter_by_release(
78
+ q,
79
+ start_col=subq.c.start_release,
80
+ end_col=subq.c.end_release,
81
+ release_id=release_id,
82
+ )
78
83
  q = q.order_by(subq.c.table_code)
79
84
 
80
85
  return BaseQuery(session, q)
@@ -91,7 +96,12 @@ class TableQuery:
91
96
  subq.c.table_code == table_code, subq.c.row_code.isnot(None)
92
97
  )
93
98
 
94
- q = filter_by_release(q, release_id, subq.c.start_release, subq.c.end_release)
99
+ q = filter_by_release(
100
+ q,
101
+ start_col=subq.c.start_release,
102
+ end_col=subq.c.end_release,
103
+ release_id=release_id,
104
+ )
95
105
  q = q.order_by(subq.c.row_code)
96
106
 
97
107
  return BaseQuery(session, q)
@@ -108,7 +118,12 @@ class TableQuery:
108
118
  subq.c.table_code == table_code, subq.c.column_code.isnot(None)
109
119
  )
110
120
 
111
- q = filter_by_release(q, release_id, subq.c.start_release, subq.c.end_release)
121
+ q = filter_by_release(
122
+ q,
123
+ start_col=subq.c.start_release,
124
+ end_col=subq.c.end_release,
125
+ release_id=release_id,
126
+ )
112
127
  q = q.order_by(subq.c.column_code)
113
128
 
114
129
  return BaseQuery(session, q)
@@ -127,7 +142,12 @@ class TableQuery:
127
142
  subq.c.sheet_code != "",
128
143
  )
129
144
 
130
- q = filter_by_release(q, release_id, subq.c.start_release, subq.c.end_release)
145
+ q = filter_by_release(
146
+ q,
147
+ start_col=subq.c.start_release,
148
+ end_col=subq.c.end_release,
149
+ release_id=release_id,
150
+ )
131
151
  q = q.order_by(subq.c.sheet_code)
132
152
 
133
153
  return BaseQuery(session, q)
@@ -208,9 +208,9 @@ class OperandsChecking(ASTTemplate, ABC):
208
208
  # Apply release filter
209
209
  query = filter_by_release(
210
210
  query,
211
- self.release_id,
212
- TableVersion.startreleaseid,
213
- TableVersion.endreleaseid,
211
+ start_col=TableVersion.startreleaseid,
212
+ end_col=TableVersion.endreleaseid,
213
+ release_id=self.release_id,
214
214
  )
215
215
 
216
216
  # Execute query and convert to DataFrame
@@ -542,10 +542,9 @@ class ASTToJSONVisitor(NodeVisitor):
542
542
 
543
543
  return result
544
544
 
545
-
546
545
  # Original serialization functions (kept for backward compatibility)
547
546
  import json
548
- from py_dpm.dpm_xl.ast import nodes
547
+ from py_dpm.dpm_xl.ast import nodes as ASTObjects
549
548
 
550
549
 
551
550
  def expand_with_expression(node):
@@ -759,4 +758,4 @@ def ast_from_json_string(json_str):
759
758
  AST object instance
760
759
  """
761
760
  data = json.loads(json_str)
762
- return deserialize_ast(data)
761
+ return deserialize_ast(data)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydpm_xl
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Python library for DPM-XL data processing and analysis
5
5
  Author-email: "MeaningfulData S.L." <info@meaningfuldata.eu>
6
6
  License: GPL-3.0-or-later
@@ -1,4 +1,4 @@
1
- py_dpm/__init__.py,sha256=rbhfed7zNfD34iEi3bPOB9D7x1mpkcUaXZjtqQecZfo,1858
1
+ py_dpm/__init__.py,sha256=f5HSKe3TKudiLPviLZ9Tc47ePZMOG3hNRwQS7-UqbB8,1858
2
2
  py_dpm/api/__init__.py,sha256=g0w2FOtETU1ZMuhGnbdgBmmTZwmWoBtBEDmkLR1t8sc,1824
3
3
  py_dpm/api/explorer.py,sha256=1dBc2ZidcAR5DfPEBRiyVk54Xv9u_G9mU66u7PA9Z-E,86
4
4
  py_dpm/api/semantic.py,sha256=QT0znXXa4ihqk4GmlmJQrdceCRy1o_3J17koW6rT5PE,1304
@@ -10,11 +10,11 @@ py_dpm/api/dpm/migration.py,sha256=9FT7zzz4QdUIRR6MD01gMODBtfq9HH_RF4hRgZqMcZc,2
10
10
  py_dpm/api/dpm/operation_scopes.py,sha256=Vw9cdPiFM7uCsQyMY1AgT5XhHbxFcVeMwIcIXANuty4,48486
11
11
  py_dpm/api/dpm_xl/__init__.py,sha256=rjiIf9XDi2IGf0G_LiOWp29e5ANyoREfzl5Z5phJU_8,603
12
12
  py_dpm/api/dpm_xl/ast_generator.py,sha256=-wOgUEM1DMpyVwflkplLr7BOZFfjaDeXi-R_PLhsAxo,16160
13
- py_dpm/api/dpm_xl/complete_ast.py,sha256=rBfzGQ5RnJXlLcG46jMpArfnllQSPN1ny4Ou_Y_HGAc,31002
14
- py_dpm/api/dpm_xl/semantic.py,sha256=hbyS0tQITZjeXNid6j4Rvc_PkV-8tfmZrj2_1XlAKwg,13422
13
+ py_dpm/api/dpm_xl/complete_ast.py,sha256=XmXvE1zWLxL732FvyUpK4WffKwZSrw5yrzJI-QGOpFI,24341
14
+ py_dpm/api/dpm_xl/semantic.py,sha256=Buo_t-sEv65r6RmYDy1xkCWGlU2pB2WQsDM-X-FX4cc,13629
15
15
  py_dpm/api/dpm_xl/syntax.py,sha256=Ke_kKd9ModoJ6siL3GPT9j9QClmopryCRcdDAT3M5-E,5954
16
16
  py_dpm/cli/__init__.py,sha256=UrfGHoQ0sZLjWfA0hoOoI4iTrn-bjr2f9Q8wDWd5nMo,133
17
- py_dpm/cli/main.py,sha256=UACXaWiPZH6vxfmdasSMTVXAk7IceOcon30qtOugPz4,22304
17
+ py_dpm/cli/main.py,sha256=Cu04d3hpv0UdcROdkvpNipNfiAkde59YCbPu0gKKCYA,22444
18
18
  py_dpm/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  py_dpm/dpm/__init__.py,sha256=moagUo5Gxf24-Tl9FL_3n2wmVoD_oXtpC-YIGktH_rc,212
20
20
  py_dpm/dpm/migration.py,sha256=ivO_ObvKzVomTns6qfo-o5FuciWxkXbMd_gJ4_tu7Xc,14110
@@ -26,7 +26,7 @@ py_dpm/dpm/queries/explorer_queries.py,sha256=Co8CzdzlDrOL5-ZxY7_HoHPaP_j-xjLDSs
26
26
  py_dpm/dpm/queries/filters.py,sha256=fxC2KLYpIvtmuyuJFb0te2ULiyDnQBZfVM79VQnr6qA,4901
27
27
  py_dpm/dpm/queries/glossary.py,sha256=2SqKZghQTw-E8NWwHebDHuDC8BC389fGe-0UBIVfJ8Q,1571
28
28
  py_dpm/dpm/queries/hierarchical_queries.py,sha256=FYO2p_OxZioynXW4nGCQ3UG3p3uzE28KdsmMaQSk1wk,31538
29
- py_dpm/dpm/queries/tables.py,sha256=ZaUwvQzj5EXR7BVv2VLYZ7Iii3aMFMlZ3rX25NtBuMg,4411
29
+ py_dpm/dpm/queries/tables.py,sha256=oEucVoUsb3jbgYefqr8_3svy_9oRGRhWXxcBxd20NJU,4763
30
30
  py_dpm/dpm_xl/__init__.py,sha256=fN3AvMthyaVC893iza5IMzi3uVuLer411WdmKor6tY4,158
31
31
  py_dpm/dpm_xl/semantic_analyzer.py,sha256=vZjtEzCkGNZN20EoU8yDMee8vIwRhDxvN5-JhZFTFhI,15746
32
32
  py_dpm/dpm_xl/symbols.py,sha256=XSAiFSffxfPcnGdEDYEMjJrrhEJeuNIeasmHBp5C5Fc,7637
@@ -36,7 +36,7 @@ py_dpm/dpm_xl/ast/ml_generation.py,sha256=Lw_1Btln2x1ewD9xH-2Ea4NJJP3PIqFoivWASX
36
36
  py_dpm/dpm_xl/ast/module_analyzer.py,sha256=ZnldoYn-s41UMiJpcAV6hjIwH6fssZeOpc564epngg8,2872
37
37
  py_dpm/dpm_xl/ast/module_dependencies.py,sha256=tbCqoDcE1n1lJOjtbpD3rNPkXrLk-k2rM5zyVwmsNpc,8355
38
38
  py_dpm/dpm_xl/ast/nodes.py,sha256=5ob8MsCW0fPZgz9yP_6IgVTH2SGeoTk5VncJuQ2SgrE,25035
39
- py_dpm/dpm_xl/ast/operands.py,sha256=xe3MwgJzqxKPzyik1IjAtHqCgBBv_N3rQXqNtAVRDpw,21099
39
+ py_dpm/dpm_xl/ast/operands.py,sha256=UN69SQB0S8VG4sjQPz6CNfwjg1uDPEXqKsJtVIgiGGA,21128
40
40
  py_dpm/dpm_xl/ast/template.py,sha256=QhYm7Jh_a-ws3kSmf0hqXFLzB_quO9GgKcmcFe22_fg,3045
41
41
  py_dpm/dpm_xl/ast/visitor.py,sha256=yL9UpPMQlq8ToHR8COyFYpuSChnDRjnkQHbCyYX0tsY,509
42
42
  py_dpm/dpm_xl/ast/where_clause.py,sha256=g3cslQ8vmlm0doqQ_ghjXzhzItc_xlC_bQ9odn87FGk,328
@@ -70,7 +70,7 @@ py_dpm/dpm_xl/utils/data_handlers.py,sha256=a0E-IaP_-CDKLcj-Gt2ggAziKIOUiwnT2D9I
70
70
  py_dpm/dpm_xl/utils/operands_mapping.py,sha256=LG0hPlUuTM2X2uWOtiD6HkmNeDEJkWJ8gV-Fxej_8QM,2241
71
71
  py_dpm/dpm_xl/utils/operator_mapping.py,sha256=BFgbVbSCSuutFNHJ4gtgm5VuG38pcl8Kmfi-sefg6JU,1913
72
72
  py_dpm/dpm_xl/utils/scopes_calculator.py,sha256=nCx2mz_qtw61BESp38ORQYlF2uRT8SyUKawSX9OQljM,17832
73
- py_dpm/dpm_xl/utils/serialization.py,sha256=VkjTTcg7okQ9uw1WGsM9xyYGRTrHcDjEuveeS92taxM,32468
73
+ py_dpm/dpm_xl/utils/serialization.py,sha256=LPcmudFfzHeEjIIr57kr5BvGPZbxshOAAeUYOrLl7XM,32482
74
74
  py_dpm/dpm_xl/utils/tokens.py,sha256=VRIrPDi5ttwgH-on5Qt4-l4ho4bLA755-nfTalponcA,3496
75
75
  py_dpm/dpm_xl/validation/__init__.py,sha256=pzSTkLzUgK16XsV_maXn__erzs0blDBDRApuRWJwwMs,250
76
76
  py_dpm/dpm_xl/validation/generation_utils.py,sha256=2UvYorpLor-8PiEUTWFFVr-xEzKjxQzZrLXz3lvedPk,22655
@@ -80,9 +80,9 @@ py_dpm/dpm_xl/validation/variants.py,sha256=LM_2U_sCf8rnlUyt6k4WQwSKj5eTJLt4Ba8q
80
80
  py_dpm/exceptions/__init__.py,sha256=yDERfUxYW7NUUEiTQChGpuJx6abr7IDe2XUpwVFPtvM,416
81
81
  py_dpm/exceptions/exceptions.py,sha256=6S3p-_i5O1oStvSMixt_JQG0xwTeSfBcdzrwL8yBy6Q,2413
82
82
  py_dpm/exceptions/messages.py,sha256=UwY6QIK8c-POcDCc9HYbZFGArCIYAanUGNh2LNKPx3U,7534
83
- pydpm_xl-0.2.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
84
- pydpm_xl-0.2.0.dist-info/METADATA,sha256=O0-W3yLmeS50GBcIt4VBH0cB4tEMApbJS7Vnjxr4u00,7974
85
- pydpm_xl-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
86
- pydpm_xl-0.2.0.dist-info/entry_points.txt,sha256=6DDmBfw-AjtgvMHgq_I730i_LAAs_7-N3C95HD_bRr4,47
87
- pydpm_xl-0.2.0.dist-info/top_level.txt,sha256=495PvWZRoKl2NvbQU25W7dqWIBHqY-mFMPt83uxPpcM,7
88
- pydpm_xl-0.2.0.dist-info/RECORD,,
83
+ pydpm_xl-0.2.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
84
+ pydpm_xl-0.2.2.dist-info/METADATA,sha256=AG1po-jCkskQP5DFl49SMCF0y4QJHivL287Y3KLE3T0,7974
85
+ pydpm_xl-0.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
86
+ pydpm_xl-0.2.2.dist-info/entry_points.txt,sha256=6DDmBfw-AjtgvMHgq_I730i_LAAs_7-N3C95HD_bRr4,47
87
+ pydpm_xl-0.2.2.dist-info/top_level.txt,sha256=495PvWZRoKl2NvbQU25W7dqWIBHqY-mFMPt83uxPpcM,7
88
+ pydpm_xl-0.2.2.dist-info/RECORD,,