pydpm_xl 0.2.10__py3-none-any.whl → 0.2.12__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.10"
44
+ __version__ = "0.2.12"
45
45
  __author__ = "MeaningfulData S.L."
46
46
  __email__ = "info@meaningfuldata.eu"
47
47
  __license__ = "GPL-3.0-or-later"
@@ -358,6 +358,7 @@ class ASTGeneratorAPI:
358
358
  module_code: Optional[str] = None,
359
359
  preferred_module_dependencies: Optional[List[str]] = None,
360
360
  module_version_number: Optional[str] = None,
361
+ add_all_tables: bool = True,
361
362
  ) -> Dict[str, Any]:
362
363
  """
363
364
  Generate validations script with engine-ready AST and framework structure.
@@ -413,6 +414,10 @@ class ASTGeneratorAPI:
413
414
  Mutually exclusive with release_code and release_id.
414
415
  If none of release_code, release_id, or module_version_number are provided,
415
416
  the latest (active) module version is used.
417
+ add_all_tables: If True (default), include all tables and variables from the
418
+ module version in the output, regardless of whether they are referenced in
419
+ the validations. If False, only include tables and variables that are
420
+ actually referenced in the expressions.
416
421
 
417
422
  Returns:
418
423
  dict: {
@@ -483,6 +488,7 @@ class ASTGeneratorAPI:
483
488
  primary_module_vid=primary_module_vid,
484
489
  module_code=module_code,
485
490
  preferred_module_dependencies=preferred_module_dependencies,
491
+ add_all_tables=add_all_tables,
486
492
  )
487
493
 
488
494
  # Save to file if output_path is provided
@@ -960,6 +966,7 @@ class ASTGeneratorAPI:
960
966
  primary_module_vid: Optional[int] = None,
961
967
  module_code: Optional[str] = None,
962
968
  preferred_module_dependencies: Optional[List[str]] = None,
969
+ add_all_tables: bool = True,
963
970
  ) -> Dict[str, Any]:
964
971
  """
965
972
  Add framework structure for multiple expressions (operations, variables, tables, preconditions).
@@ -975,6 +982,8 @@ class ASTGeneratorAPI:
975
982
  primary_module_vid: Module VID being exported (to identify external dependencies)
976
983
  module_code: Optional module code to specify the main module
977
984
  preferred_module_dependencies: Optional list of module codes to prefer for dependencies
985
+ add_all_tables: If True, include all tables and variables from the module version.
986
+ If False, only include tables referenced in expressions.
978
987
 
979
988
  Returns:
980
989
  Dict with the enriched AST structure
@@ -1208,6 +1217,35 @@ class ASTGeneratorAPI:
1208
1217
  if not cross_deps:
1209
1218
  all_intra_instance_ops.append(operation_code)
1210
1219
 
1220
+ # After processing all expressions, add remaining tables from the module if requested
1221
+ if add_all_tables and primary_module_info:
1222
+ resolved_module_vid = primary_module_info.get("module_vid")
1223
+ if resolved_module_vid:
1224
+ # Get all tables belonging to the primary module
1225
+ module_tables = data_dict_api.get_all_tables_for_module(resolved_module_vid)
1226
+
1227
+ for table_info in module_tables:
1228
+ table_code = table_info.get("table_code")
1229
+ table_vid = table_info.get("table_vid")
1230
+
1231
+ # Skip if already added from expressions
1232
+ if table_code in all_tables:
1233
+ continue
1234
+
1235
+ # Get all variables for this table
1236
+ table_variables = data_dict_api.get_all_variables_for_table(table_vid)
1237
+
1238
+ # Query open keys for this table
1239
+ open_keys_list = data_dict_api.get_open_keys_for_table(table_code, release_id)
1240
+ open_keys = {item["property_code"]: item["data_type_code"] for item in open_keys_list}
1241
+
1242
+ all_tables[table_code] = {"variables": table_variables, "open_keys": open_keys}
1243
+ all_variables.update(table_variables)
1244
+
1245
+ # If we added any tables, mark that we have primary module operations
1246
+ if module_tables:
1247
+ has_primary_module_operation = True
1248
+
1211
1249
  finally:
1212
1250
  data_dict_api.close()
1213
1251
 
@@ -2206,12 +2244,11 @@ class ASTGeneratorAPI:
2206
2244
  entry["x"] = x_index
2207
2245
 
2208
2246
  # Calculate y coordinate (column position)
2247
+ # Only add y if there are multiple columns
2209
2248
  if cols and col_code in cols:
2210
2249
  y_index = cols.index(col_code) + 1
2211
- entry["y"] = y_index
2212
- elif not cols:
2213
- # Default to 1 if no column info
2214
- entry["y"] = 1
2250
+ if len(cols) > 1:
2251
+ entry["y"] = y_index
2215
2252
 
2216
2253
  # Calculate z coordinate (sheet position)
