pydpm_xl 0.2.5rc3__py3-none-any.whl → 0.2.7__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.
@@ -239,6 +239,7 @@ class ExplorerQuery:
239
239
  row_code: Optional[str] = None,
240
240
  column_code: Optional[str] = None,
241
241
  sheet_code: Optional[str] = None,
242
+ module_code: Optional[str] = None,
242
243
  release_id: Optional[int] = None,
243
244
  release_code: Optional[str] = None,
244
245
  date: Optional[str] = None,
@@ -326,6 +327,8 @@ class ExplorerQuery:
326
327
  q = q.filter(hv_col.code == column_code)
327
328
  if sheet_code is not None:
328
329
  q = q.filter(hv_sheet.code == sheet_code)
330
+ if module_code is not None:
331
+ q = q.filter(ModuleVersion.code == module_code)
329
332
 
330
333
  # Apply standard release/date filtering on ModuleVersion.
331
334
  # For this method, if no release argument is provided, we default
@@ -350,3 +353,119 @@ class ExplorerQuery:
350
353
 
351
354
  results = q.all()
352
355
  return [dict(row._mapping) for row in results]
356
+
357
+ @staticmethod
358
+ def get_variable_by_code(
359
+ session: Session,
360
+ variable_code: str,
361
+ release_id: Optional[int] = None,
362
+ release_code: Optional[str] = None,
363
+ ) -> Optional[Dict[str, Any]]:
364
+ """
365
+ Get variable_id and variable_vid for a given variable code.
366
+
367
+ This is useful for resolving precondition variable references like {v_C_01.00}
368
+ where the variable code is the table code (e.g., "C_01.00").
369
+
370
+ Args:
371
+ session: SQLAlchemy session
372
+ variable_code: The variable code to look up (e.g., "C_01.00")
373
+ release_id: Optional release ID to filter by
374
+ release_code: Optional release code to filter by
375
+
376
+ Returns:
377
+ Dict with variable_id and variable_vid if found, None otherwise.
378
+ If multiple versions exist, returns the one matching the release filter
379
+ or the latest active version if no filter is provided.
380
+ """
381
+ if release_id is not None and release_code is not None:
382
+ raise ValueError(
383
+ "Specify a maximum of one of release_id or release_code."
384
+ )
385
+
386
+ q = (
387
+ session.query(
388
+ VariableVersion.variableid.label("variable_id"),
389
+ VariableVersion.variablevid.label("variable_vid"),
390
+ VariableVersion.code.label("variable_code"),
391
+ VariableVersion.name.label("variable_name"),
392
+ )
393
+ .select_from(VariableVersion)
394
+ .filter(VariableVersion.code == variable_code)
395
+ )
396
+
397
+ # Apply release filtering
398
+ if release_id or release_code:
399
+ q = filter_by_release(
400
+ q,
401
+ start_col=VariableVersion.startreleaseid,
402
+ end_col=VariableVersion.endreleaseid,
403
+ release_id=release_id,
404
+ release_code=release_code,
405
+ )
406
+ else:
407
+ # Default to active-only (endreleaseid is NULL)
408
+ q = filter_active_only(q, end_col=VariableVersion.endreleaseid)
409
+
410
+ result = q.first()
411
+ if result:
412
+ return dict(result._mapping)
413
+ return None
414
+
415
+ @staticmethod
416
+ def get_variables_by_codes(
417
+ session: Session,
418
+ variable_codes: List[str],
419
+ release_id: Optional[int] = None,
420
+ release_code: Optional[str] = None,
421
+ ) -> Dict[str, Dict[str, Any]]:
422
+ """
423
+ Batch lookup of variable_id and variable_vid for multiple variable codes.
424
+
425
+ This is more efficient than calling get_variable_by_code multiple times
426
+ when resolving multiple precondition variables.
427
+
428
+ Args:
429
+ session: SQLAlchemy session
430
+ variable_codes: List of variable codes to look up
431
+ release_id: Optional release ID to filter by
432
+ release_code: Optional release code to filter by
433
+
434
+ Returns:
435
+ Dict mapping variable_code to {variable_id, variable_vid, ...}
436
+ Only includes codes that were found in the database.
437
+ """
438
+ if release_id is not None and release_code is not None:
439
+ raise ValueError(
440
+ "Specify a maximum of one of release_id or release_code."
441
+ )
442
+
443
+ if not variable_codes:
444
+ return {}
445
+
446
+ q = (
447
+ session.query(
448
+ VariableVersion.variableid.label("variable_id"),
449
+ VariableVersion.variablevid.label("variable_vid"),
450
+ VariableVersion.code.label("variable_code"),
451
+ VariableVersion.name.label("variable_name"),
452
+ )
453
+ .select_from(VariableVersion)
454
+ .filter(VariableVersion.code.in_(variable_codes))
455
+ )
456
+
457
+ # Apply release filtering
458
+ if release_id or release_code:
459
+ q = filter_by_release(
460
+ q,
461
+ start_col=VariableVersion.startreleaseid,
462
+ end_col=VariableVersion.endreleaseid,
463
+ release_id=release_id,
464
+ release_code=release_code,
465
+ )
466
+ else:
467
+ # Default to active-only (endreleaseid is NULL)
468
+ q = filter_active_only(q, end_col=VariableVersion.endreleaseid)
469
+
470
+ results = q.all()
471
+ return {row.variable_code: dict(row._mapping) for row in results}
py_dpm/dpm/utils.py CHANGED
@@ -84,7 +84,7 @@ sessionMakerObject = None
84
84
  _current_engine_url = None
