Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ Python/frozen_modules/MANIFEST
# People's custom https://docs.anthropic.com/en/docs/claude-code/memory configs.
/.claude/
CLAUDE.local.md
# Our AGENTS.md tells agents to store local notebooks and temporary files here.
/.agents/

#### main branch only stuff below this line, things to backport go above. ####
# main branch only: ABI files are not checked/maintained.
Expand Down
90 changes: 90 additions & 0 deletions AGENTS.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not a fan of committing these files to the repo/top level, both (a) as I fear more low-effort LLM driven contributions that might feel emboldened by the presence of this file and (b) as the LLM tool landscape is moving sufficiently quickly that we might want to change this in 3, 6, 12 months, and in general we seek to avoid needless churn.

Could we consider adding this file instead to the devguide, perhaps with a command to run to fetch a copy into one's local clone of the repo? That would meet the goal of having a centrally maintained copy, but also would make it more 'opt-in'

A

(Disclosure: I currently have gratis access to GitHub's Copilot and Anthropic's Claude Code.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 - I'd either opt to have this referenced in the devguide, or alternatively in Tools/ since we seem to have other miscellaneous scripts and experimental feature tooling in there.

Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Purpose

* These brief instructions help LLM agents navigate working in the cpython repo.
* **Humans** are always responsible for changes being proposed and must pre-review all agentic work before turning it into a PR.

# Context

You are in the CPython repo helping work on the implementation of the Python
language runtime and standard library itself.

Use the `gh` tool to get information about an issue or PR in the repo.

Source files in this repo can be very long. Check their size to consider if
you really need to read the entire thing.

If tools such as `rg` (ripgrep), `gh`, `jq`, or `pre-commit` are not found, ask
the user to install them. ALWAYS prefer using `rg` rather than `find` or `grep`.
Comment on lines +16 to +17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have ripgrep nor do I have pre-commit installed, and I don't like to install more tools than I need. I think it is better to rely on find and grep instead of installing the tools when possible.


# Expanding your knowledge

* ALWAYS load a `.agents/pr-{PR_NUMBER}.md` or `.agents/branch-{branch_name_without_slashes}.md` file when you are told a PR number or when the current git branch is not `main`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My branch names always contain slashes so that I can sort them as if they were directories. Would this make it impossible?

* Keep the file up to date as an engineering notebook of your learnings and project state as you work on a task and after you commit. The goal of our notebook is to make it easier to pick up and resume work later.

## Optional developer guides and PEPs

* If `REPO_ROOT/../devguide/` exists, its `developer-workflow/` and `documentation/` subdirs contain detailed info on how we like to work on code and docs.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we allow the AI agent to actually access something outside the directory? Can't we ask it to actually directly read the webpages instead when possible?

* PEPs might exist in a `REPO_ROOT/../peps/` tree.

# Source code

* The runtime is implemented in C as are many of the core types and extension modules
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe each sentence should end with a period (I don't know how sensitive an agent can be).

* The Python standard library (stdlib) itself lives in the `Lib/` tree
* stdlib C extension modules live in the `Modules/` Tree
* builtins, objects, and the runtime itself live in `Objects/` and `Python/`
* NEVER edit files in a `**/clinic/**` subdirectory; those are generated by argument clinic
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* NEVER edit files in a `**/clinic/**` subdirectory; those are generated by argument clinic
* NEVER edit files in a `**/clinic/**` subdirectory; those are generated by Argument Clinic

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say "never edit files specified in .gitattributes as generated", because we have many generated files.

* Unittests for everything live in the `Lib/test/` tree. Ex:
Copy link
Member

@picnixz picnixz Sep 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not entirely accurate. Some IDLE tests live in idlelib and if someone were to try to fix the IDLE tests on macOS that are flaky, they probably need this information as well. Maybe it's also time to move them out?

* `Lib/zipfile/` contains the code for the stdlib `zipfile` module
* `Lib/test/test_zipfile**` are tests for `zipfile`
* `Modules/_csv.c` contains the code for the stdlib `csv` module
* `Lib/test/test_csv.py` are tests for `csv`
* C header files are in the `Include/` tree
* Documentation is written in .rst format in `Doc/` - this is source for the public facing official Python documentation.
* CPython internals are documented for maintainers in @InternalDocs/README.md.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the use of @ in InternalDocs?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

providing file as a context.

* Build time tools such as Argument Clinic live under the `Tools/` tree

## Coding style

* For C, follow PEP-7. For Python, follow PEP-8.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a link to PEP-7 and PEP-8 just to be sure it knows about it.

* Be consistent with existing nearby code style unless asked to do otherwise.
* NEVER leave trailing whitespace on any line.
* ALWAYS preserve the newline at the end of files.
* We do not autoformat code in this codebase. If the user asks you to run ruff format on a specific file, it can be found in `Doc/venv/bin/ruff`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* We do not autoformat code in this codebase. If the user asks you to run ruff format on a specific file, it can be found in `Doc/venv/bin/ruff`.
* We do not autoformat code in this codebase. If the user asks you to run `ruff` format on a specific file, it can be found in `Doc/venv/bin/ruff`.

note that this is only true if users had first make venv

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* We do not autoformat code in this codebase. If the user asks you to run ruff format on a specific file, it can be found in `Doc/venv/bin/ruff`.
* We do not autoformat code in this codebase. If the user asks you to run `ruff format` on a specific file, it can be found in `Doc/venv/bin/ruff`.

* NEVER add Python type annotations to Python code in the `Lib/` tree.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some code is annotated there, like _pyrepl. maybe suggest not adding annotations to files that do have them?


## Building

ONLY build in a `build/` subdirectory that you create at the repo root.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the subdirectory already exists, should it ask whether we want to use it?


* Use sub-agents when running configure and make build steps
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Use sub-agents when running configure and make build steps
* Use sub-agents when running `configure` and `make` build steps

* `REPO_ROOT` is the root of the cpython git repo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `REPO_ROOT` is the root of the cpython git repo
* `REPO_ROOT` is the root of the CPython git repo

* let `BUILD_DIR=REPO_ROOT/build`
* Setup: `cd BUILD_DIR && ../configure --with-pydebug`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Setup: `cd BUILD_DIR && ../configure --with-pydebug`
* Setup: `cd BUILD_DIR && mkdir -p "$(pwd)/dist" && ../configure --with-pydebug --prefix="$(pwd)/dist"`

You should also say that if the underlying distribution is openSUSE for instance, then the configure should add --with-platlibdir=lib64. I wouldn't want a configuration where hitting make install actually installs anything in /usr/local/.

* `make -C BUILD_DIR -j $(nproc)` will rebuild
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it actually use "BUILD_DIR" as is or would it make the substitution? maybe an explicit substitution would be better.

* Check what OS you are running on. Let `BUILT_PY=BUILD_DIR/python` or `BUILD_DIR/python.exe` on macOS (.exe is used to avoid a case insensitive fs name conflict)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Check what OS you are running on. Let `BUILT_PY=BUILD_DIR/python` or `BUILD_DIR/python.exe` on macOS (.exe is used to avoid a case insensitive fs name conflict)
* Check what OS you are running on. Let `BUILT_PY=BUILD_DIR/python` or `BUILD_DIR/python.exe` on macOS (`.exe` is used to avoid a case insensitive file system name conflict)

* If you are on Windows, ask the user how to build.

## Running our built Python and tests

* ALWAYS use sub-agents when running builds or tests
* NEVER use `pytest`. CPython tests are `unittest` based.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* NEVER use `pytest`. CPython tests are `unittest` based.
* NEVER use `pytest`. In CPython for tests we use an interal tools called `regrtest`, which is `unittest` based.

* use `BUILT_PY` to run the interpreter we've built
* Individual test files can be run directly using `BUILT_PY Lib/test/test_csv.py`
* `BUILT_PY -m test test_zipfile -j $(nproc)` will properly run all `Lib/test/test_zipfile` tests
* `BUILT_PY -m test` supports a `--match TESTNAME_GLOB` flag to run specific tests, pass `--help` to learn its other capabilities. NEVER try to pass `-k` as this is not pytest based, use `--match` instead.
* `make -C BUILD_DIR clinic` will regenerate argument clinic generated code. Do this after you've edited a corresponding input .c file in a way that changes a C extension module function signature or docstring
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `make -C BUILD_DIR clinic` will regenerate argument clinic generated code. Do this after you've edited a corresponding input .c file in a way that changes a C extension module function signature or docstring
* `make -C BUILD_DIR clinic` will regenerate argument clinic generated code. Do this after you've edited a corresponding input `.c` file in a way that changes a C extension module function signature or docstring

* `make -C BUILD_DIR test` will run the entire test suite. Do that sparingly. Focus on specific tests first and ask before running the entire test suite.
* Some tests are packages rather than a single .py file. These require `load_tests()` logic in their `test_package/__init__.py` file in order to work via `BUILT_PY -m test` commands.
* To collect Python code coverage from part of the test suite, use `BUILT_PY -m test -j $(nproc) --coverage test_name --coveragedir .agents/coverage_dir/`; this uses a `trace` based mechanism as implemented using libregrtest.

## Common workflows

* After editing C code: `make -C BUILD_DIR && BUILT_PY -m test relevant_tests`
* After editing stdlib Python: `BUILT_PY -m test relevant_tests --match specific_test_name_glob` (no rebuild needed)
* After editing .rst documentation: `make -C BUILD_DIR/Doc check`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, the Doc folder won't be copied so this step fail. Checking docs should be done directly at the top-level, that is make -C REPO_ROOT/Doc check. Note that we should also say that make -C REPO_ROOT/Doc venv is a setup to be executed once.

* Before committing: `make -C BUILD_DIR patchcheck && pre-commit run --all-files`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would instead suggest using uvx pre-commit ... here. Installing uv instead of pre-commit globally may be better for the user (I personally have uv installed but I don't have any pre-commit binary).


## Scratch space

* NEVER create throw away idea exploration files in the top directory of the repo. Use a `.agents/sandbox/` directory for those. They will never be committed.

3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@AGENTS.md

Keep agent instructions in AGENTS.md files instead of CLAUDE.md
Loading