Документация Python неофициальный перевод
Содержание страницы

dis – Дизассемблер байт-кода Pythondis – Disassembler for Python bytecode

Исходный код: Lib/dis.py


Модуль dis поддерживает анализ байт-кода CPython путём eго дизассемблирования. Байт-код CPython, который этот модуль принимает на вход, определён в файле Include/opcode.h и используется компилятором и интерпретатором.

Особенность реализации CPython: Байт-код является деталью реализации интерпретатора CPython. Нет никаких гарантий, что байт-код не будет добавлен, удалён или изменён в разных версиях Python. Не следует рассчитывать, что использование этого модуля будет работать в разных виртуальных машинах Python или в разных релизах Python.

Изменено в версии 3.6: Для каждой инструкции используется 2 байта. Ранее количество байт зависело от инструкции.

Изменено в версии 3.10: Аргументом инструкций перехода, обработки исключений и циклов теперь является смещение инструкции, а не смещение байта.

Изменено в версии 3.11: Некоторые инструкции сопровождаются одной или несколькими записями встроенного кэша, которые имеют форму инструкций CACHE. Эти инструкции по умолчанию скрыты, но их можно показать, передав show_caches=True любой dis утилите. Кроме того, интерпретатор теперь адаптирует байт-код для специализации под разные условия выполнения. Адаптивный байт-код можно показать, передав adaptive=True.

Изменено в версии 3.12: Аргумент перехода – это смещение целевой инструкции относительно инструкции, следующей сразу за записями CACHE инструкции перехода.

Как следствие, наличие инструкций CACHE прозрачно для прямых переходов, но должно учитываться при анализе обратных переходов.

Пример: Дана функция myfunc():

def myfunc(alist):
    return len(alist)

следующую команду можно использовать для отображения дизассемблирования myfunc():

>>> dis.dis(myfunc)
  2           0 RESUME                   0

  3           2 LOAD_GLOBAL              1 (NULL + len)
             12 LOAD_FAST                0 (alist)
             14 CALL                     1
             22 RETURN_VALUE

(«2» – это номер строки).

Интерфейс командной строкиCommand-line interface

Модуль dis можно вызвать как сценарий из командной строки:

python -m dis [-h] [infile]

Принимаются следующие опции:

-h, --help

Показать справку и выйти.

Если указан infile, его дизассемблированный код выводится в stdout. В противном случае дизассемблирование выполняется для скомпилированного исходного кода, полученного из stdin.

Анализ байт-кодаBytecode analysis

Добавлено в версии 3.4.

API анализа байт-кода позволяет оборачивать фрагменты кода Python в объект Bytecode, который предоставляет удобный доступ к деталям скомпилированного кода.

class dis.Bytecode(x, *, first_line=None, current_offset=None, show_caches=False, adaptive=False)

Анализирует байткод, соответствующий функции, генератору, асинхронному генератору, корутине, методу, строке исходного кода или объекту кода (как возвращается compile()).

Это удобная обёртка над многими функциями, перечисленными ниже, особенно get_instructions(), поскольку итерация по экземпляру Bytecode возвращает операции байткода в виде экземпляров Instruction.

Если first_line не равен None, он указывает номер строки, который должен быть указан для первой строки исходного кода в дизассемблированном коде. В противном случае информация о строке исходного кода (если есть) берётся непосредственно из дизассемблированного объекта кода.

Если current_offset не равно None, оно указывает смещение инструкции в дизассемблированном коде. Установка этого значения означает, что dis() будет отображать маркер «текущая инструкция» напротив указанной операции.

Если show_caches равно True, dis() будет отображать записи inline-кэша, используемые интерпретатором для специализации байткода.

Если adaptive равно True, dis() будет отображать специализированный байткод, который может отличаться от исходного.

classmethod from_traceback(tb, *, show_caches=False)

Создаёт экземпляр Bytecode из заданного traceback, устанавливая current_offset на инструкцию, ответственную за исключение.

codeobj

Скомпилированный объект кода.

first_line

Первая строка исходного кода объекта кода (если доступна)

dis()

Возвращает форматированное представление операций байткода (то же, что выводится dis.dis(), но возвращается в виде многострочной строки).

info()

Возвращает форматированную многострочную строку с подробной информацией об объекте кода, как code_info().

Изменено в версии 3.7: Теперь может обрабатывать объекты корутин и асинхронных генераторов.

Изменено в версии 3.11: Добавлены параметры show_caches и adaptive.

Пример:

>>> bytecode = dis.Bytecode(myfunc)
>>> for instr in bytecode:
...     print(instr.opname)
...
RESUME
LOAD_GLOBAL
LOAD_FAST
CALL
RETURN_VALUE

Функции анализаAnalysis functions

Модуль dis также определяет следующие функции анализа, которые преобразуют входные данные непосредственно в желаемый вывод. Они могут быть полезны, если выполняется только одна операция, и промежуточный объект анализа не нужен:

dis.code_info(x)

Возвращает форматированную многострочную строку с подробной информацией об объекте кода для указанной функции, генератора, асинхронного генератора, корутины, метода, строки исходного кода или объекта кода.

Обратите внимание, что точное содержимое строк с информацией о коде сильно зависит от реализации и может произвольно меняться в разных реализациях Python или версиях Python.

Добавлено в версии 3.2.

Изменено в версии 3.7: Теперь может обрабатывать объекты корутин и асинхронных генераторов.

dis.show_code(x, *, file=None)

Выводит подробную информацию об объекте кода для указанной функции, метода, строки исходного кода или объекта кода в file (или sys.stdout, если file не указан).

Это удобная краткая форма для print(code_info(x), file=file), предназначенная для интерактивного исследования в приглашении интерпретатора.

Добавлено в версии 3.2.

Изменено в версии 3.4: Добавлен параметр file.

dis.dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False)

