Updated writeup about import statements to strongly recommend absolute imports from main modules
This commit is contained in:
parent
a218af0b7f
commit
09618837a9
80
pep-0338.txt
80
pep-0338.txt
|
@ -180,39 +180,67 @@ deleting ``sys.argv[0]`` (which refers to the ``runpy`` module itself)
|
||||||
and then invokes ``run_module(sys.argv[0], run_name="__main__",
|
and then invokes ``run_module(sys.argv[0], run_name="__main__",
|
||||||
alter_sys=True)``.
|
alter_sys=True)``.
|
||||||
|
|
||||||
Relative Imports
|
Import Statements and the Main Module
|
||||||
================
|
=====================================
|
||||||
|
|
||||||
2.5b1 showed an annoying interaction between this PEP and PEP 328 -
|
The release of 2.5b1 showed a surprising (although obvious in
|
||||||
explicit relative imports don't work from a main module, because
|
retrospect) interaction between this PEP and PEP 328 - explicit
|
||||||
relative imports rely on ``__name__`` to determine the current module's
|
relative imports don't work from a main module. This is due to
|
||||||
position in the package hierarchy.
|
the fact that relative imports rely on ``__name__`` to determine
|
||||||
|
the current module's position in the package hierarchy. In a main
|
||||||
|
module, the value of ``__name__`` is always ``'__main__'``, so
|
||||||
|
explicit relative imports will always fail (as they only work for
|
||||||
|
a module inside a package).
|
||||||
|
|
||||||
Accordingly, the operation of ``run_module()`` was modified so that
|
Investigation into why implicit relative imports *appear* to work when
|
||||||
another special variable ``__module_name__`` was defined in the
|
a main module is executed directly but fail when executed using -m
|
||||||
namespace of the module being executed. This variable always holds
|
showed that such imports are actually always treated as absolute
|
||||||
the true module name, even if ``__name__`` is set to something else
|
imports. Because of the way direct execution works, the package
|
||||||
(like ``'__main__'``)
|
containing the executed module is added to sys.path, so its sibling
|
||||||
|
modules are actually imported as top level modules. This can easily
|
||||||
|
lead to multiple copies of the sibling modules in the application if
|
||||||
|
implicit relative imports are used in modules that may be directly
|
||||||
|
executed (e.g. test modules or utility scripts).
|
||||||
|
|
||||||
Modules that don't rely on relative imports can be used from a
|
For the 2.5 release, the recommendation is to always use absolute
|
||||||
package as a main module without any changes. In order to both use
|
imports in any module that is intended to be used as a main module.
|
||||||
relative imports and also be usable as a main module, a module in a
|
The -m switch provides a benefit here, as it inserts the current
|
||||||
package will currently need to use a structure similar to the
|
directory into sys.path, instead of the directory contain the main
|
||||||
following::
|
module. This means that it is possible to run a module from inside a
|
||||||
|
package using -m so long as the current directory contains the top
|
||||||
|
level directory for the package. Absolute imports will work correctly
|
||||||
|
even if the package isn't installed anywhere else on sys.path. If the
|
||||||
|
module is executed directly and uses absolute imports to retrieve its
|
||||||
|
sibling modules, then the top level package directory needs to be
|
||||||
|
installed somewhere on sys.path (since the current directory won't be
|
||||||
|
added automatically).
|
||||||
|
|
||||||
# Docstring and any future statements
|
Here's an example file layout::
|
||||||
_is_main = False
|
|
||||||
if __name__ == "__main__":
|
|
||||||
_is_main = True
|
|
||||||
__name__ = __module_name__
|
|
||||||
|
|
||||||
# Support module section, including relative imports
|
devel/
|
||||||
|
pkg/
|
||||||
|
__init__.py
|
||||||
|
moduleA.py
|
||||||
|
moduleB.py
|
||||||
|
test/
|
||||||
|
__init__.py
|
||||||
|
test_A.py
|
||||||
|
test_B.py
|
||||||
|
|
||||||
if _is_main:
|
So long as the current directory is ``devel``, or ``devel`` is already
|
||||||
# Main module section
|
on ``sys.path`` and the test modules use absolute imports (such as
|
||||||
|
``import pkg moduleA`` to retrieve the module under test, PEP 338
|
||||||
|
allows the tests to be run as::
|
||||||
|
|
||||||
That said, Guido's recommended solution is to avoid using relative
|
python -m pkg.test.test_A
|
||||||
imports in the first place.
|
python -m pkg.test.test_B
|
||||||
|
|
||||||
|
The question of whether or not relative imports should be supported
|
||||||
|
when a main module is executed with -m is something that will be
|
||||||
|
revisited for Python 2.6. Permitting it would require changes to
|
||||||
|
either Python's import semantics or the semantics used to indicate
|
||||||
|
when a module is the main module, so it is not a decision to be made
|
||||||
|
hastily.
|
||||||
|
|
||||||
Resolved Issues
|
Resolved Issues
|
||||||
================
|
================
|
||||||
|
|
Loading…
Reference in New Issue