python-peps/pep-0328.txt

230 lines
6.7 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

PEP: 328
Title: Imports: Multi-Line and Absolute/Relative
Version: $Revision$
Last-Modified: $Date$
Author: Aahz <aahz@pythoncraft.com>
Status: Accepted
Type: Standards Track
Python-Version: 2.4
Content-Type: text/x-rst
Created: 21-Dec-2003
Post-History: 8-Mar-2004
Abstract
========
The ``import`` statement has two problems:
* Long ``import`` statements can be difficult to write, requiring
various contortions to fit Pythonic style guidelines.
* Imports can be ambiguous in the face of packages; within a package,
it's not clear whether ``import foo`` refers to a module within the
package or some module outside the package.
For the first problem, it is proposed that parentheses be permitted to
enclose multiple names, thus allowing Python's standard mechanisms for
multi-line values to apply. For the second problem, it is proposed
that all ``import`` statements be absolute by default (more precisely,
relative to ``sys.path``) with special syntax for accessing
package-relative imports.
Rationale for Parentheses
=========================
Currently, if you want to import a lot of names from a module or
package, you have to choose one of several unpalatable options:
* Write a long line with backslash continuations::
from Tkinter import Tk, Frame, Button, Entry, Canvas, Text, \
LEFT, DISABLED, NORMAL, RIDGE, END
* Write multiple ``import`` statements::
from Tkinter import Tk, Frame, Button, Entry, Canvas, Text
from Tkinter import LEFT, DISABLED, NORMAL, RIDGE, END
(``import *`` is *not* an option ;-)
Instead, it should be possible to use Python's standard grouping
mechanism (parentheses) to write the ``import`` statement::
from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,
LEFT, DISABLED, NORMAL, RIDGE, END)
This part of the proposal already has BDFL approval.
Rationale for Absolute Imports
==============================
In current Python, if you're reading a module located inside a
package, it is not clear whether ::
import foo
refers to a top-level module or to another module inside the package.
To resolve the ambiguity, it is proposed that ``foo`` will always be a
module or package reachable from ``sys.path``.
Because this represents a change in semantics, absolute imports will
be optional in Python 2.4 through the use of ::
from __future__ import absolute_import
This PEP will be updated when it is decided to make absolute imports
the default, probably Python 2.5 or 2.6.
This part of the proposal already has BDFL approval.
Rationale for Relative Imports
==============================
With the shift to absolute imports, the question arose whether
relative imports should be allowed at all. Several use cases were
presented, the most important of which is being able to rearrange the
structure of large packages without having to edit sub-packages. In
addition, a module inside a package can't easily import itself without
relative imports.
Guido approved of the idea of relative imports, but there has been a
lot of disagreement on the spelling (syntax). There does seem to be
agreement that relative imports will require listing specific names to
import (that is, ``import foo`` as a bare term will always be an
absolute import).
Here are the contenders:
* One from Guido::
from .foo import bar
and ::
from ...foo import bar
These two forms have a couple of different suggested semantics. One
semantic is to make each dot represent one level. There have been
many complaints about the difficulty of counting dots. Another
option is to only allow one level of relative import. That misses a
lot of functionality, and people still complained about missing the
dot in the one-dot form. The final option is to define an algorithm
for finding relative modules and packages; the objection here is
"Explicit is better than implicit". (The algorithm proposed is
"search up from current package directory until the ultimate package
parent gets hit".)
Some people have suggested other punctuation as the separator, such
as "-" or "^".
Some people have suggested using "*"::
from *.foo import bar
* The next set of options is conflated from several posters::
from __pkg__.__pkg__ import
and ::
from .__parent__.__parent__ import
Many people (Guido included) think these look ugly, but they *are*
clear and explicit. Overall, more people prefer ``__pkg__`` as the
shorter option.
* One suggestion was to allow only sibling references. In other words,
you would not be able to use relative imports to refer to modules
higher in the package tree. You would then be able to do either ::
from .spam import eggs
or ::
import .spam.eggs
* Some people favor allowing indexed parents::
from -2.spam import eggs
In this scenario, importing from the current directory would be a
simple ::
from .spam import eggs
* Finally, some people dislike the way you have to change ``import``
to ``from ... import`` when you want to dig inside a package. They
suggest completely rewriting the ``import`` syntax::
from MODULE import NAMES as RENAME searching HOW
or ::
import NAMES as RENAME from MODULE searching HOW
[from NAMES] [in WHERE] import ...
However, this most likely could not be implemented for Python 2.4
(too big a change), and allowing relative imports is sufficiently
critical that we need something now (given that the standard
``import`` will change to absolute import). More than that, this
proposed syntax has several open questions:
- What is the precise proposed syntax? (Which clauses are optional
under which circumstances?)
- How strongly does the ``searching`` clause bind? In other words,
do you write::
import foo as bar searching XXX, spam as ham searching XXX
or::
import foo as bar, spam as ham searching XXX
Guido's Decision
================
Guido has Pronounced [1]_ that relative imports will use leading dots,
one per level of parent.
References
==========
For more background, see the following python-dev threads:
- `Re: Christmas Wishlist
<http://mail.python.org/pipermail/python-dev/2003-December/040973.html>`__
- `Re: Python-Dev Digest, Vol 5, Issue 57
<http://mail.python.org/pipermail/python-dev/2003-December/041078.html>`__
- `Relative import
<http://mail.python.org/pipermail/python-dev/2003-December/041065.html>`__
- `Another Strategy for Relative Import
<http://mail.python.org/pipermail/python-dev/2003-December/041418.html>`__
.. [1] http://mail.python.org/pipermail/python-dev/2004-March/043739.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: