pum 1.3.0__py3-none-any.whl → 1.3.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.
pum/hook.py CHANGED
@@ -93,7 +93,6 @@ class HookHandler:
93
93
  self.code = code
94
94
  self.hook_instance = None
95
95
  self.sys_path_additions = [] # Store paths to add during execution
96
- self._imported_modules = [] # Track modules imported by this hook
97
96
 
98
97
  if file:
99
98
  if isinstance(file, str):
@@ -122,22 +121,25 @@ class HookHandler:
122
121
  if base_path_str not in sys.path and base_path_str != parent_dir:
123
122
  self.sys_path_additions.append(base_path_str)
124
123
 
125
- # Temporarily add paths for module loading
126
- for path in self.sys_path_additions:
124
+ # Temporarily add paths for module loading - insert at position 0 for priority
125
+ for path in reversed(self.sys_path_additions):
127
126
  sys.path.insert(0, path)
128
127
 
129
- # Track modules before loading to detect new imports
130
- modules_before = set(sys.modules.keys())
131
-
132
128
  try:
133
- spec = importlib.util.spec_from_file_location(self.file.stem, self.file)
129
+ logger.debug(f"Loading hook from: {self.file}")
130
+ logger.debug(f"sys.path additions: {self.sys_path_additions}")
131
+ spec = importlib.util.spec_from_file_location(
132
+ self.file.stem,
133
+ self.file,
134
+ submodule_search_locations=[parent_dir],
135
+ )
134
136
  module = importlib.util.module_from_spec(spec)
137
+ # Set __path__ to enable package-like imports from the hook's directory
138
+ module.__path__ = [parent_dir]
139
+ # Add to sys.modules before executing so imports can find it
140
+ sys.modules[self.file.stem] = module
135
141
  spec.loader.exec_module(module)
136
142
 
137
- # Track modules that were imported by this hook
138
- modules_after = set(sys.modules.keys())
139
- self._imported_modules = list(modules_after - modules_before)
140
-
141
143
  # Check that the module contains a class named Hook inheriting from HookBase
142
144
  # Do this BEFORE removing paths from sys.path
143
145
  hook_class = getattr(module, "Hook", None)
@@ -182,16 +184,6 @@ class HookHandler:
182
184
  if path in sys.path:
183
185
  sys.path.remove(path)
184
186
 
185
- def cleanup_imports(self):
186
- """Remove imported modules from sys.modules cache.
187
- This should be called when switching to a different module version
188
- to prevent import conflicts.
189
- """
190
- for module_name in self._imported_modules:
191
- if module_name in sys.modules:
192
- del sys.modules[module_name]
193
- self._imported_modules.clear()
194
-
195
187
  def __repr__(self) -> str:
196
188
  """Return a string representation of the Hook instance."""
197
189
  return f"<hook: {self.file}>"
pum/pum_config.py CHANGED
@@ -189,10 +189,22 @@ class PumConfig:
189
189
  This should be called when switching to a different module version to ensure
190
190
  that cached imports from the previous version don't cause conflicts.
191
191
  """
192
- for handler in self._cached_handlers:
193
- if hasattr(handler, "cleanup_imports"):
194
- handler.cleanup_imports()
195
- # Clear the cache after cleanup
192
+ # Clear all modules that were loaded from this base_path
193
+ base_path_str = str(self._base_path.resolve())
194
+ modules_to_remove = []
195
+
196
+ for module_name, module in list(sys.modules.items()):
197
+ if module is None:
198
+ continue
199
+ module_file = getattr(module, "__file__", None)
200
+ if module_file and module_file.startswith(base_path_str):
201
+ modules_to_remove.append(module_name)
202
+
203
+ for module_name in modules_to_remove:
204
+ if module_name in sys.modules:
205
+ logger.debug(f"Removing cached module: {module_name}")
206
+ del sys.modules[module_name]
207
+
196
208
  self._cached_handlers.clear()
197
209
 
198
210
  def parameters(self) -> list[ParameterDefinition]:
pum/schema_migrations.py CHANGED
@@ -74,10 +74,9 @@ class SchemaMigrations:
74
74
  "schema": psycopg.sql.Literal(self.config.config.pum.migration_table_schema),
75
75
  }
76
76
 
77
- with connection.transaction():
78
- cursor = SqlContent(query).execute(connection, parameters=parameters)
79
- result = cursor._pum_results[0] if cursor._pum_results else None
80
- return result[0] if result else False
77
+ cursor = SqlContent(query).execute(connection, parameters=parameters)
78
+ result = cursor._pum_results[0] if cursor._pum_results else None
79
+ return result[0] if result else False
81
80
 
82
81
  def exists_in_other_schemas(self, connection: psycopg.Connection) -> list[str]:
83
82
  """Check if the schema_migrations information table exists in other schemas.
