Getting ImportError and suggestion to rename module for no valid reason
Bug report
Bug description:
I can't trigger the classic "partially initialized module" ImportError anymore.
Circular imports are a different issue and not related to shadowing one of sys.stdlib_module_names for example.
# mainmod.py
from secondmod import secondaryitem
mainitem = 1
# secondmod.py
from mainmod import mainitem
secondaryitem = 2
I made sure there is no package installed providing mainmod or secondmod.
In Python 3.13.5:
# python3 mainmod.py
Traceback (most recent call last):
File "/home/as/mainmod.py", line 1, in <module>
from secondmod import secondaryitem
File "/home/as/secondmod.py", line 1, in <module>
from mainmod import mainitem
File "/home/as/mainmod.py", line 1, in <module>
from secondmod import secondaryitem
ImportError: cannot import name 'secondaryitem' from 'secondmod' (consider renaming '/home/as/secondmod.py' if it has the same name as a library you intended to import)
Before in Python 3.12.6:
python3 mainmod.py
Traceback (most recent call last):
File "/home/as/mainmod.py", line 1, in <module>
from secondmod import secondaryitem
File "/home/as/secondmod.py", line 1, in <module>
from mainmod import mainitem
File "/home/as/mainmod.py", line 1, in <module>
from secondmod import secondaryitem
ImportError: cannot import name 'secondaryitem' from partially initialized module 'secondmod' (most likely due to a circular import) (/home/as/secondmod.py)
Because it's an improvement mostly for beginners, the warning should appear only when colliding with sys.stdlib_module_names or maybe other installed third party packages. It should not trigger for modules of the same project.
I've read the threads about this new Python 3.13 feature and could not find any report on this false positive warning.
CPython versions tested on:
3.13
Operating systems tested on:
Linux
Hello, this is the issue tracker for the Python language itself.
Please open a topic in the help forum to ask about your own code:
https://discuss.python.org/c/help/7
I know the difference between Python and CPython.
And it's an issue/change in CPython. It's not about my own code.
One of these changes was from https://github.com/python/cpython/pull/112577, cc @hauntsaninja.
For reference, the "consider renaming" error was introduced by #113769
Thanks for the issue!
There are actually two separate warnings we issue, one for the standard library case and one for the potential third party case:
-
The standard library one checks against
sys.stdlib_module_namesas you suggest, and the error message is something like:AttributeError: module 'random' has no attribute 'randint' (consider renaming '/home/me/random.py' since it has the same name as the standard library module named 'random' and prevents importing that standard library module) -
The potential third party case message is something like:
AttributeError: module 'numpy' has no attribute 'array' (consider renaming '/home/me/numpy.py' if it has the same name as a library you intended to import)
Two notes:
- There are plenty of cases where we preserve the error message for circular imports as they were on Python 3.12 , see here
- The message used to say "if it has the same name as a third-party module" instead of "library", but Pablo asked for the change in: https://github.com/python/cpython/pull/123929#issuecomment-2343272160
Here are the things I'm solving for:
- I would like to issue some "consider renaming" message in the third party shadowing case
- In my experience / from forums, it is basically as common for beginners to have
numpy.pyorrequests.pyoropenai.pyas it is for them to haverandom.py, and PyPI is only becoming more and more useful
- In my experience / from forums, it is basically as common for beginners to have
- I don't think it is tenable to scan
site.getsitepackages(or try to useimportlib.metadata.distributionsor similar). This can be really slow. Also recursive imports while handling import errors can lead to some really cursed situations that can cause the interpreter to crash
Are there tweaks that would have made you less confused? For instance:
- We can restore the error message to lead with "partially initialized module" instead of "module"
- We can lead with the "if" clause, i.e. "If ... has the same name as a library you intended to import, consider renaming ..." instead of "Consider renaming ... if ...."