Дисассемблирует объект x. x может обозначать модуль, класс, метод, функцию, генератор, асинхронный генератор, корутину, объект кода, строку исходного кода или последовательность байтов сырого байткода. Для модуля дисассемблируются все функции. Для класса дисассемблируются все методы (включая методы класса и статические). Для объекта кода или последовательности сырого байткода выводится одна строка на каждую инструкцию байткода. Также рекурсивно дисассемблируются вложенные объекты кода. К ним могут относиться генераторные выражения, вложенные функции, тела вложенных классов и объекты кода, используемые для областей аннотаций. Строки сначала компилируются в объекты кода с помощью встроенной функции compile() перед дисассемблированием. Если объект не указан, эта функция дисассемблирует последний traceback.

Результат дисассемблирования выводится в виде текста в указанный аргумент file, если он передан, иначе – в sys.stdout.

Максимальная глубина рекурсии ограничивается параметром depth, если только он не равен None. depth=0 означает отсутствие рекурсии.

Если show_caches равен True, функция будет показывать записи инлайн-кэша, которые интерпретатор использует для специализации байткода.

Если adaptive равен True, функция будет показывать специализированный байткод, который может отличаться от исходного.

Изменено в версии 3.4: Добавлен параметр file.

Изменено в версии 3.7: Реализовано рекурсивное дисассемблирование и добавлен параметр depth.

Изменено в версии 3.7: Теперь может обрабатывать объекты корутин и асинхронных генераторов.

Изменено в версии 3.11: Добавлены параметры show_caches и adaptive.

dis.distb(tb=None, *, file=None, show_caches=False, adaptive=False)

Дисассемблирует функцию, находящуюся на вершине стека traceback; если traceback не передан, используется последний. Указывается инструкция, вызвавшая исключение.

Результат дисассемблирования выводится в виде текста в указанный аргумент file, если он передан, иначе – в sys.stdout.

Изменено в версии 3.4: Добавлен параметр file.

Изменено в версии 3.11: Добавлены параметры show_caches и adaptive.

dis.disassemble(code, lasti=-1, *, file=None, show_caches=False, adaptive=False)
dis.disco(code, lasti=-1, *, file=None, show_caches=False, adaptive=False)

Дисассемблирует объект кода, указывая последнюю инструкцию, если передан lasti. Результат разбит на следующие столбцы:

  1. номер строки для первой инструкции каждой строки

  2. текущая инструкция, помечена как -->,

  3. инструкция с меткой, помечена >>,

  4. адрес инструкции,

  5. название кода операции,

  6. параметры операции и

  7. интерпретация параметров в скобках.

Интерпретация параметров распознаёт имена локальных и глобальных переменных, константные значения, цели переходов и операторы сравнения.

Результат дисассемблирования выводится в виде текста в указанный аргумент file, если он передан, иначе – в sys.stdout.

Изменено в версии 3.4: Добавлен параметр file.

Изменено в версии 3.11: Добавлены параметры show_caches и adaptive.

dis.get_instructions(x, *, first_line=None, show_caches=False, adaptive=False)

Возвращает итератор по инструкциям в переданной функции, методе, строке исходного кода или объекте кода.

Итератор генерирует последовательность именованных кортежей Instruction, содержащих сведения о каждой операции в переданном коде.

Если first_line не равен None, он указывает номер строки, который должен быть указан для первой строки исходного кода в дизассемблированном коде. В противном случае информация о строке исходного кода (если есть) берётся непосредственно из дизассемблированного объекта кода.

Параметры show_caches и adaptive работают так же, как и в dis().

Добавлено в версии 3.4.

Изменено в версии 3.11: Добавлены параметры show_caches и adaptive.

dis.findlinestarts(code)

Эта функция-генератор использует метод co_lines() объекта кода code для поиска смещений, которые являются началами строк в исходном коде. Они генерируются в виде пар (offset, lineno).

Изменено в версии 3.6: Номера строк могут уменьшаться. Раньше они всегда увеличивались.

Изменено в версии 3.10: Метод PEP 626 co_lines() используется вместо атрибутов co_firstlineno и co_lnotab объекта кода.

dis.findlabels(code)

Обнаруживает все смещения в сырой скомпилированной строке байткода code, которые являются целями переходов, и возвращает список этих смещений.

dis.stack_effect(opcode, oparg=None, *, jump=None)

Вычисляет эффект стека для opcode с аргументом oparg.

Если код имеет цель перехода и jump равен True, stack_effect() возвращает эффект стека при переходе. Если jump равен False, возвращается эффект стека при отсутствии перехода. А если jump равен None (по умолчанию), возвращается максимальный эффект стека для обоих случаев.

Добавлено в версии 3.4.

Изменено в версии 3.8: Добавлен параметр jump.

Инструкции байткода PythonPython Bytecode Instructions

Функция get_instructions() и класс Bytecode предоставляют сведения об инструкциях байткода в виде экземпляров Instruction:

class dis.Instruction

Подробности об операции байткода

opcode

Числовой код операции, соответствующий значениям опкодов, перечисленным ниже, и значениям байткода в коллекциях Opcode.

opname

Человекочитаемое имя операции

arg

числовой аргумент операции (если есть), иначе None

argval

разрешённое значение аргумента (если есть), иначе None

argrepr

человекочитаемое описание аргумента операции (если есть), иначе пустая строка.

offset

начальный индекс операции в последовательности байт-кода

starts_line

Строка, с которой начинается данный опкод (если есть), иначе None.

is_jump_target

True, если другой код переходит сюда, иначе False

positions

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

Добавлено в версии 3.4.

Изменено в версии 3.11: Добавлено поле positions.

class dis.Positions

Если информация недоступна, некоторые поля могут быть None.

lineno
end_lineno
col_offset
end_col_offset

Добавлено в версии 3.12.

В настоящее время компилятор Python генерирует следующие инструкции байткода.

Общие инструкции

В дальнейшем мы будем называть стек интерпретатора STACK и описывать операции с ним так, как если бы это был список Python. Вершина стека соответствует STACK[-1] в этом языке.

NOP

Код, который ничего не делает. Используется оптимизатором байткода как заполнитель, а также для генерации событий трассировки строк.

POP_TOP

