PEP: 264
Title: Future statements in simulated shells
Version: $Revision: 1058 $
Last-Modified: $Date: 2001-10-29 14:36:27 -0800 (Mon, 29 Oct 2001) $
Author: Michael Hudson <mwh at python.net>
Status: Final
Type: Standards Track
Requires: 236
Created: 30-Jul-2001
Python-Version: 2.2
Post-History: 30-Jul-2001

Abstract

    As noted in PEP 236, there is no clear way for "simulated
    interactive shells" to simulate the behaviour of __future__
    statements in "real" interactive shells, i.e. have __future__
    statements' effects last the life of the shell.

    The PEP also takes the opportunity to clean up the other
    unresolved issue mentioned in PEP 236, the inability to stop
    compile() inheriting the effect of future statements affecting the
    code calling compile().

    This PEP proposes to address the first problem by adding an
    optional fourth argument to the builtin function "compile", adding
    information to the _Feature instances defined in __future__.py and
    adding machinery to the standard library modules "codeop" and
    "code" to make the construction of such shells easy.

    The second problem is dealt with by simply adding *another*
    optional argument to compile(), which if non-zero suppresses the
    inheriting of future statements' effects.


Specification

    I propose adding a fourth, optional, "flags" argument to the
    builtin "compile" function.  If this argument is omitted,
    there will be no change in behaviour from that of Python 2.1.

    If it is present it is expected to be an integer, representing
    various possible compile time options as a bitfield.  The
    bitfields will have the same values as the CO_* flags already used
    by the C part of Python interpreter to refer to future statements.

    compile() shall raise a ValueError exception if it does not
    recognize any of the bits set in the supplied flags.

    The flags supplied will be bitwise-"or"ed with the flags that
    would be set anyway, unless the new fifth optional argument is a
    non-zero intger, in which case the flags supplied will be exactly
    the set used.

    The above-mentioned flags are not currently exposed to Python.  I
    propose adding .compiler_flag attributes to the _Feature objects
    in __future__.py that contain the necessary bits, so one might
    write code such as:

        import __future__
        def compile_generator(func_def):
            return compile(func_def, "<input>", "suite",
                           __future__.generators.compiler_flag)

    A recent change means that these same bits can be used to tell if
    a code object was compiled with a given feature; for instance

        codeob.co_flags & __future__.generators.compiler_flag

    will be non-zero if and only if the code object "codeob" was
    compiled in an environment where generators were allowed.

    I will also add a .all_feature_flags attribute to the __future__
    module, giving a low-effort way of enumerating all the __future__
    options supported by the running interpreter.

    I also propose adding a pair of classes to the standard library
    module codeop.

    One - Compile - will sport a __call__ method which will act much
    like the builtin "compile" of 2.1 with the difference that after
    it has compiled a __future__ statement, it "remembers" it and
    compiles all subsequent code with the __future__ option in effect.

    It will do this by using the new features of the __future__ module
    mentioned above.

    Objects of the other class added to codeop - CommandCompiler -
    will do the job of the existing codeop.compile_command function,
    but in a __future__-aware way.

    Finally, I propose to modify the class InteractiveInterpreter in
    the standard library module code to use a CommandCompiler to
    emulate still more closely the behaviour of the default Python
    shell.


Backward Compatibility

    Should be very few or none; the changes to compile will make no
    difference to existing code, nor will adding new functions or
    classes to codeop.  Existing code using
    code.InteractiveInterpreter may change in behaviour, but only for
    the better in that the "real" Python shell will be being better
    impersonated.


Forward Compatibility

    The fiddling that needs to be done to Lib/__future__.py when
    adding a __future_ feature will be a touch more complicated.
    Everything else should just work.


Issues

    I hope the above interface is not too disruptive to implement for
    Jython.


Implementation

    A series of preliminary implementations are at:

        http://sourceforge.net/tracker/?func=detail&atid=305470&aid=449043&group_id=5470

    After light massaging by Tim Peters, they have now been checked in.


Copyright

    This document has been placed in the public domain.