[Python-ideas] from __future__ import range

Nick Coghlan ncoghlan at gmail.com
Wed Apr 22 14:14:35 CEST 2009

spir wrote:
> Well, if (as intended) "from __future__ import range" means "use
> future (py3) semantics for 'range'", then the compiler need to know
> it ;-)

Nope, the compiler hasn't got a clue what different functions do - it's
job is done and dusted long before the bytecode is actually executed. So
it doesn't care what the semantics of range actually are - it just cares
that it is the name of something.

The reason "__future__" is special is because the compiler *does* know
about it, so such imports can actually change the behaviour of the
parser and code generator, thus making statements and expressions
actually mean different things.

It does exist as a real module as well, which provides information about
the various features that it can be used to enable:

>>> for name in __future__.all_feature_names:
...   feature = getattr(__future__, name)
...   print("{0:18}{1.optional:22}{1.mandatory}".format(name, feature))
nested_scopes     (2, 1, 0, 'beta', 1)  (2, 2, 0, 'alpha', 0)
generators        (2, 2, 0, 'alpha', 1) (2, 3, 0, 'final', 0)
division          (2, 2, 0, 'alpha', 2) (3, 0, 0, 'alpha', 0)
absolute_import   (2, 5, 0, 'alpha', 1) (2, 7, 0, 'alpha', 0)
with_statement    (2, 5, 0, 'alpha', 1) (2, 6, 0, 'alpha', 0)
print_function    (2, 6, 0, 'alpha', 2) (3, 0, 0, 'alpha', 0)
unicode_literals  (2, 6, 0, 'alpha', 2) (3, 0, 0, 'alpha', 0)
barry_as_FLUFL    (3, 1, 0, 'alpha', 2) (3, 9, 0, 'alpha', 0)

All of those are changes which affect the behaviour of the compiler. The
nested_scopes, division, absolute_import and unicode_literals features
don't add new syntax, but they change the meaning of existing syntax
(i.e. the compiler has to generate different bytecode when they are in

The generators and with_statement features actually added new keywords
for the parser to recognise (yield for generators, with and as for the
with statement).

The print_function features goes the other way: it tells the parser
*not* to treat print as a keyword.

All the details about this mechanism and how it works can be found in
the documentation ([1], [2]) and in the PEP that added it [3].

That's all tangential to the current point though, since the change to
range's semantics *isn't* something the compiler cares about. range() is
still a function in Py3k, it just behaves differently from the way it
behaves in 2.x.

That's where future_builtins comes in: as a location for new builtins
where the Py3k semantics are sufficiently different that they can't
readily be introduced into the 2.x series, but don't involve any changes
to syntax.

Adding the Py3k range type to that module would be a good idea, since it
actually isn't exactly the same as xrange in 2.x. Unlike xrange, Py3k's
range object can handle arbitrary ranges instead of being restricted by
the size of a C integer.

I suggest making this idea (add Py3k range implementation to 2.x
future_builtins) a feature request on the bug tracker. The benefits are
consistency with other builtins that are changing in Py3k and also
providing an arbitrary length range implementation in the 2.x series.


[1] http://docs.python.org/library/__future__
[2] http://docs.python.org/reference/simple_stmts.html#future-statements
[3] http://www.python.org/dev/peps/pep-0236/

Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list