dooah
dooah

Reputation: 13

Module not found after explicitly adding package dir to sys.path at runtime

Python cannot find 'mypackage' in this scenario:

Tree:

- myproject
    - mypackage
        - __init__.py
        - mymodule.py
    - tests
        - test.py

Contents of test.py

import sys
from pathlib import Path

p = Path('.')
sys.path.append(p.absolute())

import mypackage                 # ModuleNotFoundError
from mypackage import mymodule   # ModuleNotFoundError

I also printed all the entries from sys.path, where myproject is included.

What am I missing here?

EDIT:

I am running python from the myproject folder, so the '.' technically works, but I take the point that it's probably not how you should do it. The problem however, seems to have been sys.path not handling a Path object? The solution was string conversion in this case.

Upvotes: 1

Views: 78

Answers (3)

RMPR
RMPR

Reputation: 3531

You are not correctly referencing the file, because '.' means the current working directory, use this instead:

p = str(Path(Path(__file__).parent.absolute()).parent.absolute())
sys.path.insert(0, p)

Upvotes: 1

Jean-Marc Volle
Jean-Marc Volle

Reputation: 3333

A possible solution:

in __init__.py

from .mymodule import *

Ensure myproject folder absolute path is in the PYTHONPATH environment variable eg in unix/linux:

export PYTHONPATH=path_to_my_project

or in windows: you can create a batch like this one (place in myproject)

@ echo off
echo setting PYTHONPATH to %~dp0
setx PYTHONPATH %~dp0
pause

Upvotes: 0

COVFEFE-19
COVFEFE-19

Reputation: 313

The dot in p = Path('.') just refers to whatever is the current working directory. It may not be the right directory to allow importing mypackage.

To inject the correct location it could be p = Path(__file__).parent.parent instead. But the correct solution here is actually not to append in sys.path at all, it's to install your package in development mode for running the tests. This links your code into site-packages dir, which is already on sys.path, in the more usual way.

Upvotes: 1

Related Questions