Python error – ImportError: attempted relative import with no known parent package
Question:
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.
Answers:
You can try without using from ..util.module import my_function
rather try direct import my_function
.
If it doesn’t work you need to create a new file which can be empty named as __init__.py
under both utils
folder and server
folder. __init__.py
creates an actual module that can be called for any module.
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.
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.
You can try without using from ..util.module import my_function
rather try direct import my_function
.
If it doesn’t work you need to create a new file which can be empty named as __init__.py
under both utils
folder and server
folder. __init__.py
creates an actual module that can be called for any module.
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.