I want to load Python code (if possible with an arbitrary file-extension or even from memory, source or binary) without adding it to sys.modules. Using imp.load_source works for loading a file but the returned module is added to sys.modules and might even be joined with an existing module (see this question)!
So, what I'm currently doing is using the __import__() built-in. Although it allows me to import from a package, I can not load an arbitrary file.
try:
m = __import__(name)
for n in name.split('.')[1:]:
m = getattr(m, n)
return m
except:
raise
finally:
# Restore the old module configuration. Only modules that have
# not been in sys.path before will be removed.
for k, v in sys.modules.items():
if k not in prev_modules and self.is_local(v) or not v:
del sys.modules[k]
else:
sys.modules[k] = v
- Removing all modules that haven't been in before the import is a very hacky approach to me.
- When a module with the name already exists, it is not reloaded.
- I can not load an arbitrary file or even from memory.
I am trying to avoid the exec statement because of security reasons. The source evaluated by exec could hack in to my application using sys._getframe() (and there sure are many more possibilities to do). I have looked at the implementation of the django load tag, but that just uses __import_() as well.
Is there a way to load Python code (either source or binary) from a file (or even memory) that is secure, self-contained (no adding interaction with sys.modules)? In the best case, it would not only allow me to load a file and from memory, but also load a complete package like the __import__() function.
secureandself-containedis an impossible combination here. AFAIK, importing a python module effectively executes it. The closest thing I know is seattle.cs.washington.edu/browser/seattle/branches/repy_v2/repy/…, which is attempts to build a safe exec. It's based on statically analyzing the code and removing access to 'dangerous' built-in's.