[Python-Dev] Compiler treats None both as a constant and variable

Tim Peters tim_one@email.msn.com
Sat, 29 Mar 2003 21:24:29 -0500

[Raymond Hettinger]
> >>> def f():
>  None
> >>> dis(f)
> 2           0 LOAD_GLOBAL              0 (None)
>               3 POP_TOP
>               4 LOAD_CONST               0 (None)
>               7 RETURN_VALUE
> >>> None = 1
> <stdin>:1: SyntaxWarning: assignment to None
> >>> f() == None
> False
> Is this a bug?

It's arguable, but it's always been this way, and is so boring that nobody
has bothered to argue about it before <wink>.

It's clear that explicit references to names must follow "the usual" name
resolution rules, so you can't gripe about the LOAD_GLOBAL in this function:
None is the name of a builtin, and in the language as currently defined,
builtin names can be shadowed by globals or locals.

What's arguable is the LOAD_CONST, which is generated for the implicit
reference to None.  The meaning of the Ref Man's

    A call always returns some value, possibly None, unless it raises an
    exception.  How this value is computed depends on the type of the
    callable object.

is arguably arguable, but I don't think *reasonably* so.  To me it clearly
intends "the" None, not whatever object you get by evaluating name "None"
inside the callable.  Likewise when it says the default value of
object.__doc__ is None, I think it also clearly means "the" None.

> Should the compiler use the GLOBAL in both places?

For backward compatibility it has to retain the LOAD_CONST.  In this
specific example, it doesn't matter whether the first is LOAD_CONST, or
LOAD_GLOBAL, or simply thrown away, since the


pair has no visible effect.  If it were a more interesting function, like

    def f():
        global aglobal
        aglobal = None

then for backward compatibility it would have to remain LOAD_GLOBAL.

> Or, is it reasonable to use CONST in both places?

Not today, but we should be moving in that direction.  IMO, None should
become a keyword.