Удаляет элемент с вершины стека:

STACK.pop()
END_FOR

Удаляет два верхних значения из стека. Эквивалентно POP_TOP; POP_TOP. Используется для очистки в конце циклов, отсюда название.

Добавлено в версии 3.12.

END_SEND

Реализует del STACK[-2]. Используется для очистки при завершении генератора.

Добавлено в версии 3.12.

COPY(i)

Помещает i-й элемент на вершину стека, не удаляя его из исходной позиции:

assert i > 0
STACK.append(STACK[-i])

Добавлено в версии 3.12.

SWAP(i)

Меняет местами вершину стека и i-й элемент:

STACK[-i], STACK[-1] = STACK[-1], STACK[-i]

Добавлено в версии 3.12.

CACHE

Вместо того чтобы быть реальной инструкцией, этот опкод используется для разметки дополнительного пространства, чтобы интерпретатор мог кэшировать полезные данные непосредственно в байткоде. Он автоматически скрывается всеми утилитами dis, но может быть просмотрен с помощью show_caches=True.

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

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

Добавлено в версии 3.12.

Унарные операции

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

UNARY_NEGATIVE

Реализует STACK[-1] = -STACK[-1].

UNARY_NOT

Реализует STACK[-1] = not STACK[-1].

UNARY_INVERT

Реализует STACK[-1] = ~STACK[-1].

GET_ITER

Реализует STACK[-1] = iter(STACK[-1]).

GET_YIELD_FROM_ITER

Если STACK[-1] является объектом генераторный итератор или корутина, он остаётся без изменений. В противном случае реализует STACK[-1] = iter(STACK[-1]).

Добавлено в версии 3.5.

Бинарные операции и операции на месте

Бинарные операции удаляют два верхних элемента из стека (STACK[-1] и STACK[-2]). Затем они выполняют операцию и помещают результат обратно в стек.

Операции на месте похожи на бинарные, но выполняются непосредственно в памяти (на месте), когда STACK[-2] это поддерживает, и результирующий STACK[-1] может (но не обязан) быть исходным STACK[-2].

BINARY_OP(op)

Реализует бинарные операторы и операторы на месте (в зависимости от значения op):

rhs = STACK.pop()
lhs = STACK.pop()
STACK.append(lhs op rhs)

Добавлено в версии 3.12.

BINARY_SUBSCR

Реализует:

key = STACK.pop()
container = STACK.pop()
STACK.append(container[key])
STORE_SUBSCR

Реализует:

key = STACK.pop()
container = STACK.pop()
value = STACK.pop()
container[key] = value
DELETE_SUBSCR

Реализует:

key = STACK.pop()
container = STACK.pop()
del container[key]
BINARY_SLICE

Реализует:

end = STACK.pop()
start = STACK.pop()
container = STACK.pop()
STACK.append(container[start:end])

Добавлено в версии 3.12.

STORE_SLICE

Реализует:

end = STACK.pop()
start = STACK.pop()
container = STACK.pop()
values = STACK.pop()
container[start:end] = value

Добавлено в версии 3.12.

Коды операций корутин

GET_AWAITABLE(where)

Реализует STACK[-1] = get_awaitable(STACK[-1]), где get_awaitable(o) возвращает o, если o является объектом корутины или объектом-генератором с флагом CO_ITERABLE_COROUTINE, или разрешает o.__await__.

Если операнд where не равен нулю, он указывает, где находится инструкция :

  • 1: После вызова __aenter__

  • 2: После вызова __aexit__

Добавлено в версии 3.5.

Изменено в версии 3.11: Ранее эта инструкция не имела oparg.

GET_AITER

Реализует STACK[-1] = STACK[-1].__aiter__().

Добавлено в версии 3.5.

Изменено в версии 3.7: Возврат ожидаемых объектов из __aiter__ больше не поддерживается.

GET_ANEXT

Реализует STACK.append(get_awaitable(STACK[-1].__anext__())) в стеке. См. GET_AWAITABLE для подробностей о get_awaitable.

Добавлено в версии 3.5.

END_ASYNC_FOR

Завершает цикл async for. Обрабатывает исключение, возбуждённое при ожидании следующего элемента. Стек содержит асинхронный итерируемый объект в STACK[-2] и возбуждённое исключение в STACK[-1]. Оба извлекаются. Если исключение не является StopAsyncIteration, оно возбуждается повторно.

Добавлено в версии 3.8.

Изменено в версии 3.11: Представление исключения в стеке теперь состоит из одного элемента, а не из трёх.

CLEANUP_THROW

Обрабатывает исключение, возбуждённое во время вызова throw() или close() через текущий фрейм. Если STACK[-1] является экземпляром StopIteration, извлекаются три значения из стека и помещается его член value. В противном случае STACK[-1] пробрасывается повторно.

Добавлено в версии 3.12.

BEFORE_ASYNC_WITH

Извлекает __aenter__ и __aexit__ из STACK[-1]. Помещает __aexit__ и результат __aenter__() в стек:

