`~/.pythonrc' `from __future__ import'

Tim Peters tim.one at comcast.net
Mon Jul 8 14:34:18 EDT 2002


[François Pinard]
>>> How should I proceed to activate this [future division] ]option once
>>> and for all for interactive applications?

[Tim]
>> You can write an alias to start interactive sessions by passing -Qnew to
>> Python.

[François]
> I've heard about this undocumented feature indeed, and hoped to go without
> resorting to it.

All the -Q options are documented in the division PEP:

    http://www.python.org/peps/pep-0238.html

> Moreover, this option only works for division, it does not apparently
> activate generators, for instance.

Yes, -Q is specific to division, as will become clear if you read the PEP
238 "Command Line Option" section.

> I would rather have all future features available all the time when I
> write interactively, yet I guess why some people would prefer not.

There's no way to do that, short of fiddling Python's source code.

> ...
> However, it wonder if this is all fully right.  The actual documentation
> and the PEP say that one could `import __future__' explicitly, so to
> check at run time what features are currently available in the running
> Python.

You could, although I advise against it (see below).  For example,

"""
import sys

try:
    import __future__
    div = __future__.division

except ImportError:
    print "This version of Python predates __future__ statements."

except AttributeError:
    print "This version of Python never heard of future-division."

else:
    opt = div.getOptionalRelease()
    mand = div.getMandatoryRelease()
    if mand is None:
        print "It was decided to drop future division."
    elif sys.version_info >= mand:
        print "future-division is enabled by default."
    elif sys.version_info >= opt:
        print "future-division is available if you explicitly ask for it."
    else:
        print "future-division isn't yet available."
"""

prints the truth about future-division under any version of Python that ever
was or ever will be <wink> released.

> Besides its compile-time effect, `from __future__ import division' (say)
> dynamically defines `division' at run-time in the global space, at least
> when done from the startup file,

Yes, its runtime effect is the same as

    from math import cos
or
    from difflib import SequenceMatcher

or any other "from ... import ..." statement.

> but this is no strong clue about if the feature has been activated or
> not (at least when the Python version lies between the introduction
> version and, excluded, the mandatory version).

That "from __future__ import division" doesn't raise an exception means
you're in one of the four states covered by the "else:" clause above.  The
code there shows how to distinguish among those, but again I don't recommend
trying to do so.  The possibility for this kind of introspection is for
heavy-duty site-management tools (should anyone wish to implement such
things).

> Would it mean that one has no other choice than "benchmark" the feature at
> run-time, the ugly way, to know whether it is active or not?  The current
> intent is to let an `from __future__ import FEATURE' generate an error if
> the FEATURE is wanted in a module, but not available in the current
> Python.
>
> Suppose, for example, that I write a module in which some function makes
> good use of some future feature (it could be the `yield, statement),
> but I want to provide an alternate implementation of that function which
> is less interesting (because it gets much complex and slower) in case the
> feature is not available.  Since I cannot except out of the `from
> __future__
> import' statement, for reasons I understand, I do not see how I take good
> advantage of available future features, in a program meant to be portable
> between versions.  Maybe the future statement is rougher than I expected?

It's less ambitious than you may want it to be.  It was emphatically not the
intent of future-statements to create multiple "pick and choose" dialects of
Python.  Its only design goal was to provide a transition period between
flat-out incompatible semantics, where during the transition period you:

1. Continue to get the old semantics, but also get warnings about
   code that's going to break when the semantics change.

and

2. You can explicitly request the new semantics on a module-by-module
   basis, to aid in reworking legacy code incrementally.

#2 is intended for people who want an easy way to turn new semantics on and
off while redoing their code, a bit at a time, to work either way --
provided they care about that.

For everyone else, a future-feature is a planned experimental feature that
may even get dropped (hence the possibility for .getMandatoryRelease() to
return None).  Portable distributed code should never contain a future
statement!  It wasn't designed for that, and, as you've discovered, trying
to use it for that sucks.  It's not for portability:  it's a temporary aid
to ease the transition between incompatible semantics.

Note that, e.g., the only reason generators got put under the __future__
machinery is that they make "yield" a new keyword.  That's "flat-out
incompatible semantics", and the only purpose of the future machinery here
is to give people a release cycle in which to rename their existing "yield"
identifiers (provided they have any -- I haven't yet found any code that
does, although I'm sure some exists somewhere).

the-point-of-__future__-is-mostly-to-ease-living-in-the-past-ly y'rs  - tim







More information about the Python-list mailing list