CPython Opcode Instructions
CPython compiles function into bytecode.
The opcodes for this bytecode are listed here and can also be found in OpcodeIdentifier
.
CPython bytecode structure in not stable, and opcode behaviour may change between releases.
General Format
Each opcode will be listed in the following format:
Opcode Name
Python Versions
Stack Prior: ... [expected stack state]
Stack After: ... [new stack state]
Description of Opcode
Example sources that generate the opcode
For instance, the POP_TOP
opcode, which pop a single item off the top of the stack, would look like this:
POP_TOP
Python Versions: ALL
Stack Prior: ... item
Stack After: ...
Pops a single item off the stack.
Used to discard return value of functions and to manipulate the stack.
Example Sources:
my_fun() # POP_TOP is generated after the function call
# since the result of my_fun is unused.
Instruction Addressing
Prior to 3.10, instructions are addressed by byte offsets. So the first instruction would have address 0, the second instruction would have address 2, and the third instruction would have address 4. After 3.10, instructions are addressed by instruction offsets. So the first instruction would have address 0, the second instruction would have address 1, and the third instruction would have address 2.
Absolute jumps go to the instruction with the address given by the argument. So an absolute jump with argument 2 will go to the instruction at address 2 regardless of the jump’s address.
Relative jumps go to the instruction that are argument addresses away from it. So a relative jump with argument 2 will go to the instruction at address 3 if the jump is at address 1, or 4 if the jump is at address 2.
Cell Variable Index
In Python 3.10 and below, the argument for LOAD_CLOSURE
, LOAD_CLASSDEREF
, LOAD_DEREF
, STORE_DEREF
and DELETE_DEREF
correspond to the index of the variable name in the combined list co_cellvars + co_freevars
.
For instance, if co_cellvars = ['a', 'b']
and co_freevars = ['c', 'd']
, the argument to read/modify/delete the variable corresponding to each name would be:
-
'a': 0
-
'b': 1
-
'c': 2
-
'd': 3
In Python 3.11, the indices for cell variables that do not correspond to parameters are offset by co_varnames
. If a cell variable corresponds to a parameter, it uses the parameter index in co_varnames
as its cell index. For instance, if co_varnames = ['a', 'x', 'y']
, co_cellvars = ['a', 'b']
and co_freevars = ['c', 'd']
, the argument to read/modify/delete the variable corresponding to each name would be:
-
'a': 0
-
'b': 3
-
'c': 4
-
'd': 5
Opcode Listing
NOP
Python Versions: ALL
Stack Prior: ...
Stack After: ...
Does absolutely nothing. Exists purely to simplify bytecode generation.
Example Sources:
pass # `pass` represent a NOP in Python
RESUME
Python Versions: 3.11+
Stack Prior: ...
Stack After: ...
A NOP opcode that CPython uses to perform internal tracing, debugging and optimization checks. Generally put into places where the CPython interpreter enters a function (the start of every function and after yield statements).
Example Sources:
def function():
# A RESUME opcode is placed at the start of every
# function.
return None
yield 10 # A RESUME opcode is placed after
# each YIELD_VALUE opcode
CACHE
Python Versions: 3.11+
A NOP opcode that CPython uses to record runtime conditions for the specializing adaptive interpreter.
For instance, if CPython detects a BINARY_OP opcode is usually performed on two int
,
the CPython interpreter writes that information into the CACHE opcodes that precede the BINARY_OP to specialize the BINARY_OP into INT_BINARY_ADD
.
JPyIntepreter does specialization at compile time using information from type annotation and typeflow analysis.
Example Sources:
# Several CACHE instruction precede the
# BINARY_OP
x + y
POP_TOP
Python Versions: ALL
Stack Prior: ... item
Stack After: ...
Pops a single item off the stack. Used to discard return value of functions and to manipulate the stack.
Example Sources:
my_fun() # POP_TOP is generated after the function call
# since the result of my_fun is unused.
ROT_TWO
Python Versions: <= 3.10
Stack Prior: ... second, first
Stack After: ... first, second
Swaps the top two elements of the stack. Used for stack manipulation.
Example Sources:
# Swap in Python 3.10 and below can be implemented as
# LOAD[y], LOAD[x], ROT_TWO, STORE[x], STORE[y]
x, y = y, x
ROT_THREE
Python Versions: <= 3.10
Stack Prior: ... third, second, first
Stack After: ... first, third, second
Move the top of stack down by two, raising the two items immediately below it up by one. Used for stack manipulation.
Example Sources:
# FLIP_3 in Python 3.10 and below can be implemented as
# LOAD[z], LOAD[y], LOAD[x], (stack is z, y, x)
# ROT_THREE, (stack is x, z, y)
# ROT_TWO, (stack is x, y, z)
# STORE[x], STORE[y], STORE[z]
x, y, z = z, y, x
ROT_FOUR
Python Versions: >= 3.8 and <= 3.10
Stack Prior: ... fourth, third, second, first
Stack After: ... first, fourth, third, second
Move the top of stack down by three, raising the three items immediately below it up by one. Used for stack manipulation.
Example Sources:
# FLIP_3 in Python 3.10 and below can be implemented as
# LOAD[w], LOAD[z], LOAD[y], LOAD[x], (stack is z, y, x, w)
# ROT_FOUR, (stack is w, z, y, x)
# ROT_THREE, (stack is w, x, z, y)
# ROT_TWO (stack is w, x, y, z)
# STORE[w], STORE[x], STORE[y], STORE[z]
w, x, y, z = z, y, x, w
DUP_TOP
Python Versions: >= 3.2, <= 3.10
Stack Prior: ... top
Stack After: ... top, top
Duplicates the top of stack. Used to preserve a stack value that is used in multiple operations.
Example Sources:
# Python 3.10 and below
a == b == c
DUP_TOP_TWO
Python Versions: >= 3.2, <= 3.10
Stack Prior: ... a, b
Stack After: ... a, b, a, b
Duplicates the top two elements of the stack.
Example Sources:
a[b] += a[c]
COPY(i)
Python Versions: >= 3.11
Stack Prior: ... item_i, ..., item_2, item_1
Stack After: ... item_i, ..., item_2, item_1, item_i
Copies the item at the given 1-based index in the stack to the top of stack. The item is not removed from its original position.
Example Sources:
# Python 3.11 and above
a == b == c
SWAP(i)
Python Versions: >= 3.11
Stack Prior: ... item_i, ..., item_2, item_1
Stack After: ... item_1, ..., item_2, item_i
Swaps the item at the given 1-based index in the stack with the top of stack.
Example Sources:
# Python 3.11 and above
a == b == c
UNARY_POSITIVE
Python Versions: ALL
Stack Prior: ... operand
Stack After: ... result
Implements +x
.
Pops the operand off the stack, call its __pos__
method, and push the result.
Example Sources:
+x
UNARY_NEGATIVE
Python Versions: ALL
Stack Prior: ... operand
Stack After: ... result
Implements -x
.
Pops the operand off the stack, call its __neg__
method, and push the result.
Example Sources:
-x
UNARY_INVERT
Python Versions: ALL
Stack Prior: ... operand
Stack After: ... result
Implements ~x
.
Pops the operand off the stack, call its __invert__
method, and push the result.
Example Sources:
~x
GET_ITER
Python Versions: ALL
Stack Prior: ... iterable
Stack After: ... iterator
Pops the iterable off the stack, call its __iter__
method, and push the result. Used to implement for loops.
Example Sources:
# The for loop performs GET_ITER on iterable to get the iterator,
# which is then used by FOR_ITER to loops through iterable items.
for item in iterable:
...
GET_YIELD_FROM_ITER
Python Versions: >= 3.5
Stack Prior: ... iterable
Stack After: ... iterator
If the iterable is a generator iterator or a coroutine, leave it on the stack.
Otherwise, call its __iter__
method.
Used in yield from
expressions.
Example Sources:
# GET_YIELD_FROM_ITER is used to get the
# iterator for [1, 2, 3].
yield from [1, 2, 3]
BINARY_OP(op)
Python Versions: >= 3.11
Stack Prior: ... left_operand, right_operand
Stack After: ... result
Perform the binary operator indicated by the opcode’s argument on the top two items on the stack (popping them), and push the result to the top of stack. An binary op can either be inplace or not in place. Inplace opcodes try the binary op’s inplace method first, then fall back to the standard binary op handling. The argument to binary operator mapping can be found in CPython source code. In general, first are the non-inplace opcodes in alphabetical order, followed by the inplace opcodes in alphabetical order.
The left operand is always the first element below the top of stack, and the right operand is always the top of stack. The binary operation is performed as followed:
-
Get the method for the binary operation from the left operand’s type.
-
If the method is present:
-
Call the resolved method with the left and right operands.
-
If the result is not
NotImplemented
, then it the result of thisBINARY_OP
and go to the next bytecode instruction. -
If the result is
NotImplemented
, treat it as if the left operand’s type did not have the method. -
If the left operand a builtin type and the method raises a
TypeError
, treat it as if the left operand’s type did not have the method.
-
-
If the method is not present:
-
Get the method for the reflected version of the binary operation from the right operand’s type.
-
If the reflected method is present:
-
Call the reflected resolved method with the right and left operands.
-
If the result is not
NotImplemented
, then it the result of thisBINARY_OP
and go to the next bytecode instruction. -
If the result is
NotImplemented
, treat it as if the right operand’s type did not have the reflected method.
-
-
If the reflected method is not present, raise a
TypeError
with the messagef"unsupported operand type(s) for {symbol(BINARY_OP)}: '{type(left_operand)}' and '{type(right_operand)}'"
-
In Python, it would look like this:
def binary_op(BINARY_OP, left_operand, right_operand):
UNSUPPORTED_OP_MSG = f"unsupported operand type(s) for {symbol(BINARY_OP)}: '{type(left_operand)}' and '{type(right_operand)}'"
def reflected_binary_op():
right_method = getattr(type(right_operand), reflected(BINARY_OP), None)
if right_method is not None:
reflected_out = right_method(right_operand, left_operand)
if reflected_out is NotImplemented:
raise TypeError(UNSUPPORTED_OP_MSG)
else:
return reflected_out
if is_in_place(BINARY_OP):
inplace_method = getattr(type(left_operand), BINARY_OP, None)
if inplace_method is not None:
out = inplace_method(left_operand, right_operand)
if out is not NotImplemented:
return out
BINARY_OP = get_standard_binary_op(BINARY_OP)
left_method = getattr(type(left_operand), BINARY_OP, None)
if left_method is not None:
try:
out = left_method(left_operand, right_operand)
if out is not NotImplemented:
return out
except TypeError:
if type(left_operand) in BUILTIN_TYPES:
return reflected_binary_op()
raise
return reflected_binary_op()
Example Sources:
x + 1
x -= y
BINARY_POWER
Python Versions: <= 3.10
Stack Prior: ... base, exponent
Stack After: ... result
Binary operator corresponding to __pow__
and __rpow__
. Implements **
.
Example Sources:
base ** expotent
BINARY_MULTIPLY
Python Versions: <= 3.10
Stack Prior: ... left_factor, right_factor
Stack After: ... product
Binary operator corresponding to __mul__
and __rmul__
. Implements *
.
Example Sources:
left_factor * right_factor
BINARY_MATRIX_MULTIPLY
Python Versions: >= 3.5 and <= 3.10
Stack Prior: ... left_factor, right_factor
Stack After: ... product
Binary operator corresponding to __matmul__
and __rmatmul__
. Implements @
.
Example Sources:
left_factor @ right_factor
BINARY_FLOOR_DIVIDE
Python Versions: <= 3.10
Stack Prior: ... dividend, divisor
Stack After: ... quotient
Binary operator corresponding to __floordiv__
and __rfloordiv__
. Implements //
.
Example Sources:
dividend // divisor
BINARY_TRUE_DIVIDE
Python Versions: <= 3.10
Stack Prior: ... dividend, divisor
Stack After: ... quotient
Binary operator corresponding to __truediv__
and __rtruediv__
. Implements /
.
Example Sources:
dividend / divisor
BINARY_MODULO
Python Versions: <= 3.10
Stack Prior: ... dividend, divisor
Stack After: ... modulus
Binary operator corresponding to __mod__
and __rmod__
. Implements %
.
Example Sources:
dividend % divisor
BINARY_ADD
Python Versions: <= 3.10
Stack Prior: ... augend, addend
Stack After: ... sum
Binary operator corresponding to __add__
and __radd__
. Implements +
.
Example Sources:
augend + addend
BINARY_SUBTRACT
Python Versions: <= 3.10
Stack Prior: ... minuend, subtrahend
Stack After: ... difference
Binary operator corresponding to __sub__
and __rsub__
. Implements -
.
Example Sources:
minuend - subtrahend
BINARY_LSHIFT
Python Versions: <= 3.10
Stack Prior: ... to_shift, shift
Stack After: ... result
Binary operator corresponding to __lshift__
and __rlshift__
. Implements <<
.
Example Sources:
to_shift << shift
BINARY_RSHIFT
Python Versions: <= 3.10
Stack Prior: ... to_shift, shift
Stack After: ... result
Binary operator corresponding to __rshift__
and __rrshift__
. Implements >>
.
Example Sources:
to_shift >> shift
BINARY_AND
Python Versions: <= 3.10
Stack Prior: ... left_conjunct, right_conjunct
Stack After: ... conjunction
Binary operator corresponding to __and__
and __rand__
. Implements &
.
Example Sources:
left_conjunct & right_conjunct
BINARY_OR
Python Versions: <= 3.10
Stack Prior: ... left_disjunct, right_disjunct
Stack After: ... disjunction
Binary operator corresponding to __or__
and __ror__
. Implements |
.
Example Sources:
left_disjunct | right_disjunct
BINARY_XOR
Python Versions: <= 3.10
Stack Prior: ... left_disjunct, right_disjunct
Stack After: ... disjunction
Binary operator corresponding to __xor__
and __rxor__
. Implements ^
.
Example Sources:
left_disjunct ^ right_disjunct
INPLACE_POWER
Python Versions: <= 3.10
Stack Prior: ... base, exponent
Stack After: ... result
Inplace binary operator corresponding to __ipow__
, __pow__
and __rpow__
. Implements **=
.
Example Sources:
base **= expotent
INPLACE_MULTIPLY
Python Versions: <= 3.10
Stack Prior: ... left_factor, right_factor
Stack After: ... product
Inplace binary operator corresponding to __imul__
, __mul__
and __rmul__
. Implements *
.
Example Sources:
left_factor *= right_factor
INPLACE_MATRIX_MULTIPLY
Python Versions: >= 3.5 and <= 3.10
Stack Prior: ... left_factor, right_factor
Stack After: ... product
Inplace binary operator corresponding to __imatmul__
, __matmul__
and __rmatmul__
. Implements @=
.
Example Sources:
left_factor @= right_factor
INPLACE_FLOOR_DIVIDE
Python Versions: <= 3.10
Stack Prior: ... dividend, divisor
Stack After: ... quotient
Inplace binary operator corresponding to __ifloordiv__
, __floordiv__
and __rfloordiv__
. Implements //=
.
Example Sources:
dividend //= divisor
INPLACE_TRUE_DIVIDE
Python Versions: <= 3.10
Stack Prior: ... dividend, divisor
Stack After: ... quotient
Inplace binary operator corresponding to __itruediv__
, __truediv__
and __rtruediv__
. Implements /=
.
Example Sources:
dividend /= divisor
INPLACE_MODULO
Python Versions: <= 3.10
Stack Prior: ... dividend, divisor
Stack After: ... modulus
Inplace binary operator corresponding to __imod__
, __mod__
and __rmod__
. Implements %=
.
Example Sources:
dividend %= divisor
INPLACE_ADD
Python Versions: <= 3.10
Stack Prior: ... augend, addend
Stack After: ... sum
Inplace binary operator corresponding to __iadd__
, __add__
and __radd__
. Implements +=
.
Example Sources:
augend += addend
INPLACE_SUBTRACT
Python Versions: <= 3.10
Stack Prior: ... minuend, subtrahend
Stack After: ... difference
Inplace binary operator corresponding to __isub__
, __sub__
and __rsub__
. Implements -=
.
Example Sources:
minuend -= subtrahend
INPLACE_LSHIFT
Python Versions: <= 3.10
Stack Prior: ... to_shift, shift
Stack After: ... result
Inplace binary operator corresponding to __ilshift__
, __lshift__
and __rlshift__
. Implements <<=
.
Example Sources:
to_shift <<= shift
INPLACE_RSHIFT
Python Versions: <= 3.10
Stack Prior: ... to_shift, shift
Stack After: ... result
Inplace binary operator corresponding to __irshift__
, __rshift__
and __rrshift__
. Implements >>=
.
Example Sources:
to_shift >>= shift
INPLACE_AND
Python Versions: <= 3.10
Stack Prior: ... left_conjunct, right_conjunct
Stack After: ... conjunction
Inplace binary operator corresponding to __iand__
, __and__
and __rand__
. Implements &=
.
Example Sources:
left_conjunct &= right_conjunct
INPLACE_OR
Python Versions: <= 3.10
Stack Prior: ... left_disjunct, right_disjunct
Stack After: ... disjunction
Inplace binary operator corresponding to __ior__
, __or__
and __ror__
. Implements |=
.
Example Sources:
left_disjunct |= right_disjunct
INPLACE_XOR
Python Versions: <= 3.10
Stack Prior: ... left_disjunct, right_disjunct
Stack After: ... disjunction
Inplace binary operator corresponding to __ixor__
, __xor__
and __rxor__
. Implements ^=
.
Example Sources:
left_disjunct ^= right_disjunct
BINARY_SUBSCR
Python Versions: ALL
Stack Prior: ... collection, key
Stack After: ... item
Implements collection[key]
. Acts like a binary operator, but does not have a reflective method. Pop the two top items off the stack, calls the __getitem__
method on type(collection)
with the arguments collection
and key
, and push the method result to the top of the stack.
Example Sources:
collection[key]
STORE_SUBSCR
Python Versions: ALL
Stack Prior: ... value, collection, key
Stack After: ...
Implements collection[key] = value
. Pop the three top items off the stack, calls the __setitem__
method on type(collection)
with the arguments collection
, key
and value
. Does not push the result onto the stack.
Example Sources:
collection[key] = value
DELETE_SUBSCR
Python Versions: ALL
Stack Prior: ... collection, key
Stack After: ...
Implements del collection[key]
. Pop the two top items off the stack, calls the __delitem__
method on type(collection)
with the arguments collection
and key
. Does not push the result onto the stack.
Example Sources:
del collection[key]
GET_AWAITABLE(where)
Python Versions: >= 3.5
Stack Prior: ... awaitable
Stack After: ... awaitable_iterator
If awaitable is a coroutine or a generator coroutine, leave it as is on the stack. Otherwise, replace awaitable
with the result of calling its __await__
method.
Before Python 3.11, this opcode did not have an argument.
After Python 3.11, this opcode has an argument, which indicates where the instruction occurs if non-zero:
-
1
if after a call to__aenter__
-
2
if after a call to__aexit__
Example Sources:
await awaitable
GET_AITER
Python Versions: >= 3.5
Stack Prior: ... async_iterable
Stack After: ... async_iterator
Pops the async iterable off the stack, call its __aiter__
method, and push the result. Used to implement async for loops.
Example Sources:
# The for loop performs GET_AITER on async_iterable to get the async iterator.
# GET_ANEXT is then called on the async iterator.
# The object returned by GET_ANEXT is sent None,
# and the object returned from the send operation is the next item in the async for loop.
async for item in iterable:
print(item)
The bytecode in 3.11 looks like this:
6 LOAD_FAST 0 (iterable)
8 GET_AITER
================= begin try block =====================
>> 10 GET_ANEXT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+
12 LOAD_CONST 0 (None) ^
>> 14 SEND 3 (to 22) ------+>>+ ^
16 YIELD_VALUE ^ v ^
18 RESUME 3 ^ v ^
20 JUMP_BACKWARD_NO_INTERRUPT 4 (to 14)-+ v ^
================== end try block ===================v=^>v
>> 22 STORE_FAST 1 (item) <<<<<<<<<<+ ^ v
24 LOAD_GLOBAL 1 (NULL + print) ^ v
36 LOAD_FAST 1 (item) ^ v
38 PRECALL 1 ^ v
42 CALL 1 ^ v
52 POP_TOP ^ v
54 JUMP_BACKWARD 23 (to 10)>>>>>>>>>>>>+ v
================== begin finally ======================<+
>> 56 END_ASYNC_FOR
================== end finally ========================
GET_ANEXT
Python Versions: >= 3.5
Stack Prior: ... awaitable_iterator
Stack After: ... awaitable_item
Pops awaitable_iterator
off the stack.
Calls __anext__
on awaitable_iterator
.
If the result is a coroutine or a generator coroutine, push it as is on the stack.
Otherwise, call the result’s __await__
method and push that to the stack.
Used to implement async for loops.
Example Sources:
See GET_AITER for an example.
END_ASYNC_FOR
Python Versions: >= 3.5, <= 3.10
Stack Prior: ... async_iterable, tb1, ex1, ex_type1, tb2, ex2, ex_type2
Stack After: ...
Python Versions: >= 3.11
Stack Prior: ... async_iterable, exception
Stack After: ...
Terminates an async for loop.
Behavior prior to 3.11:
If ex_type2
is StopAsyncIteration
, pop 7 values from the stack, restoring exception state from tb1
, ex1
and ex_type1
.
Otherwise, re-raise ex2
.
Behavior after 3.11:
If exception
is an instance of StopAsyncIteration
, pop both async_iterable
and exception
off the stack.
Otherwise, re-raise exception
.
Example Sources:
See GET_AITER for an example.
BEFORE_ASYNC_WITH
Python Versions: >= 3.5
Stack Prior: ... async_context_manager
Stack After: ... async_exit_function, async_enter_result
Pops async_context_manager
off the stack and resolve its __aexit__
and __aenter__
methods.
The __aexit__
function is pushed to the stack,
followed by the object return by calling __aenter__
.
Used to implement asynchronous context managers
Example Sources:
async with async_context_manager as async_context:
pass
SETUP_ASYNC_WITH
Python Versions: >= 3.5, <= 3.10
Stack Prior: ...
Stack After: ...
Create the try…finally
block used for asynchronous context managers.
Example Sources:
async with async_context_manager as async_context:
pass
PRINT_EXPR
Python Versions: ALL
Stack Prior: ... to_print
Stack After: ...
Pops off the top of the stack, calls its __repr__
method, and prints the result.
Used by the CPython interactive interpreter to print an entered expression.
It is never emitted as an opcode in a function.
Example Sources:
It cannot be emitted in a function, and thus has no example sources. It is emitted as the final opcode when the CPython interactive interpreter compiles an expression outside a block.
SET_ADD(i)
Python Versions: ALL
Stack Prior: ... s_i, ..., s_1, s_0
Stack After: ... s_i, ..., s_1
Pops off the top of the stack and call s_i.add(s_0)
.
s_i
remains on the stack so it can be reused.
Used to implement set comprehensions.
Example Sources:
{point for point in point_list}
LIST_APPEND(i)
Python Versions: ALL
Stack Prior: ... s_i, ..., s_1, s_0
Stack After: ... s_i, ..., s_1
Pops off the top of the stack and call s_i.append(s_0)
.
s_i
remains on the stack so it can be reused.
Used to implement list comprehensions.
Example Sources:
[point for point in point_list]
MAP_ADD(i)
Python Versions: ALL
Stack Prior: ... s_i, ..., s_1, s_0, value
Stack After: ... s_i, ..., s_1
Pops off the top two items on the stack and call s_i.__setitem__(s_0, value)
.
s_i
remains on the stack so it can be reused.
Used to implement dict comprehensions.
Example Sources:
{key: value for key, value in item_list}
RETURN_VALUE
Python Versions: ALL
Stack Prior: ... return_value
Stack After: N/A
Returns the item at the top of the stack.
Example Sources:
def function():
pass # A `return None` is placed at the end of the function
return # This is actually `return None` in disguise
return value
RETURN_GENERATOR
Python Versions: >= 3.11
Stack Prior: ...
Stack After: ...
Creates a new generator from the current frame. Used to implement generators.
Generators basically act as two separate functions:
-
One outer function that just set locals and return a generator object that wraps the inner function.
-
One inner function that yield values.
In this way, it is similar to returning a new anonymous class in a Java function, where we need to pass the function locals to the anonymous class.
However, unlike Java, the outer function and the inner function share the same bytecode. So a generator will start with the RETURN_GENERATOR
opcode (which returns the generator object), followed by the bytecode for the generator.
JPyInterpreter treats this opcode as a no-op, since we use separate classes for the outer function and the inner functions.
Example Sources:
def function():
# A RETURN_GENERATOR will be placed at the start
# of the generator
yield
GEN_START(kind)
Python Versions: == 3.10
Stack Prior: ... top
Stack After: ...
Pops off the top of stack.
This is the first opcode for generators in 3.10.
The stack is not empty, since calling a generator is the same as sending the generator None
, which push None
to the top of the stack.
The kind
argument indicates what kind of generator it is:
-
0 is a normal generator.
-
1 is a coroutine.
-
2 is an async generator.
Example Sources:
def function():
# A GEN_START(0) will be placed at the start
# of the generator
yield
SEND(target_delta)
Python Versions: >= 3.11
Stack Prior: ... subgenerator, sent_value
Stack if subgenerator is not exhausted: ... subgenerator, yielded_value
Stack if subgenerator is exhausted: ... subgenerator
Pops off the top of stack, and sends it to the sub-generator of this generator.
If the sub-generator is not exhausted, the yielded value is pushed to the top of the stack.
Otherwise, jump forward by target_delta
, leaving subgenerator
on the stack.
Used to implement yield from
and await
statements.
Example Sources:
# yield from subgenerator is implemented as the following loop
# (with None initially at the top of the stack)
#
# SEND (sends the top of stack to the subgenerator)
# YIELD_VALUE (returns the yielded value to the caller)
# JUMP_BACKWARDS (to SEND)
#
# Before the loop, GET_YIELD_FROM_ITER is used to get the generator
# that will act as the subgenerator
yield from subgenerator
# await is a yield from in disguise,
# and is implemented by the same loop
#
# Before the loop, GET_AWAITABLE is used to get the awaitable
# that will act as the subgenerator
await awaitable
YIELD_VALUE
Python Versions: ALL
Stack Prior: ... yielded_value
Stack After: ... sent_value
Pops off the top of the stack and yields it to the calling function.
The function is then paused, and is resumed by either a .send(sent_value)
or .throw(raised_exception)
call.
If .send(sent_value)
is used, that value is pushed to the top of the stack.
Otherwise, the exception passed to .throw(raised_exception)
is raised at this opcode position.
Calling next
on a generator acts as generator.send(None)
.
Example Sources:
# the sent value is ignored here
yield 10
# the sent value is stored in sent_value here
sent_value = yield 10
YIELD_FROM
Python Versions: >= 3.3, <= 3.10
Stack Prior: ... subgenerator, sent_value
Stack After: ... final_yielded_value
Pops off the top of the stack, and set this generator subgenerator to the element immediately below it. Control is then passed to the subgenerator. If the subgenerator is not a generator but an iterable, it is treated as the following pseudo-generator:
def iterable_generator(iterable):
for item in iterable:
sent_value = yield item
if sent_value is not None:
raise AttributeError(f"'{type(iter(iterable))}' object has no attribute 'send'")
When the subgenerator is not exhausted, send
and throw
calls are proxied to it.
When the subgenerator is exhausted, its final yielded value is pushed to the top of the stack and this generator resumes.
In Python 3.11 and above, the YIELD_FROM opcode is replaced by a SEND + YIELD_VALUE while loop, as documented in the SEND(target_delta).
Example Sources:
yield from subgenerator
SETUP_ANNOTATIONS
Python Versions: >= 3.6
Stack Prior: ...
Stack After: ...
Checks if the variable __annotations__
is defined.
If __annotations__
is not defined, it is initialized to an empty dict
.
Otherwise, __annotations__
keep it current value.
It is emitted for a class and module bodies which contain static variable annotations.
This opcode is not emitted for function bodies.
Example Sources:
class MyClass:
# SETUP_ANNOTATIONS is emitted here,
# for a later __annotations__['x'] = int
# call
x: int
IMPORT_STAR
Python Versions: ALL
Stack Prior: ... modulevalue
Stack After: ...
Loads all symbols not starting with '_' directly from the module located at the top of the stack to the local namespace.
The module is popped after loading all names, whose values are copied to the module’s local variables.
This opcode implements from module import *
.
It is illegal to use from module import *
in a function.
Example Sources:
from module import *
POP_BLOCK
Python Versions: <= 3.10
Stack Prior: ...
Stack After: ...
Pops the block that store exception handler information off the stack. Since the JVM store the exception table separate from the bytecode, this is a no-op for JPyInterpreter. In CPython 3.11, the CPython interpreter also stores the exception table separate from the bytecode, removing the need for this opcode.
Example Sources:
try:
something()
# A POP_BLOCK opcode is placed
# at the end of a try block.
except:
pass
POP_EXCEPT
Python Versions: ALL
Python 3.10 and below
Stack Prior: ... traceback, exception, exception_type
Stack After: ...
Python 3.11 and above
Stack Prior: ... exception
Stack After: ...
Pop off exception data off the stack, which is used to restore the exception state. Before Python 3.11, this pop off three values (traceback, exception and type(exception)). After Python 3.11, this pop off one value (exception). This is placed at the beginning of every except block
Example Sources:
try:
something()
except:
# A POP_EXCEPT opcode is placed
# at the beginning of an except block.
pass
PUSH_EXC_INFO
Python Versions: >= 3.11
Stack Prior: ... top
Stack After: ... exception, top
Inserts the currently active exception behind the item currently at the top of stack. Used to allow the current exception to be stored if an except block uses it.
Example Sources:
try:
pass
# A PUSH_EXC_INFO is emitted at the start of the
# try block exception handler, which goes through
# a series of conditional jumps to determine which
# except block to enter.
# The except block then decide if they should store
# the current exception, or pop it off the stack.
except ValueError as e:
pass
except Exception:
pass
CHECK_EXC_MATCH
Python Versions: >= 3.11
Stack Prior: ... exception, exception_type
Stack After: ... exception, test_result
Test if exception
is an instance of exception_type
.
If so, it pushes True
to the top of stack; otherwise, it pushes False
.
exception_type
is popped off the stack; exception
remains on the stack.
Used to implement except
blocks that catch particular types of exceptions.
Example Sources:
try:
pass
except ValueError: # CHECK_EXC_MATCH is used here with
# exception and ValueError
# on the stack.
pass
RERAISE(set_f_lasti)
Python Versions: >= 3.9
If set_f_lasti
is not set
Stack Prior: ... exception_or_type
Stack After: N/A
If set_f_lasti
is set
Stack Prior: ... index, exception_or_type
Stack After: N/A
The item at the top of the stack is either an exception or type.
If it is an exception, throw it.
If it is a type, construct and throw a new instance of that type.
Used to implement a bare raise
in an except block.
Note: CPython uses the index
below the exception/type to set the last index if the bytecode argument not 0.
JPyInterpreter can ignore the argument, since the JVM keep track of frames for us.
Example Sources:
try:
pass
except:
raise # this emits RERAISE
WITH_EXCEPT_START
Python Versions: >= 3.9
Before 3.11
Stack Prior: ... exit_function, instruction, stack_size, label, traceback, exception, exception_type
Stack After: N/A
After 3.11
Stack Prior: ... exit_function, traceback, exception, exception_type
Stack After: N/A
Calls exit_function
with arguments exception_type, exception, traceback
, and push the returned value to the top of the stack.
The returned value should be a boolean.
If the returned value is Truthy, the context manager handled the exception and execution continue.
If the returned value is Falsy, the exception is propagated.
If no exception occurred, exception_type, exception, traceback are all None.
Example Sources:
with context:
pass
LOAD_ASSERTION_ERROR
Python Versions: >= 3.9
Stack Prior: ...
Stack After: ... AssertionError
Pushes the type AssertionError
onto the stack.
Used in assert
statements.
Example Sources:
assert False
LOAD_BUILD_CLASS
Python Versions: ALL
Stack Prior: ...
Stack After: ... __build_class__
Pushes the function builtins.__build_class__
onto the stack.
Used to construct classes.
The function signature for __build_class__
is:
def __build_class__(class_body: function,
class_name: str,
*bases: List[Type],
metaclass: Type,
**metaclass_parameters: Dict[str, Any]) \
-> Type
Example Sources:
class C:
pass
# this translates roughly to:
# __build_class__(<func>, 'C')
class C(A, B):
pass
# this translates roughly to:
# __build_class__(<func>, 'C', A, B)
class C(A, metaclass=M, metaclass_arg=1):
pass
# this translates roughly to:
# __build_class__(<func>, 'C', A, metaclass=M, metaclass_arg=1)
SETUP_WITH(except_delta)
Python Versions: <= 3.10
Stack Prior: ... context_manager
Stack After: ... exit_function, start_function_result
Stack On Exception: ... instruction, stack_size, label, traceback, exception, exception_type
Pops off the top of the stack, and push its __exit__
function and the result of calling its __enter__
function to the top of the stack.
except_delta
points to the exception handler for the which block.
If an exception occurs, the follow items will be pushed to the stack:
-
The bytecode instruction index that was executing when the exception happened.
-
The size of the stack before the with block.
-
The exception handler label.
-
The traceback for the exception.
-
The actual exception.
-
The type of the exception.
Example Sources:
with context_manager:
pass
STORE_NAME(namei)
Python Versions: ALL
Stack Prior: ... value
Stack After: ...
Sets either the global or local variable with the name co_names[namei]
to the item currently at the top of stack.
The top of stack is then popped.
This opcode is only emitted for module bodies and classes.
Example Sources:
class C:
x = 10 # this emits a STORE_NAME('x') opcode
# with 10 on the top of the stack
DELETE_NAME(namei)
Python Versions: ALL
Stack Prior: ...
Stack After: ...
Deletes either the global or local variable with the name co_names[namei]
.
This opcode is only emitted for module bodies and classes.
Example Sources:
class C:
x = 10
del x # this emits a DELETE_NAME('x') opcode
UNPACK_SEQUENCE(count)
Python Versions: ALL
Stack Prior: ... iterable
Stack After: ... item_{count - 1}, ..., item_1, item_0
Top of stack is an iterable.
In reverse order, push its items to the stack (making the new item at the top of stack the first item in the iterable).
The iterable is then popped off the stack.
If the iterable does not have exactly count
items, a ValueError
is raised.
The items are received using an iterator loop:
iterator = iter(iterable)
items = []
while True:
try:
items.append(next(iterator))
except StopIteration:
break
Example Sources:
# This is compiled as:
# UNPACK_SEQUENCE(2)
# STORE_FAST('x') (1)
# STORE_FAST('y') (2)
x, y = (1, 2)
UNPACK_EX((high byte) end_index | (low byte) start_index)
Python Versions: ALL
Stack Prior: ... iterable
Stack After: ... after_0, after_1, ..., after_{end_index - 1}, extra, before_{start_index - 1}, ..., before_1, before_0
Top of stack is an iterable.
Collect its item into a list.
Push each item in the slice [-end_index:] to the stack in forward order (empty if end_index == 0).
Push a list containing the slice [start_index:end_index] to the stack as a single item.
Push each item in the slice [:start_index] in reverse order (empty if start_index == 0).
The iterable is then popped off the stack.
If the iterable does not have at least start_index + end_index
items, a ValueError
is raised.
The items are received using an iterator loop:
iterator = iter(iterable)
items = []
while True:
try:
items.append(next(iterator))
except StopIteration:
break
before = items[:start_index]
after = items[-end_index:]
extra = items[start_index:end_index]
Example Sources:
# This is compiled as:
# UNPACK_EX((2 << 8) | 1) (= 513)
# STORE_FAST('b_0') (1)
# STORE_FAST('extra') ([2, 3])
# STORE_FAST('a_0') (4)
# STORE_FAST('a_1') (5)
b_0, *extra, a_0, a_1 = (1, 2, 3, 4, 5)
STORE_ATTR(namei)
Python Versions: ALL
Stack Prior: ... value, object
Stack After: ...
Sets the attribute with the name co_names[namei]
on the object at the top of the stack to the value immediately below it.
Both the object and the value are popped.
The value is set by calling the __setattr__(self, name: str, value: Any)
method on the type of object with object
, co_names[namei]
and value
as the arguments.
Example Sources:
# equivalent to
# type(my_object).__setattr__(my_object, 'attribute', value)
my_object.attribute = value
DELETE_ATTR(namei)
Python Versions: ALL
Stack Prior: ... object
Stack After: ...
Deletes the attribute with the name co_names[namei]
on the object at the top of the stack.
The object is then popped off the stack.
The value is deleted by calling the __delattr__(self, name: str)
method on the type of object with object
and co_names[namei]
as the arguments.
Example Sources:
# equivalent to
# type(my_object).__delattr__(my_object, 'attribute')
del my_object.attribute
STORE_GLOBAL(namei)
Python Versions: ALL
Stack Prior: ... value
Stack After: ...
Sets the global variable with the name co_names[namei]
to the value currently at the top of the stack.
The value is then popped from the stack.
Each module has a unique global namespace used to store global variables.
Functions in the same module use the same namespace.
Example Sources:
# required, otherwise it be a STORE_FAST
global variable
variable = 5
DELETE_GLOBAL(namei)
Python Versions: ALL
Stack Prior: ...
Stack After: ...
Deletes the global variable with the name co_names[namei]
.
Each module has a unique global namespace used to store global variables.
Functions in the same module use the same namespace.
Example Sources:
# required, otherwise it be a DELETE_FAST
global variable
del variable
LOAD_CONST(consti)
Python Versions: ALL
Stack Prior: ...
Stack After: ... constant
Loads the constant co_constants[consti]
.
Example Sources:
'A string constant'
1 # an int constant
(1, 2, 3) # a tuple constant
LOAD_NAME(namei)
Python Versions: ALL
Stack Prior: ...
Stack After: ... value
Pushes either the global or local variable with the name co_names[namei]
to the top of stack.
This opcode is only emitted for module bodies and classes.
Example Sources:
class C:
x # this emits a LOAD_NAME('x') opcode
BUILD_TUPLE(count)
Python Versions: ALL
Stack Prior: ... item_0, item_1, ..., item_{count - 1}
Stack After: ... item_tuple
Construct a tuple from the top count
items on the stack.
The items are placed in the reverse order that they are encountered from the top of stack (making the top of stack the last element).
The top count
items are then popped from the stack, and the newly constructed tuple is pushed to the stack.
Example Sources:
x = 1
y = 2
z = (x, y) # This creates a BUILD_TUPLE opcode:
# LOAD_FAST('x')
# LOAD_FAST('y')
# BUILD_TUPLE(2)
BUILD_LIST(count)
Python Versions: ALL
Stack Prior: ... item_0, item_1, ..., item_{count - 1}
Stack After: ... item_tuple
Construct a list from the top count
items on the stack.
The items are placed in the reverse order that they are encountered from the top of stack (making the top of stack the last element).
The top count
items are then popped from the stack, and the newly constructed list is pushed to the stack.
Example Sources:
x = 1
y = 2
z = [x, y] # This creates a BUILD_LIST opcode:
# LOAD_FAST('x')
# LOAD_FAST('y')
# BUILD_LIST(2)
BUILD_SET(count)
Python Versions: ALL
Stack Prior: ... item_0, item_1, ..., item_{count - 1}
Stack After: ... item_tuple
Construct a set from the top count
items on the stack.
The items are placed in the reverse order that they are encountered from the top of stack (making the top of stack the last element).
The top count
items are then popped from the stack, and the newly constructed set is pushed to the stack.
The items lower in the stack are prioritized over items higher in stack (i.e. if item_0 == item_1
, then item_0
be added to the set, not item_1
).
Example Sources:
x = 1
y = 2
z = {x, y} # This creates a BUILD_SET opcode:
# LOAD_FAST('x')
# LOAD_FAST('y')
# BUILD_SET(2)
BUILD_MAP(count)
Python Versions: ALL
Stack Prior: ... , key_0, value_0, key_1, value_1, ..., key_{count - 1}, value_{count - 1}
Stack After: ... item_map
Construct a dict from the top 2 * count
items on the stack.
The items are put in the reverse order that they are encountered from the top of stack (making the top two items on the stack the last key-value pair).
The top 2 * count
items are then popped from the stack, and the newly constructed dict is pushed to the stack.
The items higher in the stack are prioritized over items higher in stack (i.e. if key_0 == key_1
, then key_1 = value_1
be put in the dict, not key_0 = value_0
).
Example Sources:
key_0 = 1
value_0 = 2
key_1 = 3
value_1 = 4
z = {
key_0: value_0,
key_1: value_1
}
# This creates a BUILD_MAP opcode:
# LOAD_FAST('key_0')
# LOAD_FAST('value_0')
# LOAD_FAST('key_1')
# LOAD_FAST('value_1')
# BUILD_MAP(2)
BUILD_CONST_KEY_MAP(count)
Python Versions: >= 3.6
Stack Prior: ... , value_0, value_1, ..., value_{count - 1}, key_tuple
Stack After: ... item_map
Construct a dict from the top count + 1
items on the stack.
The item at the top of the stack is a tuple of constants of length count, which stores the dict’s keys.
There are count
items below it representing each key’s corresponding value.
The key-value pairs are put in the reverse order that they are encountered from the top of stack (making key_tuple[-1], value_{count - 1}
the last key-value pair to be added to the dict).
The top count + 1
items are then popped from the stack, and the newly constructed dict is pushed to the stack.
The items higher in the stack are prioritized over items higher in stack (i.e. if tuple[0] == tuple[1]
, then tuple[1] = value_1
be put in the dict, not tuple[0] = value_0
).
Example Sources:
value_0 = 1
value_1 = 2
z = {
'a': value_0,
'b': value_1
}
# This creates a BUILD_CONST_KEY_MAP opcode:
# LOAD_FAST('value_0')
# LOAD_FAST('value_1')
# LOAD_CONSTANT (('a', 'b'))
# BUILD_CONST_KEY_MAP(2)
BUILD_STRING(count)
Python Versions: >= 3.6
Stack Prior: ... string_0, string_1, ..., string_{count - 1}
Stack After: ... result
Concatenate the top count
items on the stack into a single string.
Each of the top count
items on the stack must be a string.
The strings are concatenated from the lowest item up
(i.e. string_0 + string_1 + … + string_{count - 1}
).
Used to implement f-strings.
Example Sources:
a = 'before'
b = 'after'
f'{a} {b}'
# Bytecode:
# LOAD_FAST(a)
# FORMAT_VALUE(str)
# LOAD_CONST(' ')
# LOAD_FAST(b)
# FORMAT_VALUE(str)
# BUILD_STRING(3)
LIST_TO_TUPLE
Python Versions: >= 3.9
Stack Prior: ... list
Stack After: ... tuple
The top of the stack is a list. Pop off the top of the stack, and replace it with a tuple with the same values in the same order. Used to unpack a list into a tuple.
Example Sources:
(*[1, 2, 3],)
#
# BUILD_LIST(0) # Construct an empty list
# to store the final result
#
# BUILD_LIST(0) # Construct an empty list
# # to store the immediate [1, 2, 3]
# # since lists cannot be constants
#
# LOAD_CONST((1, 2, 3)) # Load the constant (1, 2, 3)
#
# LIST_EXTEND(1) # Convert the constant (1, 2, 3)
# to [1, 2, 3]
#
# LIST_EXTEND(1) # Unpacks [1, 2, 3] into the
# # final result
#
# LIST_TO_TUPLE # Convert the final result into a tuple
LIST_EXTEND(i)
Python Versions: >= 3.9
Stack Prior: ... s_i, ..., s_1, s_0
Stack After: ... s_i, ..., s_1
The top of the stack is an iterable and s_i
is a list.
Pop off the top of the stack, and add its contents to s_i
.
s_i
remains on the stack so it can be reused.
Used to implement list unpacking.
Example Sources:
See LIST_TO_TUPLE.
SET_UPDATE(i)
Python Versions: >= 3.9
Stack Prior: ... s_i, ..., s_1, s_0
Stack After: ... s_i, ..., s_1
The top of the stack is an iterable and s_i
is a set.
Pop off the top of the stack, and add its contents to s_i
.
The added content will not replace items already in the set
.
s_i
remains on the stack so it can be reused.
Used to implement set unpacking.
Example Sources:
{*(1, 2, 3)}
# BUILD_SET(0) # Create an empty set to
# # store the result
#
# LOAD_CONST((1, 2, 3)) # Load the constant (1, 2, 3)
#
# SET_UPDATE(1) # Unpacks (1, 2, 3) into the result
DICT_UPDATE(i)
Python Versions: >= 3.9
Stack Prior: ... s_i, ..., s_1, s_0
Stack After: ... s_i, ..., s_1
The top of the stack is an mapping and s_i
is a dict.
Pop off the top of the stack, and add its contents to s_i
.
The added content will replace the value assigned to keys already in the dict
.
s_i
remains on the stack so it can be reused.
Used to implement dict unpacking.
Example Sources:
{
'a': 1,
**b
}
# LOAD_CONSTANT('a')
# LOAD_CONSTANT(1)
#
# BUILD_MAP(1) # Create a dict with items
# # ('a', 1)
#
# LOAD_FAST(n) # Load b
#
# DICT_UPDATE(1) # Unpacks b into the result dict
DICT_MERGE(i)
Python Versions: >= 3.9
Stack Prior: ... s_i, ..., s_1, s_0
Stack After: ... s_i, ..., s_1
The top of the stack is an mapping and s_i
is a dict.
Pop off the top of the stack, and add its contents to s_i
.
If the mapping at the top of the stack share any keys with s_i
, a TypeError
is raised.
s_i
remains on the stack so it can be reused.
Used to implement dict unpacking in function calls.
Example Sources:
my_function(a=1, **b)
# LOAD_CONSTANT('a')
# LOAD_CONSTANT(1)
#
# BUILD_MAP(1) # Create a dict with items
# # ('a', 1)
#
# LOAD_FAST(n) # Load b
#
# DICT_MERGE(1) # Unpacks b into the result dict,
# raise an exception if b has a value
# for the key 'a'
LOAD_ATTR(namei)
Python Versions: ALL
Stack Prior: ... object
Stack After: ... attribute
Loads the attribute with the name co_names[namei]
on the object at the top of the stack; the top of stack is popped.
The value is retrieved by calling the __getattribute__(self, name: str)
method on the type of object with object
and co_names[namei]
as the arguments.
Example Sources:
# equivalent to
# type(my_object).__getattribute__(my_object, 'attribute')
my_object.attribute
COMPARE_OP(op)
Python Versions: ALL
Stack Prior: ... left_comparable, right_comparable
Stack After: ... comparison_result
A BINARY_OP(op) that correspond to the comparison operation indicated by the op
argument.
The comparison operation that op
refers to is cmp_op[op]
(where cmp_op
is defined here). In particular:
-
0 corresponds to
__lt__
(normal) and__gt__
(reflected) -
1 corresponds to
__le__
(normal) and__ge__
(reflected) -
2 corresponds to
__eq__
(normal) and__eq__
(reflected) -
3 corresponds to
__ne__
(normal) and__ne__
(reflected) -
4 corresponds to
__gt__
(normal) and__lt__
(reflected) -
5 corresponds to
__ge__
(normal) and__le__
(reflected)
The top two items on the top of the stack are popped, the comparison operation is performed, and the result (not necessary a boolean) is pushed to the top of the stack.
Example Sources:
left_comparable < right_comparable
left_comparable == right_comparable
IS_OP(invert)
Python Versions: ALL
Stack Prior: ... left, right
Stack After: ... is_same
Pop off the top two items on the stack.
Push True
if the two items refer to the same reference, False
otherwise.
If invert == 1
, then the result is negated.
Example Sources:
left = []
right = []
left is right # False
left = []
right = left
left is right # True
left is not right
CONTAINS_OP(invert)
Python Versions: ALL
Stack Prior: ... query, container
Stack After: ... is_contained
Pop the two top items off the stack.
The top item is the container
, and the item immediately below it is the query
.
If container
has a __contain__(self, object)
method, it is called, and its result is converted to a boolean value (i.e. None
is converted to True
).
Otherwise, an iterator is obtained by calling the __iter__
method on container
.
If the iterator returns an object equal to query
, True
is pushed to the stack.
If the iterator get exhausted before that, False
is pushed to the stack.
If the iterator is infinite and does not contain query
, an infinite loop occurs.
If invert == 1
, then the result is negated.
Example Sources:
1 in (1, 2, 3)
1 not in (1, 2, 3)
IMPORT_NAME(namei)
Python Versions: ALL
Stack Prior: ... level, from_list
Stack After: ... module
Calls the _import_ builtin function with the arguments co_names[namei]
, globals()
, locals()
, from_list
and level
.
The top two elements of the stack are popped, and the imported module is pushed.
from_list
can either be None
or a list of strings containing names to import from the module.
level
indicates if the import is absolute or relative.
If level
is 0
, then it is an absolute import (the default).
Otherwise, level
indicates how many parents directories need to be navigated to perform the relative import (for instance, 1
is same directory as the current module, 2
is parent directory of the current module, 3
is the parent of the parent directory).
The namespace is not modified; that is done by a subsequent [STORE_FAST[namei]] instruction(s).
Example Sources:
import module
from module import a, b, c
IMPORT_FROM(namei)
Python Versions: ALL
Stack Prior: ... module
Stack After: ... module, attribute
Loads the attribute with the name co_names[namei]
from the module that is on the top of the stack.
The top of stack is not popped, and the loaded attribute is pushed to the top of the stack.
The namespace is not modified; that is done by a subsequent [STORE_FAST[namei]] instruction(s).
Example Sources:
from module import a, b, c
JUMP_FORWARD(target_delta)
Python Versions: ALL
Stack Prior: ...
Stack After: ...
Performs a forced relative jump forward by target_delta
addresses (see Instruction Addressing for details).
Used to implement skipping unentered blocks in if…elif…else
blocks and skipping exception handlers in try…except…finally
blocks.
Example Sources:
if cond:
x = 1
# a JUMP_FORWARD is put here
# to skip the else
else:
x = 2
return x * 2
JUMP_BACKWARD(target_delta)
Python Versions: >= 3.11
Stack Prior: ...
Stack After: ...
Performs a forced relative jump backwards by target_delta
addresses (see Instruction Addressing for details).
CPython checks for interrupts during this instruction.
Used to implement for
and while True
loops.
Example Sources:
for item in iterable:
pass
# a JUMP_BACKWARD is put here
# to jump back to the start of
# the FOR_ITER instruction
# (which ends the loop if the
# iterator is exhausted)
while True:
pass
# a JUMP_BACKWARD is put here
# to jump back to the start of
# the while block
JUMP_BACKWARD_NO_INTERRUPT(target_delta)
Python Versions: >= 3.11
Stack Prior: ...
Stack After: ...
Performs a forced relative jump backwards by target_delta
addresses (see Instruction Addressing for details).
CPython does not checks for interrupts during this instruction.
Used to implement yield from
statements.
Example Sources:
yield from generator
# A JUMP_BACKWARD_NO_INTERRUPT is used to
# jump back to the SEND opcode (which will
# break out of the loop when the generator
# is exhausted).
POP_JUMP_IF_TRUE(target)
Python Versions: <= 3.10
Stack Prior: ... condition
Stack After: ...
If condition
is truthy, jump to target
, which represents an absolute address (see Instruction Addressing for details).
Used to implement going to the next block when there a negated condition in an if…elif…else
chain or start of a while
loop.
Example Sources:
if not cond: # A POP_JUMP_IF_TRUE
# is put here to jump
# to else if cond is truthy
print('case 1')
else:
print('case 2')
while not cond: # A POP_JUMP_IF_TRUE
# is put here to skip
# the loop if cond is
# truthy
pass
POP_JUMP_FORWARD_IF_TRUE(target_delta)
Python Versions: >= 3.11
Stack Prior: ... condition
Stack After: ...
If condition
is truthy, jump forward by target_delta
, which represents a relative addresses (see Instruction Addressing for details).
Used to implement going to the next block when there a negated condition in an if…elif…else
chain.
Example Sources:
if not cond: # A POP_JUMP_FORWARD_IF_TRUE
# is put here to jump to else
# if cond is truthy
print('case 1')
else:
print('case 2')
while not cond: # A POP_JUMP_FORWARD_IF_TRUE
# is put here to skip
# the loop if cond is
# truthy
pass
POP_JUMP_BACKWARD_IF_TRUE(target_delta)
Python Versions: >= 3.11
Stack Prior: ... condition
Stack After: ...
If condition
is truthy, jump backward by target_delta
, which represents a relative addresses (see Instruction Addressing for details).
Used to implement looping in a while
loop.
Example Sources:
while cond:
pass
# A POP_JUMP_BACKWARD_IF_TRUE is put here
# with a test on cond
POP_JUMP_IF_FALSE(target)
Python Versions: <= 3.10
Stack Prior: ... condition
Stack After: ...
If condition
is falsely, jump to target
, which represents an absolute addresses (see Instruction Addressing for details).
Used to implement going to the next block when there a positive condition in an if…elif…else
chain.
Example Sources:
if cond: # A POP_JUMP_IF_FALSE is
# put here to jump to else
# else if cond is falsely
print('case 1')
else:
print('case 2')
while cond: # A POP_JUMP_IF_FALSE
# is put here to skip
# the loop if cond is
# falsely
pass
POP_JUMP_FORWARD_IF_FALSE(target_delta)
Python Versions: >= 3.11
Stack Prior: ... condition
Stack After: ...
If condition
is falsely, jump forward by target_delta
, which represents a relative addresses (see Instruction Addressing for details).
Used to implement going to the next block when there a positive condition in an if…elif…else
chain.
Example Sources:
if cond: # A POP_JUMP_IF_FALSE is
# put here to jump to else
# else if cond is falsely
print('case 1')
else:
print('case 2')
while cond: # A POP_JUMP_IF_FALSE
# is put here to skip
# the loop if cond is
# falsely
pass
POP_JUMP_BACKWARD_IF_FALSE(target_delta)
Python Versions: >= 3.11
Stack Prior: ... condition
Stack After: ...
If condition
is falsely, jump backward by target_delta
, which represents a relative addresses (see Instruction Addressing for details).
Used to implement looping in a negated while
loop.
Example Sources:
while not cond:
pass
# A POP_JUMP_BACKWARD_IF_FALSE is put here
# with a test on cond
POP_JUMP_FORWARD_IF_NOT_NONE(target_delta)
Python Versions: >= 3.11
Stack Prior: ... item
Stack After: ...
If item
is not None, jump forward by target_delta
, which represents a relative addresses (see Instruction Addressing for details).
Used to implement going to the next block when there a is None
condition in an if…elif…else
chain.
Example Sources:
if item is None: # POP_JUMP_FORWARD_IF_NOT_NONE
# is put here to jump to else
# if item is not None
print('case 1')
else:
print('case 2')
# POP_JUMP_FORWARD_IF_NOT_NONE
# is put here to skip
# the loop if cond is
# truthy
while item is None:
pass
POP_JUMP_BACKWARD_IF_NOT_NONE(target_delta)
Python Versions: >= 3.11
Stack Prior: ... item
Stack After: ...
If condition
is falsely, jump backward by target_delta
, which represents a relative addresses (see Instruction Addressing for details).
Used to implement looping in a while item is not None
loop.
Example Sources:
while item is not None:
pass
# A POP_JUMP_BACKWARD_IF_NOT_NONE
# is put here with a test on item
POP_JUMP_FORWARD_IF_NONE(target_delta)
Python Versions: >= 3.11
Stack Prior: ... item
Stack After: ...
If item
is None, jump forward by target_delta
, which represents a relative addresses (see Instruction Addressing for details).
Used to implement going to the next block when there a is not None
condition in an if…elif…else
chain.
Example Sources:
if item is not None: # POP_JUMP_FORWARD_IF_NONE
# is put here to jump to else
# if item is not None
print('case 1')
else:
print('case 2')
# POP_JUMP_FORWARD_IF_NONE
# is put here to skip
# the loop if cond is
# truthy
while item is not None:
pass
POP_JUMP_BACKWARD_IF_NONE(target_delta)
Python Versions: >= 3.11
Stack Prior: ... item
Stack After: ...
If condition
is falsely, jump backward by target_delta
, which represents a relative addresses (see Instruction Addressing for details).
Used to implement looping in a while item is None
loop.
Example Sources:
while item is None:
pass
# A POP_JUMP_BACKWARD_IF_NONE
# is put here with a test on item
JUMP_IF_NOT_EXC_MATCH(target)
Python Versions: >= 3.9, <= 3.10
Stack Prior: ... exception_type, test_type
Stack After: ...
If exception_type
is not a subclass of test_type
, jump to target
, which represents an absolute address (see Instruction Addressing for details).
Used to determine which except block to enter.
Example Sources:
try:
pass
except ValueError as e:
# JUMP_IF_NOT_EXC_MATCH is used here
# with type(e), ValueError on the stack
pass
JUMP_IF_TRUE_OR_POP(target)
Python Versions: ALL
Stack Prior: ... item
Stack After if truthy: ... item
Stack After if falsely: ...
If item
is truthy, jump to target
and keep item
on the stack.
Otherwise, pop item
from the stack.
In Python 3.10 and below, target is an absolute address. In Python 3.11 and above, target is a relative address (see Instruction Addressing for details).
|
Used to implement or
.
Example Sources:
# if a is truthy, b is not evaluated at all
# since JUMP_IF_TRUE_OR_POP jumps past it
# as such, after this statement,
# the stack is either:
# a, if a is truthy
# b, if a is falsely
a or b
JUMP_IF_FALSE_OR_POP(target)
Python Versions: ALL
Stack Prior: ... item
Stack After if truthy: ... item
Stack After if falsely: ...
If item
is falsely, jump to target
and keep item
on the stack.
Otherwise, pop item
from the stack.
In Python 3.10 and below, target is an absolute address. In Python 3.11 and above, target is a relative address (see Instruction Addressing for details).
|
Used to implement and
.
Example Sources:
# if a is falsely, b is not evaluated at all
# since JUMP_IF_FALSE_OR_POP jumps past it
# as such, after this statement,
# the stack is either:
# a, if a is falsely
# b, if a is truthy
a and b
JUMP_ABSOLUTE(target)
Python Versions: ALL
Stack Prior: ...
Stack After: ...
Jump to target
, which represents an absolute address (see Instruction Addressing for details).
Used to implement looping in for
and while
loops.
Example Sources:
for item in iterable:
pass
# a JUMP_ABSOLUTE to FOR_ITER is placed here
while True:
pass
# a JUMP_ABSOLUTE to place here
FOR_ITER(target_delta)
Python Versions: ALL
Stack Prior: ... iterator
Stack After if not exhausted: ... iterator item
Stack After if exhausted: ...
If the iterator at the top of the stack is exhausted, jump forward by target_delta
, which represents a relative addresses (see Instruction Addressing for details) and pop iterator off the stack.
Otherwise, keep iterator on the stack, and push its next item (obtained by calling iterator.__next__()
) to the top of the stack.
In Python code, it looks like this:
while True:
try:
item = next(iterator)
except StopIteration:
break
# ... The for block
Used to implement for
loops.
Example Sources:
for item in iterable:
pass
LOAD_GLOBAL(namei)
Python Versions: ALL
Stack Prior: ...
Stack After (1): ... global
Stack After (2): ... NULL, global
Prior 3.11:
Push the global variable with the name co_names[namei]
to the top of the stack.
After 3.11:
Push the global variable with the name co_names[namei >> 1]
to the top of the stack. If namei & 1
is set, push NULL
before the global variable.
Used to read global variables.
Example Sources:
global variable
# NULL will not be pushed here after 3.11
variable
global function
# NULL will be pushed here after 3.11
function(1,2,3)
SETUP_FINALLY(target_delta)
Python Versions: <= 3.10
Stack Prior: ...
Stack After: ...
Stack On Exception: ... instruction, stack_size, label, traceback, exception, exception_type
Creates a try block whose handler is at the given target_delta
relative address (see Instruction Addressing for details).
The try block starts at this instruction, and ends at the start of its handler.
When an exception occurs, the stack prior to the SETUP_FINALLY
is restored, and the following is pushed to the stack:
-
The instruction index that created the block (i.e. this
SETUP_FINALLY
address) -
The stack depth at the time the block was created
-
The exception handler start address
-
The traceback for the exception
-
The exception itself
-
The type of the exception
Used to implement try blocks.
Example Sources:
try:
# A SETUP_FINALLY is emitted here, which
# points to the except block
pass
except:
pass
LOAD_FAST(var_num)
Python Versions: ALL
Stack Prior: ...
Stack After: ... local
Push the local variable with the name co_varnames[var_num]
to the top of the stack.
Used to read local variables.
Example Sources:
variable
STORE_FAST(var_num)
Python Versions: ALL
Stack Prior: ... value
Stack After: ...
Pops off the top item on the stack and sets the local variable with the name co_varnames[var_num]
to it.
Used to set local variables.
Example Sources:
variable = value
DELETE_FAST(var_num)
Python Versions: ALL
Stack Prior: ...
Stack After: ...
Deletes the local variable with the name co_varnames[var_num]
.
Used to implement del variable
.
Example Sources:
del variable
MAKE_CELL(i)
Python Versions: >= 3.11
Stack Prior: ...
Stack After: ...
Creates a new cell in slot i
. If that slot is not empty then that value is stored into the new cell.
Used to initialize cell variables.
This is a NOP for JPyInterpreter, which initializes cell variables at function definition.
Example Sources:
def outer_function():
# MAKE_CELL will be emitted here for a,
# since it is used in inner_function
a = 10
def inner_function():
nonlocal a
print(a)
def outer_function(a):
# MAKE_CELL will be emitted here for a,
# since it is used in inner_function
def inner_function():
nonlocal a
print(a)
COPY_FREE_VARS(n)
Python Versions: >= 3.11
Stack Prior: ...
Stack After: ...
Copies the n
free variables from the closure into the frame.
Removes the need for special code on the caller’s side when calling closures.
This is a NOP for JPyInterpreter, which initializes free variables at function definition.
Example Sources:
def outer_function():
a = 10
def inner_function():
# COPY_FREE_VARS(1) is emitted here
nonlocal a
print(a)
def outer_function(a):
def inner_function():
# COPY_FREE_VARS(1) is emitted here
nonlocal a
print(a)
LOAD_CLOSURE(i)
Python Versions: ALL
Stack Prior: ...
Stack After: ... cell
Loads the cell (not its value) in slot i
as described by Cell Variable Index.
A cell corresponds to either a shared or free variable.
Used to pass shared variables from an outer function to an inner function (where they be free variables).
Example Sources:
def outer():
x = 10
# LOAD_CLOSURE(x) is generated here
# so x's cell can be put into a tuple
# that is passed to inner's MAKE_FUNCTION
# (allowing inner to access it).
def inner():
nonlocal x
return x
LOAD_DEREF(i)
Python Versions: ALL
Stack Prior: ...
Stack After: ... cell_value
Loads the value contained in the cell at slot i
as described by Cell Variable Index.
A cell corresponds to either a shared or free variable.
Used to read shared and free variables.
Example Sources:
def outer():
x = 10
print(x) # LOAD_DEREF(x) is used here
# since x is used in inner
def inner():
nonlocal x
# ...
def outer():
x = 10
def inner():
nonlocal x
print(x) # LOAD_DEREF(x) is used here
# since x is a free variable
LOAD_CLASSDEREF(i)
Python Versions: ALL
Stack Prior: ...
Stack After: ... cell_value
If locals has a variable corresponding to the name of slot i
, push its value.
Otherwise, push the value contained in the cell at slot i
as described by Cell Variable Index.
A cell corresponds to either a shared or free variable.
Used to read shared and free variables in class bodies.
Example Sources:
def outer():
x = 10
class InnerClass:
my_value = x # LOAD_CLASSDEREF(x) is
# used here since x is a
# free variable in a class
# body.
STORE_DEREF(i)
Python Versions: ALL
Stack Prior: ... cell_value
Stack After: ...
Pop off the top of the stack and sets the value contained in the cell at slot i
as described by Cell Variable Index to the popped value.
A cell corresponds to either a shared or free variable.
Used to set shared and free variables.
Example Sources:
def outer():
x = 10 # STORE_DEREF(x) is used here
# since x is used in inner
print(x)
def inner():
nonlocal x
# ...
def outer():
x = 10
def inner():
nonlocal x
x = 20 # STORE_DEREF(x) is used here
# since x is a free variable
inner()
print(x) # 20
DELETE_DEREF(i)
Python Versions: ALL
Stack Prior: ...
Stack After: ...
Deletes the value contained in the cell at slot i
as described by Cell Variable Index.
The actual cell is NOT deleted, but has no associated
value.
A cell corresponds to either a shared or free variable.
Used to delete shared and free variables.
Example Sources:
def outer():
x = 10
del x # DELETE_DEREF(x) is used here
# since x is used in inner
def inner():
nonlocal x
# ...
def outer():
x = 10
def inner():
nonlocal x
del x # DELETE_DEREF(x) is used here
# since x is a free variable
RAISE_VARARGS(argc)
Python Versions: ALL
Stack Prior (argc = 0): ...
Stack Prior (argc = 1): ... exception
Stack Prior (argc = 2): ... exception cause
Stack After: N/A
Does one of three things depends on argc
:
-
If
argc = 0
, reraise the last raised exception. Used to implement a bareraise
in an except block. -
If
argc = 1
, the top of stack is either an exception or an exception type. If it is an exception instance, raise it; otherwise, create a new instance of the exception type. Used to implementraise Exception
andraise Exception()
-
If
argc = 2
, the top of stack is an exception and the item immediately below it is an exception or an exception type. Ifexception
is an exception instance, set its__cause__
tocause
and raise it. Otherwise, construct a new instance ofexception
, set its__cause__
tocause
and raise it. Used to implementraise Exception from cause
andraise Exception() from cause
.
Example Sources:
try:
# ...
except:
raise # argc = 0
raise Exception # argc = 1
raise Exception() # argc = 1
raise Exception from cause # argc = 2
raise Exception() from cause # argc = 2
KW_NAMES(consti)
Python Versions: >= 3.11
Stack Prior: ...
Stack After: ...
Sets the keyword names for the next CALL(argc) opcode to the tuple of strings stored in co_consts[consti]
.
Used to implement calling a function with keyword arguments
Example Sources:
# Assume co_const[3] = ('a', 'b'),
# then KW_NAMES(3) would be emitted here
my_function(a=1, b=2)
PRECALL(argc)
Python Versions: >= 3.11
Stack Prior: ...
Stack After: ...
A NOP.
CPython uses it to allow the specialization of function calls. argc
is the number of arguments as described in CALL(argc).
Used when calling a function.
Example Sources:
# A PRECALL(3) is put here
my_function(1, 2, a=3)
PUSH_NULL
Python Versions: >= 3.11
Stack Prior: ...
Stack After: ... NULL
Pushes NULL
to the top of the stack.
Used in the call sequence to match the NULL pushed by LOAD_METHOD(namei) for non-method calls.
Example Sources:
# 3
# A PUSH_NULL is used here
my_function(1, 2, a=3)
CALL(argc)
Python Versions: >= 3.11
Stack Prior (1): ... NULL, callable, arg_1, arg_2, ..., arg_{argc}
Stack Prior (2): ... method, object, arg_1, arg_2, ..., arg_{argc}
Stack After: ... return_value
Calls a function from the top argc + 2
items on the stack.
The first argc
items on the stack are the arguments to the function.
For the arguments, the keyword names internal variable length is checked, and the top len(keyword names)
items are keyword arguments, and the bottom argc - len(keyword names)
items are positional arguments.
The two items below the arguments are either:
-
An unbound method object and an object
-
NULL and an arbitrary callable
If it is NULL and an arbitrary callable, the given positional and keyword arguments are used. If it is an unbound method object and an object, object is inserted as the first item in the positional argument list. All the arguments and the two items below the arguments are popped, and the result of the function call is pushed to the top of the stack. The keyword names are reset to an empty list after this call. Used to implement function calls that do not unpack an iterable or mapping.
Example Sources:
# This is a CALL in NULL, CALLABLE form
my_function(1, 2, a=3)
# This is a CALL in METHOD, OBJECT form
my_object.my_function(1, 2, a=3)
CALL_FUNCTION(argc)
Python Versions: <= 3.10
Stack Prior: ... callable, arg_1, arg_2, ..., arg_{argc}
Stack After: ... return_value
Calls a function from the top argc + 1
items on the stack.
The first argc
items on the stack are the positional arguments to the function (there are no keyword arguments).
The item below the arguments is the callable to call.
All the arguments and the item below them are popped, and the result of the function call is pushed to the top of the stack.
Used to implement function calls without keyword arguments.
Example Sources:
# This is CALL_FUNCTION(3)
function(1, 2, 3)
CALL_FUNCTION_KW(argc)
Python Versions: <= 3.10
Stack Prior: ... callable, arg_1, arg_2, ..., arg_{argc}, kw_names
Stack After: ... return_value
Calls a function from the top argc + 2
items on the stack.
The item on the top of the stack is a tuple containing the names of keyword arguments.
The argc
items below that are the arguments to the function.
For the arguments, the tuple at the top of the stack length is checked, and the top len(keyword names)
items are keyword arguments, and the bottom argc - len(keyword names)
items are positional arguments.
The item below the arguments is the callable to call.
The keyword argument name tuple, arguments and the callable are popped and the result of the function call is pushed to the top of the stack.
Used to implement function calls with keyword arguments.
Example Sources:
# This is CALL_FUNCTION_KW(3) with
# the tuple ('arg_1',) at the top of the stack
function(1, 2, arg_1=3)
CALL_FUNCTION_EX(flags)
Python Versions: ALL
Stack Prior (1): ... function, iterable
Stack Prior (2): ... function, iterable, mapping
Stack Prior (3): ... NULL, function, iterable
Stack Prior (4): ... NULL, function, iterable, mapping
Stack After: ... return_value
There are two modes for this function, controlled by its flags:
-
If
flags & 1
is set, this is a function call with both positional and keyword arguments, and the stack containscallable
,iterable
,mapping
. The items in the iterable and mapping are unpacked, and are used to make the function call. Used to implementfunction(*iterable, **mapping)
-
If
flags & 1
is unset, this is a function call with only positional arguments, and the stack containscallable
,iterable
. The items in the iterable are unpacked and are used to make the function call. Used to implementfunction(*iterable)
If the Python version is at least 3.11, a NULL
is put beneath callable.
In all cases, the argument containers, callable (and possibly NULL
) are popped and the returned value is pushed to the top of the stack.
Used to implement function calls that unpack arguments.
Example Sources:
# CALL_FUNCTION_EX(0)
function(*iterable)
# CALL_FUNCTION_EX(0)
function(1, 2, 3, *iterable)
# CALL_FUNCTION_EX(1)
function(*iterable, **mapping)
# CALL_FUNCTION_EX(1)
function(**mapping)
# CALL_FUNCTION_EX(1)
function(1, arg=1, *iterable)
LOAD_METHOD(namei)
Python Versions: ALL
Stack Prior: ... object
Stack After (1): ... unbound_method, object
Stack After (2): ... function, NULL
Stack After (3): ... NULL, function
Load the method with the name co_names[namei]
from the object at the top of the stack.
If the method exists (and is an instance method, not a class method, static method or a callable), the unbounded method is put beneath the object at the top of the stack.
Otherwise, the object at the top of the stack is popped, attribute lookup is performed, and the result of the lookup is pushed to the stack (with a NULL either before or after the lookup result depending on the Python version).
Used to implement attribute lookups for function calls.
Example Sources:
# This emits LOAD_METHOD
my_object.function()
# This DOES NOT emit LOAD_METHOD
my_onject.function
CALL_METHOD(argc)
Python Versions: <= 3.10
Stack Prior (1): ... method, object, arg_1, ..., arg_{argc}
Stack Prior (2): ... callable, NULL, arg_1, ..., arg_{argc}
Stack After: ... return_value
Calls a method with argc
positional arguments (and no keyword arguments).
The top argc
items on the stack are the positional arguments.
The item immediately below the argument is either an object (which will be used as the self parameter) or NULL.
The item below that is either an unbound method or a callable to call.
All the arguments, the object/NULL, and the method/callable are all popped, and the return value is pushed to the top of the stack.
Used to implement method calls.
Example Sources:
# This emits CALL_METHOD
my_object.function()
MAKE_FUNCTION(flags)
Python Versions: ALL
Stack Prior: ... [default_positional_args], [default_keyword_args], [annotation_directory_or_tuple], [cell_tuple], function_code, [function_name]
Stack After: ... function
Creates a function from the code object.
Expected stack varies depending on flags
and Python version.
-
If the Python version is prior to 3.11, at the top of the stack is the qualified name of the function, with the code object for the function below it. Otherwise, at the top of the stack is the code object (and the qualified name of the function is received via the code object).
-
If
flags & 8
is set, the next item below is a tuple containing the closure for the created function. The closure is a tuple that consists of the cells the inner function shares with the outer function. -
If
flags & 4
is set, the next item below are the annotations for the created function. Prior to 3.10, this is atuple
containing(key, value)
pairs. After 3.10, this is adict
. -
If
flags & 2
is set, the next item below are the default values for keyword-only arguments (as adict
). -
Finally, if
flags & 1
is set, the next item below are the default values for allow-positional arguments (as atuple
).
All these items are popped off the stack and are used to create a new function object, which is pushed to the top of the stack. Used to create inner functions.
Example Sources:
def outer():
fun_list = []
for i in range(10):
# MAKE_FUNCTION(1)
def inner(value=i):
return value
fun_list.append(inner)
fun_list[0]() # 0 because it
# the default parameter
# for fun_list[0]
def outer():
for i in range(10):
# MAKE_FUNCTION(8)
def inner():
return i
fun_list.append(inner)
fun_list[0]() # 9 because
# it the current value of i
def outer():
# MAKE_FUNCTION(4)
# on the stack is either
# (('a', str),) or {'a': str}
# depending on Python version
def inner(a: str):
return a
def outer():
# MAKE_FUNCTION(2)
def inner(*, keyword_arg=1):
return keyword_arg
BUILD_SLICE(argc)
Python Versions: ALL
Stack Prior (argc=2): ... start, end
Stack Prior (argc=3): ... start, end, step
Stack After: ... function
At the top of the stack is either two or three items depending on argc
:
-
If
argc = 2
, at the top of the stack are two objects to use as the start and end index of a slice. -
If
argc = 3
, at the top of the stack are three objects to use as the start, end and step of a slice.
Any items on the stack that are not int
or None
are converted to int
by calling their __index__()
method.
The arguments are popped, and the created slice is pushed to the top of the stack.
Used to implement slice indexing.
Example Sources:
# BUILD_SLICE(2)
my_list[:]
my_list[1:]
my_list[:2]
my_list[1:-1]
# BUILD_SLICE(3)
my_list[::]
my_list[1::]
my_list[:2:]
my_list[::3]
my_list[1:2:]
my_list[:2:3]
my_list[1:2:3]
EXTENDED_ARG(ext)
Python Versions: ALL
Stack Prior: ...
Stack After: ...
A NOP. Used to extend an opcode argument range beyond one byte by prefixing up to three EXTENDED_ARG opcodes before it.
Example Sources:
# Dynamic list of length 260,
# which is too large to fit into a byte (256)
# So EXTENDED_ARG is used to extend
# BUILD_LIST argument like so:
# EXTENDED_ARG(0x01) BUILD_LIST(0x04)
# = BUILD_LIST(0x0104 = 260)
[
a[0x00], a[0x01], a[0x02], a[0x03],
a[0x04], a[0x05], a[0x06], a[0x07],
# ...
a[0xFC], a[0xFD], a[0xFE], a[0xFF],
a[0x100], a[0x101], a[0x102], a[0x103]
]
FORMAT_VALUE(flags)
Python Versions: ALL
Stack Prior: ... object, [format_spec]
Stack After: ... formatted_string
Formats an object with an optional format specifier string.
Acts different depending on flags
:
-
If
flags & 4
is set, there is a format specifier on the top of the stack, with the object to format below it. Otherwise, the object to format is at the top of the stack (andNone
will be used as the format specifier). -
If
(flags & 3) == 0
, the object is formatted as is. -
If
(flags & 3) == 1
, the object is converted viastr()
before formatting. -
If
(flags & 3) == 2
, the object is converted viarepr()
before formatting. -
If
(flags & 3) == 3
, the object is converted viaascii()
before formatting.
Example Sources:
f'{my_object}' # FORMAT_VALUE(0)
f'{my_object!s}' # FORMAT_VALUE(1)
f'{my_object!r}' # FORMAT_VALUE(2)
f'{my_object!a}' # FORMAT_VALUE(3)
f'{my_object:my_spec}' # FORMAT_VALUE(4)
f'{my_object!s:my_spec}' # FORMAT_VALUE(5)