This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: `import as` does not work when module has same same as parent module
Type: behavior Stage: resolved
Components: Versions: Python 3.6, Python 3.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: David Hagen, brett.cannon, eric.snow, ncoghlan, r.david.murray, serhiy.storchaka
Priority: normal Keywords:

Created on 2017-09-07 19:11 by David Hagen, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (4)
msg301614 - (view) Author: David Hagen (David Hagen) Date: 2017-09-07 19:11
Consider the following Python project:

bugtest/
  __init__.py (Contents: from .foo import *)
  foo/
    __init__.py (Contents: from .foo import *)
    foo.py (Contents: <empty file>)

Then in a Python session, the following line executes without error (as expected):

>>> import bugtest.foo.foo

However, the following line gives an error (not as expected):

>>> import bugtest.foo.foo as bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'bugtest.foo.foo' has no attribute 'foo'

Note that this behavior is dependent on the folder foo and the file foo.py having the same base name. But is not dependent on actually trying to import bugtest.foo.foo. Trying to import bugtest.foo.baz will also fail as long as bugtest.foo.foo exists.

It is also dependent on the __init__.py files importing something from their respective submodules.
msg301621 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-09-07 19:47
It seems likely that this is related to the problems discussed (and hopefully solved) in issue 30024.
msg301634 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-09-07 21:48
In 3.7 the error is different:

>>> import bugtest.foo.foo as bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'foo' from 'bugtest.foo.foo' (/home/serhiy/py/cpython/bugtest/foo/foo.py)

The statement "from .foo import *" in bugtest/__init__.py imports name foo from the module bugtest.foo and rewrites the attribute foo.

>>> import bugtest
>>> bugtest.foo
<module 'bugtest.foo.foo' from '/home/serhiy/py/cpython/bugtest/foo/foo.py'>

This behavior is the same in all supported Python versions.
msg301642 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2017-09-07 22:29
As Serhiy notes, this isn't a bug in the import name resolution, it's a consequence of the wildcard import in bugtest's __init__.py replacing its own "bug.foo" submodule attribute with a reference to "bug.foo.foo".

If the star imports can't be avoided, then a potential workaround is to restore "bugtest.foo" from sys.modules:

    foo = sys.modules[__name__ + ".foo"]
History
Date User Action Args
2022-04-11 14:58:52adminsetgithub: 75566
2017-09-07 22:29:22ncoghlansetstatus: open -> closed
resolution: not a bug
messages: + msg301642

stage: resolved
2017-09-07 21:48:09serhiy.storchakasetnosy: + eric.snow, serhiy.storchaka, brett.cannon, ncoghlan
messages: + msg301634
2017-09-07 19:47:14r.david.murraysetnosy: + r.david.murray
messages: + msg301621
2017-09-07 19:11:59David Hagencreate