Reputation: 37516
I have a Python module I'm working on to add some unit tests.
The project layout looks something like this:
myproj\
__init__.py
myproj.py
test\
test_myproj.py
In test_myproj.py
I'm trying to import the parent module as follows:
from .. import myproj
When I try and run it though, I get this:
Traceback (most recent call last):
File "C:\Projects\myproj\test\test_myproj.py", line 6, in <module>
from .. import myproj
SystemError: Parent module '' not loaded, cannot perform relative import
Various sources on the internet suggest this should work so what am I missing?
Upvotes: 1
Views: 199
Reputation: 6341
You have to make your test
directory a package - add __init__.py
file to the test
directory. After this you need your test_myproj.py
file to have a __name__
of myproj.test.test_myproj
when it is executed, so that it could compute the relative import path to myproj
. Which will lead to from .. import myproj
being interpreted as from myproj import myproj
. But when you run your test file directly the __name__
is set to __main__
, so it can't calculate relative import. To fix this, the test file should be imported instead of being run directly. Create a separate file (e.g. testrunner.py
), which you will run to perform tests, and in that file import your test module(s) (e.g. test_myproj.py), obviously without relative import syntax or the problem will repeat. The import will lead to your test file being executed with the __name__
value, that will allow to calculate relative import. E.g.:
Add testrunner.py
as shown:
testrunner.py
myproj\
__init__.py
myproj.py
test\
__init__.py
test_myproj.py
testrunner.py
content:
from myproj.test import test_myproj.py
run your test using:
python C:\Projects\testrunner.py
or
cd C:\Projects\
python testrunner.py
This way it's probably best to add another directory that will keep both testrunner.py
and your myproj
package.
See more thorough explanation on relative import in the answer here.
There's a note in official docs for this matter:
Note that relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application must always use absolute imports.
Upvotes: 2