Oddity in 2.4 with eval('None')

Raymond Hettinger vze4rx4y at verizon.net
Mon Dec 20 23:13:38 CET 2004

"Leif K-Brooks" <eurleif at ecritters.biz>
> In Python 2.4, although None can't be directly assigned to,
> globals()['None'] can still be; however, that won't change the value of
> the expression "None" in ordinary statements. Except with the eval
> function, it seems:
> Python 2.4 (#2, Dec  3 2004, 17:59:05)
> [GCC 3.3.5 (Debian 1:3.3.5-2)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> print None
> None
>  >>> print eval('None')
> None
>  >>> globals()['None'] = "spam"
>  >>> print None
> None
>  >>> print eval('None')
> spam
> I don't really mind this weird behavior; I'm just curious about it. Does
> anyone know what might be going on in Python's internals to cause the
> difference between "print None" and "print eval('None')"?

It is a nuance of how None is being made constant.

For backwards compatability, None still has to be in the globals dictionary.
Like all entries in the globals dictionary, you can change it if you try hard
enough (which you did).

For Py2.4, whenever bytecode is generated for a code object, references to
"None" in the globals dictionary are bypassed and replaced with a constant
reference to Py_None, the one, true, singleton instance of None.  That will
occur even if you've mucked with None entry in the globals dictionary.

Bytecode for eval() doesn't go through the bytecode optimizer so its dictionary
lookup is retained (producing the effect in your example).

To have made None a literal constant would have been a much more radical step.
Py2.4 simulates this and gives you the real benefit being sought, faster
function execution, without having incurred the costs of having a new literal.

It's possible to fool the simulation, but who cares.

Raymond Hettinger

More information about the Python-list mailing list