Given a stack frame and a variable name, how do I tell if that variable is nonlocal? Example:
import inspect
def is_nonlocal(frame, varname):
# How do I implement this?
return varname not in frame.f_locals # This does NOT work
def f():
x = 1
def g():
nonlocal x
x += 1
assert is_nonlocal(inspect.currentframe(), 'x')
g()
assert not is_nonlocal(inspect.currentframe(), 'x')
f()
Check the frame's code object's
co_freevars, which is a tuple of the names of closure variables the code object uses:Note that this is specifically closure variables, the kind of variables that the
nonlocalstatement looks for. If you want to include all variables that aren't local, you should check againstco_varnames(local variables not used in inner scopes) andco_cellvars(local variables used in inner scopes):Also, don't mix things up with
co_names, which is currently misdocumented. Theinspectdocs sayco_namesis for local variables, butco_namesis kind of an "everything else" bin. It includes global names, attribute names, and several kinds of names involved in imports - mostly, if execution is expected to actually need the string form of the name, it goes inco_names.