compiler1RESUME2LOAD_FAST n3LOAD_CONST 24BINARY_OP *5LOAD_CONST 16BINARY_OP +7RETURN_VALUEVM1def bump(n):2 return n * 2 + 13print(bump(4))nstack 0stack 1sourcecode object44219
Code cards: bump.py and its bytecode; the highlighted line is the one runningCompiler and virtual machine (VM): the two halves of CPythonFrame: the local slot n and the two-slot value stackCPython runs bump.py in two stages: the compiler turns the source into bytecode, then the virtual machine runs the bytecode one instruction at a time. Each step lights the parts it is about. During the call a token carries each pushed value onto the frame's value stack; BINARY_OP pops two values and the stack's boxes crossfade to the result; RETURN_VALUE carries 9 back to line 3. In the last step three instruction names fade to the specialized forms CPython swaps in once the function is hot.

Compile

  1. bump.py is plain text. CPython, the standard Python, does not run that text directly. It first translates it into bytecode: short, simple instructions for a small machine built in software, the virtual machine (VM).

Run

Speed up

Try it yourself

;; step 1/11
# bump.py
def bump(n):
    return n * 2 + 1
print(bump(4))

$ python bump.py
9

The bytecode shown is CPython 3.13's. Bytecode is an implementation detail and changes between versions: CPython 3.14 prints LOAD_FAST_BORROW for the first load and LOAD_SMALL_INT for the two constants. The card shows each instruction's name and what its argument means; dis also prints the raw argument number. When you import a module, CPython saves its compiled bytecode in a __pycache__ folder as a .pyc file, so the next import can skip the compiler. The file you run directly is compiled every time and not cached.