Compare commits

...
Author SHA1 Message Date
praisonai-triage-agent[bot]andMervin Praison becd74a91c fix: balance nested same-instance ImportProfiler enter/exit
Track per-instance entry depth so `with profiler: with profiler:` only
uninstalls the import hook after the final exit, matching the number of
enters. Previously the first inner exit unregistered the context and
restored builtins.__import__, silently stopping profiling for the still-open
outer scope.

Co-authored-by: Mervin Praison <[email protected]>
2026-08-13 16:11:16 +00:00
2 changed files with 18 additions and 0 deletions

No files matched your search

+8
View File
@@ -1073,6 +1073,7 @@ class ImportProfiler:
def __init__(self):
self._imports: List[ImportRecord] = []
self._active = False
self._entry_depth = 0
def __enter__(self):
import builtins
@@ -1080,12 +1081,14 @@ class ImportProfiler:
with _IMPORT_HOOK_LOCK:
if self._active:
self._entry_depth += 1
return self
if not _IMPORT_HOOK_CONTEXTS:
_IMPORT_HOOK_ORIGINAL = builtins.__import__
builtins.__import__ = _profiled_import
_IMPORT_HOOK_CONTEXTS.append(self)
self._active = True
self._entry_depth = 1
return self
def __exit__(self, exc_type, exc_val, exc_tb):
@@ -1093,6 +1096,11 @@ class ImportProfiler:
global _IMPORT_HOOK_ORIGINAL
with _IMPORT_HOOK_LOCK:
if not self._active:
return False
self._entry_depth -= 1
if self._entry_depth > 0:
return False
if self in _IMPORT_HOOK_CONTEXTS:
_IMPORT_HOOK_CONTEXTS.remove(self)
self._active = False
@@ -343,10 +343,20 @@ def test_import_profiler_defensive_and_idempotent_paths(monkeypatch):
profiler = ImportProfiler()
try:
original_hook = builtins.__import__
assert profiler.__enter__() is profiler
installed_hook = builtins.__import__
assert profiler.__enter__() is profiler
assert builtins.__import__ is installed_hook
assert profiler in profiler_module._IMPORT_HOOK_CONTEXTS
profiler.__exit__(None, None, None)
assert profiler._active is True
assert builtins.__import__ is installed_hook
assert profiler in profiler_module._IMPORT_HOOK_CONTEXTS
profiler.__exit__(None, None, None)
assert profiler._active is False
assert profiler not in profiler_module._IMPORT_HOOK_CONTEXTS
assert builtins.__import__ is original_hook
finally:
profiler.__exit__(None, None, None)