The description for co_names in the inspect module reads:
tuple of names of local variables
However in practice it appears that co_names is a tuple of global variable names while co_varnames is a tuple of local variable names (and argument names). For example:
a = 1
def f(b):
c = a + b
print(f.__code__.co_varnames) # prints ('b', 'c')
print(f.__code__.co_names) # prints ('a',)
Furthermore in the docs for the dis module many instruction descriptions imply that co_names contains names of global variables. For example the LOAD_GLOBAL description reads:
Loads the global named co_names[namei] onto the stack.
Am I misunderstanding something here? Does co_names really contain "names of local variables"?
As mentioned in the comments/answers this appears to be a documentation error. Bug issue filed here.
Pull request to fix this documentation error approved and waiting to be merged.
Pull request was merged 09/24/2021.
As other's have already said, this seems to be a documentation error. The documentation for code objects clearly contradicts the documentation for inspect:
co_varnamesis a tuple containing the names of the local variables (starting with the argument names); [...]co_namesis a tuple containing the names used by the bytecode;
Also, accessing the attributes co_names and co_varnames of code objects conflicts with what was stated in inspect:
>>> def f():
... a = 1
... b = 2
...
>>> f.__code__.co_names
()
>>> f.__code__.co_varnames
('a', 'b')
Furthermore, comments in the source code for CPython's compiler explicitly mention that co_varnames is for local variables:
PyObject *u_names; /* all names */
PyObject *u_varnames; /* local variables */
The reason you don't see co_varnames is because the above code is initializing attributes for the compiler object that Python uses to compile code. u_names and u_varnames are both later passed into PyCode_New - the constructor for CPython code objects:
names = dict_keys_inorder(c->u->u_names, 0);
varnames = dict_keys_inorder(c->u->u_varnames, 0);
...
co = PyCode_New(..., names, varnames, ... );
And PyCode_New assigns names and varnames to the co_names and co_varnames attributes respectively:
Py_INCREF(names);
co->co_names = names;
Py_INCREF(varnames);
co->co_varnames = varnames;
If you already have not, I suggest filling out a bug report at bugs.python.org to let the Python development team know about this inconsistency in the documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With