Use this skill when you need to compile CPython, run tests, verify your changes work, check if a fix is correct, or debug test failures. Covers building from source with ./configure and make, ccache for faster rebuilds, Argument Clinic regeneration, and the unittest-based test system (NOT pytest). Essential for any task that requires running code or tests.
Build in a build/ subdirectory at repo root, never in the source tree.
# Build directory setup
REPO_ROOT=<path-to-cpython-git-repo>
BUILD_DIR=$REPO_ROOT/build
$BUILD_DIR, $BUILT_PY, and $NCPU throughout this skill (and the style and jit skills) are placeholders, not persistent shell state. Each Bash invocation starts a fresh shell, so substitute the concrete values into every command you run — e.g. make -C build patchcheck, not make -C $BUILD_DIR patchcheck in a shell where the variable was never set.
Run nproc (Linux) or sysctl -n hw.ncpu (macOS) to get the number of CPU cores.
Avoid $(nproc) or $(sysctl -n hw.ncpu) command substitution inside other commands — embedded substitutions make commands harder for the user to audit and can trigger extra permission prompts. Read the output once and use the literal number:
NCPU=<number from nproc or sysctl output>
ccache dramatically speeds up rebuilds by caching compilation results. Check if available:
which ccache
If ccache is not installed:
brew install ccache (no sudo required)apt-get install -y ccache or dnf install -y ccachesudo apt-get install ccachesudo dnf install ccacheConfigure with ccache (if available):
cd $BUILD_DIR && CC="ccache gcc" ../configure --with-pydebug
Configure without ccache (fallback):
cd $BUILD_DIR && ../configure --with-pydebug
When doing benchmarking or performance measurement of C code changes, omit --with-pydebug from configure:
cd $BUILD_DIR && CC="ccache gcc" ../configure # No --with-pydebug
Debug builds have significant overhead that distorts performance measurements. However, do not use --enable-optimizations unless explicitly asked—it enables PGO (Profile-Guided Optimization) which is slow to compile. Non-PGO release builds are sufficient for the majority of performance comparison work.
# Build using all CPU cores (initial or incremental)
make -C $BUILD_DIR -j $NCPU
Platform notes:
BUILT_PY=$BUILD_DIR/pythonBUILT_PY=$BUILD_DIR/python.exe (note .exe extension)After editing .c files that change function signatures, docstrings, or argument specs:
make -C $BUILD_DIR clinic
Never edit files in **/clinic/** subdirectories - they're auto-generated.
Clinic is one of several generated-source families. When you edit a source-of-truth file, rerun its generator rather than hand-editing the output — CI's make regen-all consistency check fails on hand-merged generated files:
make regen-cases — after editing Python/bytecodes.c (interpreter/uop definitions)make regen-all — regenerates everything; slower, but the safe catch-allmake -C $BUILD_DIR regen-jit — JIT stencils (see the jit skill)$BUILT_PY --version
$BUILT_PY -c "print('Hello from CPython!')"
make clean in BUILD_DIR and rebuildmake -C $BUILD_DIR clinicrm -rf $BUILD_DIR && mkdir $BUILD_DIR && cd $BUILD_DIR && CC="ccache gcc" ../configure --with-pydebug && make -j $NCPU (omit CC=... if ccache unavailable)Critical rules:
$BUILT_PY (the locally-built interpreter), never python/python3 from $PATH - the system Python won't have your changes. (Exception: Tools/ build and regen scripts, e.g. Tools/jit/build.py, are designed to run under a pre-existing python3.)unittest based - never use pytest--match, which takes a glob pattern - not -k (this is not pytest)Prerequisite: BUILT_PY=build/python or build/python.exe
# Single test module (recommended - proper discovery, parallel execution)
$BUILT_PY -m test test_zipfile -j $NCPU
# Multiple modules
$BUILT_PY -m test test_csv test_json -j $NCPU
# Direct execution (quick but may miss test packages)
$BUILT_PY Lib/test/test_csv.py
# Specific test by glob pattern (use --match, NOT -k!)
$BUILT_PY -m test test_zipfile --match "*large*" -j $NCPU
$BUILT_PY -m test test_csv --match "TestDialect*"
$BUILT_PY -m test test_json --match "TestEncode.test_encode_string"
# Full test suite (takes significant time - prefer targeted modules for iteration)
make -C $BUILD_DIR test
# Useful flags: -v (verbose), -f (fail fast), --timeout 120 (detect hangs), --list-tests, --help
Test packages (directories like test_asyncio/) require load_tests() in __init__.py to work with python -m test.
# Collect coverage (uses trace mechanism via libregrtest)
$BUILT_PY -m test --coverage test_csv test_json --coveragedir .claude/coverage/ -j $NCPU
# Reports go to specified coveragedir
Add breakpoint() in test code, then run the test with -v for verbose output.
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer