1

SUMMARY

I am fairly new to designing full-fledged python projects, and all my Python work earlier has been with Jupyter Notebooks. Now that I am designing some application with Python, I am having considerable difficulty making it 'run'.

I have visited the following sites -

  1. Relative imports in Python

  2. Ultimate answer to relative python imports

  3. python relative import example code does not work

But none of them seem to solve my issue.

PROBLEM

Here's my repo structure -

my_app/
    __init__.py
    
    code/
        __init__.py
        module_1/
            some_code_1.py
        module_2/
            some_code_2.py
        module_3/
            some_code_3.py

        main.py

    tests/
        __init__.py
        module_1/
            test_some_code_1.py
        module_2/
            test_some_code_2.py
        module_3/
            test_some_code_3.py

    resources/
        __init__.py
        config.json
        data.csv

I am primarily using PyCharm and VS Code for development and testing.

The main.py file has the following imports -

from code.module_1.some_code_1 import class_1
from code.module_2.some_code_2 import class_2
from code.module_3.some_code_3 import class_3

In the PyCharm run configuration, I have the working directory set to `User/blah/blah/my_app/

Whenever I run the main.py from PyCharm, it runs perfectly.

But if I run the program from terminal like -

$ python code/main.py

Traceback (most recent call last):
  File "code/main.py", line 5, in <module>
    from code.module_1.some_code_1 import class_1
ModuleNotFoundError: No module named 'code.module_1.some_code_1'; 'code' is not a package

I get the same error if I run the main.py from VS Code.

Is there a way to make this work for PyCharm as well as terminal?

If I change the imports to -

from module_1.some_code_1 import class_1
from module_2.some_code_2 import class_2
from module_3.some_code_3 import class_3

This works on the terminal but doesn't work in PyCharm. The test cases fail too.

Is there something I am missing, or some configuration that can be done to make all this work seamlessly?

Can someone help me with this?

Thanks!

Community
  • 1
  • 1
Adhish Thite
  • 463
  • 2
  • 5
  • 20

1 Answers1

2

The problem is when you do python code/main.py it makes your current working directory code/, which makes all of your absolute imports incorrect since Python doesn't see above that directory unless you explicitly change a setting like the PYTHONPATH environment variable.

Your best option is to rename main.py to __main__.py and then use python -m code (although do note that package name clashes with a module in the stdlib).

You also don't need the __init__.py in my_app/ unless you're going to treat that entire directory as a package.

And I would consider using relative imports instead of absolute ones (and I would also advise importing to the module and not the object/class in a module in your import statements to avoid circular import issues). For instance, for the from code.module_1.some_code_1 import class_1 line in code.main, I would make it from .module_1 import some_code_1.

Brett Cannon
  • 14,438
  • 3
  • 45
  • 40
  • Thanks, Brett! Can you please elaborate - 'And I would consider using relative imports instead of absolute ones (and I would also advise importing to the module and not the object/class in a module in your import statements to avoid circular import issues).' That would be great! – Adhish Thite Sep 18 '19 at 19:00
  • @AdhishThite I edited my response to provide an example. – Brett Cannon Sep 19 '19 at 18:40