First, about the exception, I think your IDE doesn't respect the python specs :
A scope defines the visibility of a name within a block. If a local variable is defined in a block, its scope includes that block.
[...]
If a name is bound in a block, it is a local variable of that block.
If a name is bound at the module level, it is a global variable. (The
variables of the module code block are local and global.) If a
variable is used in a code block but not defined there, it is a free
variable.
[...]
When a name is not found at all, a NameError exception is raised. If
the name refers to a local variable that has not been bound, a
UnboundLocalError exception is raised. UnboundLocalError is a subclass
of NameError.
https://docs.python.org/2.7/reference/executionmodel.html#naming-and-binding
Thus, I understand the whole block is parsed, it finds your variable, and it is added to the local scope, but before its assignment, it's considered as a free variable
EDIT
About inspect
, I think it lists the bound variables in the local namespace, thus, you don't see your variable. it's pretty logical : what value would you give to the key 'MyClass' if it is not bound yet ?
Actually, you should use the inspect.currentframe().f_code.co_varnames
to get what you want ;)
import inspect
from pprint import pprint
class MyClass(object):
def __init__(self):
print("MyClass init() method called successfully")
def newscope():
pprint(inspect.currentframe().f_code.co_varnames)
print("----------")
pprint(inspect.currentframe().f_locals)
print("----------")
pprint(inspect.currentframe().f_globals)
print("----------")
try:
pprint(MyClass)
except Exception as e:
print(e)
MyClass = 5
pprint(inspect.currentframe().f_locals)
print("----------")
pprint(inspect.currentframe().f_globals)
print("----------")
if __name__ == '__main__':
newscope()
and you get :
('MyClass', 'e')
----------
{}
----------
{'MyClass': <class '__main__.MyClass'>,
'__builtins__': <module 'builtins' (built-in)>,
'__cached__': None,
'__doc__': None,
'__file__': 'test.py',
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f2fa3901160>,
'__name__': '__main__',
'__package__': None,
'__spec__': None,
'inspect': <module 'inspect' from '/usr/lib/python3.5/inspect.py'>,
'newscope': <function newscope at 0x7f2fa39b8f28>,
'pprint': <function pprint at 0x7f2fa1fe66a8>}
----------
local variable 'MyClass' referenced before assignment
{'MyClass': 5}
----------
{'MyClass': <class '__main__.MyClass'>,
'__builtins__': <module 'builtins' (built-in)>,
'__cached__': None,
'__doc__': None,
'__file__': 'test.py',
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f2fa3901160>,
'__name__': '__main__',
'__package__': None,
'__spec__': None,
'inspect': <module 'inspect' from '/usr/lib/python3.5/inspect.py'>,
'newscope': <function newscope at 0x7f2fa39b8f28>,
'pprint': <function pprint at 0x7f2fa1fe66a8>}
----------
Remove your variable
import inspect
from pprint import pprint
class MyClass(object):
def __init__(self):
print("MyClass init() method called successfully")
def newscope():
pprint(inspect.currentframe().f_code.co_varnames)
print("----------")
pprint(inspect.currentframe().f_locals)
print("----------")
pprint(inspect.currentframe().f_globals)
print("----------")
try:
pprint(MyClass)
except Exception as e:
print(e)
# MyClass = 5
pprint(inspect.currentframe().f_locals)
print("----------")
pprint(inspect.currentframe().f_globals)
print("----------")
if __name__ == '__main__':
newscope()
and you get :
('e',)
----------
{}
----------
{'MyClass': <class '__main__.MyClass'>,
'__builtins__': <module 'builtins' (built-in)>,
'__cached__': None,
'__doc__': None,
'__file__': 'test.py',
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fc6d3fcb160>,
'__name__': '__main__',
'__package__': None,
'__spec__': None,
'inspect': <module 'inspect' from '/usr/lib/python3.5/inspect.py'>,
'newscope': <function newscope at 0x7fc6d4082f28>,
'pprint': <function pprint at 0x7fc6d26b06a8>}
----------
<class '__main__.MyClass'>
{}
----------
{'MyClass': <class '__main__.MyClass'>,
'__builtins__': <module 'builtins' (built-in)>,
'__cached__': None,
'__doc__': None,
'__file__': 'test.py',
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fc6d3fcb160>,
'__name__': '__main__',
'__package__': None,
'__spec__': None,
'inspect': <module 'inspect' from '/usr/lib/python3.5/inspect.py'>,
'newscope': <function newscope at 0x7fc6d4082f28>,
'pprint': <function pprint at 0x7fc6d26b06a8>}
----------