2217
2254
  if sheets and sheet_code in sheets:
@@ -2238,13 +2275,16 @@ class ASTGeneratorAPI:
2238
2275
  Remove extra fields from data entries in the AST.
2239
2276
 
2240
2277
  Keeps only the fields required by the engine:
2241
- - datapoint, operand_reference_id, y, column, x (if multiple rows), z (if multiple sheets)
2278
+ - datapoint, operand_reference_id (always)
2279
+ - x and row (only if multiple rows - rows are variable)
2280
+ - y and column (only if multiple columns - columns are variable)
2281
+ - z and sheet (only if multiple sheets - sheets are variable)
2242
2282
 
2243
2283
  Removes internal/debug fields:
2244
- - data_type, cell_code, table_code, table_vid, row
2284
+ - data_type, cell_code, table_code, table_vid
2245
2285
  """
2246
- # Fields to keep in data entries
2247
- ALLOWED_FIELDS = {"datapoint", "operand_reference_id", "x", "y", "z", "column", "sheet"}
2286
+ # Base fields to always keep in data entries
2287
+ BASE_FIELDS = {"datapoint", "operand_reference_id"}
2248
2288
 
2249
2289
  def clean_node(node):
2250
2290
  if isinstance(node, dict):
@@ -2252,9 +2292,22 @@ class ASTGeneratorAPI:
2252
2292
  if node.get("class_name") == "VarID" and "data" in node:
2253
2293
  cleaned_data = []
2254
2294
  for data_entry in node["data"]:
2295
+ # Build allowed fields based on which coordinates are present
2296
+ # Only keep row/column/sheet if the corresponding x/y/z coordinate exists
2297
+ allowed = set(BASE_FIELDS)
2298
+ if "x" in data_entry:
2299
+ allowed.add("x")
2300
+ allowed.add("row")
2301
+ if "y" in data_entry:
2302
+ allowed.add("y")
2303
+ allowed.add("column")
2304
+ if "z" in data_entry:
2305
+ allowed.add("z")
2306
+ allowed.add("sheet")
2307
+
2255
2308
  # Keep only allowed fields
2256
2309
  cleaned_entry = {
2257
- k: v for k, v in data_entry.items() if k in ALLOWED_FIELDS
2310
+ k: v for k, v in data_entry.items() if k in allowed
2258
2311
  }
2259
2312
  cleaned_data.append(cleaned_entry)
2260
2313
  node["data"] = cleaned_data
@@ -406,9 +406,9 @@ class ASTToJSONVisitor(NodeVisitor):
406
406
  }
407
407
 
408
408
  def visit_GetOp(self, node):
409
- """Visit GetOp nodes."""
409
+ """Visit GetOp nodes and serialize as GetClauseOp."""
410
410
  result = {
411
- 'class_name': 'GetOp',
411
+ 'class_name': 'GetClauseOp',
412
412
  'operand': self.visit(node.operand),
413
413
  'component': node.component
414
414
  }
@@ -419,6 +419,15 @@ class ASTToJSONVisitor(NodeVisitor):
419
419
 
420
420
  return result
421
421
 
422
+ def visit_SubOp(self, node):
423
+ """Visit SubOp nodes and serialize as SubClauseOp."""
424
+ return {
425
+ 'class_name': 'SubClauseOp',
426
+ 'operand': self.visit(node.operand),
427
+ 'property_code': node.property_code,
428
+ 'value': self.visit(node.value)
429
+ }
430
+
422
431
  def visit_WhereClauseOp(self, node):
423
432
  """Visit WhereClauseOp nodes."""
424
433
  return {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydpm_xl
3
- Version: 0.2.10
3
+ Version: 0.2.12
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=8RZiE-F0XPTFPGEyFhEp9cS-0ahXQN5PMGSlLRrarL8,1859
1
+ py_dpm/__init__.py,sha256=ymVfDvLwtVz1BFDL70Tv8rY5NBXcAYLeNmZomO1_0XM,1859
2
2
  py_dpm/api/__init__.py,sha256=bPWo4KWW99GmGkQbq0yQ3_tbTxvidEVVrWmcDXWz-xA,828
3
3
  py_dpm/api/dpm/__init__.py,sha256=HQflgiRbs1eDi3KTadNhxS1NoaG6PGQDVMvFnuIEfXo,506
4
4
  py_dpm/api/dpm/data_dictionary.py,sha256=q6w_5bFdc6WPd5Z601PpDaCcnIw39CnI4wdby3GJmFU,29893
@@ -7,7 +7,7 @@ py_dpm/api/dpm/hierarchical_queries.py,sha256=X4AbpsWy3iItOTVIdVbtaTmRgOHPf0Y64I
7
7
  py_dpm/api/dpm/instance.py,sha256=v3DWzdaM5gPCecLjwjZ49FGfqZzUR3dPC0U8zGwdttk,3795
8
8
  py_dpm/api/dpm/migration.py,sha256=9FT7zzz4QdUIRR6MD01gMODBtfq9HH_RF4hRgZqMcZc,2404
9
9
  py_dpm/api/dpm_xl/__init__.py,sha256=SOsCtwxuCkFQIdYoTcU6tVJdK1j96dPF4ZQpr8okLPc,576
10
- py_dpm/api/dpm_xl/ast_generator.py,sha256=hmfy2qV5t_RFGgmid7YuCXbrkjknv1KuQaJGxbXuHLs,97583
10
+ py_dpm/api/dpm_xl/ast_generator.py,sha256=38Kvz9b_SxX1rCMeJ5FqD4y73yNxoQvAPlmqGT5aMNM,100504
11
11
  py_dpm/api/dpm_xl/complete_ast.py,sha256=jjn9tsns4X7EN4RV5mFh5DRxxZfBOuX2b1wic4oB_ls,3967
12
12
  py_dpm/api/dpm_xl/operation_scopes.py,sha256=v2t3f2-AiF39hspNtpf_PA94T69JqbymFK9a5hpckRs,48831
13
13
  py_dpm/api/dpm_xl/semantic.py,sha256=Ddmh2Wj_iXIpQZ4jCjqOI-6ddFCquaO9RTu6W9i1Rts,13968
@@ -69,16 +69,16 @@ py_dpm/dpm_xl/utils/data_handlers.py,sha256=a0E-IaP_-CDKLcj-Gt2ggAziKIOUiwnT2D9I
69
69
  py_dpm/dpm_xl/utils/operands_mapping.py,sha256=LG0hPlUuTM2X2uWOtiD6HkmNeDEJkWJ8gV-Fxej_8QM,2241
70
70
  py_dpm/dpm_xl/utils/operator_mapping.py,sha256=BFgbVbSCSuutFNHJ4gtgm5VuG38pcl8Kmfi-sefg6JU,1913
71
71
  py_dpm/dpm_xl/utils/scopes_calculator.py,sha256=do_emsUqD1TbrjguKlOOqFleaVhxzqm-NnlgdrdIb6I,20906
72
- py_dpm/dpm_xl/utils/serialization.py,sha256=4ZBHIP-67_19QSxqzkv8GPh3RNJ861if26GKbV9Bxj8,33088
72
+ py_dpm/dpm_xl/utils/serialization.py,sha256=leCZFHyaPjskLM1P27oupXfTdO5Pcbf7R_MFsLCMT28,33429
73
73
  py_dpm/dpm_xl/utils/tokens.py,sha256=VRIrPDi5ttwgH-on5Qt4-l4ho4bLA755-nfTalponcA,3496
74
74
  py_dpm/exceptions/__init__.py,sha256=yDERfUxYW7NUUEiTQChGpuJx6abr7IDe2XUpwVFPtvM,416
75
75
  py_dpm/exceptions/exceptions.py,sha256=6S3p-_i5O1oStvSMixt_JQG0xwTeSfBcdzrwL8yBy6Q,2413
76
76
  py_dpm/exceptions/messages.py,sha256=UwY6QIK8c-POcDCc9HYbZFGArCIYAanUGNh2LNKPx3U,7534
77
77
  py_dpm/instance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
78
  py_dpm/instance/instance.py,sha256=gRSg2dh1nEa0Srx9yKcN3bxiYidvZyRU_jsTNaKkP5I,10882
79
- pydpm_xl-0.2.10.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
80
- pydpm_xl-0.2.10.dist-info/METADATA,sha256=SPIgOJT90xDaqE4CYrE2VIsWXOAzGmXbLlI8Yl7yv9I,9154
81
- pydpm_xl-0.2.10.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
82
- pydpm_xl-0.2.10.dist-info/entry_points.txt,sha256=6DDmBfw-AjtgvMHgq_I730i_LAAs_7-N3C95HD_bRr4,47
83
- pydpm_xl-0.2.10.dist-info/top_level.txt,sha256=495PvWZRoKl2NvbQU25W7dqWIBHqY-mFMPt83uxPpcM,7
84
- pydpm_xl-0.2.10.dist-info/RECORD,,
79
+ pydpm_xl-0.2.12.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
80
+ pydpm_xl-0.2.12.dist-info/METADATA,sha256=lVK_kKSvGgw03PWz5sgSETcEPgeoep0tr9xf7E6L5yA,9154
81
+ pydpm_xl-0.2.12.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
82
+ pydpm_xl-0.2.12.dist-info/entry_points.txt,sha256=6DDmBfw-AjtgvMHgq_I730i_LAAs_7-N3C95HD_bRr4,47
83
+ pydpm_xl-0.2.12.dist-info/top_level.txt,sha256=495PvWZRoKl2NvbQU25W7dqWIBHqY-mFMPt83uxPpcM,7
84
+ pydpm_xl-0.2.12.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5