Issue
I'm using libusb1 and noticed an import error when there is a platform module in my main module:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/duranda/.local/lib/python3.6/site-packages/usb1/__init__.py", line 61, in <module>
from . import libusb1
File "/home/duranda/.local/lib/python3.6/site-packages/usb1/libusb1.py", line 199, in <module>
libusb = _loadLibrary()
File "/home/duranda/.local/lib/python3.6/site-packages/usb1/libusb1.py", line 161, in _loadLibrary
system = platform.system()
AttributeError: module 'platform' has no attribute 'system'
This can be easily reproduced by launching a Python interpreter from a directory containing a platform.py
or platform/__init__.py
and then importing usb1 using import usb1
.
How is it possible that a local module shadows another module (in this case the platform
module from the standard lib) from a third party module? To the best of my knowledge, libusb1 imports platform
directly and doesn't do anything crazy with globals.
Solution
Since the module platform in your working directory, and Python interpreter would insert current working directory into sys.path at the beginning. You could print sys.path out to check.
Thus, Python interpreter use the first one found when looking for module based on sys.path, which is your own module instead of the one in standard library.
A workaround (trick) is to move the current working directory to the end position; Note to put it at the top of file, and then import the module
import sys
# move the current working directory to the end position
sys.path = sys.path[1:] + sys.path[:1]
More Comments:
To reply @gelonida: suppose that we really want to use both modules, we could import one first and give it an alias, and then modify sys.path to import another one
import sys
# <------- newly added
_platform = patch_module('platform', '_platform') # our own module
# move the current working directory to the end position
sys.path = sys.path[1:] + sys.path[:1]
And the above code use a patch_module() method
def patch_module(source_module_name, target_module_name):
""" All imported modules are cached in *sys.modules*
"""
__import__(source_module_name)
m = sys.modules.pop(source_module_name)
sys.modules[target_module_name] = m
target_module = __import__(target_module_name)
return target_module
Answered By - Jacky Wang
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.