STACK.extend((__aexit__, __aenter__())

Добавлено в версии 3.5.

Прочие опкоды

SET_ADD(i)

Реализует:

item = STACK.pop()
set.add(STACK[-i], item)

Используется для реализации включений множеств.

LIST_APPEND(i)

Реализует:

item = STACK.pop()
list.append(STACK[-i], item)

Используется для реализации включений списков.

MAP_ADD(i)

Реализует:

value = STACK.pop()
key = STACK.pop()
dict.__setitem__(STACK[-i], key, value)

Используется для реализации включений словарей.

Добавлено в версии 3.1.

Изменено в версии 3.8: Значение карты – STACK[-1], а ключ карты – STACK[-2]. Ранее они были переставлены местами.

Для всех инструкций SET_ADD, LIST_APPEND и MAP_ADD, когда добавленное значение или пара ключ/значение извлекаются, объект-контейнер остаётся в стеке, чтобы быть доступным для последующих итераций цикла.

RETURN_VALUE

Возвращает STACK[-1] вызывающей стороне функции.

RETURN_CONST(consti)

Возвращает co_consts[consti] вызывающей стороне функции.

Добавлено в версии 3.12.

YIELD_VALUE

Производит STACK.pop() из генератора.

Изменено в версии 3.11: oparg теперь равен глубине стека.

Изменено в версии 3.12: oparg теперь равен глубине блока исключений для эффективного закрытия генераторов.

SETUP_ANNOTATIONS

Проверяет, определён ли __annotations__ в locals(); если нет, он устанавливается в пустой dict. Этот опкод генерируется, только если тело класса или модуля статически содержит аннотации переменных.

Добавлено в версии 3.6.

POP_EXCEPT

Извлекает значение из стека, которое используется для восстановления состояния исключения.

Изменено в версии 3.11: Представление исключения в стеке теперь состоит из одного элемента, а не из трёх.

RERAISE

Повторно возбуждает исключение, находящееся на вершине стека. Если oparg не равен нулю, извлекает из стека дополнительное значение, которое используется для установки f_lasti текущего фрейма.

Добавлено в версии 3.9.

Изменено в версии 3.11: Представление исключения в стеке теперь состоит из одного элемента, а не из трёх.

PUSH_EXC_INFO

Извлекает значение из стека. Помещает текущее исключение на вершину стека. Возвращает обратно в стек то значение, которое было извлечено. Используется в обработчиках исключений.

Добавлено в версии 3.12.

CHECK_EXC_MATCH

Выполняет сопоставление исключений для except. Проверяет, является ли STACK[-2] исключением, соответствующим STACK[-1]. Извлекает STACK[-1] и помещает в стек логический результат проверки.

Добавлено в версии 3.12.

CHECK_EG_MATCH

Выполняет сопоставление исключений для except*. Применяет split(STACK[-1]) к gруппе исключений, представляющей STACK[-2].

В случае совпадения извлекает из стека два элемента и помещает несовпадающую подгруппу (None при полном совпадении), а затем совпадающую подгруппу. При отсутствии совпадения извлекает один элемент (тип сопоставления) и помещает None.

Добавлено в версии 3.12.

WITH_EXCEPT_START

Вызывает функцию, находящуюся на позиции 4 в стеке, с аргументами (type, val, tb), представляющими исключение на вершине стека. Используется для реализации вызова context_manager.__exit__(*exc_info()), когда исключение возникло в операторе with.

Добавлено в версии 3.9.

Изменено в версии 3.11: Функция __exit__ теперь находится на позиции 4 в стеке, а не на 7. Представление исключения в стеке теперь состоит из одного элемента, а не из трёх.

LOAD_ASSERTION_ERROR

Помещает AssertionError в стек. Используется оператором assert.

Добавлено в версии 3.9.

LOAD_BUILD_CLASS

Помещает builtins.__build_class__() в стек. Затем она вызывается для создания класса.

BEFORE_WITH

Этот опкод выполняет несколько операций перед началом блока with. Сначала, он загружает __exit__() из контекстного менеджера и помещает его в стек для последующего использования WITH_EXCEPT_START. Затем, вызывается __enter__(). Наконец, результат вызова метода __enter__() помещается в стек.

Добавлено в версии 3.12.

GET_LEN

Выполняет STACK.append(len(STACK[-1])). Используется в операторах match, где требуется сравнение со структурой шаблона.

Добавлено в версии 3.10.

MATCH_MAPPING

Если STACK[-1] является экземпляром collections.abc.Mapping (или, более технически: если у него установлен флаг Py_TPFLAGS_MAPPING в его tp_flags), поместить True в стек. В противном случае поместить False.

Добавлено в версии 3.10.

MATCH_SEQUENCE

Если STACK[-1] является экземпляром collections.abc.Sequence и не является экземпляром str/bytes/bytearray (или, более технически: если у него установлен флаг Py_TPFLAGS_SEQUENCE в его tp_flags), поместить True в стек. В противном случае поместить False.

Добавлено в версии 3.10.

MATCH_KEYS

STACK[-1] – кортеж ключей отображения, а STACK[-2] – объект сопоставления. Если STACK[-2] содержит все ключи из STACK[-1], поместить tuple, содержащий соответствующие значения. В противном случае поместить None.

Добавлено в версии 3.10.

Изменено в версии 3.11: Ранее эта инструкция также помещала в стек логическое значение, указывающее на успех (True) или неудачу (False).

STORE_NAME(namei)

Реализует name = STACK.pop(). namei – это индекс имени в атрибуте co_names объекта кода. Компилятор старается использовать STORE_FAST или STORE_GLOBAL, если это возможно.

DELETE_NAME(namei)

Реализует del name, где namei – это индекс в co_names атрибуте объекта кода.

UNPACK_SEQUENCE(count)

Распаковывает STACK[-1] в count отдельных значений, которые помещаются в стек справа налево. Требуется, чтобы было ровно count значений.

assert(len(STACK[-1]) == count)
STACK.extend(STACK.pop()[:-count-1:-1])
UNPACK_EX(counts)

Реализует присваивание с целевым именем со звёздочкой: распаковывает итерируемый объект из STACK[-1] в отдельные значения, при этом общее количество значений может быть меньше, чем количество элементов в итерируемом объекте: одно из новых значений будет списком всех оставшихся элементов.

Количество значений до и после спискового значения ограничено 255.

Количество значений до спискового значения кодируется в аргументе опкода. Количество значений после списка, если таковые имеются, кодируется с помощью EXTENDED_ARG. Следовательно, аргумент можно рассматривать как двухбайтовое значение, где младший байт counts – это количество значений до спискового значения, а старший байт counts – количество значений после него.

Извлечённые значения помещаются в стек справа налево, т.е. a, *b, c = d после выполнения будет храниться как STACK.extend((a, b, c)).

STORE_ATTR(namei)

Реализует:

obj = STACK.pop()
value = STACK.pop()
obj.name = value

где namei – это индекс имени в co_names объекта кода.

DELETE_ATTR(namei)

Реализует:

obj = STACK.pop()
del obj.name

где namei – это индекс имени в co_names объекта кода.

STORE_GLOBAL(namei)

Работает как STORE_NAME, но сохраняет имя как глобальное.

DELETE_GLOBAL(namei)

Работает как DELETE_NAME, но удаляет глобальное имя.

LOAD_CONST(consti)

Помещает co_consts[consti] в стек.

LOAD_NAME(namei)

Помещает значение, связанное с co_names[namei], в стек. Имя ищется в locals, затем в globals, затем в builtins.

LOAD_LOCALS

Помещает ссылку на словарь locals в стек. Это используется для подготовки словарей пространств имён для LOAD_FROM_DICT_OR_DEREF и LOAD_FROM_DICT_OR_GLOBALS.

Добавлено в версии 3.12.

LOAD_FROM_DICT_OR_GLOBALS(i)

Извлекает отображение из стека и ищет значение для co_names[namei]. Если имя не найдено там, ищет его в globals, затем в builtins, аналогично LOAD_GLOBAL. Это используется для загрузки глобальных переменных в областях видимости аннотаций внутри тел классов.

Добавлено в версии 3.12.

BUILD_TUPLE(count)

Создаёт кортеж, потребляя count элементов из стека, и помещает полученный кортеж в стек:

if count == 0:
    value = ()
else:
    value = tuple(STACK[-count:])
    STACK = STACK[:-count]

STACK.append(value)
BUILD_LIST(count)

Работает как BUILD_TUPLE, но создаёт список.

BUILD_SET(count)

Работает как BUILD_TUPLE, но создаёт множество.

BUILD_MAP(count)

Помещает новый объект словаря в стек. Извлекает 2 * count элементов так, чтобы словарь содержал count записей: {..., STACK[-4]: STACK[-3], STACK[-2]: STACK[-1]}.

Изменено в версии 3.5: Словарь создаётся из элементов стека, а не создаётся пустой словарь, предварительно размещённый для count элементов.

BUILD_CONST_KEY_MAP(count)

Версия BUILD_MAP, оптимизированная для константных ключей. Снимает верхний элемент стека, содержащий кортеж ключей, затем, начиная с STACK[-2], снимает count значений и формирует словарь.

Добавлено в версии 3.6.

BUILD_STRING(count)

Конкатенирует count строк из стека и помещает результирующую строку в стек.

Добавлено в версии 3.6.

LIST_EXTEND(i)

Реализует:

seq = STACK.pop()
list.extend(STACK[-i], seq)

Используется для построения списков.

Добавлено в версии 3.9.

SET_UPDATE(i)

Реализует:

seq = STACK.pop()
set.update(STACK[-i], seq)

Используется для построения множеств.

Добавлено в версии 3.9.

DICT_UPDATE(i)

Реализует:

map = STACK.pop()
dict.update(STACK[-i], map)

Используется для построения словарей.

Добавлено в версии 3.9.

DICT_MERGE(i)

Как DICT_UPDATE, но вызывает исключение для повторяющихся ключей.

Добавлено в версии 3.9.

LOAD_ATTR(namei)

Если младший бит namei не установлен, это заменяет STACK[-1] на getattr(STACK[-1], co_names[namei>>1]).

Если установлен младший бит namei, опкод пытается загрузить метод с именем co_names[namei>>1] из объекта STACK[-1]. STACK[-1] извлекается из стека. Этот байткод различает два случая: если STACK[-1] имеет метод с правильным именем, байткод помещает в стек непривязанный метод и STACK[-1]. STACK[-1] будет использоваться как первый аргумент (self) опкодом CALL при вызове непривязанного метода. В противном случае помещаются NULL и объект, возвращённый поиском атрибута.

Изменено в версии 3.12: Если установлен младший бит namei, то в стек перед атрибутом или несвязанным методом соответственно помещается NULL или self.

LOAD_SUPER_ATTR(namei)

Этот опкод реализует super() как в форме без аргументов, так и в форме с двумя аргументами (например, super().method(), super().attr и super(cls, self).method(), super(cls, self).attr).

Извлекает из стека три значения (сверху вниз): - self: первый аргумент текущего метода - cls: класс, в котором определён текущий метод - глобальный объект super

По отношению к своему аргументу работает аналогично LOAD_ATTR, за исключением того, что namei сдвигается влево на 2 бита, а не на 1.

Младший бит namei указывает на попытку загрузки метода, как и LOAD_ATTR, что приводит к помещению в стек NULL и загруженного метода. Если бит сброшен, в стек помещается одно значение.

Второй бит снизу namei, если установлен, означает, что это был вызов super() с двумя аргументами (сброшен означает вызов без аргументов).

Добавлено в версии 3.12.

COMPARE_OP(opname)

Выполняет логическую операцию. Имя операции можно найти в cmp_op[opname >> 4].

Изменено в версии 3.12: Индекс cmp_op теперь хранится в четырёх старших битах oparg вместо четырёх младших.

IS_OP(invert)

Выполняет сравнение is или is not, если invert равно 1.

Добавлено в версии 3.9.

CONTAINS_OP(invert)

Выполняет сравнение in или not in, если invert равно 1.

Добавлено в версии 3.9.

IMPORT_NAME(namei)

Импортирует модуль co_names[namei]. STACK[-1] и STACK[-2] извлекаются из стека и предоставляют аргументы fromlist и level для __import__(). Объект модуля помещается в стек. Текущее пространство имён не затрагивается: для корректного оператора import последующая инструкция STORE_FAST изменяет пространство имён.

IMPORT_FROM(namei)

Загружает атрибут co_names[namei] из модуля, находящегося в STACK[-1]. Полученный объект помещается в стек для последующего сохранения инструкцией STORE_FAST.

JUMP_FORWARD(delta)

Увеличивает счётчик байт-кода на delta.

JUMP_BACKWARD(delta)

Уменьшает счётчик байт-кода на delta. Проверяет прерывания.

Добавлено в версии 3.12.

JUMP_BACKWARD_NO_INTERRUPT(delta)

Уменьшает счётчик байт-кода на delta. Не проверяет прерывания.

Добавлено в версии 3.12.

POP_JUMP_IF_TRUE(delta)

Если STACK[-1] истинно, увеличивает счётчик байт-кода на delta. STACK[-1] извлекается из стека.

Изменено в версии 3.11: Аргумент oparg теперь является относительным смещением, а не абсолютным адресом. Этот код операции – псевдоинструкция, заменяемая в окончательном байт-коде на направленные версии (вперёд/назад).

Изменено в версии 3.12: Эта инструкция больше не является псевдо-инструкцией.

POP_JUMP_IF_FALSE(delta)

Если STACK[-1] ложно, увеличивает счётчик байт-кода на delta. STACK[-1] извлекается из стека.

Изменено в версии 3.11: Аргумент oparg теперь является относительным смещением, а не абсолютным адресом. Этот код операции – псевдоинструкция, заменяемая в окончательном байт-коде на направленные версии (вперёд/назад).

Изменено в версии 3.12: Эта инструкция больше не является псевдо-инструкцией.

POP_JUMP_IF_NOT_NONE(delta)

Если STACK[-1] не равно None, увеличивает счётчик байткода на delta. STACK[-1] извлекается из стека.

Этот опкод является псевдоинструкцией, заменяемой в итоговом байткоде на направленные версии (вперёд/назад).

Добавлено в версии 3.12.

Изменено в версии 3.12: Эта инструкция больше не является псевдо-инструкцией.

POP_JUMP_IF_NONE(delta)

Если STACK[-1] равно None, увеличивает счётчик байткода на delta. STACK[-1] извлекается из стека.

Этот опкод является псевдоинструкцией, заменяемой в итоговом байткоде на направленные версии (вперёд/назад).

Добавлено в версии 3.12.

Изменено в версии 3.12: Эта инструкция больше не является псевдо-инструкцией.

FOR_ITER(delta)

STACK[-1] – это итератор. Вызовите его метод __next__(). Если он возвращает новое значение, поместите его в стек (оставляя итератор под ним). Если итератор сообщает, что он исчерпан, то счётчик байткода увеличивается на delta.

Изменено в версии 3.12: До версии 3.11 итератор извлекался из стека, когда он исчерпывался.

LOAD_GLOBAL(namei)

Загружает глобальную переменную co_names[namei>>1] в стек.

Изменено в версии 3.11: Если младший бит namei установлен, то NULL помещается в стек перед глобальной переменной.

LOAD_FAST(var_num)

Помещает ссылку на локальную переменную co_varnames[var_num] в стек.

Изменено в версии 3.12: Теперь этот опкод используется только в ситуациях, где локальная переменная гарантированно инициализирована. Он не может вызвать UnboundLocalError.

LOAD_FAST_CHECK(var_num)

Помещает ссылку на локальную переменную co_varnames[var_num] в стек, вызывая UnboundLocalError, если локальная переменная не была инициализирована.

Добавлено в версии 3.12.

LOAD_FAST_AND_CLEAR(var_num)

Помещает ссылку на локальную переменную co_varnames[var_num] в стек (или помещает NULL в стек, если локальная переменная не была инициализирована) и устанавливает co_varnames[var_num] в NULL.

Добавлено в версии 3.12.

STORE_FAST(var_num)

Сохраняет STACK.pop() в локальную переменную co_varnames[var_num].

DELETE_FAST(var_num)

Удаляет локальную переменную co_varnames[var_num].

MAKE_CELL(i)

Создаёт новую ячейку в слоте i. Если этот слот не пуст, то это значение сохраняется в новую ячейку.

Добавлено в версии 3.12.

LOAD_CLOSURE(i)

Помещает ссылку на ячейку, содержащуюся в слоте i хранилища «быстрых локальных переменных». Имя переменной – co_fastlocalnames[i].

Обратите внимание, что LOAD_CLOSURE по сути является псевдонимом для LOAD_FAST. Он существует, чтобы сделать байт-код немного более читаемым.

Изменено в версии 3.11: i больше не смещается на длину co_varnames.

LOAD_DEREF(i)

Загружает ячейку, находящуюся в слоте i хранилища «быстрых локальных переменных». Помещает в стек ссылку на объект, содержащийся в этой ячейке.

Изменено в версии 3.11: i больше не смещается на длину co_varnames.

LOAD_FROM_DICT_OR_DEREF(i)

Извлекает отображение из стека и ищет имя, связанное со слотом i хранилища «быстрых локальных переменных», в этом отображении. Если имя там не найдено, загружает его из ячейки, содержащейся в слоте i, аналогично LOAD_DEREF. Это используется для загрузки свободных переменных в телах классов (ранее для этого использовалось LOAD_CLASSDEREF) и в областях аннотаций внутри тел классов.

Добавлено в версии 3.12.

STORE_DEREF(i)

Сохраняет STACK.pop() в ячейку, находящуюся в слоте i хранилища «быстрых локальных переменных».

Изменено в версии 3.11: i больше не смещается на длину co_varnames.

DELETE_DEREF(i)

Очищает ячейку, находящуюся в слоте i хранилища «быстрых локальных переменных». Используется оператором del.

Добавлено в версии 3.2.

Изменено в версии 3.11: i больше не смещается на длину co_varnames.

COPY_FREE_VARS(n)

Копирует n свободных переменных из замыкания во фрейм. Устраняет необходимость в специальном коде на стороне вызывающего при вызове замыканий.

Добавлено в версии 3.12.

RAISE_VARARGS(argc)

Вызывает исключение, используя одну из трёх форм оператора raise, в зависимости от значения argc:

  • 0: raise (повторный вызов предыдущего исключения)

  • 1: raise STACK[-1] (вызов экземпляра или типа исключения по адресу STACK[-1])

  • 2: raise STACK[-2] from STACK[-1] (вызов экземпляра или типа исключения по адресу STACK[-2] с __cause__, установленным в STACK[-1])

CALL(argc)

Вызывает вызываемый объект с количеством аргументов, указанным argc, включая именованные аргументы, указанные предшествующей инструкцией KW_NAMES, если таковые имеются. В стеке находятся (в порядке возрастания) либо:

  • NULL

  • Вызываемый объект

  • Позиционные аргументы

  • Именованные аргументы

или:

  • Вызываемый объект

  • self

  • Оставшиеся позиционные аргументы

  • Именованные аргументы

argc – это общее количество позиционных и именованных аргументов, за исключением self, если NULL отсутствует.

CALL извлекает все аргументы и вызываемый объект из стека, вызывает вызываемый объект с этими аргументами и помещает возвращаемое значение, возвращённое вызываемым объектом.

Добавлено в версии 3.12.

CALL_FUNCTION_EX(flags)

Вызывает вызываемый объект с набором позиционных и именованных аргументов переменной длины. Если установлен младший бит flags, на вершине стека находится отображающий объект (mapping), содержащий дополнительные именованные аргументы. Перед вызовом вызываемого объекта отображающий объект и итерируемый объект «распаковываются», и их содержимое передаётся как именованные и позиционные аргументы соответственно. CALL_FUNCTION_EX извлекает из стека все аргументы и вызываемый объект, вызывает вызываемый объект с этими аргументами и помещает в стек возвращаемое значение, возвращённое вызываемым объектом.

Добавлено в версии 3.6.

PUSH_NULL

Помещает NULL в стек. Используется в последовательности вызова для сопоставления с NULL, помещённым LOAD_METHOD для вызовов не-методов.

Добавлено в версии 3.12.

KW_NAMES(consti)

Является префиксом для CALL. Сохраняет ссылку на co_consts[consti] во внутреннюю переменную для использования CALL. co_consts[consti] должна быть кортежем строк.

Добавлено в версии 3.12.

MAKE_FUNCTION(flags)

Помещает новый объект функции в стек. Снизу вверх потребляемый стек должен состоять из значений, если аргумент содержит указанное значение флага.

  • 0x01 кортеж значений по умолчанию для только-позиционных и позиционно-именованных параметров в позиционном порядке

  • 0x02 словарь значений по умолчанию только-именованных параметров

  • 0x04 кортеж строк, содержащих аннотации параметров

  • 0x08 кортеж, содержащий ячейки для свободных переменных, образующий замыкание

  • код, связанный с функцией (по STACK[-1])

Изменено в версии 3.10: Значение флага 0x04 теперь является кортежем строк вместо словаря

Изменено в версии 3.11: Квалифицированное имя по адресу STACK[-1] удалено.

BUILD_SLICE(argc)

Помещает объект среза в стек. argc должно быть 2 или 3. Если равно 2, реализует:

end = STACK.pop()
start = STACK.pop()
STACK.append(slice(start, end))

если равно 3, реализует:

step = STACK.pop()
end = STACK.pop()
start = STACK.pop()
STACK.append(slice(start, end, step))

Смотрите встроенную функцию slice() для получения дополнительной информации.

EXTENDED_ARG(ext)

Является префиксом для любой операции, аргумент которой слишком велик, чтобы поместиться в один байт по умолчанию. ext содержит дополнительный байт, который выступает в качестве старших битов аргумента. Для каждой операции допускается не более трёх префиксов EXTENDED_ARG, формирующих аргумент от двух до четырёх байт.

FORMAT_VALUE(flags)

Используется для реализации форматированных строковых литералов (f-строк). Извлекает из стека необязательную спецификацию формата, затем обязательное значение. Флаги интерпретируются следующим образом:

  • (flags & 0x03) == 0x00: значение форматируется как есть.

  • (flags & 0x03) == 0x01: вызвать str() для значения перед форматированием.

  • (flags & 0x03) == 0x02: вызвать repr() для значения перед форматированием.

  • (flags & 0x03) == 0x03: извлечь спецификацию формата из стека и использовать её, иначе использовать пустую спецификацию формата.

  • (flags & 0x04) == 0x04: pop fmt_spec from the stack and use it, else use an empty fmt_spec.

Форматирование выполняется с помощью PyObject_Format(). Результат помещается в стек.

Добавлено в версии 3.6.

MATCH_CLASS(count)

STACK[-1] – это кортеж имен ключевых атрибутов, STACK[-2] – класс, с которым производится сопоставление, а STACK[-3] – объект сопоставления. count – это количество позиционных подшаблонов.

Извлечь STACK[-1], STACK[-2] и STACK[-3]. Если STACK[-3] является экземпляром STACK[-2] и имеет позиционные и ключевые атрибуты, требуемые count и STACK[-1], поместить в стек кортеж извлеченных атрибутов. В противном случае поместить None.

Добавлено в версии 3.10.

Изменено в версии 3.11: Ранее эта инструкция также помещала в стек логическое значение, указывающее на успех (True) или неудачу (False).

RESUME(where)

Пустая операция. Выполняет внутренние проверки трассировки, отладки и оптимизации.

Операнд where отмечает, где происходит RESUME:

  • 0 Начало функции, которая не является ни генератором, корутиной, ни асинхронным генератором

  • 1 После выражения yield

  • 2 После выражения yield from

  • 3 После выражения await

Добавлено в версии 3.12.

RETURN_GENERATOR

Создает генератор, корутину или асинхронный генератор из текущего фрейма. Используется как первая опкода в объекте кода для указанных вызываемых объектов. Очищает текущий фрейм и возвращает вновь созданный генератор.

Добавлено в версии 3.12.

SEND(delta)

Эквивалентно STACK[-1] = STACK[-2].send(STACK[-1]). Используется в операторах yield from и await.

Если вызов вызывает исключение StopIteration, извлечь верхнее значение из стека, поместить атрибут value исключения и увеличить счетчик байт-кода на delta.

Добавлено в версии 3.12.

HAVE_ARGUMENT

Это на самом деле не опкод. Он определяет границу между опкодами в диапазоне [0,255], которые не используют свой аргумент, и теми, которые используют (соответственно < HAVE_ARGUMENT и >= HAVE_ARGUMENT).

Если ваше приложение использует псевдоинструкции, вместо них используйте коллекцию hasarg .

Изменено в версии 3.6: Теперь каждая инструкция имеет аргумент, но опкоды < HAVE_ARGUMENT игнорируют его. Раньше аргумент был только у опкодов >= HAVE_ARGUMENT.

Изменено в версии 3.12: Псевдоинструкции были добавлены в модуль dis, и для них неверно, что сравнение с HAVE_ARGUMENT указывает, используют ли они свой аргумент.

CALL_INTRINSIC_1

Вызывает встроенную функцию с одним аргументом. Передаёт STACK[-1] в качестве аргумента и записывает результат в STACK[-1]. Используется для реализации функциональности, не критичной к производительности.

Операнд определяет, какая встроенная функция вызывается:

Операнд

Описание

INTRINSIC_1_INVALID

Недействительно

INTRINSIC_PRINT

Выводит аргумент в стандартный вывод. Используется в REPL.

INTRINSIC_IMPORT_STAR

Выполняет import * для указанного модуля.

INTRINSIC_STOPITERATION_ERROR

Извлекает возвращаемое значение из исключения StopIteration.

INTRINSIC_ASYNC_GEN_WRAP

Оборачивает значение асинхронного генератора

INTRINSIC_UNARY_POSITIVE

Выполняет унарную операцию +

INTRINSIC_LIST_TO_TUPLE

Преобразует список в кортеж

INTRINSIC_TYPEVAR

Создаёт typing.TypeVar

INTRINSIC_PARAMSPEC

Создаёт typing.ParamSpec

INTRINSIC_TYPEVARTUPLE

Создаёт typing.TypeVarTuple

INTRINSIC_SUBSCRIPT_GENERIC

Возвращает typing.Generic, индексированный аргументом

INTRINSIC_TYPEALIAS

Создаёт typing.TypeAliasType; используется в операторе type. Аргумент – кортеж из имени псевдонима типа, параметров типа и значения.

Добавлено в версии 3.12.

CALL_INTRINSIC_2

Вызывает встроенную функцию с двумя аргументами. Используется для реализации функциональности, не критичной к производительности:

arg2 = STACK.pop()
arg1 = STACK.pop()
result = intrinsic2(arg1, arg2)
STACK.push(result)

Операнд определяет, какая встроенная функция вызывается:

Операнд

Описание

INTRINSIC_2_INVALID

Недействительно

INTRINSIC_PREP_RERAISE_STAR

Вычисляет ExceptionGroup, которое нужно возбудить из try-except*.

INTRINSIC_TYPEVAR_WITH_BOUND

Создаёт typing.TypeVar с границей.

INTRINSIC_TYPEVAR_WITH_CONSTRAINTS

Создаёт typing.TypeVar с ограничениями.

INTRINSIC_SET_FUNCTION_TYPE_PARAMS

Устанавливает атрибут __type_params__ функции.

Добавлено в версии 3.12.

Псевдоинструкции

Эти опкоды не встречаются в байткоде Python. Они используются компилятором, но заменяются реальными опкодами или удаляются до генерации байткода.

SETUP_FINALLY(target)

Настраивает обработчик исключений для следующего блока кода. Если возникает исключение, уровень стека значений восстанавливается до текущего состояния, и управление передаётся обработчику исключений по адресу target.

SETUP_CLEANUP(target)

Как SETUP_FINALLY, но в случае исключения также помещает последнюю инструкцию (lasti) в стек, чтобы RERAISE могла её восстановить. Если возникает исключение, уровень стека значений и последняя инструкция на фрейме восстанавливаются до текущего состояния, и управление передаётся обработчику исключений по адресу target.

SETUP_WITH(target)

Подобно SETUP_CLEANUP, но в случае исключения из стека извлекается ещё один элемент перед передачей управления обработчику исключений по адресу target.

Этот вариант используется в конструкциях with и async with, которые помещают возвращаемое значение __enter__() или __aenter__() менеджера контекста в стек.

POP_BLOCK

Отмечает конец блока кода, связанного с последним SETUP_FINALLY, SETUP_CLEANUP или SETUP_WITH.

JUMP
JUMP_NO_INTERRUPT

Ненаправленные инструкции относительного перехода, которые заменяются ассемблером на их направленные (вперёд/назад) аналоги.

LOAD_METHOD

Оптимизированный поиск несвязанного метода. Испускается как опкод LOAD_ATTR с установленным флагом в аргументе.

Коллекции опкодовOpcode collections

Эти коллекции предоставляются для автоматического самоанализа инструкций байткода:

Изменено в версии 3.12: Теперь коллекции содержат также псевдоинструкции и инструментированные инструкции. Это опкоды со значениями >= MIN_PSEUDO_OPCODE и >= MIN_INSTRUMENTED_OPCODE.

dis.opname

Последовательность имён операций, индексируемая с помощью байткода.

dis.opmap

Словарь, сопоставляющий имена операций с байткодами.

dis.cmp_op

Последовательность всех имён операций сравнения.

dis.hasarg

Последовательность байткодов, использующих свой аргумент.

Добавлено в версии 3.12.

dis.hasconst

Последовательность байткодов, обращающихся к константе.

dis.hasfree

Последовательность байткодов, обращающихся к свободной переменной. «free» в данном контексте относится к именам в текущей области видимости, на которые ссылаются внутренние области видимости, или к именам во внешних областях, на которые ссылается текущая область. Она не включает ссылки на глобальные или встроенные области видимости.

dis.hasname

Последовательность байткодов, обращающихся к атрибуту по имени.

dis.hasjrel

Последовательность байткодов, имеющих относительную цель перехода.

dis.hasjabs

Последовательность байткодов, имеющих абсолютную цель перехода.

dis.haslocal

Последовательность байткодов, обращающихся к локальной переменной.

dis.hascompare

Последовательность байткодов логических операций.

dis.hasexc

Последовательность байткодов, устанавливающих обработчик исключений.

Добавлено в версии 3.12.