pum 1.3.1__py3-none-any.whl → 1.3.3__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):
@@ -112,32 +111,38 @@ class HookHandler:
112
111
  parent_dir = str(self.file.parent.resolve())
113
112
 
114
113
  # Store paths that need to be added for hook execution
115
- # Add parent directory of the hook file
116
- if parent_dir not in sys.path:
117
- self.sys_path_additions.append(parent_dir)
114
+ # Always add paths even if already in sys.path - we need them at position 0
115
+ # for priority and we'll track what we added for cleanup
116
+ self.sys_path_additions.append(parent_dir)
118
117
 
119
118
  # Also add base_path if provided, to support imports from sibling directories
120
119
  if base_path is not None:
121
120
  base_path_str = str(base_path.resolve())
122
- if base_path_str not in sys.path and base_path_str != parent_dir:
121
+ if 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
+ # 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())
128
+ # Invalidate caches so Python recognizes the new paths
129
+ importlib.invalidate_caches()
131
130
 
132
131
  try:
133
- spec = importlib.util.spec_from_file_location(self.file.stem, self.file)
132
+ logger.debug(f"Loading hook from: {self.file}")
133
+ logger.debug(f"sys.path additions: {self.sys_path_additions}")
134
+ spec = importlib.util.spec_from_file_location(
135
+ self.file.stem,
136
+ self.file,
137
+ submodule_search_locations=[parent_dir],
138
+ )
134
139
  module = importlib.util.module_from_spec(spec)
140
+ # Set __path__ to enable package-like imports from the hook's directory
141
+ module.__path__ = [parent_dir]
142
+ # Add to sys.modules before executing so imports can find it
143
+ sys.modules[self.file.stem] = module
135
144
  spec.loader.exec_module(module)
136
145
 
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
146
  # Check that the module contains a class named Hook inheriting from HookBase
142
147
  # Do this BEFORE removing paths from sys.path
143
148
  hook_class = getattr(module, "Hook", None)
@@ -176,21 +181,22 @@ class HookHandler:
176
181
  arg for arg in arg_names if arg not in ("self", "connection")
177
182
  ]
178
183
 
179
- finally:
180
- # Remove all paths that were added
181
- for path in self.sys_path_additions:
182
- if path in sys.path:
183
- sys.path.remove(path)
184
+ except Exception:
185
+ # On error, clean up paths we added
186
+ self.cleanup_sys_path()
187
+ raise
188
+
189
+ def cleanup_sys_path(self) -> None:
190
+ """Remove paths that were added to sys.path for this hook.
184
191
 
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.
192
+ This should be called when the hook is no longer needed to prevent
193
+ sys.path pollution.
189
194
  """
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()
195
+ for path in self.sys_path_additions:
196
+ # Remove all occurrences of this path (we may have added it multiple times)
197
+ while path in sys.path:
198
+ sys.path.remove(path)
199
+ self.sys_path_additions.clear()
194
200
 
195
201
  def __repr__(self) -> str:
196
202
  """Return a string representation of the Hook instance."""
pum/pum_config.py CHANGED
@@ -184,15 +184,31 @@ class PumConfig:
184
184
  return self._base_path
185
185
 
186
186
  def cleanup_hook_imports(self) -> None:
187
- """Clean up imported modules from hooks to prevent conflicts when switching versions.
187
+ """Clean up imported modules and sys.path entries from hooks.
188
188
 
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
+ # First, clean up sys.path additions from all cached handlers
192
193
  for handler in self._cached_handlers:
193
- if hasattr(handler, "cleanup_imports"):
194
- handler.cleanup_imports()
195
- # Clear the cache after cleanup
194
+ handler.cleanup_sys_path()
195
+
196
+ # Clear all modules that were loaded from this base_path
197
+ base_path_str = str(self._base_path.resolve())
198
+ modules_to_remove = []
199
+
200
+ for module_name, module in list(sys.modules.items()):
201
+ if module is None:
202
+ continue
203
+ module_file = getattr(module, "__file__", None)
204
+ if module_file and module_file.startswith(base_path_str):
205
+ modules_to_remove.append(module_name)
206
+
207
+ for module_name in modules_to_remove:
208
+ if module_name in sys.modules:
209
+ logger.debug(f"Removing cached module: {module_name}")
210
+ del sys.modules[module_name]
211
+
196
212
  self._cached_handlers.clear()
197
213
 
198
214
  def parameters(self) -> list[ParameterDefinition]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pum
3
- Version: 1.3.1
3
+ Version: 1.3.3
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=twhlQtklBHUY2W9PAseTKTMhpsnkl8hNG36I-9oz8iU,12841
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=l9PybZURB4ZUbvVC-QeXyLrtawByWt3OiN2CS5BKiwM,15565
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
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.1.dist-info/licenses/LICENSE,sha256=2ylvL381vKOhdO-w6zkrOxe9lLNBhRQpo9_0EbHC_HM,18046
21
- pum-1.3.1.dist-info/METADATA,sha256=xcbQ-mlS84gzT_6xj2tzxj4JeA2LPf6PowfHY83CfYA,3236
22
- pum-1.3.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
23
- pum-1.3.1.dist-info/entry_points.txt,sha256=U6dmxSpKs1Pe9vWiR29VPhJMDjrmZeJCSxvfLGR8BD4,36
24
- pum-1.3.1.dist-info/top_level.txt,sha256=ddiI4HLBhY6ql-NNm0Ez0JhoOHdWDIzrHeCdHmmagcc,4
25
- pum-1.3.1.dist-info/RECORD,,
20
+ pum-1.3.3.dist-info/licenses/LICENSE,sha256=2ylvL381vKOhdO-w6zkrOxe9lLNBhRQpo9_0EbHC_HM,18046
21
+ pum-1.3.3.dist-info/METADATA,sha256=CKhXiAoGzcAz_bHXF-4g1tyd3XHYNyJ0yU7ug5p31CM,3236
22
+ pum-1.3.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
23
+ pum-1.3.3.dist-info/entry_points.txt,sha256=U6dmxSpKs1Pe9vWiR29VPhJMDjrmZeJCSxvfLGR8BD4,36
24
+ pum-1.3.3.dist-info/top_level.txt,sha256=ddiI4HLBhY6ql-NNm0Ez0JhoOHdWDIzrHeCdHmmagcc,4
25
+ pum-1.3.3.dist-info/RECORD,,
File without changes