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
==========

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

Copyright
=========

This document has been placed in the public domain.

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