[Python-Dev] Update to PEP 366 (Relative imports from the main module)

Guido van Rossum guido at python.org
Fri Nov 30 21:38:28 CET 2007


This looks good. Please make the appropriate changes to the PEP and to
PEP 0 to mark it as accepted.

I think the implementation is fine too (others will have to check it
more carefully) but I noticed that the promised functionality of -m
doesn't work yet: I created a file Lib/test/foo.py whose sole contents
was "from . import test_support". Then I tried to import this using
-m:

$ ./python.exe -m test.foo
Traceback (most recent call last):
  File "/Users/guido/p/Lib/runpy.py", line 104, in _run_module_as_main
    "__main__", fname, loader)
  File "/Users/guido/p/Lib/runpy.py", line 34, in _run_code
    exec code in run_globals
  File "/Users/guido/p/Lib/test/foo.py", line 1, in <module>
    from . import test_support
ValueError: Attempted relative import in non-package
$

What's missing here?

--Guido

On Nov 22, 2007 6:45 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> I've updated PEP 366 with a proposed implementation, as well as a few
> changes to the proposed semantics to make the implementation feasible
> (the old proposal called for imp.new_module to calculate a value when it
> didn't have access to all of the relevant information).
>
> The updated text is below, and should turn up on python.org before too long.
>
> Regards,
> Nick.
>
> --------------------------------------------
> PEP: 366
> Title: Main module explicit relative imports
> Version: $Revision$
> Last-Modified: $Date$
> Author: Nick Coghlan <ncoghlan at 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, 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.
>
>
> 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.
>
>
> 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.
>
> 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 [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 cached 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)
>
> .. [4] PEP 366 implementation patch
>     (http://bugs.python.org/issue1487)
>
> Copyright
> =========
>
> This document has been placed in the public domain.
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
>



-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list