Reputation: 77
I have inherited some python scripts that I am trying to run. These include some custom modules and I get an error when importing one of them, which seems to be due to one of the modules importing itself. What I find strange is that it works on one computer, but not on another computer.
The directory structure is as follows:
/path/to/packages/python_packages/x
|
/path/to/packages/python_packages/x/mod1.py
/path/to/packages/python_packages/x/mod2.py
/path/to/packages/python_packages/x/mod3.py
I add (and cross-check using print(sys.path)) the path as follows:
sys.path.append("/path/to/packages/python_packages/")
Then I do:
import x.mod1 as mod1
import x.mod2 as mod2
import x.mod3 as mod3
Importing mod1 works.
Importing mod2 does not work:
AttributeError: module 'x' has no attribute mod2
Traceback complains about this line, present in mod2.py:
import x.mod2 as mod2
Importing mod3 does not work, as it needs to import mod2, which it does in the same way as above.
In the traceback from ipython I can see that it finds the correct python files, since it prints out the code from the files and their names, full paths.
I have tried removing all init.py and pycache.
I tried running it on another computer, and there I can import the modules without any issues.
On the computer with the problem, I have Python 3.6.8, running on CentOS7 (3.10.0-1160.21.1.el7.x86_64) and on the computer where it works, I have Python 3.9.2, running on Manjaro (5.4.108-1-MANJARO).
I do not have root access on the computer with the problem.
The full traceback is as follows (I changed path and file names to be consistent with above explanation):
In [9]: import x.mod2 as mod2
AttributeError Traceback (most recent call last)
<ipython-input-9-8c4b062c2395> in <module>
----> 1 import x.mod2 as mod2
/path/to/packages/python_packages/x/mod2.py in <module>
2 import numpy as np
3
----> 4 import x.mod2 as mod2
5
6
AttributeError: module 'x' has no attribute 'mod2'
Upvotes: 1
Views: 444
Reputation: 42748
There is no need to import mod2
only to access mod2.__file__
, since it is also available as __file__
.
Instead of string fiddling you should use pathlib
:
reference_path = Path(__file__).absolute().parents[2] / "reference"
Instead of using as
use from
:
from x import mod1
or, since you are already in the same package:
from . import mod1
Upvotes: 5
Reputation: 43083
It imports itself in order to access the path one level up from where it is placed.
reference_path = "/".join(mod2.__file__.split("/")[0:-2]+["reference/"])
You should be able to use __file__
directly.
Upvotes: 2