So, my files/folders structure is the following:
project/
├─ utils/
│ ├─ module.py
├─ server/
│ ├─ main.py
Inside project/server/main.py
I'm trying to import project/utils/module.py
using this syntax: from ..utils.module import my_function
.
I'm using VSCode, and it even autocomplete for me as I type the module path. But when I run the file project/server/main.py
, I get the error in the title.
I've read dozens of answers here on stack overflow about this topic but none of them used an example like this.
Here is a reference that explains this problem well. Basically, the problem is that __package__
is not set when running standalone scripts.
File structure
.
└── project
├── server
│ └── main.py
└── utils
└── module.py
project/server/main.py
if __name__ == '__main__':
print(__package__)
Output
$ python3 project/server/main.py
None
As we can see, the value of __package__
is None
. This is a problem because it is the basis of relative imports as stated here:
__package__
... This attribute is used instead of
__name__
to calculate explicit relative imports for main modules, as defined in PEP 366...
Where PEP 366 explains this further:
The major proposed change is the introduction of a new module level attribute,
__package__
. When it is present, relative imports will be based on this attribute rather than the module__name__
attribute.
To resolve this, you can run it as a module via -m flag instead of a standalone script.
Output
$ python3 -m project.server.main # This can be <python3 -m project.server> if the file was named project/server/__main__.py
project.server
project/server/main.py
from ..utils.module import my_function
if __name__ == '__main__':
print(__package__)
print("Main")
my_function()
Output
$ python3 -m project.server.main
project.server
Main
My function
Now, __package__
is set, which means it can now resolve the explicit relative imports as documented above.