Updated writeup about import statements to strongly recommend absolute imports from main modules

This commit is contained in:
Nick Coghlan 2006-07-06 12:36:24 +00:00
parent a218af0b7f
commit 09618837a9
1 changed files with 54 additions and 26 deletions

View File

@ -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
================ ================