a20
a20

Reputation: 77

Attribute error when module imports itself - works on some computers

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

Answers (2)

Daniel
Daniel

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

aaron
aaron

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

Related Questions