Circular dependency in Python how to solve it? - python

Here's the structure of my project:
MyProject
|
|---- package1
| |
| |---- classA needs classXYZ
| |-----classB needs classXYZ
| |-----classC
|
|-----package2
| |
| |-----classXYZ (path creator)
|
|-----package3
| |
| |-----classQ (subclass of classR)
| |-----classR
|
|-----package4
| |
| |-----classDB needs classXYZ
ClassQ needs classA, classB, classR, classDB and classXYZ, So, in classQ I have:
from package1 import classA
from package1 import classB
from package2 import classXYZ
from package3 import classR
from package4 import classDB
However, both class classA and classB use classXYZ which results in fact that in classQ I'm getting the error: Import Error: no module named classR. (Class Q inherits from class R).
The question is: how to solve this? Class Q is some kind of main class, which uses functions available in other modules to make a working application. Any help will be appreciated.

Related

No module named... in Django proyect

I have a pretty standart Django project and i can't find a way to import /middleware/utils/compare.py from /middleware/utils/request.py
This is the proyect tree:
|--middleware/
| |--utils/
| | |--compare.py
| | |--request.py
| |--__init__.py
| |--asgi.py
| |--settings.py
| |--urls.py
| |--views.py
| |--wsgi.py
|--manage.py
Where __init__.py, asgi.py, settings.py, urls.py, wsgi.py have no major modifications. (__init__.py is empty)
# middleware/views.py
from .utils.request import requests # This line works fine
# middleware/utils/request.py
from compare import compare # ModuleNotFoundError: No module named 'compare'
from .compare import compare # Attempted relative import beyond top-level package pylint(relative-beyond-top-level)
# ^^^ This line absolutly breaks my code, but it runs
from utils.compare import compare # ModuleNotFoundError: No module named 'utils'
from .utils.compare import compare # ModuleNotFoundError: No module named 'middleware.utils.utils'
Note: compare.py has a function named compare, i also tried renaming it but had the same problems.
This might be obvious, but i run the proyect with python manage.py runserver
Simply add empty __init__.py in utils folder.
And read more about it here:
https://docs.python.org/3/tutorial/modules.html#packages
Change your file tree like this,
|--middleware/
| |--utils/
| |--|__init__.py # Added this file
| | |--compare.py
| | |--request.py
| |--__init__.py
| |--asgi.py
| |--settings.py
| |--urls.py
| |--views.py
| |--wsgi.py
|--manage.py
And import like this,
from utils.compare import compare

relative paths in python not finding parent package

I have a file system like this at the moment.
app
|--__init__.py (empty)
|
|--domain
| |--__init__.py (empty)
| |--model.py
| |--questionmatcher.py
|
|--interface
| |--__init__.py (empty)
| |--basiccli.py
| |--userinterface.py
|
|--parser
| |--__init__.py (empty)
| |--json_loader.py
| |--parsing.py
|
|--testfiles
| |--__init__.py (empty)
| |--testsuite.py
I am trying to run the testsuite.py which will need to import classes from various files in directory.
I have tried this structure:
import unittest
from ..parser.json_loader import JsonLoader
from ..parser.parsing import get_vectors, parseThreadsFromFile, getPostsFromThreads
from ..domain import UniversalEncoder, SentBERT
class TestParsing(unittest.TestCase):
def test(self):
pass
class TestJson(unittest.TestCase):
def test(self):
pass
class TestModelEncoders(unittest.TestCase):
def test(self):
pass
if __name__ == "__main__":
unittest.main()
However when I go to run the test I get:
from ..parser.json_loader import JsonLoader
ImportError: attempted relative import with no known parent package
EDIT:
I have tried
from parser.json_loader import JsonLoader
but now I get
from parser.json_loader import JsonLoader
ModuleNotFoundError: No module named 'parser.json_loader'; 'parser' is not a package
you can add this package to your PYTHONPATH environmental variable:
export PYTHONPATH=$PYTHONPATH:/path/to/parser

Pytest - ModuleNotFoundError: No module named 'x'

****solved: added __init__.py to Test/ and renamed testcode.py to test_code.py. To run tests cd -> Zee and type pytest****
Structure:
|--Zee/
| |--Test/
| | |--__init__.py
| | |--test_code.py
| |--Codetotest/
| | |--code.py
in code.py
class Foo():
some code...
in testcode.py
from Codetotest.code import Foo
def test_foo():
assert ...
When I move to the Zee directory in my command line and run pytest Test/testcode.py I get ModuleNotFoundError: No module named Zee. How can I fix this?
I tried making Test a module by adding Test/__init__.py as suggested here. Ran from multiple directories, no dice.
Pytest version 5.3.4, imported from python 3.6
What I don't understand is, when I add __init__.py to Zee/, it gives me the same error
You need a __init__.py in the module directory.
Here's a typical project structure:
|--zee-project-directory/
| |--tests/
| | |--test_zee.py
| |--zee/
| | |--__init__.py
| | |--code.py
code.py
class Foo():
some code...
test_zee.py
from zee.code import Foo
def test_foo():
assert ...

Python Relative import not working

main_package
|
| __init__.py
| folder_1
| | __init__.py
| |script_a.py
| |
| folder_2
| | __init__.py
| | script_b.py
I want to access script_b from script_a and import b_class with relative import
script_a.py:
from ..folder2.script_b import b_class
Gives me error => ValueError: attempted relative import beyond top-level package
http://dosya.co/y6aqrgp993fu/main_package.rar.html
try, as it is package
from main_package.folder_2.script_b import b_class
OR
from .main_package.folder_2.script_b import b_class
OR (May be patch)
import sys
sys.path.append(pathofyourproject) // `/home/prject`
import folder_2.script_b.py

Python relative-import script two levels up

I've been struggling with imports in my package for the last hour.
I've got a directory structure like so:
main_package
|
| __init__.py
| folder_1
| | __init__.py
| | folder_2
| | | __init__.py
| | | script_a.py
| | | script_b.py
|
| folder_3
| | __init__.py
| | script_c.py
I want to access code in script_b.py as well as code from script_c.py from script_a.py. How can I do this?
If I put a simple import script_b inside script_a.py, when I run
from main_package.folder_1.folder_2 import script_b
I am met with an
ImportError: no module named "script_b"
For accessing script_c.py, I have no clue. I wasn't able to find any information about accessing files two levels up, but I know I can import files one level up with
from .. import some_module
How can I access both these files from script_a.py?
To access script_c and script_b from script_a, you would use:
from ...folder_3 import script_c
from . import script_b
Or if you use python3, you can import script_b from script_a by just using:
import script_b
However, you should probably use absolute imports:
from mypackage.folder_3 import script_c
from mypackage.folder1.folder2 import script_b
Also see: Absolute vs Relative imports

Categories