PEP: 264 Title: Future statements in simulated shells Version:
$Revision$ Last-Modified: $Date$ Author: Michael Hudson <mwh@python.net>
Status: Final Type: Standards Track Content-Type: text/x-rst 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
integer, 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[1].

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

References

Copyright

This document has been placed in the public domain.

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