Что такое co_names?

описание для co_names в модуле проверки читает:

кортеж имен локальных переменных

Однако на практике кажется, что co_names является кортежем имен глобальных переменных, а co_varnames является кортежем имен локальных переменных (и имен аргументов). Например:

a = 1

def f(b):
    c = a + b

print(f.__code__.co_varnames)  # prints ('b', 'c')
print(f.__code__.co_names)     # prints ('a',)

Кроме того, в документах для модуля dis многие описания команд подразумевают, что co_names содержит имена глобальных переменных. Например, LOAD_GLOBAL description читает:

Загружает глобальные имена co_names [namei] в стек.

Я что-то не понимаю? Действительно ли co_names содержит "имена локальных переменных"?

Редактировать 07/17/2017

Как уже упоминалось в комментариях/ответах, это ошибка документации. Ошибка в файле здесь.

Редактировать 07/22/2017

Извлечь запрос, чтобы исправить эту ошибку документации, одобренную и ожидающую объединения.

Ответы

Ответ 1

Как уже говорилось, это выглядит как ошибка документации. Документация для объектов кода явно противоречит документации для inspect:

co_varnames кортеж, содержащий имена локальных переменных (начиная с имен аргументов); [...] co_names представляет собой кортеж , содержащий имена, используемые байт-кодом;

Кроме того, доступ к атрибутам co_names и co_varnames объектов кода противоречит тому, что было указано в inspect:

>>> def f():
...     a = 1
...     b = 2
... 
>>> f.__code__.co_names
()
>>> f.__code__.co_varnames
('a', 'b')

Кроме того, комментарии в исходном коде компилятор CPython явно указывают, что co_varnames для локальных переменных:

PyObject *u_names;     /* all names */
PyObject *u_varnames; /* local variables */

Причина, по которой вы не видите co_varnames, состоит в том, что вышеупомянутый код инициализирует атрибуты для объекта компилятора, который использует Python для компиляции кода. u_names и u_varnames обе позже передаются в PyCode_New - конструктор для объектов кода CPython:

names = dict_keys_inorder(c->u->u_names, 0);
varnames = dict_keys_inorder(c->u->u_varnames, 0);

...

co = PyCode_New(..., names, varnames, ... );

И PyCode_New присваивает names и varnames атрибутам co_names и co_varnames соответственно:

Py_INCREF(names);
co->co_names = names;
Py_INCREF(varnames);
co->co_varnames = varnames;

Если вы уже этого не сделали, я предлагаю заполнить отчет об ошибке в bugs.python.org, чтобы команда разработчиков Python знала об этой несогласованности в документация.