Master the fundamental concepts of cpython internals through this focused micro-challenge.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksA Python function call crosses several C layers before your bytecode runs. Understanding \`PyObject_Call\`, frame setup, and the eval loop explains stack traces, profiling, and debugger breakpoints.
Rough path from \`f()\` to execution:
Each frame holds:
For example, calling \`add(2, 3)\` pushes arguments onto the new frame's stack, runs \`LOAD_FAST\`/\`BINARY_ADD\`, then returns via \`RETURN_VALUE\`.
Frame objects are among the hottest allocations in CPython. The interpreter caches empty frames and reuses them where possible. Watch `PyFrame_New` in profiles when optimizing call-heavy Python code.
This exercise asks you to document the CPython call path from Python source to \`ceval.c\`. You will trace frame creation, argument binding, and return so you can read real interpreter source with context.
You will use the same mental model here when reading production interpreter source later in the track. Sketch one concrete input on paper, predict the outcome, then confirm with code. That discipline catches logic errors early and makes debugging far faster when you extend the implementation in follow-on tasks.
Trace a function call through a model of CPython's eval loop. Each function is a code object: a name, co_argcount, co_varnames and bytecode. Each call creates a frame: f_back (the caller), f_code, f_lasti (the current instruction), fast locals and a value stack. CALL_FUNCTION moves the arguments from the caller's stack into the callee's locals and switches frames. RETURN_VALUE pushes the result onto the caller's stack. Errors print a traceback by walking the f_back chain.
cLoading…
Everything after # on a line is ignored.
Instructions:
LOAD_CONST n, LOAD_FAST x, STORE_FAST x;BINARY_ADD, BINARY_SUBTRACT, BINARY_MULTIPLY, BINARY_FLOOR_DIVIDE;COMPARE_LT (pushes 1 or 0);POP_JUMP_IF_FALSE off, JUMP_ABSOLUTE off;CALL_FUNCTION name argc;RETURN_VALUE.2i, as in dis. Jump targets are offsets.UnboundLocalError: local variable 'x' referenced before assignment.-7 // 2 == -4).RecursionError: maximum recursion depth exceeded.TypeError: f() takes N positional argument(s) but M was/were givenNameError: name 'f' is not definedZeroDivisionError: integer division or modulo by zeroSystemError: stack underflow in OPNAME(ARGS) = V [F frame(s), max depth D, I instructions].call f(a=1, b=2) f_back=CALLER (or None) and return V from f, indented two spaces per depth level beyond 1.For an error raised while running, print the chain from the outermost frame to the innermost one, then the error:
cLoading…
A line identical to the previous one (same function and offset) is printed at most 3 times in a row. The remaining repeats are summarized in brackets (1 more time in the singular). Errors raised before any frame exists, such as a bad run, print just the error line.
Input:
cLoading…
Output:
cLoading…
f_back chain. The traceback is built only by following it from the failing frame.CALL_FUNCTION, with the result on its stack.Hidden tests cover hitting the recursion limit (with collapsed traceback lines), an unbound local, floor division of negatives, division by zero, an undefined function, and a stack underflow.