1
0
Fork 0
mirror of synced 2024-12-22 06:01:07 -05:00

Stop patches in the reverse order they were started

Because some functions are patched twice (like `os.rename()`),
stopping the patches in the same order they were started
can result in restoration of one of the patches.

For example:

```
fn = os.rename

# Patch nesting order: 1 then 2
os.rename = patch_1(fn)
os.rename = patch_2(patch_1(fn))

# Unpatch 1 then 2: A still-patched function is restored
os.rename = fn
os.rename = patch_1(fn)

# Unpatch 2 then 1: The original function is restored
os.rename = patch_1(fn)
os.rename = fn
```

Fixes #365
This commit is contained in:
Kurt McKee 2024-12-18 08:31:31 -06:00
parent 7e6ec66718
commit 33f5390a62
No known key found for this signature in database
GPG key ID: 64713C0B5BA8E1C2

View file

@ -217,7 +217,9 @@ def root(standardize_tmp):
try: try:
yield current_root yield current_root
finally: finally:
[patch.stop() for patch in patches] # Patches must be stopped in reverse order because some patches are nested.
# Stopping in the reverse order restores the original function.
[patch.stop() for patch in reversed(patches)]
os.chdir(current_working_directory) os.chdir(current_working_directory)
if sys.version_info >= (3, 12): if sys.version_info >= (3, 12):
rmtree(current_root, onexc=rmtree_error_handler) rmtree(current_root, onexc=rmtree_error_handler)