Author martin.panter
Recipients brett.cannon, eric.snow, martin.panter, ncoghlan, wolma
Date 2016-07-13.00:44:04
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1468370648.54.0.85836846068.issue27487@psf.upfronthosting.co.za>
In-reply-to
Content
In trying to understand this, I built a package with two simple files:

$ cat package/*.py
# package/__init__.py:
from . import module
# package/module.py:
import sys
sys.modules[__name__] = object()

With this I can reproduce your __spec__ error, and I see it works without error in 3.5.0 and 2.7.11. FWIW, with the current 3.3 branch, I get a different error:

/media/disk/home/proj/python/cpython/python: Error while finding loader for 'package.module' (<class 'AttributeError'>: 'object' object has no attribute '__loader__')

The revision that causes the regression is 3202d143a194. Since I made that change, I feel responsible for it. But I don’t have much time ATM to come up with an ideal solution. One quick solution would be to revert my change, but since this is an obscure use case, I am not enthusiastic about doing that :)

Is it possible to set the __spec__ attribute to work around the problem? I don’t really understand the “module spec” business, but “runpy” seems to rely on that attribute. Is replacing sys.modules entries like this even supported usage?

Even in 3.5.0, I can still produce the error by importing the package before using runpy:

$ python3.5 -c 'import runpy, package; runpy.run_module("package.module")'
Traceback (most recent call last):
  File "/usr/lib/python3.5/runpy.py", line 104, in _get_module_details
    spec = importlib.util.find_spec(mod_name)
  File "/usr/lib/python3.5/importlib/util.py", line 99, in find_spec
    raise ValueError('{}.__spec__ is not set'.format(name)) from None
ValueError: package.module.__spec__ is not set

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.5/runpy.py", line 178, in run_module
    mod_name, mod_spec, code = _get_module_details(mod_name)
  File "/usr/lib/python3.5/runpy.py", line 110, in _get_module_details
    raise ImportError(msg.format(mod_name, type(ex), ex)) from ex
ImportError: Error while finding spec for 'package.module' (<class 'ValueError'>: package.module.__spec__ is not set)
[Exit 1]

Wolfgang: Do you want to propose a specific wording to add to the documentation? Maybe something like “runpy and the ‘python -m’ option require that after the module is imported, it should have a __spec__ attribute”. Where should this go? In the runpy, command line, and/or What’s New documentation?

FWIW, 2.7.11 gives an even stranger error; perhaps this is a different bug:

$ python2.7 -c 'import runpy, package.module; runpy.run_module("package.module")'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.7/runpy.py", line 170, in run_module
    mod_name, loader, code, fname = _get_module_details(mod_name)
  File "/usr/lib/python2.7/runpy.py", line 101, in _get_module_details
    loader = get_loader(mod_name)
  File "/usr/lib/python2.7/pkgutil.py", line 464, in get_loader
    return find_loader(fullname)
  File "/usr/lib/python2.7/pkgutil.py", line 474, in find_loader
    for importer in iter_importers(fullname):
  File "/usr/lib/python2.7/pkgutil.py", line 424, in iter_importers
    if fullname.startswith('.'):
AttributeError: 'object' object has no attribute 'startswith'
[Exit 1]
History
Date User Action Args
2016-07-13 00:44:08martin.pantersetrecipients: + martin.panter, brett.cannon, ncoghlan, eric.snow, wolma
2016-07-13 00:44:08martin.pantersetmessageid: <1468370648.54.0.85836846068.issue27487@psf.upfronthosting.co.za>
2016-07-13 00:44:08martin.panterlinkissue27487 messages
2016-07-13 00:44:04martin.pantercreate