ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://peps.python.org/pep-0366/ |
| Last Crawled | 2026-04-06 22:54:40 (20 hours ago) |
| First Indexed | 2022-03-09 22:40:00 (4 years ago) |
| HTTP Status Code | 200 |
| Meta Title | PEP 366 – Main module explicit relative imports | peps.python.org |
| Meta Description | 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. |
| Meta Canonical | null |
| Boilerpipe Text | Author
:
Alyssa Coghlan <ncoghlan at gmail.com>
Status
:
Final
Type
:
Standards Track
Created
:
01-May-2007
Python-Version
:
2.6, 3.0
Post-History
:
01-May-2007, 04-Jul-2007, 07-Jul-2007, 23-Nov-2007
Table of Contents
Abstract
Proposed Change
Rationale for Change
Reference Implementation
Alternative Proposals
References
Copyright
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
[5]
.
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)
[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
Copyright
This document has been placed in the public domain. |
| Markdown | # Python Enhancement Proposals
- [Python](https://www.python.org/ "The Python Programming Language") »
- [PEP Index](https://peps.python.org/pep-0000/) »
- PEP 366
Toggle light / dark / auto colour theme
PEP 366 – Main module explicit relative imports
# PEP 366 – Main module explicit relative imports
Author:
Alyssa Coghlan \<ncoghlan at gmail.com\>
Status:
Final
Type:
Standards Track
Created:
01-May-2007
Python-Version:
2\.6, 3.0
Post-History:
01-May-2007, 04-Jul-2007, 07-Jul-2007, 23-Nov-2007
***
Table of Contents
- [Abstract](https://peps.python.org/pep-0366/#abstract)
- [Proposed Change](https://peps.python.org/pep-0366/#proposed-change)
- [Rationale for Change](https://peps.python.org/pep-0366/#rationale-for-change)
- [Reference Implementation](https://peps.python.org/pep-0366/#reference-implementation)
- [Alternative Proposals](https://peps.python.org/pep-0366/#alternative-proposals)
- [References](https://peps.python.org/pep-0366/#references)
- [Copyright](https://peps.python.org/pep-0366/#copyright)
## [Abstract](https://peps.python.org/pep-0366/#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](https://peps.python.org/pep-0328/ "PEP 328 – Imports: Multi-Line and Absolute/Relative") and [PEP 338](https://peps.python.org/pep-0338/ "PEP 338 – Executing modules as scripts").
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 [\[5\]](https://peps.python.org/pep-0366/#id10).
## [Proposed Change](https://peps.python.org/pep-0366/#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](https://peps.python.org/pep-0302/ "PEP 302 – New Import Hooks") 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](https://peps.python.org/pep-0366/#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\]](https://peps.python.org/pep-0366/#id6), 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\]](https://peps.python.org/pep-0366/#id7)).
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](https://peps.python.org/pep-0338/ "PEP 338 – Executing modules as scripts") on relative imports and the main module provides further details and background on this problem.
## [Reference Implementation](https://peps.python.org/pep-0366/#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\]](https://peps.python.org/pep-0366/#id9) is the proposed implementation for this PEP.
## [Alternative Proposals](https://peps.python.org/pep-0366/#alternative-proposals)
[PEP 3122](https://peps.python.org/pep-3122/ "PEP 3122 – Delineation of the main module") 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\]](https://peps.python.org/pep-0366/#id8).
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](https://peps.python.org/pep-0366/#references)
\[[1](https://peps.python.org/pep-0366/#id2)\]
Absolute/relative import not working? (<https://github.com/python/cpython/issues/43535>)
\[[2](https://peps.python.org/pep-0366/#id3)\]
c.l.p. question about modules and relative imports (<http://groups.google.com/group/comp.lang.python/browse_thread/thread/c44c769a72ca69fa/>)
\[[3](https://peps.python.org/pep-0366/#id5)\]
Guido’s rejection of PEP 3122 (<https://mail.python.org/pipermail/python-3000/2007-April/006793.html>)
\[[4](https://peps.python.org/pep-0366/#id4)\]
PEP 366 implementation patch (<https://github.com/python/cpython/issues/45828>)
\[[5](https://peps.python.org/pep-0366/#id1)\]
Acceptance of the PEP (<https://mail.python.org/pipermail/python-dev/2007-November/075475.html>)
## [Copyright](https://peps.python.org/pep-0366/#copyright)
This document has been placed in the public domain.
***
Source: <https://github.com/python/peps/blob/main/peps/pep-0366.rst>
Last modified: [2025-02-01 08:59:27 GMT](https://github.com/python/peps/commits/main/peps/pep-0366.rst)
## Contents
- [Abstract](https://peps.python.org/pep-0366/#abstract)
- [Proposed Change](https://peps.python.org/pep-0366/#proposed-change)
- [Rationale for Change](https://peps.python.org/pep-0366/#rationale-for-change)
- [Reference Implementation](https://peps.python.org/pep-0366/#reference-implementation)
- [Alternative Proposals](https://peps.python.org/pep-0366/#alternative-proposals)
- [References](https://peps.python.org/pep-0366/#references)
- [Copyright](https://peps.python.org/pep-0366/#copyright)
[Page Source (GitHub)](https://github.com/python/peps/blob/main/peps/pep-0366.rst?plain=1) |
| Readable Markdown | Author:
Alyssa Coghlan \<ncoghlan at gmail.com\>
Status:
Final
Type:
Standards Track
Created:
01-May-2007
Python-Version:
2\.6, 3.0
Post-History:
01-May-2007, 04-Jul-2007, 07-Jul-2007, 23-Nov-2007
***
Table of Contents
- [Abstract](https://peps.python.org/pep-0366/#abstract)
- [Proposed Change](https://peps.python.org/pep-0366/#proposed-change)
- [Rationale for Change](https://peps.python.org/pep-0366/#rationale-for-change)
- [Reference Implementation](https://peps.python.org/pep-0366/#reference-implementation)
- [Alternative Proposals](https://peps.python.org/pep-0366/#alternative-proposals)
- [References](https://peps.python.org/pep-0366/#references)
- [Copyright](https://peps.python.org/pep-0366/#copyright)
## [Abstract](https://peps.python.org/pep-0366/#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](https://peps.python.org/pep-0328/ "PEP 328 – Imports: Multi-Line and Absolute/Relative") and [PEP 338](https://peps.python.org/pep-0338/ "PEP 338 – Executing modules as scripts").
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 [\[5\]](https://peps.python.org/pep-0366/#id10).
## [Proposed Change](https://peps.python.org/pep-0366/#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](https://peps.python.org/pep-0302/ "PEP 302 – New Import Hooks") 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](https://peps.python.org/pep-0366/#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\]](https://peps.python.org/pep-0366/#id6), 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\]](https://peps.python.org/pep-0366/#id7)).
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](https://peps.python.org/pep-0338/ "PEP 338 – Executing modules as scripts") on relative imports and the main module provides further details and background on this problem.
## [Reference Implementation](https://peps.python.org/pep-0366/#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\]](https://peps.python.org/pep-0366/#id9) is the proposed implementation for this PEP.
## [Alternative Proposals](https://peps.python.org/pep-0366/#alternative-proposals)
[PEP 3122](https://peps.python.org/pep-3122/ "PEP 3122 – Delineation of the main module") 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\]](https://peps.python.org/pep-0366/#id8).
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](https://peps.python.org/pep-0366/#references)
## [Copyright](https://peps.python.org/pep-0366/#copyright)
This document has been placed in the public domain. |
| Shard | 16 (laksa) |
| Root Hash | 10954876678907435016 |
| Unparsed URL | org,python!peps,/pep-0366/ s443 |