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_varnames
is a tuple containing the names of the local variables (starting with the argument names); [...]co_names
is 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