Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Python select this unexpected module to import

I am working with a project that has a user-written module called types.py buried in a second-level package (its path from the project root is package/subpackage/types.py).

This is causing problems because the Python library also has a types module. When enum.py, another Python library module, attempts to import types, the user-written version is imported instead, wreaking havoc.

What's puzzling me is that the import inside enum.py does not qualify types with any package names:

# line 10 of enum.py:
from types import MappingProxyType, DynamicClassAttribute

so why is Python selecting the user-written types which is in a two-level subpackage? It seems to me the user-written types would only be imported if one uses

# what I expect an 'import' would have to be like to access the user-written types.py
from package.subpackage.types import ...

Another possible explanation would be that sys.path contained the package/subpackage directory, but this is not the case when I print its content right before the enum.py import:

enum.py: Path:
/home/me/PycharmProjects/myproject
/home/me/anaconda3/envs/myproject/lib/python37.zip
/home/me/anaconda3/envs/myproject/lib/python3.7
/home/me/anaconda3/envs/myproject/lib/python3.7/lib-dynload
/home/me/anaconda3/envs/myproject/lib/python3.7/site-packages

So, how can the importing of the user-written types.py module be explained?

UPDATE: the first comment suggests this happens because my project's path is the first item in sys.path. However, I set up a really simple project in which a module called mymodule is in package.subpackage:

Sandbox Project

Importing from mymodule without using the package and subpackage names does not work:

# main.py
# Works:
from package.subpackage.mymodule import my_module_field

# Does not work:
# from mymodule import my_module_field

So I still do not understand why the from types import in enum.py can work find the user-written types.py without the packages names.

UPDATE 2: printing out more information, I see that when I print sys.path as soon as enum.py starts (I modified the standard library file to print it), I see that the package/subpackage directory is in sys.path, even though it was not at the beginning of execution. So this explains why the user-written typos.py is being used.

The issue now is why sys.path is appended with the package/subpackage directory. I searched all occurrences of sys.path in my code and even though the current directory is appended to it at some points, it is never the package/subpackage directory. Where can this be happening?

like image 543
user118967 Avatar asked Apr 01 '26 03:04

user118967


1 Answers

Not sure this counts as a real answer because it would not be possible to answer it based on the question information by itself (and adding all the details to the question is impractical). In any case, here's the solution.

Basically, upon greater inspection I found out that a script invokes another script as an external process, and this latter script is in the package/subpackage directory, which is added to sys.path in the new process. About this last point, I'm not sure why; I am assuming that a script's current directory is always added to sys.path.

like image 127
user118967 Avatar answered Apr 03 '26 16:04

user118967



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!