Partial initialization issues after moving a Python module into a subfolder

Viewed 31

I originally had a Python module that was structured like this:

mymod
├── config.py
└── __init__.py

And the files contained this code:

# __init__.py
import mymod.config
mymod.config.foo()

# config.py
def foo():
    print('here')

Running this with python3 -c "import mymod" will print "here", as expected.

Now as part of a refactor, the directory structure looks like this:

mymod
├── core
│   ├── config.py
│   └── __init__.py
└── __init__.py

I want the same initialization code in core/__init__.py to run when importing mymod, so the new root __init__.py looks like this:

# __init__.py
import mymod.core

And the other files just need to have the module paths fixed:

# core/__init__.py
import mymod.core.config
mymod.core.config.foo()
 
# core/config.py (no change)
def foo():
    print('here')

But now I get an AttributeError relating to a partially initialized module:

$ python3 -c  "import mymod"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/gsgx/code/mymod/__init__.py", line 1, in <module>
    import mymod.core
  File "/home/gsgx/code/mymod/core/__init__.py", line 3, in <module>
    mymod.core.config.foo()
AttributeError: partially initialized module 'mymod' has no attribute 'core' (most likely due to a circular import)

I think I understand why: I'm trying to access mymod.core while in the middle of the original statement importing it. But I realized I could fix it by changing the import in config.py to use a from ... import instead:

# core/__init__.py
from mymod.core import config
config.foo()

My question is, while this technically fixes the issue, I was wondering if there's any other workaround for this. I don't want to have to go through all the imports and fix any name conflicts that result from doing this. It feels like I should be able to move a module into a subfolder without major refactoring and without running into partial initialization issues. I've read various answers on SO about Python imports, but wasn't able to find anything to help with this particular issue.

0 Answers
Related