4

I've been getting an error I don't understand and I managed to boil it down to this. Here is the directory structure:

temp
 temp2
 __init__.py
 mod.py
 mod2.py

Here are the contents of the files:

#__init__.py
from temp.temp2.mod import *
from temp.temp2.mod2 import *
#mod.py
def f():
 pass
#mod2.py
import temp.temp2.mod as mod

Then I open a new python 3.6.8 console in ipython and try to load mod2 and i get this:

>>>import temp.temp2.mod2
Traceback (most recent call last):
 File "<ipython-input-1-...>", line 1, in <module>
 import temp.temp2.mod2
 File ".../temp/temp2/__init__.py", line 2, in <module>
 from temp.temp2.mod2 import *
 File ".../temp/temp2/mod2.py", line 1, in <module>
 import temp.temp2.mod as mod
AttributeError: module 'temp' has no attribute 'temp2'

Some other facts.

First, if I change the file mod2.py to either import temp.temp2.mod or from temp.temp2.mod import f then it works fine with no error. It is only the import as that results in an error.

Second, if I don't have the nested modules, and just put mod.py, mod2.py and __init__.py inside of temp (and change the imports accordingly), then I also don't get any error.

Any idea what is going on?

On Edit:

Attribute not added to module after importing gives a partial explanation as to what is happening. The reason temp has no attribute temp2 is that the package temp.temp2 is still loading at this time, and the attribute temp2 in the package temp is not set until after this load is complete. But it still doesn't answer the question as to why import and import as cause different behaviors.

To reiterate, this is the only mod2.py file that causes the error:

#mod2.py -- results in error
import temp.temp2.mod as mod

These all work fine:

#mod2.py -- works OK
import temp.temp2.mod
#mod2.py -- works OK
from temp.temp2.mod import f
#mod2.py -- works OK
from temp.temp2 import mod
#mod2.py -- works OK
from temp.temp2 import mod as mod

So, at least to me, the fact that the attribute temp2 in the package temp doesn't get set until after temp.temp2 is loaded doesn't explain why these four versions of "mod2.py" work while the one above gives an error.

Obviously, I have workarounds I can use, but I want to know what is going on behind the scenes that is causing this, preferably if it is documented. I've tried to find some documentation explaining details of module loading that would explain this behavior, but I haven't found the answer.

wim
369k114 gold badges682 silver badges822 bronze badges
asked Apr 9, 2019 at 15:46
12
  • If you put an empty __init__.py directly under the temp folder, then retry, what happens? Commented Apr 9, 2019 at 15:52
  • Then it works fine. It also works fine if i comment out #from temp.temp2.mod2 import * in __init__.py Commented Apr 9, 2019 at 15:56
  • import temp.whatever should never work if your temp is a directory that doesn't have a __init.py__ in it. The errors aren't surprising; that you ever fail to get them is. Commented Apr 9, 2019 at 17:12
  • Putting an __init__.py file in temp does not change the behavior at all -- the error still occurs. Commented Apr 9, 2019 at 18:00
  • 2
    Also note this issue has been fixed in Python 3.7. Commented Apr 10, 2019 at 15:58

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.