0

In the following structure:

src:
    model:
        - boardmodel.py
        - tests.py
        exceptions:
            - exceptions.py
    - visual.py

I'm running visual.py from the terminal. In my boardmodel.py, I have the following import:

from exceptions.exceptions import ZeroError, OverlapError, ArgumentError, ProximityError

This line causes an error when running visual.py:

Traceback (most recent call last):
  File "visual.py", line 3, in <module>
    from model.boardModel import Board
  File "/Users/sahandzarrinkoub/Documents/Programming/pythonfun/BouncingBalls/balls/src/model/boardModel.py", line 5, in <module>
    from exceptions.exceptions import ZeroError, OverlapError, ArgumentError, ProximityError
ModuleNotFoundError: No module named 'exceptions'

What is the correct way to solve this problem? Should I change the import statement inside boardmodel.py to from model.exceptions.exceptions import ZeroError....? That doesn't feel like a sustainable solution, because what if I want to use boardmodel.py in another context? Let me her your thoughts.

EDIT:

I changed the structure to:

src:
    model:
        - __init__.py
        - boardmodel.py
        - tests.py
        exceptions:
            - __init__.py
            - exceptions.py
    - visual.py

But still I get the same error.

Sahand
  • 7,980
  • 23
  • 69
  • 137
  • You could use relative imports, or adding _model_ folder to _PYTHONPATH_ env var (or to `sys.path` from code). – CristiFati Sep 22 '17 at 19:38
  • The complete problem would have been clearer if you showed the first few lines (including the `import` statements) from `visual.py` and `boardmodel.py` – kdopen Sep 22 '17 at 19:51

2 Answers2

4

Place an empty file called __init__.py in each of the subdirectories to make them packages.

See What is __init__.py for? for more details

Then, within boardmodel.py you need to either use relative imports

from .exceptions.exceptions import ...

or absolute ones (from the root of PYTHONPATH)

from model.exceptions.exceptions import ...

When you execute a script from the command line, the directory containing the script is automatically added to your PYTHONPATH, and becomes the root for import statements

kdopen
  • 8,032
  • 7
  • 44
  • 52
  • You also need to use relative imports, as Laurent says. But you did need the `__init__.py` files for them to work – kdopen Sep 22 '17 at 19:48
1

You are not at the root of your package so you need relative import.

Add a dot before exceptions:

from .exceptions.exceptions import ZeroError, OverlapError, ArgumentError, ProximityError

One dot mean "from the current directory"…

Laurent LAPORTE
  • 21,958
  • 6
  • 58
  • 103