@@ -100,9 +99,8 @@ class SchemaMigrations:
100
99
  parameters = {
101
100
  "schema": psycopg.sql.Literal(self.config.config.pum.migration_table_schema),
102
101
  }
103
- with connection.transaction():
104
- cursor = SqlContent(query).execute(connection, parameters=parameters)
105
- return [row[0] for row in (cursor._pum_results or [])]
102
+ cursor = SqlContent(query).execute(connection, parameters=parameters)
103
+ return [row[0] for row in (cursor._pum_results or [])]
106
104
 
107
105
  def create(
108
106
  self,
@@ -346,14 +344,13 @@ INSERT INTO {table} (
346
344
  "table": self.migration_table_identifier,
347
345
  }
348
346
 
349
- with connection.transaction():
350
- cursor = SqlContent(query).execute(connection, parameters=parameters)
351
- row = cursor._pum_results[0] if cursor._pum_results else None
352
- if row is None:
353
- raise PumSchemaMigrationNoBaselineError(
354
- f"Baseline version not found in the {self.migration_table_identifier_str} table."
355
- )
356
- return packaging.version.parse(row[0])
347
+ cursor = SqlContent(query).execute(connection, parameters=parameters)
348
+ row = cursor._pum_results[0] if cursor._pum_results else None
349
+ if row is None:
350
+ raise PumSchemaMigrationNoBaselineError(
351
+ f"Baseline version not found in the {self.migration_table_identifier_str} table."
352
+ )
353
+ return packaging.version.parse(row[0])
357
354
 
358
355
  def migration_details(self, connection: psycopg.Connection, version: str | None = None) -> dict:
359
356
  """Return the migration details from the migration table.
@@ -404,14 +401,13 @@ INSERT INTO {table} (
404
401
  "version": psycopg.sql.Literal(version),
405
402
  }
406
403
 
407
- with connection.transaction():
408
- cursor = SqlContent(query).execute(connection, parameters=parameters)
409
- row = cursor._pum_results[0] if cursor._pum_results else None
410
- if row is None:
411
- raise PumSchemaMigrationError(
412
- f"Migration details not found for version {version} in the {self.migration_table_identifier_str} table."
413
- )
414
- return dict(zip([desc[0] for desc in cursor._pum_description], row, strict=False))
404
+ cursor = SqlContent(query).execute(connection, parameters=parameters)
405
+ row = cursor._pum_results[0] if cursor._pum_results else None
406
+ if row is None:
407
+ raise PumSchemaMigrationError(
408
+ f"Migration details not found for version {version} in the {self.migration_table_identifier_str} table."
409
+ )
410
+ return dict(zip([desc[0] for desc in cursor._pum_description], row, strict=False))
415
411
 
416
412
  def compare(self, connection: psycopg.Connection) -> int:
417
413
  """Compare the migrations details in the database to the changelogs in the source.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pum
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: Pum stands for "Postgres Upgrades Manager". It is a Database migration management tool very similar to flyway-db or Liquibase, based on metadata tables.
5
5
  Author-email: Denis Rouzaud <denis@opengis.ch>
6
6
  License-Expression: GPL-2.0-or-later
@@ -8,18 +8,18 @@ pum/dependency_handler.py,sha256=1A6720Tv0rBME-gJVLn9PYK46YPXLMD-r9hpNNX8ApY,696
8
8
  pum/dumper.py,sha256=FFRidaOg3ENePNZ61TGbnAdp0TItvWbA4j292Xlf9bA,3878
9
9
  pum/exceptions.py,sha256=h1TEPHI_hSbLLQc6zYfTpFexczv1iKIN7OuTsLTN590,1439
10
10
  pum/feedback.py,sha256=pbZYdhsocjmJbjcdUpvYhI8XLio15htyVg-Cay6HHdE,3810
11
- pum/hook.py,sha256=G-qI1J4erWPWw5mRa-BHFVtA9yYTGcTK3aYmqaoKep8,12528
11
+ pum/hook.py,sha256=KQ-9Y8iHmaN6LVo8WSAHvNzK_JGgO5321HRzsi_yYrY,12316
12
12
  pum/info.py,sha256=75Fr4Bn-ARe36aK8KV31MSCNWDkAdiMgJ-4IvMF73zU,1346
13
13
  pum/parameter.py,sha256=e7Lm5fp2Xg4SEkIDmbxSyNTsYvELCkeyPUeS6CCs6EA,2646
14
- pum/pum_config.py,sha256=k-YF2nL73HcfybjV09G042Xuiu8nRWSxAI43JyiCTsg,14952
14
+ pum/pum_config.py,sha256=XBRUZ8lKnmW445sQmQ61ihX5-ZAs2-MaDhvR7NRTB68,15433
15
15
  pum/report_generator.py,sha256=upv6gpVZ_kk7O6IhcO7LWMlPHg_u_V0wx_LxQebMp-c,38908
16
16
  pum/role_manager.py,sha256=_LG5LR8osc5bVQVb-AKGU3wvXBrIe9J3IV1ECzhiwnA,15991
17
- pum/schema_migrations.py,sha256=P3x15wQaHa4lusY2mfGKLJ8O5Ujo0Btm0s4pWDYjbS4,16536
17
+ pum/schema_migrations.py,sha256=-yR84KkG1mLY5yeEWzidNPam1hrE_1mMC5KJaHOUxiA,16304
18
18
  pum/sql_content.py,sha256=BY5XMS713sIOUT4xLHByOzQhxYItucvkCFEyzmwSTR4,12969
19
19
  pum/upgrader.py,sha256=skGfwfuAb0TLMqCPjRbcJNf1VKmekaaQLm_C-abs61E,18353
20
- pum-1.3.0.dist-info/licenses/LICENSE,sha256=2ylvL381vKOhdO-w6zkrOxe9lLNBhRQpo9_0EbHC_HM,18046
21
- pum-1.3.0.dist-info/METADATA,sha256=6kUys9BbQV0loi32auRRroyWgNDnonPIchQ6Jq8InHg,3236
22
- pum-1.3.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
23
- pum-1.3.0.dist-info/entry_points.txt,sha256=U6dmxSpKs1Pe9vWiR29VPhJMDjrmZeJCSxvfLGR8BD4,36
24
- pum-1.3.0.dist-info/top_level.txt,sha256=ddiI4HLBhY6ql-NNm0Ez0JhoOHdWDIzrHeCdHmmagcc,4
25
- pum-1.3.0.dist-info/RECORD,,
20
+ pum-1.3.2.dist-info/licenses/LICENSE,sha256=2ylvL381vKOhdO-w6zkrOxe9lLNBhRQpo9_0EbHC_HM,18046
21
+ pum-1.3.2.dist-info/METADATA,sha256=5Y-jYtwZGL8ePS1oUL4VnKqJpKj81t8RQQpv9c3SVe8,3236
22
+ pum-1.3.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
23
+ pum-1.3.2.dist-info/entry_points.txt,sha256=U6dmxSpKs1Pe9vWiR29VPhJMDjrmZeJCSxvfLGR8BD4,36
24
+ pum-1.3.2.dist-info/top_level.txt,sha256=ddiI4HLBhY6ql-NNm0Ez0JhoOHdWDIzrHeCdHmmagcc,4
25
+ pum-1.3.2.dist-info/RECORD,,
File without changes