[Python-Dev] Update to PEP 366 (Relative imports from the main module) (original) (raw)
Guido van Rossum guido at python.org
Fri Nov 30 21:38:28 CET 2007
- Previous message: [Python-Dev] Update to PEP 366 (Relative imports from the main module)
- Next message: [Python-Dev] Backquote deprecation warning
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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 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.newmodule 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: RevisionRevisionRevision Last-Modified: DateDateDate 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 useimp.newmodule()
to create the module object will have the new attribute set automatically toNone
. When the import system encounters an explicit relative import in a module without_package_
set (or with it set toNone
), 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. Therunpy
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 toNone
. 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 viasys.path
. Additional code that manipulatessys.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_modulename_
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/browsethread/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/)
- Previous message: [Python-Dev] Update to PEP 366 (Relative imports from the main module)
- Next message: [Python-Dev] Backquote deprecation warning
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]