[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
LOAD_GLOBAL 0
POP_TOP
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.