1

I have read a ton of stackoverflow answers and a bunch of tutorials. In addition, I tried to read the Python documentation, but I cannot make this import work.

This is how the directory looks like:

myDirectory ├── __init__.py ├── LICENSE ├── project.py ├── README.md ├── stageManager.py └── tests ├── __init__.py └── test_project.py 

There is a class in project.py called Project, and I want to import it in a file under tests directory. I have tried the following:

Relative import:

from ..project import Project def print_sth(): print("something") 

This gives me the following error: (running from the tests directory as python test_project.py and from myDirectory as python tests/test_project.py)

Traceback (most recent call last): File "test_project.py", line 1, in <module> from ..project import Project SystemError: Parent module '' not loaded, cannot perform relative import 

Absolute import with package name:

If I have something like the following, I get ImportError (with the same run command as above).

from project import Project def print_sth(): print("something") ------------------------------------------------------ Traceback (most recent call last): File "test_project.py", line 1, in <module> from project import Project ImportError: No module named 'project' 

and this too:

from myDirectory.project import Project def print_sth(): print("something") ------------------------------------------------------ Traceback (most recent call last): File "test_project.py", line 1, in <module> from myDirectory.project import Project ImportError: No module named 'myDirectory' 

Finally, I tried adding the if __name__ == '__main__' statement within the test_project.py file, but it still failed. I would really appreciate if anyone could help. If there is a solution where I do not have to write a verbose command, I would prefer that.

2
  • Have you tried simply from project import Project without the leading ..? Python imports are related to folder structure, but they are not the folder structure and having the leading dots makes it skip the next module up, which is the one you want. Commented Feb 28, 2018 at 5:26
  • I tried that too, did not work. (I added the code and error up there) Commented Feb 28, 2018 at 6:27

1 Answer 1

1

When you run a Python script by filename, the Python interpreter assumes that it is a top-level module (and it adds the directory the script is in to the module search path). If the script is in a package, that's not correct. Instead, you should run the module using the -m flag, which takes a module name in the same format as an import statement (dotted separators) and puts the current directory in the module search path.

So, you could run the test from myDirectory with: python -m tests.test_project. When you run the script this way, either of the kinds of imports you tried will work.

But if myDirectory is supposed to be a top-level package itself (as the __init__.py file suggests), you should probably go up one level further up, to myDirectory's parent, and run the script with two levels of package names: python -m myDirectory.tests.test_project. If you do this and want the test to use an absolute import you'd need to name the top level package that the project module is in: from myDirectory.project import Project.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks so much. I was able to run this from the test_project from myDirectory with the -m flag. However, it sort of restricts the usability of the module. Additionally, I would be dealing with a lot of cd and mkdir commands in this project. Is it possible to run test_project.py while in the tests directory?
You can add myDirectory (or it's parent) to the global module search path using environment variables (PYTHONPATH), and then do an absolute import from a script running anywhere. You could also then enable relative imports by setting the __package__ variable in the script (see PEP 366 for details). But in general, running scripts from packages is not an encouraged idiom. You may want to have a top level entry point for scripts you're running frequently (it can just import and run some code from inside the package).
Thanks for the explanation. It appears that I need to look into the style guides more, and since a large part of my project is dependent on creating/modifying files/directories in different locations, I need to review some design principles and practices. Thanks for your effort!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.