python-peps/pep-0366.txt

136 lines
4.6 KiB
Plaintext

PEP: 366
Title: Main module explicit relative imports
Version: $Revision$
Last-Modified: $Date$
Author: Nick Coghlan <ncoghlan@gmail.com>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 1-May-2007
Python-Version: 2.6, 3.0
Post-History: 1-May-2007, 4-Jul-2007, 7-Jul-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.
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
``__name__.rpartition('.')[0]``.
``runpy.run_module`` will also set the new attribute, basing it off the
``mod_name`` argument, rather than the ``run_name`` argument. 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 the empty string. 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 not __package_name__:
__package_name__ = "<expected_pacakage_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.
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) [1]_,
and has most likely been a factor in at least a few queries on
comp.lang.python (such as Alan Isaac's question in [2]_).
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.
A new patch will be developed for 2.6, and forward ported to
Py3k via svnmerge.
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 [3]_.
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 stored in the module
globals, rather than having to be worked out again for each relative
import.
References
==========
.. [1] Absolute/relative import not working?
(http://www.python.org/sf/1510172)
.. [2] c.l.p. question about modules and relative imports
(http://groups.google.com/group/comp.lang.python/browse_thread/thread/c44c769a72ca69fa/)
.. [3] Guido's rejection of PEP 3122
(http://mail.python.org/pipermail/python-3000/2007-April/006793.html)
Copyright
=========
This document has been placed in the public domain.
..
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
End: