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: It should be possible to use a module name with the same name as a package name
Type: enhancement Stage: resolved
Components: Interpreter Core Versions:
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: barry, brett.cannon, eric.snow, hakonhagland, ncoghlan, steven.daprano
Priority: normal Keywords:

Created on 2017-05-29 08:22 by hakonhagland, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (3)
msg294682 - (view) Author: Håkon Hægland (hakonhagland) Date: 2017-05-29 08:22
I have the following folder structure:

.
├── aaa
│   ├── bbb
│   │   ├── ccc.py
│   │   └── __init__.py
│   ├── bbb.py
│   └── __init__.py
├── __init__.py
└── t.py

./t.py:

import sys
sys.path = ['.']
import aaa.bbb
print(aaa.bbb.get_name())

./aaa/bbb.py:

def get_name():
    return "aaa/bbb"

however, when I run the main script:

$ python -B t.py 
Traceback (most recent call last):
  File "t.py", line 5, in <module>
    print(aaa.bbb.get_name())
AttributeError: module 'aaa.bbb' has no attribute 'get_name'

The reason is that there is also a package with name 'aaa.bbb' (i.e. file "./aaa/bbb/__init__.py") and python will see this package before it sees my module "./aaa/bbb.py" and will never load the module.

If this is correct, than this is a bad design in my opinion. I should be possible to use a module with the same name as a package. 

Thanks for considering this issue, and let me know if I can help improve Python at this point.

Note: I asked the question first at stackoverflow.com:
https://stackoverflow.com/q/44227763/2173773
msg294727 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2017-05-30 00:32
This is just module shadowing in action. If you have two or more modules, or packages, in the module search path, the first one found will block access to the others.

> this is a bad design in my opinion.

*shrug* It is what it is.

Often it is inconvenient. Occasionally it is useful. It is the same way nearly all other languages with a library search path works: the compiler searches for a library until it finds a match, then stops.

How would you change this? Here are some unacceptable or impractical solutions:

- get rid of the search path, and force the programmer to specify the full file system path of every module (package) they import;

- use different syntax for importing a .py module and a package;

- after an import, if there's an error, Python should automatically re-do the import with the next module in the module search path;

- "I don't care how you fix it, that's your problem not mine".


I think the answer here is: don't do this. Don't use a package with the same name as a module.
msg294748 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2017-05-30 10:49
As Steven notes, packages are simply modules that reserve the right to contain other submodules

As a result, Python considers "aaa.py", "aaa.pyc", "aaa.<C_extension_suffix>", "aaa/__init__.py", and "aaa/__init__.pyc" all to be candidate filesystem mappings for a module named "aaa", and once it finds one of them, it will ignore the others (the "module shadowing" Steven mentions).

The last time changing this was seriously considered was when native namespace package support was added in PEP 420: https://www.python.org/dev/peps/pep-0420/

Specifically, one of the competing proposals was PEP 402, which proposed allowing all modules to implicitly also be namespace packages: https://www.python.org/dev/peps/pep-0402/

This was ultimately rejected in favour of the approach in PEP 420, where single file modules, self-contained packages, and native namespace packages all have clearly distinct filesystem layouts.
History
Date User Action Args
2022-04-11 14:58:47adminsetgithub: 74688
2017-05-30 10:49:42ncoghlansetstatus: open -> closed
resolution: not a bug
messages: + msg294748

stage: resolved
2017-05-30 00:32:38steven.dapranosetnosy: + steven.daprano
messages: + msg294727
2017-05-29 15:21:54barrysetnosy: + barry
2017-05-29 08:35:14serhiy.storchakasetnosy: + brett.cannon, ncoghlan, eric.snow
2017-05-29 08:22:55hakonhaglandcreate