2

I am new to python and trying to figure out how to do things the "right way" and encountered the following problem:

My project has a structure that looks a little this:

├─packageA
│     functions.py
│     __init__.py
│
└─tests
      some_tests.py

packageA/__init__.py is empty.

packageA/functions.py looks like this:

def some_function(x):
    return x*x

And finally, tests/some_tests.py:

import packageA.functions

if __name__ == '__main__':
    print(packageA.functions.some_function(2))

If I run test.py using pycharm it works fine. However, when I open up a console and start it by running python.exe ./tests/some_tests.py I get

    Traceback (most recent call last):
  File ".\tests\some_tests.py", line 1, in <module>
    import packageA.functions
ModuleNotFoundError: No module named 'packageA'

While writing this, I figured out that pycharm adds source folders to PYTHONPATH - when I turn this off I get the same error. Is the folder structure above a sensible way to structure a python project? If not, how should it be organized instead?

m00am
  • 5,910
  • 11
  • 53
  • 69
padrino
  • 299
  • 3
  • 14
  • You can leave your folder structure if it is if you use the standard `unittest` module for your tests. Then the tests can be run with `python -m unittest` from the root directory and the import of `packageA` succeeds. I am not sure why this works, while `python ./tests/some_tests.py` does not. Can someone enlighten me? Edit: https://stackoverflow.com/a/24266885/6095394 gave me the answer: The `TestLoader` of the `unittest` module adds the package directory to `sys.path`. – pschill Feb 04 '18 at 13:38

1 Answers1

1

There are several options. However, the accepted answer in a similar SO question isn't ideal.

The below answer addresses your issue by explicitly adding the parent directory path at the start of your sys.path list.

import os, sys, inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir) 

import packageA.functions
jpp
  • 159,742
  • 34
  • 281
  • 339