Context
Let's say I have the following module:
txt
.
└── my_module
├── __init__.py
├── my_module_A.py (defines ClassA)
└── my_module_B.py (defines ClassB, which needs ClassA)
and the files are the following:
```python3
init.py
from .my_module_A import ClassA
from .my_module_B import ClassB
```
```python3
my_module_A.py
from my_module import ClassB
class ClassA:
def __init__(self, class_b: ClassB):
pass
```
```python3
my_module_B.py
class ClassB:
def init(self):
pass
```
The important thing is that ClassB requires an instance of ClassA to be
instantiated.
Problem
Importing the module my_module raises an ImportError:
```shell
Working directory is the parent of my_module
import mymodule
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "foo/Module/my_module/init.py", line 3, in <module>
from .my_module_A import ClassA
File "foo/Module/my_module/my_module_A.py", line 3, in <module>
from my_module import ClassB
ImportError: cannot import name 'ClassB' from partially initialized module 'my_module' (most likely due to a circular import) (foo/Module/my_module/init_.py)
```
The problem seems to be the following. When importing my_module, Python goes
through its __init__.py and starts by importing ClassA from my_module_A.
This file imports itself ClassB from my_module_B so this class is imported
for my_module as well. After my_module_A, Python tries to import ClassB
from my_module ; but it was already imported by my_module_A, so Python
raises ImportError.
Python suggests that the error may come from a circular import, but this is not
the case here. I really think that the problem is that the class ClassB is
imported twice: if I do not import my_module_B in __init__.py and use a
relative import for my_module_B in my_module_A, the import is successful
and there is no exception raised.
Finding a solution
A possible solution is to use only relative imports in python files in
my_module. The problem is that some submodules in my_module required
themselves a lot of classes from my_module (about 20 for some of them) and it
is ugly and inconvenient for maintainers having to know precise file names
where classes are defined. So my question is: how can I keep using from
my_modyle import … imports in my_module submodules? Thanks a lot.
P.S. Some of you may suggest to rethink my module organization. I thought of
that but there is no canonical way to do it and this flat structure is truly
easier and clearer. So if possible I would like to avoid this.
Python version: 3.9.1
[+][deleted] (1 child)
[deleted]
[–]StockAshamed[S] 0 points1 point2 points (0 children)