In PEP 366 - Main module explicit relative imports which introduced the module-scope variable __package__
to allow explicit relative imports in submodules, there is the following excerpt:
When the main module is specified by its filename, then the
__package__
attribute will be set toNone
. To allow relative imports when the module is executed directly, boilerplate similar to the following would be needed before the first relative import statement:if __name__ == "__main__" and __package__ is None: __package__ = "expected.package.name"
Note that this boilerplate is sufficient only if the top level package is already accessible via
sys.path
. Additional code that manipulatessys.path
would be needed in order for direct execution to work without the top level package already being importable.This approach also has the same disadvantage as the use of absolute imports of sibling modules - if the script is moved to a different package or subpackage, the boilerplate will need to be updated manually. It has the advantage that this change need only be made once per file, regardless of the number of relative imports.
I have tried to use this boilerplate in the following setting:
Directory layout:
foo ├── bar.py └── baz.py
Contents of the bar.py submodule:
if __name__ == "__main__" and __package__ is None: __package__ = "foo" from . import baz
The boilerplate works when executing the submodule bar.py from the file system (the PYTHONPATH
modification makes the package foo/ accessible on sys.path
):
PYTHONPATH=$(pwd) python3 foo/bar.py
The boilerplate also works when executing the submodule bar.py from the module namespace:
python3 -m foo.bar
However the following alternative boilerplate works just as well in both cases as the contents of the bar.py submodule:
if __package__:
from . import baz
else:
import baz
Furthermore this alternative boilerplate is simpler and does not require any update of the submodule bar.py when it is moved with the submodule baz.py to a different package (since it does not hard code the package name "foo"
).
So here are my questions about the boilerplate of PEP 366:
- Is the first subexpression
__name__ == "__main__"
necessary or is it already implied by the second subexpression__package__ is None
? - Shouldn’t the second subexpression
__package__ is None
benot __package__
instead, in order to handle the case where__package__
is the empty string (like in a__main__.py
submodule executed from the file system by supplying the containing directory:PYTHONPATH=$(pwd) python3 foo/
)?