You are correct : the better solution would be to rename that module. Hacking around the import system may lead to sad headaches down the road, and more hackeries. Break the pattern : rename the module, make everyone happy.
A poor man's solution would be to change the sys.path
order. If you manage to put the path ......./lib/site-packages
before the path to the directory containing your package containing the typing
module, and if you do that before any other module of the WHOLE Python program imports any typing
, it can work.
Here is my setup :
stack_overflow/
├─ annoying/
│ ├─ __init__.py
│ ├─ innocent.py
│ ├─ typing.py
│ ├─ main.py
# file: innocent.py
import typing
print("'typing' imported")
abc: typing.List[str] = ["a", "b", "c"]
# file: main.py
import sys
print(sys.path)
import innocent
and both __init__.py
and typing.py
are empty.
When I execute my main I get :
['C:\\PycharmProjects\\stack_overflow\\annoying', ... Python regular stuff ...]
'typing' imported
Traceback (most recent call last):
[...]
AttributeError: module 'typing' has no attribute 'List'
because the wrong file was imported, due to the sys.path
order such that Python searched for typing
in the annoying
directory before to search in its site-packages
.
I am now putting the path to the library at the end :
# file: main.py
import sys
print(sys.path)
annoying_library_index_in_syspath, annoying_library_path = next((i, path) for i, path in enumerate(sys.path))
sys.path.pop(annoying_library_index_in_syspath)
sys.path.append(annoying_library_path)
print(sys.path)
import innocent
which prints :
['C:\\PycharmProjects\\stack_overflow\\annoying', ... Python regular stuff ...]
[... Python regular stuff ..., 'C:\\PycharmProjects\\stack_overflow\\annoying']
'typing' imported
now that the order is reversed, Python imports typing
from its site-packages
in priority, and everything works as expected. But if I have an import (even transitive) to to module which imports a typing
before I change the sys.path
, it will fail again :
# file: main.py
import sys
import innocent # raise AttributeError: module 'typing' has no attribute 'List'
print(sys.path)
annoying_library_index_in_syspath, annoying_library_path = next((i, path) for i, path in enumerate(sys.path))
sys.path.pop(annoying_library_index_in_syspath)
sys.path.append(annoying_library_path)
print(sys.path)
import innocent
But messing with sys.path
is prone to errors, conflicts, pain and sadness. That's why is discouraged to reuse standard library names for user modules. So please fix the file, it really is the best solution.