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.