85
85
 
86
86
 
87
- def create_engine_from_url(connection_url):
87
+ def create_engine_from_url(connection_url, pool_config=None):
88
88
  """
89
89
  Create SQLAlchemy engine from a connection URL with appropriate pooling parameters.
90
90
 
@@ -96,6 +96,12 @@ def create_engine_from_url(connection_url):
96
96
 
97
97
  Args:
98
98
  connection_url (str): SQLAlchemy connection URL (e.g., 'sqlite:///path.db', 'postgresql://user:pass@host/db')
99
+ pool_config (dict, optional): Custom pool configuration. Supported keys:
100
+ - pool_size (int): Maximum number of connections to maintain in the pool (default: 20)
101
+ - max_overflow (int): Maximum overflow connections beyond pool_size (default: 10)
102
+ - pool_timeout (int): Seconds to wait before giving up on getting a connection (default: 30)
103
+ - pool_recycle (int): Seconds before recycling connections (default: 180)
104
+ - pool_pre_ping (bool): Health check connections before using from pool (default: True)
99
105
 
100
106
  Returns:
101
107
  sqlalchemy.engine.Engine: Configured database engine
@@ -103,6 +109,8 @@ def create_engine_from_url(connection_url):
103
109
  Examples:
104
110
  >>> engine = create_engine_from_url('sqlite:///database.db')
105
111
  >>> engine = create_engine_from_url('postgresql://user:pass@localhost/mydb')
112
+ >>> engine = create_engine_from_url('postgresql://user:pass@localhost/mydb',
113
+ ... pool_config={'pool_size': 5, 'max_overflow': 10})
106
114
  """
107
115
  global engine, sessionMakerObject, _current_engine_url
108
116
 
@@ -123,12 +131,22 @@ def create_engine_from_url(connection_url):
123
131
  engine = create_engine(connection_url, pool_pre_ping=True)
124
132
  else:
125
133
  # Server-based databases (PostgreSQL, MySQL, etc.) with connection pooling
134
+ # Default pool configuration
135
+ default_pool_config = {
136
+ 'pool_size': 20,
137
+ 'max_overflow': 10,
138
+ 'pool_timeout': 30,
139
+ 'pool_recycle': 180,
140
+ 'pool_pre_ping': True,
141
+ }
142
+
143
+ # Merge custom pool_config with defaults
144
+ if pool_config:
145
+ default_pool_config.update(pool_config)
146
+
126
147
  engine = create_engine(
127
148
  connection_url,
128
- pool_size=20,
129
- max_overflow=10,
130
- pool_recycle=180,
131
- pool_pre_ping=True,
149
+ **default_pool_config
132
150
  )
133
151
 
134
152
  # Initialize global sessionMakerObject
