Message213289
I found the problem. _frozen_importlib is being loaded by C code which is using the equivalent of _imp.init_frozen(). importlib.machinery.FrozenImporter is doing a more controlled, manual approach of using _imp.get_frozen_object() and then initializing the module itself. Problem is that the former sets __file__ to '<frozen>' and the latter doesn't; this was an unintended side-effect of updating FrozenImporter for PEP 451 as this was the only way to make exec_module() work w/o serious C hacking. You can see the difference this way:
>>> import _imp
>>> __hello__again = _imp.init_frozen('__hello__')
Hello world!
>>> __hello__again.__spec__.has_location
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'has_location'
>>> __hello__again.__file__
'<frozen>'
compared to:
>>> import __hello__
Hello world!
>>> __hello__.__spec__.has_location
False
>>> __hello__.__spec__.origin
'frozen'
>>> __hello__.__file__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__file__'
The clean solution is to fix PyImport_ImportFrozenModuleObject() to stop setting __file__ and then fix importlib/__init__.py to deal with the lack of file path (this should implicitly fix _frozen_importlib when it's __spec__ is set in _setup). The more backwards-compatible would be to toss '<frozen>' back in for __spec__.origin and set __spec__.has_location to True which is all semantically wrong.
I vote for the clean solution along with a backported note into What's New. |
|
Date |
User |
Action |
Args |
2014-03-12 20:10:42 | brett.cannon | set | recipients:
+ brett.cannon, barry, ncoghlan, ned.deily, r.david.murray, Jurko.Gospodnetić, eric.snow, takluyver |
2014-03-12 20:10:42 | brett.cannon | set | messageid: <1394655042.66.0.844677286603.issue20884@psf.upfronthosting.co.za> |
2014-03-12 20:10:42 | brett.cannon | link | issue20884 messages |
2014-03-12 20:10:42 | brett.cannon | create | |
|