I created a project using python and happily finished implementing functions with following structure.
- project
|
- pipelines
| |
| - functions.py
|
- tests
|
- unittest.py
I created unittest/integration test and then I saw this exception
Traceback (most recent call last):
File "/home/xxxx/anaconda3/lib/python3.7/unittest/loader.py", line 154, in loadTestsFromName
module = __import__(module_name)
File "/home/xxxx/datascience.my-project/test/test-unittest.py", line 1, in <module>
from .my_great_script import queryer
ImportError: attempted relative import with no known parent package
i was so frustrated.
but don’t be after you see this post.
before we tackle this problem, let us understand what does python do to import.
what does python do to import a module Link to heading
When a module named
spamis imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file namedspam.pyin a list of directories given by the variablesys.path.sys.pathis initialized from these locations:
- The directory containing the input script (or the current directory when no file is specified).
PYTHONPATH(a list of directory names, with the same syntax as the shell variable PATH).- The installation-dependent default.
basically python will search according to some rules and find the correct location for a module.
error related to structure? Link to heading
I don’t think so. in contrast, I think it is a good structure.
error related to relative import? Link to heading
for my perspective, the answer is yes and no.
yes, it is related to relative import, because for this case, when importing in test script, it cannot find the module under current path.
and no, the solution for this (as far as I am using) is not changing the relative import in pipeline scripts.
and one more suggest, don’t try to change your function scripts’ import because your functions are your first priority.
in the other word, one must deal with this situation that make sure function scripts run first and then think about test scripts.
At first, I want to solve it by changing relative import in pipeline’s script, and I was really happy when it seems to be ‘solved’. But later on, when I found my pipeline didn’t run, I realized that I shouldn’t solve it this way.
my solution for this exception Link to heading
because what i develop is first develop functions and then test. so when I met this exception in test script, I just simply import all path of interest into current script. by doing so, python will search my newly added path and import.
it has flaws though.
first of all, it may add time searching. secondly, this is not a systematically way solving similar issue. for every error you encounter, you have to decide which path to add.
but I don’t see a silver bullet to solve this issue, and I will use this method for now.