@@ -170,7 +188,7 @@ def create_engine_object(url):
170
188
  return engine
171
189
 
172
190
 
173
- def get_engine(owner=None, database_path=None, connection_url=None):
191
+ def get_engine(owner=None, database_path=None, connection_url=None, pool_config=None):
174
192
  """
175
193
  Get database engine based on configuration or explicit parameters.
176
194
 
@@ -184,13 +202,14 @@ def get_engine(owner=None, database_path=None, connection_url=None):
184
202
  owner: Owner for SQL Server databases (EBA/EIOPA) - legacy support
185
203
  database_path: Explicit SQLite database path
186
204
  connection_url: Explicit SQLAlchemy connection URL (e.g., for PostgreSQL)
205
+ pool_config: Connection pool configuration dict (for PostgreSQL/MySQL)
187
206
 
188
207
  Returns:
189
208
  SQLAlchemy Engine
190
209
  """
191
210
  # Priority 1: If explicit connection URL is provided, use it directly
192
211
  if connection_url:
193
- return create_engine_from_url(connection_url)
212
+ return create_engine_from_url(connection_url, pool_config=pool_config)
194
213
 
195
214
  # Priority 2: If explicit database_path is provided, use SQLite with that path
196
215
  if database_path:
@@ -71,9 +71,19 @@ class OperationScopeService:
71
71
  if len(modules_info_dataframe) == 1:
72
72
  module_vid = modules_vids[0]
73
73
  from_date = modules_info_dataframe["FromReferenceDate"].values[0]
74
+ to_date = modules_info_dataframe["ToReferenceDate"].values[0]
75
+ module_code = modules_info_dataframe["ModuleCode"].values[0]
76
+ version_number = modules_info_dataframe["VersionNumber"].values[0]
74
77
  operation_scope = self.create_operation_scope(from_date)
75
78
  self.create_operation_scope_composition(
76
- operation_scope=operation_scope, module_vid=module_vid
79
+ operation_scope=operation_scope,
80
+ module_vid=module_vid,
81
+ module_info={
82
+ "code": module_code,
83
+ "version_number": version_number,
84
+ "from_reference_date": from_date,
85
+ "to_reference_date": to_date,
86
+ },
77
87
  )
78
88
  else:
79
89
  intra_modules = []
@@ -83,11 +93,10 @@ class OperationScopeService:
83
93
  if table_codes:
84
94
  unique_operands_number = len(table_codes) + len(precondition_items)
85
95
 
86
- # Categorize modules by lifecycle: starting vs ending in this release
87
- starting_modules = (
88
- {}
89
- ) # Modules that START in this release (replacements)
90
- ending_modules = {} # Modules that END in this release (being replaced)
96
+ # First pass: categorize modules by table code and lifecycle
97
+ # We track lifecycle to handle version transitions within the SAME module
98
+ starting_by_code = {} # table_code -> [module_vids that START in this release]
99
+ ending_by_code = {} # table_code -> [module_vids that END or are active]
91
100
 
92
101
  for module_vid, group_df in modules_info_dataframe.groupby(MODULE_VID):
