Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NameError vs global NameError

I'm trying to reproduce a bug that I've encountered that shows this:

NameError: global name 'sdrent' is not defined

However, if I open up the interpreter and type in sdrent, I get the following error:

>>> sdrent
NameError: name 'sdrent' is not defined

What is the difference between NameError: global name... and NameError: name..., and how would I reproduce the former?

like image 303
David542 Avatar asked Aug 27 '26 20:08

David542


2 Answers

CPython has two opcodes used for global variable lookups, LOAD_GLOBAL and LOAD_NAME. LOAD_NAME looks for a local variable before a global variable, while LOAD_GLOBAL goes straight to globals. LOAD_NAME is primarily useful for class statements, but in the absence of a global declaration, the compiler also happens to emit LOAD_NAME for global variable lookups at module level.

Back before Python 3.4, LOAD_GLOBAL used to say global name 'whatever' is not defined when the lookup fails, and LOAD_NAME used to say name 'whatever' is not defined. This got changed when someone argued that "global" was confusing for cases where someone mistyped a local variable name.

You're on Python 2.7. When you run a variable lookup for a nonexistent name at top level, you get the LOAD_NAME error message, but inside a function, you get the LOAD_GLOBAL error message, which still says "global" on Python 2.

like image 181
user2357112 supports Monica Avatar answered Aug 29 '26 08:08

user2357112 supports Monica


It seems this happens in the context of a function or method, where the LEGB stops at G(lobal), knowing the builtins already and exits/complains at that scope.

For example, to reproduce:

>>> def hi():
...     sdrent
...
>>> hi()
NameError: global name 'sdrent' is not defined

Or even simpler:

>>> (lambda: sdrent)()
NameError: global name 'sdrent' is not defined

And in a class method:

>>> class X:
        def __call__(_): sdrent
>>> X()()
NameError: global name 'sdrent' is not defined
like image 37
David542 Avatar answered Aug 29 '26 09:08

David542



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!