[Tutor] A slight bug in IDLE

eryksun eryksun at gmail.com
Sat Jul 13 09:54:19 CEST 2013


On Sat, Jul 13, 2013 at 2:14 AM, Jim Mooney <cybervigilante at gmail.com> wrote:
>
> If I run IDLE, which I thought was pretty reliable, and do this:
>
> from __future__ import division
>
> Then save the file and run the shell from IDLE, __future__ division fails.
> But if I then import __future__ division from the shell, it works.

A __future__ import modifies compilation of the current module. The
"division" directive tells the compiler to use BINARY_TRUE_DIVIDE
instead of BINARY_DIVIDE. This works by setting a flag in the code
object:

    >>> __future__.CO_FUTURE_DIVISION  # flag
    8192
    >>> __future__.division
    _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)

The flag is inherited in interactive mode, so you only have to set it once:

    >>> sys._getframe().f_code.co_flags & CO_FUTURE_DIVISION
    0
    >>> from __future__ import division
    >>> sys._getframe().f_code.co_flags & CO_FUTURE_DIVISION
    8192

Just having the division feature defined in a namespace doesn't affect
the code flags. The compiler looks explicitly for "from __future__
..." statements at the beginning and only the beginning[1] of the
current compilation unit.

    >>> x = 5; y = 3; from __future__ import division; x / y
      File "<stdin>", line 1
    SyntaxError: from __future__ imports must occur at the beginning
    of the file

[1] An initial string/docstring is allowed, as are multiple __future__ imports.


Given this, can you figure out what's going on with IDLE? After
running the file you see that "division" is defined, but the
CO_FUTURE_DIVISION flag isn't set.


> By the way, why can't I just import __future__ ? That doesn't work. It
> always has to be from __future__

The compiler looks for an "ImportFrom" node in the abstract syntax tree:

    >>> print ast.dump(ast.parse('from __future__ import division').body[0])
    ImportFrom(module='__future__',
               names=[alias(name='division', asname=None)],
               level=0)

It looks specifically for the names as defined in compile.h, so you
can't do a star import either.


More information about the Tutor mailing list