Skip to content

Instantly share code, notes, and snippets.

@bskinn
Created January 12, 2025 04:18
Show Gist options
  • Save bskinn/7e5f8ba50109f6bbfbf0b6e642c0040b to your computer and use it in GitHub Desktop.
Save bskinn/7e5f8ba50109f6bbfbf0b6e642c0040b to your computer and use it in GitHub Desktop.
Demonstration of 'import stomping' behavior of imports inside functions
import os as foo
import os as bar
print()
print(f"Initial {'rmdir' in dir(foo)=}")
print(f"Initial {'rmdir' in dir(bar)=}")
print()
def no_global():
import sys as foo
print(f"Inside no_global {'rmdir' in dir(foo)=}")
print(f"Inside no_global {'rmdir' in dir(bar)=}")
no_global()
print()
print(f"After no_global() {'rmdir' in dir(foo)=}")
print(f"After no_global() {'rmdir' in dir(bar)=}")
print()
def with_global():
global foo
import sys as foo
print(f"Inside with_global {'rmdir' in dir(foo)=}")
print(f"Inside with_global {'rmdir' in dir(bar)=}")
with_global()
print()
print(f"After with_global() {'rmdir' in dir(foo)=}")
print(f"After with_global() {'rmdir' in dir(bar)=}")
print()
@bskinn
Copy link
Author

bskinn commented Jan 12, 2025

We print 'rmdir' in dir(thing) as a probe for whether thing is the os module or not. If the test yields True, then it's os.

Output on Windows Python 3.12.8:

>python import_stomp.py

Initial 'rmdir' in dir(foo)=True
Initial 'rmdir' in dir(bar)=True

Inside no_global 'rmdir' in dir(foo)=False
Inside no_global 'rmdir' in dir(bar)=True

After no_global() 'rmdir' in dir(foo)=True
After no_global() 'rmdir' in dir(bar)=True

Inside with_global 'rmdir' in dir(foo)=False
Inside with_global 'rmdir' in dir(bar)=True

After with_global() 'rmdir' in dir(foo)=False
After with_global() 'rmdir' in dir(bar)=True

foo and bar are both os at first.

Inside no_global, the import overwrites foo to be sys, but once the function exits and the overwritten foo goes out of scope, foo in the module scope is os again.

Inside with_global, though, the import overwrites the module-scope foo. Module-scope foo is then checked inside with_global and found to be sys, and then checked again outside with_global and found to be sys there also.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment