Why not being able to call modules from lib folder into test folder although I have __init__.py file both?

dieter dieter at handshake.de
Fri Apr 26 01:44:13 EDT 2019

Arup Rakshit <ar at zeit.io> writes:
> I am not able to call modules from lib folder in my test folder, but outside of tests folder I can access them. How should I fix this?
> Mocks$ tree .
> .
> ├── lib
> │   ├── __init__.py
> │   ├── __pycache__
> │   │   ├── __init__.cpython-37.pyc
> │   │   └── product.cpython-37.pyc
> │   └── product.py
> └── tests
>     ├── __init__.py
>     └── product_test.py
> 3 directories, 6 files
> Mocks$ python3
> ...
>>>> from lib.product import ProductionKlass
> ...
>>>> ProductionKlass()
> <lib.product.ProductionKlass object at 0x10d5f2128>
> ...
> Mocks$ python3 tests/product_test.py 
> Traceback (most recent call last):
>   File "tests/product_test.py", line 4, in <module>
>     from lib.product import ProductionKlass
> ModuleNotFoundError: No module named 'lib'

Python's import is controlled by "sys.path" -- typically a sequence of
folders where Python should look for modules/packages to import.

When you start a Python script, it puts the folder containing
the script automatically on "sys.path" (to facilitate imports
by this script). When you start Python interactively, it puts
the current working directory on "sys.path".

These differences explain your observations.
In the first case, "lib" can be imported because
the current working directory has been put on "sys.path".
In the second case, "lib" cannot be imported because the subfolder
"tests" has been put on "sys.path" (not the current working directory

A modern approach to avoid such situations looks like:

 * make your project into a package
   (see "https://packaging.python.org/")

 * use either package relative imports or absolute imports with
   the package as prefix to access modules in your package

 * install your package into a Python installation
   (use "virtualenv" to get a light weight local Python installation,
   if necessary)

 * have tiny script wrappers for scripts in your package.
   Packageing tools (such as "setuptools"
   --> "https://setuptools.readthedocs.io/en/latest/")
   can create thoses wrappers for you on installation.

More information about the Python-list mailing list