93
102
  table_codes_in_module = (
@@ -105,31 +114,55 @@ class OperationScopeService:
105
114
  end_release = group_df["EndReleaseID"].values[0]
106
115
 
107
116
  # Determine if this is a "new" module starting in this release
108
- # or an "old" module ending in this release
109
117
  is_starting = start_release == release_id
110
- is_ending = end_release == release_id or end_release == float(
111
- release_id
112
- )
113
118
 
114
119
  if len(table_codes_in_module) == unique_operands_number:
115
120
  # Intra-module: include ALL modules active in the release
116
- # (don't filter by lifecycle - that's only for cross-module)
117
121
  intra_modules.append(module_vid)
118
122
  else:
119
- # For cross-module, group by table code AND lifecycle stage
120
- target_dict = (
121
- starting_modules if is_starting else ending_modules
122
- )
123
+ # Track modules by table code and lifecycle
123
124
  for table_code in table_codes_in_module:
124
- if table_code not in target_dict:
125
- target_dict[table_code] = []
126
- target_dict[table_code].append(module_vid)
127
-
128
- # Process cross-module scopes separately for each generation
129
- if starting_modules:
130
- cross_modules["_starting"] = starting_modules
131
- if ending_modules:
132
- cross_modules["_ending"] = ending_modules
125
+ if is_starting:
126
+ if table_code not in starting_by_code:
127
+ starting_by_code[table_code] = []
128
+ starting_by_code[table_code].append(module_vid)
129
+ else:
130
+ if table_code not in ending_by_code:
131
+ ending_by_code[table_code] = []
132
+ ending_by_code[table_code].append(module_vid)
133
+
134
+ # Second pass: determine if lifecycle separation is needed
135
+ # Only separate if a table code has modules in BOTH starting and ending
136
+ # (indicating a version transition for that table)
137
+ needs_lifecycle_separation = any(
138
+ code in starting_by_code and code in ending_by_code
139
+ for code in set(starting_by_code.keys()) | set(ending_by_code.keys())
140
+ )
141
+
142
+ if needs_lifecycle_separation:
143
+ # Separate into starting and ending scopes
144
+ starting_modules = {}
145
+ ending_modules = {}
146
+ for code, vids in starting_by_code.items():
147
+ starting_modules[code] = vids
148
+ for code, vids in ending_by_code.items():
149
+ ending_modules[code] = vids
150
+ if starting_modules:
151
+ cross_modules["_starting"] = starting_modules
152
+ if ending_modules:
153
+ cross_modules["_ending"] = ending_modules
154
+ else:
155
+ # No version transitions - combine all modules by table code
156
+ all_by_code = {}
157
+ for code, vids in starting_by_code.items():
158
+ if code not in all_by_code:
159
+ all_by_code[code] = []
160
+ all_by_code[code].extend(vids)
161
+ for code, vids in ending_by_code.items():
162
+ if code not in all_by_code:
163
+ all_by_code[code] = []
164
+ all_by_code[code].extend(vids)
165
+ cross_modules = all_by_code
133
166
  else:
134
167
  # Original logic for table VIDs
135
168
  unique_operands_number = len(tables_vids) + len(precondition_items)
@@ -268,12 +301,21 @@ class OperationScopeService:
268
301
  :param modules_vids: list with module version ids
269
302
  """
270
303
  for module_vid in modules_vids:
271
- from_date = modules_info[modules_info["ModuleVID"] == module_vid][
272
- "FromReferenceDate"
273
- ].values[0]
304
+ module_row = modules_info[modules_info["ModuleVID"] == module_vid].iloc[0]
305
+ from_date = module_row["FromReferenceDate"]
306
+ to_date = module_row["ToReferenceDate"]
307
+ module_code = module_row["ModuleCode"]
308
+ version_number = module_row["VersionNumber"]
274
309
  operation_scope = self.create_operation_scope(from_date)
275
310
  self.create_operation_scope_composition(
276
- operation_scope=operation_scope, module_vid=module_vid
311
+ operation_scope=operation_scope,
312
+ module_vid=module_vid,
313
+ module_info={
314
+ "code": module_code,
315
+ "version_number": version_number,
316
+ "from_reference_date": from_date,
317
+ "to_reference_date": to_date,
318
+ },
277
319
  )
278
320
 
279
321
  def process_cross_module(self, cross_modules, modules_dataframe):
@@ -313,8 +355,18 @@ class OperationScopeService:
313
355
  operation_scope = self.create_operation_scope(from_submission_date)
314
356
  combination = set(combination)
315
357
  for module in combination:
358
+ module_row = modules_dataframe[
359
+ modules_dataframe[MODULE_VID] == module
360
+ ].iloc[0]
316
361
  self.create_operation_scope_composition(
317
- operation_scope=operation_scope, module_vid=module
362
+ operation_scope=operation_scope,
363
+ module_vid=module,
364
+ module_info={
365
+ "code": module_row["ModuleCode"],
366
+ "version_number": module_row["VersionNumber"],
367
+ "from_reference_date": module_row[FROM_REFERENCE_DATE],
368
+ "to_reference_date": module_row[TO_REFERENCE_DATE],
369
+ },
318
370
  )
319
371
 
320
372
  def create_operation_scope(self, submission_date):
@@ -340,17 +392,21 @@ class OperationScopeService:
340
392
  self.session.add(operation_scope)
341
393
  return operation_scope
342
394
 
343
- def create_operation_scope_composition(self, operation_scope, module_vid):
395
+ def create_operation_scope_composition(self, operation_scope, module_vid, module_info=None):
344
396
  """
345
397
  Method to populate OperationScopeComposition table
346
398
  :param operation_scope: Operation scope data
347
399
  :param module_vid: Module version id
400
+ :param module_info: Optional dict with module info (code, from_reference_date, to_reference_date)
348
401
  """
349
402
  operation_scope_composition = OperationScopeComposition(
350
403
  operation_scope=operation_scope,
351
404
  modulevid=module_vid,
352
405
  rowguid=str(uuid.uuid4()),
353
406
  )
407
+ # Store module info as transient attribute for to_dict() access
408
+ if module_info:
409
+ operation_scope_composition._module_info = module_info
354
410
  self.session.add(operation_scope_composition)
355
411
 
356
412
  def get_scopes_with_status(self):
@@ -361,12 +361,14 @@ class ASTToJSONVisitor(NodeVisitor):
361
361
  'op': node.op,
362
362
  'operand': self.visit(node.operand),
363
363
  }
364
- # Add grouping_clause if present and has actual components
364
+ # Always include grouping_clause (null when not present or empty)
365
+ grouping_clause = None
365
366
  if hasattr(node, 'grouping_clause') and node.grouping_clause is not None:
366
367
  gc = self.visit(node.grouping_clause)
367
- # Only include grouping_clause if it has components
368
+ # Only set to actual value if it has components
368
369
  if gc and gc.get('components'):
369
- result['grouping_clause'] = gc
370
+ grouping_clause = gc
371
+ result['grouping_clause'] = grouping_clause
370
372
  return result
371
373
 
372
374
  def visit_GroupingClause(self, node):
@@ -169,6 +169,7 @@ class Instance:
169
169
  row_code=None,
170
170
  column_code=None,
171
171
  sheet_code=None,
172
+ module_code=instance_json["module_code"],
172
173
  date=ref_period,
173
174
  )
174
175
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydpm_xl
3
- Version: 0.2.5rc3
3
+ Version: 0.2.7
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,27 +1,27 @@
1
- py_dpm/__init__.py,sha256=zPA7CdwYtnZIaZc8jniwDoBwlzur7Wj1qOl35ZvmcHo,1861
2
- py_dpm/api/__init__.py,sha256=n79vAD7qatlYaXaI2N5IAD9m_8Fgb00EOdapVXZYTpI,1081
1
+ py_dpm/__init__.py,sha256=a2pLEJ-WUNGj-wIL9gxgvcBpavgpyCKq-DbzJMC2dbA,1858
2
+ py_dpm/api/__init__.py,sha256=6ElO0NKEjuqiHNxK7pxkzLNlaUOrYKnY3N0fUDDobik,1021
3
3
  py_dpm/api/dpm/__init__.py,sha256=HQflgiRbs1eDi3KTadNhxS1NoaG6PGQDVMvFnuIEfXo,506
4
- py_dpm/api/dpm/data_dictionary.py,sha256=g0h6Yfschz7rboYly9LTbP-2SS5UxltU3AXu0v0tqrU,29457
5
- py_dpm/api/dpm/explorer.py,sha256=gW2RC59XwGl9YbEA-M4syHAs6MvqPWVw4wR_XdVFJ4Y,7888
4
+ py_dpm/api/dpm/data_dictionary.py,sha256=q6w_5bFdc6WPd5Z601PpDaCcnIw39CnI4wdby3GJmFU,29893
5
+ py_dpm/api/dpm/explorer.py,sha256=xgrSdh2D83RivypF26WWo20rbQifYBEH7PXvINoi07Y,10861
6
6
  py_dpm/api/dpm/hierarchical_queries.py,sha256=X4AbpsWy3iItOTVIdVbtaTmRgOHPf0Y64Ig-_377uns,4054
7
7
  py_dpm/api/dpm/instance.py,sha256=v3DWzdaM5gPCecLjwjZ49FGfqZzUR3dPC0U8zGwdttk,3795
8
8
  py_dpm/api/dpm/migration.py,sha256=9FT7zzz4QdUIRR6MD01gMODBtfq9HH_RF4hRgZqMcZc,2404
9
- py_dpm/api/dpm_xl/__init__.py,sha256=aRjaMAf_i2a33UAGTg-TF1BfO6miOOrbCydTUqAVvRU,910
10
- py_dpm/api/dpm_xl/ast_generator.py,sha256=GHu_F3YKaMpqvu16ABIvj8BwlmWXehvk0eUJVQkCphE,55204
11
- py_dpm/api/dpm_xl/complete_ast.py,sha256=VkmcBatrydu97Inwp3pHjz93F38q2JRo-4Lohdu30RY,7684
12
- py_dpm/api/dpm_xl/operation_scopes.py,sha256=7AyOFAn9h012JPF9H5EtZ3sPzv6DOxkoinpj5ArzVOc,48492
13
- py_dpm/api/dpm_xl/semantic.py,sha256=Buo_t-sEv65r6RmYDy1xkCWGlU2pB2WQsDM-X-FX4cc,13629
9
+ py_dpm/api/dpm_xl/__init__.py,sha256=cwqeYgmowGH6MK8kQMQkjQaTL9qKEnC8-M5rueqhrPI,850
10
+ py_dpm/api/dpm_xl/ast_generator.py,sha256=7EEUEmXMwck7obL3rnBjHeDnsM0F-LHnpUZNd3rVjHI,94929
11
+ py_dpm/api/dpm_xl/complete_ast.py,sha256=_FSxA0FmNXuW0OLS3c8yzp14yjkmdR0rTebBAs1pg-E,8141
12
+ py_dpm/api/dpm_xl/operation_scopes.py,sha256=v2t3f2-AiF39hspNtpf_PA94T69JqbymFK9a5hpckRs,48831
13
+ py_dpm/api/dpm_xl/semantic.py,sha256=Ddmh2Wj_iXIpQZ4jCjqOI-6ddFCquaO9RTu6W9i1Rts,13968
14
14
  py_dpm/api/dpm_xl/syntax.py,sha256=Ke_kKd9ModoJ6siL3GPT9j9QClmopryCRcdDAT3M5-E,5954
15
15
  py_dpm/cli/__init__.py,sha256=UrfGHoQ0sZLjWfA0hoOoI4iTrn-bjr2f9Q8wDWd5nMo,133
16
- py_dpm/cli/main.py,sha256=v8ZgIjg4Zqf6UWNv2bydYlZV6KfDLnPACyqplNIJyNE,22447
16
+ py_dpm/cli/main.py,sha256=LJ7JBk7lyWXe7ZYxnbxmohM1Dbha4sIdQzSTYKd9ZNo,22457
17
17
  py_dpm/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  py_dpm/dpm/__init__.py,sha256=moagUo5Gxf24-Tl9FL_3n2wmVoD_oXtpC-YIGktH_rc,212
19
19
  py_dpm/dpm/migration.py,sha256=ivO_ObvKzVomTns6qfo-o5FuciWxkXbMd_gJ4_tu7Xc,14110
20
- py_dpm/dpm/models.py,sha256=d70oZ_3wXsKBRGM2TJRlsuDrHWSVkzetLAZeMIoImwc,124821
21
- py_dpm/dpm/utils.py,sha256=JNdAeOXjzQtye94jLPRHHGUMcvkGtTsjA5HFl92rWig,12783
20
+ py_dpm/dpm/models.py,sha256=Rt1b8zOSayXd9KhwyfkGJVhCai3YxUakmLYgwaiICWA,135660
21
+ py_dpm/dpm/utils.py,sha256=lyAZjMVrvVXXNw4e-3J0W6Q6o4YeZTgBtgn6BkPFTfI,13953
22
22
  py_dpm/dpm/queries/base.py,sha256=EddMeJMwtp63DyyIFO7_XxGvdlCtJQWWpeOVImlKp4I,3648
23
23
  py_dpm/dpm/queries/basic_objects.py,sha256=JOXC235lMDfVENrFAhZAl7_nqePJ4RrwJhFF0WDyk0M,955
24
- py_dpm/dpm/queries/explorer_queries.py,sha256=Co8CzdzlDrOL5-ZxY7_HoHPaP_j-xjLDSsB8EKT5aC8,13034
24
+ py_dpm/dpm/queries/explorer_queries.py,sha256=HcLfwpdGWX-q-i1L-7W0nwTxL_0OiDliqPUeoZ9zHZ4,17453
25
25
  py_dpm/dpm/queries/filters.py,sha256=fxC2KLYpIvtmuyuJFb0te2ULiyDnQBZfVM79VQnr6qA,4901
26
26
  py_dpm/dpm/queries/glossary.py,sha256=2SqKZghQTw-E8NWwHebDHuDC8BC389fGe-0UBIVfJ8Q,1571
27
27
  py_dpm/dpm/queries/hierarchical_queries.py,sha256=FYO2p_OxZioynXW4nGCQ3UG3p3uzE28KdsmMaQSk1wk,31538
@@ -68,17 +68,17 @@ py_dpm/dpm_xl/utils/__init__.py,sha256=4-jXa7AdHjx2DpikAzjZVKqBktdrHgSAx6pibb4sM
68
68
  py_dpm/dpm_xl/utils/data_handlers.py,sha256=a0E-IaP_-CDKLcj-Gt2ggAziKIOUiwnT2D9IkWCS68o,4402
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
- py_dpm/dpm_xl/utils/scopes_calculator.py,sha256=nCx2mz_qtw61BESp38ORQYlF2uRT8SyUKawSX9OQljM,17832
72
- py_dpm/dpm_xl/utils/serialization.py,sha256=LPcmudFfzHeEjIIr57kr5BvGPZbxshOAAeUYOrLl7XM,32482
71
+ py_dpm/dpm_xl/utils/scopes_calculator.py,sha256=do_emsUqD1TbrjguKlOOqFleaVhxzqm-NnlgdrdIb6I,20906
72
+ py_dpm/dpm_xl/utils/serialization.py,sha256=ouQpkmZWc6_T0hVzjwmxpHRu9yheNyyMBBaOZERe0qM,32558
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
- py_dpm/instance/instance.py,sha256=OPSEPgSYAxhgqhKuxbMpMPTfBnaFNzURTrUUT4kvGKc,10820
79
- pydpm_xl-0.2.5rc3.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
80
- pydpm_xl-0.2.5rc3.dist-info/METADATA,sha256=W-1lvyIWG91rZpsouuv4hzolwcUT6pksvJlj_9pl-dE,9305
81
- pydpm_xl-0.2.5rc3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
82
- pydpm_xl-0.2.5rc3.dist-info/entry_points.txt,sha256=6DDmBfw-AjtgvMHgq_I730i_LAAs_7-N3C95HD_bRr4,47
83
- pydpm_xl-0.2.5rc3.dist-info/top_level.txt,sha256=495PvWZRoKl2NvbQU25W7dqWIBHqY-mFMPt83uxPpcM,7
84
- pydpm_xl-0.2.5rc3.dist-info/RECORD,,
78
+ py_dpm/instance/instance.py,sha256=gRSg2dh1nEa0Srx9yKcN3bxiYidvZyRU_jsTNaKkP5I,10882
79
+ pydpm_xl-0.2.7.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
80
+ pydpm_xl-0.2.7.dist-info/METADATA,sha256=Tg3xyWRxhUd3w1pKuv5iNBYTRq_VkZzIH533JzyaBYQ,9302
81
+ pydpm_xl-0.2.7.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
82
+ pydpm_xl-0.2.7.dist-info/entry_points.txt,sha256=6DDmBfw-AjtgvMHgq_I730i_LAAs_7-N3C95HD_bRr4,47
83
+ pydpm_xl-0.2.7.dist-info/top_level.txt,sha256=495PvWZRoKl2NvbQU25W7dqWIBHqY-mFMPt83uxPpcM,7
84
+ pydpm_xl-0.2.7.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5