How to block a module import
I thought that in order to block a module from being imported, one would need to assign None to the corresponding entry in sys.modules. However, it looks like the code in test.support uses 0 instead of None: def _save_and_block_module(name, orig_modules): """Helper function to save and block a module in sys.modules Return value is True if the module was in sys.modules and False otherwise.""" saved = True try: orig_modules[name] = sys.modules[name] except KeyError: saved = False sys.modules[name] = 0 # <--- I would expect None here return saved In my experiments, 0 is not equivalent to None:
import sys, time sys.modules['time'] = 0 __import__('time') 0 sys.modules['time'] = None __import__('time') Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named time
Am I missing something?
On Tue, Jul 13, 2010 at 10:37 AM, Alexander Belopolsky <alexander.belopolsky@gmail.com> wrote:
In my experiments, 0 is not equivalent to None:
import sys, time sys.modules['time'] = 0 __import__('time') 0 sys.modules['time'] = None __import__('time') Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named time
Am I missing something?
I don't think so. I suspect I got away with this mistake because the imports I was trying to block in the test suite were all C acceleration imports of the form "from <module> import *", and those will blow up anyway since zero doesn't have __dict__ or __all__ attributes. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Tue, Jul 13, 2010 at 05:48, Nick Coghlan <ncoghlan@gmail.com> wrote:
On Tue, Jul 13, 2010 at 10:37 AM, Alexander Belopolsky <alexander.belopolsky@gmail.com> wrote:
In my experiments, 0 is not equivalent to None:
import sys, time sys.modules['time'] = 0 __import__('time') 0 sys.modules['time'] = None __import__('time') Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named time
Am I missing something?
I don't think so. I suspect I got away with this mistake because the imports I was trying to block in the test suite were all C acceleration imports of the form "from <module> import *", and those will blow up anyway since zero doesn't have __dict__ or __all__ attributes.
Nick's right; 0 fails on an import * to pull anything in of interest. And as I said on python-checkins -- you can ignore that email, Alexander -- there is a historical reason because in Python 2 if you tried an implicit relative import a value of None met to do an absolute import. This doesn't have that effect in py3k as explicit relative imports are the only way to do relative imports (and luckily importlib does the proper thing for this as well =).
On Tue, Jul 13, 2010 at 4:34 PM, Brett Cannon <brett@python.org> wrote: ..
Nick's right; 0 fails on an import * to pull anything in of interest.
but if the imported module has try: import blocked_module except ImportError: do_something_important() then import_fresh_module() will create a broken module with do_something_important() not executed.
And as I said on python-checkins -- you can ignore that email, Alexander
Too late. I already replied. :-)
-- there is a historical reason because in Python 2 if you tried an implicit relative import a value of None met to do an absolute import. This doesn't have that effect in py3k as explicit relative imports are the only way to do relative imports (and luckily importlib does the proper thing for this as well =).
Is there a problem with this change for 3.x?
Nick's right; 0 fails on an import * to pull anything in of interest. And as I said on python-checkins -- you can ignore that email, Alexander -- there is a historical reason because in Python 2 if you tried an implicit relative import a value of None met to do an absolute import. This doesn't have that effect in py3k as explicit relative imports are the only way to do relative imports (and luckily importlib does the proper thing for this as well =).
Ah, thank you - I knew we had a reason for doing it that way, I just couldn't remember what it was :) @Alexander: yes, it should be changed to None for 2.7, 3.1 and 3.2, since none of those allow implicit relative imports. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
participants (3)
-
Alexander Belopolsky -
Brett Cannon -
Nick Coghlan