Master the fundamental concepts of cpython internals through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
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 worksCPython exposes a C API for writing native modules that import like Python code. Extensions accelerate hot paths and wrap system libraries. NumPy, optional C helpers in networking libraries, and countless stdlib modules all build on this same scaffolding.
A minimal extension exports a PyMethodDef table and a module init function:
cLoading…
Key pieces you will wire up:
PyModule_CreateBuild with python3-config --cflags --ldflags or setuptools. Reference counting rules apply: Py_INCREF/Py_DECREF around objects you create or borrow.
For example, a C add that parses two PyLong arguments and returns a new PyLong runs at native speed when called from Python.
Reference counts on borrowed versus new references trip up most first extensions. Document whether each helper returns a borrowed reference from a tuple slot or a new reference you must decref.
This exercise asks you to scaffold a C extension module from scratch. You will implement method definitions, argument parsing with PyArg_ParseTuple, and module initialization so Python can import your native code.
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.
Write the C side of a CPython extension module, fastmath, together with the thin interpreter harness around it. This means:
PyMethodDef table and a PyModuleDef;PyInit_fastmath;PyArg_ParseTuple supporting the l (C long) and s (C string) units, which raises CPython's exact TypeError/OverflowError messages.A C function signals an error the CPython way: it sets an exception and returns NULL. The harness then prints Type: message.
One Python-like line at a time:
cLoading…
| method | flags | format | behaviour |
|---|---|---|---|
add(a, b) | METH_VARARGS | "ll:add" | a + b. On overflow: OverflowError: add overflows a C long |
power(base, exp) | METH_VARARGS | "ll:power" | base ** exp. exp < 0 raises ValueError: exponent must be >= 0. On overflow: OverflowError: power overflows a C long |
repeat(s, n) | METH_VARARGS | "sl:repeat" | s repeated n times ('' for n ≤ 0). More than 200 characters raises ValueError: result longer than 200 characters |
version() | METH_NOARGS | '1.0' | |
typename(obj) | METH_O | the argument's type name: int, float, str or NoneType |
The docs are printed with repr like any other string:
Fast integer helpers;add(a, b): sum of two C longs;power(base, exp): integer power;repeat(s, n): s repeated n times;version(): module version;typename(obj): name of the object's type.import fastmath runs PyInit_fastmath once and prints PyInit_fastmath() -> <module 'fastmath'> with 5 methods. A second import prints nothing, because sys.modules caches it. Using fastmath before importing it raises NameError: name 'fastmath' is not defined. Other modules raise ModuleNotFoundError: No module named 'X', and any other name raises a NameError.add() takes exactly 2 arguments (1 given);l given a float: integer argument expected, got float;l given another non-int: an integer is required (got type str);l given an int outside a 64-bit C long: OverflowError: Python int too large to convert to C long;s given a non-str: repeat() argument 1 must be str, not int (not None for None).version() takes no arguments (1 given);typename() takes exactly one argument (0 given).AttributeError: module 'fastmath' has no attribute 'X', and malformed lines print SyntaxError: invalid syntax.repr. Strings are single-quoted, unless they contain ' and no ", in which case they are double-quoted. fastmath prints <module 'fastmath'> and fastmath.power prints <built-in function power>.Input:
cLoading…
Output:
cLoading…
ml_flags, as PyCFunction call slots do. Don't special-case method names in the call path.Hidden tests cover C long boundaries (LONG_MIN passes, one past it overflows), power edge cases (0**0, (-1)**odd, (-2)**63), wrong argument types including None, METH_O/METH_NOARGS count errors, the doc strings, and unknown modules or attributes.