PEP: 366 Title: Main module explicit relative imports Version:
$Revision$ Last-Modified: $Date$ Author: Alyssa Coghlan
<ncoghlan@gmail.com> Status: Final Type: Standards Track Content-Type:
text/x-rst Created: 01-May-2007 Python-Version: 2.6, 3.0 Post-History:
01-May-2007, 04-Jul-2007, 07-Jul-2007, 23-Nov-2007

Abstract

This PEP proposes a backwards compatible mechanism that permits the use
of explicit relative imports from executable modules within packages.
Such imports currently fail due to an awkward interaction between PEP
328 and PEP 338.

By adding a new module level attribute, this PEP allows relative imports
to work automatically if the module is executed using the -m switch. A
small amount of boilerplate in the module itself will allow the relative
imports to work when the file is executed by name.

Guido accepted the PEP in November 2007[1].

Proposed Change

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.

As with the current __name__ attribute, setting __package__ will be the
responsibility of the PEP 302 loader used to import a module. Loaders
which use imp.new_module() to create the module object will have the new
attribute set automatically to None. When the import system encounters
an explicit relative import in a module without __package__ set (or with
it set to None), it will calculate and store the correct value
(__name__.rpartition('.')[0] for normal modules and __name__ for package
initialisation modules). If __package__ has already been set then the
import system will use it in preference to recalculating the package
name from the __name__ and __path__ attributes.

The runpy module will explicitly set the new attribute, basing it off
the name used to locate the module to be executed rather than the name
used to set the module's __name__ attribute. This will allow relative
imports to work correctly from main modules executed with the -m switch.

When the main module is specified by its filename, then the __package__
attribute will be set to None. 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 manipulates
sys.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.

Note that setting __package__ to the empty string explicitly is
permitted, and has the effect of disabling all relative imports from
that module (since the import machinery will consider it to be a top
level module in that case). This means that tools like runpy do not need
to provide special case handling for top level modules when setting
__package__.

Rationale for Change

The current inability to use explicit relative imports from the main
module is the subject of at least one open SF bug report (#1510172)[2],
and has most likely been a factor in at least a few queries on
comp.lang.python (such as Alan Isaac's question in[3]).

This PEP is intended to provide a solution which permits explicit
relative imports from main modules, without incurring any significant
costs during interpreter startup or normal module import.

The section in PEP 338 on relative imports and the main module provides
further details and background on this problem.

Reference Implementation

Rev 47142 in SVN implemented an early variant of this proposal which
stored the main module's real module name in the __module_name__
attribute. It was reverted due to the fact that 2.5 was already in beta
by that time.

Patch 1487[4] is the proposed implementation for this PEP.

Alternative Proposals

PEP 3122 proposed addressing this problem by changing the way the main
module is identified. That's a significant compatibility cost to incur
to fix something that is a pretty minor bug in the overall scheme of
things, and the PEP was rejected[5].

The advantage of the proposal in this PEP is that its only impact on
normal code is the small amount of time needed to set the extra
attribute when importing a module. Relative imports themselves should be
sped up fractionally, as the package name is cached in the module
globals, rather than having to be worked out again for each relative
import.

References

Copyright

This document has been placed in the public domain.

[1] Acceptance of the PEP
(https://mail.python.org/pipermail/python-dev/2007-November/075475.html)

[2] Absolute/relative import not working?
(https://github.com/python/cpython/issues/43535)

[3] c.l.p. question about modules and relative imports
(http://groups.google.com/group/comp.lang.python/browse_thread/thread/c44c769a72ca69fa/)

[4] PEP 366 implementation patch
(https://github.com/python/cpython/issues/45828)

[5] Guido's rejection of PEP 3122
(https://mail.python.org/pipermail/python-3000/2007-April/006793.html)