It seems, from Python docs and experimenting, that relative imports (involving ., .. etc) only work if
- the importing module has a
__name__
other than __main__
, and further,
- the
__name__
of the importing module is pkg.module_name, i.e., it has to be imported from above in the directory hierarchy (to have a parent pkg as part of it's __name__
.)
OR
the importing module is being specified via module syntax that includes a parent pkg as python -m pkg.module
, in which case it's __name__
is still __main__
, so it is being run as a script, yet relative imports will work. Here __package__
is set and used to find the parent package while __name__
is __main__
; more here.
[After all that, it appears that __package__
and sys.path
are key to determining if/how relative imports work. __name__
indicates script or module(i.e., __main__
or module_name
). __package__
indicates where in the package the relative imports occur with respect to, and the top of __package__
needs to be in sys.path
.]
So, continuing with @AmitTendulkar 's example, if you run this as > python main.py
or > python -m main
or > python -m ecommerce.products
from the project root directory, or enter interactive python from that root directory and import main
, or import ecommerce.products
the relative imports in products.py will work.
But if you > python products.py
or > python -m products
from within ecommerce directory, or enter interactive python from that ecommerce directory and import products
they will fail.
It is helpful to add
print("In module products __package__, __name__ ==", __package__, __name__)
etc. in each file to debug.
UPDATE:
How imports work depend on sys.path
and __package__
, not on __name__
.
Issued from /home/jj
, > python sub/mod.py
has a sys.path
, __package__
of /home/jj/sub
, None
-absolute imports of modules in sys.path
work, relative imports fail.
> python -m sub.mod
has sys.path
, __package__
of /home/jj
, sub
-absolute imports of modules in sys.path
work, relative imports work relative to sys.path
+ __package__
.
It is more helpful to add
import sys
print("In module products sys.path[0], __package__ ==", sys.path[0], __package__)
etc. in each file to debug.