PEP: 221 Title: Import As Version: $Revision$ Last-Modified: $Date$
Author: thomas\@python.org (Thomas Wouters) Status: Final Type:
Standards Track Content-Type: text/x-rst Created: 15-Aug-2000
Python-Version: 2.0 Post-History:

Introduction
============

This PEP describes the `import as` proposal for Python 2.0. This PEP
tracks the status and ownership of this feature. It contains a
description of the feature and outlines changes necessary to support the
feature. The CVS revision history of this file contains the definitive
historical record.

Rationale
=========

This PEP proposes an extension of Python syntax regarding the `import`
and `from <module> import` statements. These statements load in a
module, and either bind that module to a local name, or binds objects
from that module to a local name. However, it is sometimes desirable to
bind those objects to a different name, for instance to avoid name
clashes. This can currently be achieved using the following idiom::

    import os
    real_os = os
    del os

And similarly for the `from ... import` statement::

    from os import fdopen, exit, stat
    os_fdopen = fdopen
    os_stat = stat
    del fdopen, stat

The proposed syntax change would add an optional `as` clause to both
these statements, as follows::

    import os as real_os
    from os import fdopen as os_fdopen, exit, stat as os_stat

The `as` name is not intended to be a keyword, and some trickery has to
be used to convince the CPython parser it isn't one. For more advanced
parsers/tokenizers, however, this should not be a problem.

A slightly special case exists for importing sub-modules. The statement
::

    import os.path

stores the module `os` locally as `os`, so that the imported submodule
`path` is accessible as `os.path`. As a result, ::

    import os.path as p

stores `os.path`, not `os`, in `p`. This makes it effectively the same
as ::

    from os import path as p

Implementation details
======================

This PEP has been accepted, and the suggested code change has been
checked in. The patch can still be found in the SourceForge patch
manager \[1\]\_. Currently, a `NAME` field is used in the grammar rather
than a bare string, to avoid the keyword issue. It introduces a new
bytecode, `IMPORT_STAR`, which performs the `from module import *`
behaviour, and changes the behaviour of the `IMPORT_FROM` bytecode so
that it loads the requested name (which is always a single name) onto
the stack, to be subsequently stored by a `STORE` opcode. As a result,
all names explicitly imported now follow the `global` directives.

The special case of `from module import *` remains a special case, in
that it cannot accommodate an `as` clause, and that no `STORE` opcodes
are generated; the objects imported are loaded directly into the local
namespace. This also means that names imported in this fashion are
always local, and do not follow the `global` directive.

An additional change to this syntax has also been suggested, to
generalize the expression given after the `as` clause. Rather than a
single name, it could be allowed to be any expression that yields a
valid l-value; anything that can be assigned to. The change to
accommodate this is minimal, as the patch \[2\]\_ proves, and the
resulting generalization allows a number of new constructs that run
completely parallel with other Python assignment constructs. However,
this idea has been rejected by Guido, as "hypergeneralization".

Copyright
=========

This document has been placed in the Public Domain.

References
==========

.. \[1\] https://hg.python.org/cpython/rev/18385172fac0

.. \[2\]
http://sourceforge.net/patch/?func=detailpatch&patch\_id=101234&group\_id=5470

.. Local Variables: mode: indented-text indent-tabs-mode: nil End:
