co_code holds the instructions of a code object. This page lists every
instruction a Python 3.12 .pyc file can hold, with its number, as Python
3.12’s own opcode module gives them. Pseudo-instructions, the specialised
forms the interpreter makes while it runs and the INSTRUMENTED_* forms used
for monitoring are left out: they never appear in a file.
Encoding
co_code is a sequence of 16-bit code units, each one byte of opcode and
one byte of argument. Every instruction occupies one code unit, plus any
inline cache units after it. An instruction with no
argument still has the argument byte; it is zero, and it is ignored.
The instructions that take an argument are listed by opcode.hasarg. In
Python 3.12 they are exactly those numbered 90 or more,
opcode.HAVE_ARGUMENT.
EXTENDED_ARG widens an argument. It goes before the instruction, and its argument becomes the higher byte: up to three prefixes give the following instruction a 32-bit argument.
Inline caches
Some instructions are followed by a fixed number of 16-bit cache entries. The
interpreter fills them in while the program runs, to specialise the instruction. In a
file they are all zero. They are part of the instruction that precedes them:
dis hides them unless asked, as CACHE instructions. A reader
must step over them.
| Instruction | Cache units | Fields, in units |
|---|---|---|
BINARY_OP | 1 | counter 1 |
BINARY_SUBSCR | 1 | counter 1 |
CALL | 3 | counter 1, func_version 2 |
COMPARE_OP | 1 | counter 1 |
FOR_ITER | 1 | counter 1 |
LOAD_ATTR | 9 | counter 1, version 2, keys_version 2, descr 4 |
LOAD_GLOBAL | 4 | counter 1, index 1, module_keys_version 1, builtin_keys_version 1 |
LOAD_SUPER_ATTR | 1 | counter 1 |
SEND | 1 | counter 1 |
STORE_ATTR | 4 | counter 1, version 2, index 1 |
STORE_SUBSCR | 1 | counter 1 |
UNPACK_SEQUENCE | 1 | counter 1 |
Jump arguments
Every jump is relative. Its argument counts 16-bit code units, not bytes, from the point just after the instruction, past its inline caches. In bytes:
target = offset + 2 + 2 × caches ± 2 × argument
The sign is minus for JUMP_BACKWARD and
JUMP_BACKWARD_NO_INTERRUPT. It is plus for every other jump:
JUMP_FORWARD, the four POP_JUMP_IF_* instructions, and
FOR_ITER and SEND, which each have one cache unit. Conditional
jumps only go forward in Python 3.12; a loop that tests at the bottom jumps back with
JUMP_BACKWARD.
Every instruction
The argument, where one is used, is called arg. Local slot numbers index
co_localsplusnames; a name index goes into co_names and a
constant index into co_consts.
| Name | Number | Meaning |
|---|---|---|
BEFORE_ASYNC_WITH | 52 | Takes __aenter__ and __aexit__ from the top; pushes __aexit__, then the result of calling __aenter__() |
BEFORE_WITH | 53 | Pushes the context manager’s __exit__, calls __enter__(), pushes its result |
BINARY_OP | 122 | Pops two values, pushes the result. arg is the operator |
BINARY_SLICE | 26 | Pops end, start and container; pushes container[start:end] |
BINARY_SUBSCR | 25 | Pops key and container; pushes container[key] |
BUILD_CONST_KEY_MAP | 156 | Pops a tuple of keys, then arg values; pushes a dictionary |
BUILD_LIST | 103 | Pops arg items, pushes a list |
BUILD_MAP | 105 | Pops 2 × arg items, pushes a dictionary of arg entries |
BUILD_SET | 104 | Pops arg items, pushes a set |
BUILD_SLICE | 133 | arg is 2 or 3. Pops start and end, and step if 3; pushes a slice |
BUILD_STRING | 157 | Pops arg strings and pushes them joined |
BUILD_TUPLE | 102 | Pops arg items, pushes a tuple |
CACHE | 0 | Not a real instruction. Opcode 0 is the value of a zeroed inline cache entry |
CALL | 171 | Calls with arg arguments, counting those named by KW_NAMES. Below the arguments are either NULL and the callable, or the callable and self, which then is not counted. Pops them all and pushes the result |
CALL_FUNCTION_EX | 142 | Calls with an iterable of positional arguments, and a keyword mapping when arg bit 0 is set |
CALL_INTRINSIC_1 | 173 | Replaces the top of the stack with the result of an intrinsic selected by arg |
CALL_INTRINSIC_2 | 174 | Pops two values and pushes the result of an intrinsic selected by arg |
CHECK_EG_MATCH | 37 | For except*: splits the exception group below the top by the type on top; pushes the rest and the match |
CHECK_EXC_MATCH | 36 | Pops the type on top; pushes whether the exception below matches it |
CLEANUP_THROW | 55 | If the top is a StopIteration, pops three values and pushes None and the exception’s value; otherwise re-raises it. Handles an exception from throw() or close() |
COMPARE_OP | 107 | Pops two values, pushes the comparison. See comparison operators for the argument |
CONTAINS_OP | 118 | Pops two values, pushes in, or not in if arg is 1 |
COPY | 120 | Pushes a copy of the item arg places down, counting the top as 1 |
COPY_FREE_VARS | 149 | Copies arg free variables from the closure into the frame |
DELETE_ATTR | 96 | Pops an object; del obj.name. arg is a name index |
DELETE_DEREF | 139 | Empties the cell in slot arg |
DELETE_FAST | 126 | Deletes the local in slot arg |
DELETE_GLOBAL | 98 | Deletes a global. arg is a name index |
DELETE_NAME | 91 | Deletes a name. arg is a name index |
DELETE_SUBSCR | 61 | Pops key and container; del container[key] |
DICT_MERGE | 164 | Like DICT_UPDATE, but raises an error on a duplicate key |
DICT_UPDATE | 165 | Pops a mapping and adds it to the dictionary arg places down |
END_ASYNC_FOR | 54 | Ends an async for: pops the iterable and the exception; re-raises it unless it is StopAsyncIteration |
END_FOR | 4 | Removes the top two values. The compiler puts it at the end of each for loop; FOR_ITER jumps past it when the loop ends |
END_SEND | 5 | Removes the item below the top, when a sub-generator has finished |
EXTENDED_ARG | 144 | Gives the next instruction’s argument more high bits |
FORMAT_VALUE | 155 | f-string formatting. arg bits 0–1 pick the conversion (0 none, 1 str, 2 repr, 3 ascii); bit 2 means a format spec is on the stack |
FOR_ITER | 93 | Calls __next__() on the iterator on top and pushes the value, leaving the iterator below it. When the iterator is exhausted, pops it and jumps forward by arg, and then over the END_FOR found there |
GET_AITER | 50 | Replaces the top with __aiter__() of it |
GET_ANEXT | 51 | Pushes an awaitable of __anext__() of the top |
GET_AWAITABLE | 131 | Replaces the top with an awaitable. arg is 1 after __aenter__, 2 after __aexit__, else 0 |
GET_ITER | 68 | Replaces the top with iter() of it |
GET_LEN | 30 | Pushes len() of the top |
GET_YIELD_FROM_ITER | 69 | Leaves a generator or coroutine on top unchanged; replaces anything else with iter() of it |
IMPORT_FROM | 109 | Pushes an attribute of the module on top. arg is a name index |
IMPORT_NAME | 108 | Pops level and fromlist; pushes the imported module. arg is a name index |
INTERPRETER_EXIT | 3 | Leaves the interpreter loop. Used only by the interpreter’s internal frames |
IS_OP | 117 | Pops two values, pushes is, or is not if arg is 1 |
JUMP_BACKWARD | 140 | Jumps back by arg and checks for interrupts |
JUMP_BACKWARD_NO_INTERRUPT | 134 | Jumps back by arg without checking for interrupts |
JUMP_FORWARD | 110 | Jumps forward by arg |
KW_NAMES | 172 | Goes before CALL: arg is the constant index of a tuple of keyword names for that call |
LIST_APPEND | 145 | Pops an item and appends it to the list arg places down |
LIST_EXTEND | 162 | Pops an iterable and extends the list arg places down |
LOAD_ASSERTION_ERROR | 74 | Pushes AssertionError |
LOAD_ATTR | 106 | Replaces the top with an attribute of it. The name index is arg >> 1. If bit 0 is set it loads a method: it pushes the unbound method and the object, which CALL passes as self, or NULL and the attribute |
LOAD_BUILD_CLASS | 71 | Pushes the function builtins.__build_class__, which a following call uses to make a class |
LOAD_CLOSURE | 136 | Pushes the cell in slot arg, to build a closure. It works like LOAD_FAST |
LOAD_CONST | 100 | Pushes a constant. arg is a constant index |
LOAD_DEREF | 137 | Pushes the object in the cell in slot arg |
LOAD_FAST | 124 | Pushes the local in slot arg. The compiler uses it only where the local is known to be set |
LOAD_FAST_AND_CLEAR | 143 | Pushes the local in slot arg, or NULL if it is not set, and clears the slot. Used to save a variable an inlined comprehension reuses |
LOAD_FAST_CHECK | 127 | Pushes the local in slot arg, or raises UnboundLocalError if it is not set |
LOAD_FROM_DICT_OR_DEREF | 176 | Pops a mapping and looks up the name of slot arg in it; falls back to the cell. Used in class bodies |
LOAD_FROM_DICT_OR_GLOBALS | 175 | Pops a mapping and looks up a name in it, then in globals and builtins. arg is a name index |
LOAD_GLOBAL | 116 | Pushes a global. The name index is arg >> 1; if bit 0 is set, a NULL is pushed first, for a call |
LOAD_LOCALS | 87 | Pushes the locals dictionary |
LOAD_NAME | 101 | Pushes a name found in locals, globals or builtins. arg is a name index |
LOAD_SUPER_ATTR | 141 | Pops self, the class and super; loads an attribute as super() does. The name index is arg >> 2; bit 0 asks for a method load; bit 1 marks the two-argument super |
MAKE_CELL | 135 | Makes a new cell in slot arg, holding the slot’s value if it has one |
MAKE_FUNCTION | 132 | Pushes a function made from the code object on top. arg holds flags for extra items below it on the stack |
MAP_ADD | 147 | Pops a value and key, stores them in the dictionary arg places down |
MATCH_CLASS | 152 | Pops the keyword names, class and subject; pushes a tuple of attributes, or None. arg is the number of positional sub-patterns |
MATCH_KEYS | 33 | The top is a tuple of keys, the item below a mapping. Pushes a tuple of the values, or None |
MATCH_MAPPING | 31 | Pushes whether the top is a mapping |
MATCH_SEQUENCE | 32 | Pushes whether the top is a sequence and not text or bytes |
NOP | 9 | Does nothing |
POP_EXCEPT | 89 | Pops a value and uses it to restore the exception state |
POP_JUMP_IF_FALSE | 114 | Pops the top; if false, jumps forward by arg |
POP_JUMP_IF_NONE | 129 | Pops the top; if None, jumps forward by arg |
POP_JUMP_IF_NOT_NONE | 128 | Pops the top; if not None, jumps forward by arg |
POP_JUMP_IF_TRUE | 115 | Pops the top; if true, jumps forward by arg |
POP_TOP | 1 | Pops and discards the top |
PUSH_EXC_INFO | 35 | Pops a value, pushes the current exception, pushes the value back |
PUSH_NULL | 2 | Pushes NULL, for the calling sequence |
RAISE_VARARGS | 130 | Raises: arg 0 re-raises, 1 raises the top, 2 raises the item below the top with the top as its cause |
RERAISE | 119 | Pops the exception on top and re-raises it. If arg is nonzero, first sets f_lasti from the offset found arg places below the exception |
RESERVED | 17 | A reserved number. Executing it is an interpreter error |
RESUME | 151 | No visible effect; a point for tracing, debugging and optimisation checks. arg says where it is |
RETURN_CONST | 121 | Returns a constant. arg is a constant index |
RETURN_GENERATOR | 75 | Makes a generator, coroutine or async generator from the frame and returns it |
RETURN_VALUE | 83 | Returns the top of the stack |
SEND | 123 | Sends the top value into the sub-generator below it, for yield from and await, and replaces the top with what it yields. When the sub-generator finishes, it jumps forward by arg |
SETUP_ANNOTATIONS | 85 | Makes __annotations__ an empty dictionary in the locals, if it is missing |
SET_ADD | 146 | Pops an item and adds it to the set arg places down |
SET_UPDATE | 163 | Pops an iterable and adds its items to the set arg places down |
STORE_ATTR | 95 | Pops an object and a value; sets the attribute. arg is a name index |
STORE_DEREF | 138 | Pops a value into the cell in slot arg |
STORE_FAST | 125 | Pops a value into the local in slot arg |
STORE_GLOBAL | 97 | Pops a value into a global. arg is a name index |
STORE_NAME | 90 | Pops a value into a name. arg is a name index |
STORE_SLICE | 27 | Pops end, start, container and value; container[start:end] = value |
STORE_SUBSCR | 60 | Pops key, container and value; container[key] = value |
SWAP | 99 | Swaps the top with the item arg places down, counting the top as 1 |
UNARY_INVERT | 15 | Replaces the top with ~ of it |
UNARY_NEGATIVE | 11 | Replaces the top with - of it |
UNARY_NOT | 12 | Replaces the top with not of it |
UNPACK_EX | 94 | Unpacks the top with a starred target. The low byte of arg is the count before the list, and the high byte the count after it |
UNPACK_SEQUENCE | 92 | Replaces the top with its arg items, pushed right to left |
WITH_EXCEPT_START | 49 | Calls the __exit__ function below the exception on top, for with |
YIELD_VALUE | 150 | Pops the top and yields it. arg is the depth of exception blocks at that point, which lets a generator be closed quickly |
Unary +, import *, printing in the REPL and turning a list
into a tuple have no instruction of their own in Python 3.12; they are
intrinsics.
Comparison operators
COMPARE_OP’s argument holds the index of the operator in its upper bits,
arg >> 4. The low four bits are a mask of the outcomes that make
the comparison true: 1 unordered, 2 less, 4 greater, 8 equal. So < has
mask 2, <= 10, != 7 and >= 12. The
interpreter’s specialised forms of the instruction use the mask; the operator index alone
gives the meaning. For example a == b compiles to
COMPARE_OP 40, which is index 2 and mask 8.
| Index | Operator |
|---|---|
| 0 | < |
| 1 | <= |
| 2 | == |
| 3 | != |
| 4 | > |
| 5 | >= |
BINARY_OP operators
| arg | Operator | arg | Operator |
|---|---|---|---|
| 0 | + | 13 | += |
| 1 | & | 14 | &= |
| 2 | // | 15 | //= |
| 3 | << | 16 | <<= |
| 4 | @ | 17 | @= |
| 5 | * | 18 | *= |
| 6 | % | 19 | %= |
| 7 | | | 20 | |= |
| 8 | ** | 21 | **= |
| 9 | >> | 22 | >>= |
| 10 | - | 23 | -= |
| 11 | / | 24 | /= |
| 12 | ^ | 25 | ^= |
Intrinsics
CALL_INTRINSIC_1:
| arg | Name | Does |
|---|---|---|
| 0 | INTRINSIC_1_INVALID | Not valid |
| 1 | INTRINSIC_PRINT | Prints the argument to standard output, in the REPL |
| 2 | INTRINSIC_IMPORT_STAR | import * from the module object given, into the local namespace |
| 3 | INTRINSIC_STOPITERATION_ERROR | Turns a StopIteration (or, in an async generator, StopAsyncIteration) that escapes a generator or coroutine into a RuntimeError |
| 4 | INTRINSIC_ASYNC_GEN_WRAP | Wraps an async generator value |
| 5 | INTRINSIC_UNARY_POSITIVE | Unary + |
| 6 | INTRINSIC_LIST_TO_TUPLE | Converts a list to a tuple |
| 7 | INTRINSIC_TYPEVAR | Creates a TypeVar |
| 8 | INTRINSIC_PARAMSPEC | Creates a ParamSpec |
| 9 | INTRINSIC_TYPEVARTUPLE | Creates a TypeVarTuple |
| 10 | INTRINSIC_SUBSCRIPT_GENERIC | typing.Generic subscripted with the argument |
| 11 | INTRINSIC_TYPEALIAS | Creates a TypeAliasType, for the type statement |
CALL_INTRINSIC_2:
| arg | Name | Does |
|---|---|---|
| 0 | INTRINSIC_2_INVALID | Not valid |
| 1 | INTRINSIC_PREP_RERAISE_STAR | Computes the exception group to raise from try–except* |
| 2 | INTRINSIC_TYPEVAR_WITH_BOUND | Creates a TypeVar with a bound |
| 3 | INTRINSIC_TYPEVAR_WITH_CONSTRAINTS | Creates a TypeVar with constraints |
| 4 | INTRINSIC_SET_FUNCTION_TYPE_PARAMS | Sets a function’s __type_params__ |
Function flags
The argument of MAKE_FUNCTION is a set of these bits. Each set bit means
one more item lies below the code object on the stack, in this order from the
bottom.
| Bit | Value |
|---|---|
| 0x01 | Tuple of defaults for positional parameters |
| 0x02 | Dictionary of keyword-only defaults |
| 0x04 | Tuple of strings holding parameter annotations |
| 0x08 | Tuple of cells for free variables, the closure |
RESUME argument
| arg | Where the RESUME is |
|---|---|
| 0 | The start of a function or module |
| 1 | After a yield |
| 2 | After a yield from |
| 3 | After an await |