Documenting Complexity Modules
Produce a complete, evidence-backed page rather than filling a prose template.
Treat English documentation as the source of truth and complexity claims as
the repository's highest-risk content.
Establish Scope and Evidence
Read AGENTS.md, CONTRIBUTING.md, and the reference pair:
docs/stdlib/csv.md
tests/test_csv_complexity.py
That pair is the style anchor for every page and test file in this
repository. The most recently modified pages are not a substitute: a page
modelled on its neighbours inherits their departures from the reference
and adds its own. Read the reference pair in full before writing, and
compare the finished page against it, not against its neighbours.
Identify every public class, function, constant, and public method the page
should cover. Use official Python documentation plus runtime inspection such
as dir(module) and dir(class). Filter private names, then distinguish
callables from data attributes. Record intentional omissions in the page or
test rationale; do not silently omit APIs. Reconcile the result with
the shared audit gate - see Coverage Is a Claim below.
Define every size variable before using it. Avoid an ambiguous n when an
operation depends on several dimensions; use terms such as input length,
output length, fields, vertices, edges, matches, or returned items.
Verify implementation-specific claims against the corresponding released
CPython branch, never main. Read every Python version the project
supports - a bound can move in a middle release - but run the pinned
interpreter unless a claim is about a particular version, in which case run
that one for the tests asserting it; CI covers the matrix. Use official
documentation where behavior is contractual and source where implementation
determines the bound.
Do not trust an existing claim, a plausible review comment, or a generic
complexity rule without checking the operation's actual code path.
Write the Page
Use docs/stdlib/csv.md as the structural reference. The rules below
describe its shape; where a rule allows a choice, choose what the csv page
did:
Title: # <name> Module Complexity or the established builtin equivalent.
Give a short performance-focused introduction: what the module does, what
its unit of work is, and what it does or does not hold in memory. Two
paragraphs at most.
Define every size variable in prose right after the introduction, before
the table, in one place: "n is rows, k is the characters in one row".
State any cost-model assumption there too, such as treating key hashing as
O(1). A variable used by a single subsection's table may instead be defined
in that table's Notes, as s = sample length is in the Sniffer rows.
Put ## Complexity Reference next and include a table with exactly these
semantic columns:
| Operation | Time | Space | Notes |
|-----------|------|-------|-------|
Split the reference into ### subsections, one per class or natural group
(### reader, ### DictReader, ### Dialects and field limits,
### Constants and exceptions), each with its own table. Head a subsection
with the class name where there is one. Write the Operation cell as the
qualified call with its signature (csv.DictReader(f, fieldnames=None, ...),
DictWriter.writerow(rowdict)), the qualified name for an attribute or
constant (DictReader.fieldnames, csv.QUOTE_ALL), and a short label for
a protocol such as iteration ("Iterating a DictReader"), so the audit can
match the name. Price every row, including constants and exception
classes: reading a constant is O(1) attribute access, so say O(1) rather
than leaving a dash, and a class whose construction does work gets that
cost instead.
Follow the reference with topic sections whose headings name the subject in
Title Case (## Reading CSV Files, ### Lazy vs Eager Reading,
## Sniffing an Unknown Format), not a sentence stating the claim. Each
opens with one or two sentences saying what the cost is and why, then a
runnable example; where the sentences would only restate the table, go
straight to the example. Nest ### under a ## topic where a topic has
several facets.
Close with, in this order: ## Common Patterns where a realistic
read-transform-write or aggregation example helps; ## Performance Best Practices as a ✅ Do list and a ❌ Avoid list, each item tied to a
cost on this page; ## Version Notes as a bulleted list of
**Python 3.x+**: ... entries for changes on supported versions and
**All Python 3**: ... for a caveat that holds on every one; and
## Related Modules as **[name](name.md)** - why a reader would go there.
Omit a closing section only when the module has nothing to put in it.
Cover all scoped operations at the altitude set by Document the Common
Case below: one bound per operation, with its size variables defined.
Distinguish best, average, amortized and worst only where they differ
asymptotically and ordinary use can reach the difference; state eager versus
lazy work, cache effects, output-sensitive terms, and version boundaries
where they change the result on a version this project supports.
Add topic sections only where a non-obvious cost changes a practical
choice. Exclude generic usage advice unrelated to complexity, and prefer no
section to one that restates the table in sentences.
Include runnable examples that demonstrate the documented operation or a
performance consequence. Write them the way the csv page does: import at
the top, self-contained inputs (in memory, such as io.StringIO or a
literal, where the API allows; a temporary resource the block creates and
removes where it does not), a trailing # O(...) comment on the
operations whose cost the example demonstrates (repeated calls and
incidental setup need not each carry one), and assert statements that
pin the result so the block proves something when the test suite runs it.
Where the result is an exception, catch it, assert on its message, and
add an else that raises, so a block that stops raising fails. No
print() output to read by eye. Avoid huge allocations or slow
benchmark-style examples in docs.
Link related operations when the comparison helps readers choose between
different costs.
Every table row, annotation, caption, example comment, explanatory sentence,
warning, and recommendation that describes cost or behavior is a claim. Make a
claim inventory while writing; do not review only text containing O(...).
Document the Common Case
The page exists so a reader can choose between operations. Its subject is the
Big-O characteristic that governs that choice, not a full account of the CPython
code path that produced it. A row that is correct but exhaustive costs more than
it returns: it reads worse, it goes stale sooner, and every added clause is one
more claim to test.
Keep these off the page:
- Measured constant factors. "roughly 1,400x dearer", "some 50x", "wins by
eight times". A ratio is a property of one machine, one input shape and one
release. The page cannot re-run it, the reader cannot act on it, and nothing
fails when it drifts. Where a magnitude really does drive a choice, say which
side wins and why, not by how much; the number stays in the test that guards
it.
- Pathological-input costs. An argument whose
__hash__ scans 100,000
elements does make hashing dominate a cache hit, but pricing that into the
cache's row teaches nothing about the cache. Document the cost the operation
itself controls; where caller-supplied cost dominates, name it once as a
variable (h, f, the callback) and move on.
- Per-release micro-changes. A version boundary earns a mention when it
changes the bound or the recommendation on a supported version. Shifts in
constant factors between minor releases do not, and neither does an
implementation detail stated so precisely that the next release falsifies it.
- Restated mechanism. The C function reached, the struct field consulted,
the order of two statements: that is evidence for the test file, not content
for the page, unless the reader must do something differently because of it.
Apply one test to every note: would removing it change how someone uses the
operation? If not, cut it. An empty Notes cell beside a correct bound is a good
outcome, not an unfinished one.
A deliberately loose bound fails that test even when it is honest about being
loose. Bounding a recursive tree walk by the whole tree's metadata is true, and
tells the reader that shape does not matter - when two trees of equal entry
count differ eightfold by shape. Give the tight bound and its size variables;
"conservative" is a bound no release can ever falsify, which is the same as one
no reader can use.
Coverage Is a Claim
Use the shared public API audit as the completeness gate for the page being
written or reviewed. Run it before the claim review and again on the final page:
uv run python scripts/audit_documentation.py --page docs/stdlib/os.md --check --include-review
Replace the path with the actual English page. Scope by page, including submodule
APIs assigned to it (such as os.path in os.md), rather than filtering output
by a module-name prefix. The audit uses the current interpreter's versioned
Python API inventory and deduplicates aliases across the full audit. Use that
shared inventory instead of writing another dir(module) completeness test.
Runtime inspection and official documentation still supplement inventory gaps.
Resolve every reported miss with substantive documentation or correct an audit
classification/matching defect with a regression test. Group related APIs when
they share a bound. Do not add token mentions to obtain a pass, silently suppress
names, or treat an inspection failure or empty inventory as zero misses.
The gate checks name coverage, not complexity correctness. Review the scoped
unresolved/unavailable and unclassified diagnostics too; record explicit names
and reasons for intentional exclusions or platform/version limitations in the
module test rationale. A successful exit does not discharge those diagnostics.
Inspect the official inventory for relevant supported-version APIs absent from
the running interpreter; run another version only when resolving a claim about
that version. One platform's successful audit does not establish all-platform
coverage.
A Foreign Platform's Gap Is Not This Platform's Blocker
Some modules cannot be imported where the work is happening: winreg, msvcrt
and asyncio.windows_events on Linux, and their equivalents elsewhere. The
audit reports each as an inspection error, and its exit status counts every
inspection error as a failure. That conflates two different things, and only
one of them is yours to fix.
Sort each inspection error into one of three classes:
- Imports here. The ordinary case, including your own platform's APIs. A
miss or a failing test is a blocker.
- Belongs to another platform.
winreg on Linux. Nothing you write makes
it inspectable, and no build of this interpreter would, so it is not a
coverage defect. Name it and its reason in the module test rationale, and
move on.
- Belongs to this platform but is missing from this build.
dbm.gnu
without _gdbm. You cannot inspect it here either, so it does not block
finishing - but it is not discharged, because an interpreter built with it
would surface real misses. Record it as unresolved, under that name, and do
not report the module's coverage as established.
So a --check run reporting zero missing names whose only inspection
errors are foreign-platform modules has met the coverage bar, whatever its exit
status says. Report it that way - "0 missing; the gate cannot exit clean on
Linux because these two modules are Windows-only" - rather than presenting a
red gate as an open coverage gap, or implying a green one the tool cannot
produce. Never quote the exit status alone as evidence in either direction:
read the missing-name count and the error list. Where a missing-build module is
among the errors, say that the count is provisional on that build.
What this does not license: a reachable module that fails to import is a real
failure, and an inspection error is never a reason to skip reading the official
inventory for that module's APIs. A page still documents the APIs its module
exposes on platforms you are not running, sourced from the official docs, with
the platform named in the row.
A full review is complete only when the scoped gate reports no missing names,
every remaining coverage diagnostic is accounted for - fixed if it imports
here, discharged if it belongs to another platform, carried as an explicit
unresolved item if this build simply lacks it - and every documented claim has
evidence.
Report API completeness and claim correctness separately. If the work is an
explicitly scoped correction, report remaining API gaps rather than describing
the whole page as reviewed. Newly documented APIs need the same claim inventory,
behavioral tests, and example verification as the existing rows.
Test Every Claim
Use the testing-complexity-claims skill if available. Otherwise apply its core
contract directly:
- A module-specific
tests/test_<module>_complexity.py covers the page's table.
- Explanatory claims beyond the table receive focused tests, preferably based on
observable behavior rather than elapsed time.
- Claims that execution cannot settle are listed with the reason in a relevant
test module's docstring; do not add a fake or permanently skipped test.
- Test or explicitly account for every fenced code block using the code-section
rules below.
- Maintain a one-to-one claim inventory showing a test or an explicit
untestable rationale for each claim.
Do not write documentation first and defer its evidence to later work.
Test Every Code Section
Account for every fenced code block in the English page, not just blocks that
contain complexity annotations. Test each block when safely and meaningfully
possible; for a block that cannot be executed, record the block's location and
the concrete reason, such as required network access, interactive input,
deliberately incomplete names, destructive behavior, or an intentional
exception without an established marker. Translations do not need duplicate
execution because their code fences must be byte-for-byte identical to English.
Follow the isolation lessons from repository issue #7 when building or extending
a documentation-code runner:
- dedent each extracted block so fences nested in admonitions compile correctly;
- run each block independently in a subprocess with a hard timeout, a fresh
namespace, closed stdin, and a temporary working directory;
- do not rely on text matching for unsafe or interactive calls:
breakpoint(),
help(), pdb.set_trace(), sys.stdin.read(), and getpass.getpass() are
pitfalls alongside obvious input() calls;
- isolate or explicitly exclude process, thread, network, browser, system,
signal, destructive filesystem, and indefinitely blocking examples;
- support intentional exceptions through an explicit convention rather than
treating all raised exceptions as broken examples;
- report every failure with its Markdown file and fence line number, and restore
captured output before emitting diagnostics;
- assert the expected block count or accounted-for locations so extraction
cannot silently test nothing;
- mutation-test the runner with a known broken example and first assert that the
mutation actually changed its target.
Execution proves only that a block does not crash; it does not prove that the
block demonstrates what its prose, comments, or output claims. Add semantic
assertions for results, exceptions, state changes, operation counts, and
complexity behavior wherever those claims can be tested. Retain claim-specific
unit tests even when a generic code-block runner also executes the example.
Integrate the Page
Add the English page to the appropriate alphabetized navigation section in
mkdocs.yml.
Run make audit to print live coverage without writing files. Coverage tests
compare the current interpreter with the English documentation tree; CI also
checks the pinned newest supported Python patch. Preserve navigation targets
for historical modules even when the current interpreter no longer has them.
Look for existing translations at the equivalent docs/<locale>/... path.
If they exist, faithfully mirror the English change and run:
uv run python scripts/validate_translations.py --update-hashes <locale>
Never hand-edit source_sha. Keep fenced code byte-for-byte identical to
English, and preserve heading levels, table shape, links, and complexity
notation. Missing translations may continue to fall back to English.
Verify
Run the narrowest useful checks while iterating, then finish with:
make check
Also inspect the final diff for:
- a scoped public API audit reporting no missing names, with every remaining
coverage diagnostic accounted for and any unreachable-platform module named
as such rather than left looking like a gap;
- defined size variables and bounds qualified only where the qualification
changes a decision;
- notes that survive the removal test, carrying no measured constants,
pathological-input pricing, or restated mechanism;
- the same section order, heading style, table layout and example shape as
docs/stdlib/csv.md, checked against that page rather than against the
pages edited most recently;
- every claim mapped to evidence;
- every fenced code section tested or explicitly accounted for, with semantic
assertions where execution alone is insufficient;
- alphabetized navigation and passing live coverage checks;
- translations updated where an equivalent page exists;
- no unrelated formatting or content changes.
If a claim remains unverified, describe the missing evidence and do not present
the page as complete.
1---2name: documenting-complexity-modules3description: Authors, expands, or reviews Python builtin and standard-library complexity pages, including API coverage, navigation, examples, translations, audit metadata, and verification. Use when adding a module/type page, materially expanding one, or reviewing an existing one for correctness - a review covers what the page omits as well as what it claims.4---56# Documenting Complexity Modules78Produce a complete, evidence-backed page rather than filling a prose template.9Treat English documentation as the source of truth and complexity claims as10the repository's highest-risk content.1112## Establish Scope and Evidence13141. Read `AGENTS.md`, `CONTRIBUTING.md`, and the reference pair:15 - `docs/stdlib/csv.md`16 - `tests/test_csv_complexity.py`1718 That pair is the style anchor for every page and test file in this19 repository. The most recently modified pages are not a substitute: a page20 modelled on its neighbours inherits their departures from the reference21 and adds its own. Read the reference pair in full before writing, and22 compare the finished page against it, not against its neighbours.232. Identify every public class, function, constant, and public method the page24 should cover. Use official Python documentation plus runtime inspection such25 as `dir(module)` and `dir(class)`. Filter private names, then distinguish26 callables from data attributes. Record intentional omissions in the page or27 test rationale; do not silently omit APIs. Reconcile the result with28 the shared audit gate - see *Coverage Is a Claim* below.293. Define every size variable before using it. Avoid an ambiguous `n` when an30 operation depends on several dimensions; use terms such as input length,31 output length, fields, vertices, edges, matches, or returned items.324. Verify implementation-specific claims against the corresponding released33 CPython branch, never `main`. Read every Python version the project34 supports - a bound can move in a middle release - but run the pinned35 interpreter unless a claim is about a particular version, in which case run36 that one for the tests asserting it; CI covers the matrix. Use official37 documentation where behavior is contractual and source where implementation38 determines the bound.3940Do not trust an existing claim, a plausible review comment, or a generic41complexity rule without checking the operation's actual code path.4243## Write the Page4445Use `docs/stdlib/csv.md` as the structural reference. The rules below46describe its shape; where a rule allows a choice, choose what the csv page47did:48491. Title: `# <name> Module Complexity` or the established builtin equivalent.502. Give a short performance-focused introduction: what the module does, what51 its unit of work is, and what it does or does not hold in memory. Two52 paragraphs at most.533. Define every size variable in prose right after the introduction, before54 the table, in one place: "`n` is rows, `k` is the characters in one row".55 State any cost-model assumption there too, such as treating key hashing as56 O(1). A variable used by a single subsection's table may instead be defined57 in that table's Notes, as `s = sample length` is in the Sniffer rows.584. Put `## Complexity Reference` next and include a table with exactly these59 semantic columns:6061 ```markdown62 | Operation | Time | Space | Notes |63 |-----------|------|-------|-------|64 ```6566 Split the reference into `###` subsections, one per class or natural group67 (`### reader`, `### DictReader`, `### Dialects and field limits`,68 `### Constants and exceptions`), each with its own table. Head a subsection69 with the class name where there is one. Write the Operation cell as the70 qualified call with its signature (`csv.DictReader(f, fieldnames=None, ...)`,71 `DictWriter.writerow(rowdict)`), the qualified name for an attribute or72 constant (`DictReader.fieldnames`, `csv.QUOTE_ALL`), and a short label for73 a protocol such as iteration ("Iterating a `DictReader`"), so the audit can74 match the name. Price every row, including constants and exception75 classes: reading a constant is O(1) attribute access, so say O(1) rather76 than leaving a dash, and a class whose construction does work gets that77 cost instead.785. Follow the reference with topic sections whose headings name the subject in79 Title Case (`## Reading CSV Files`, `### Lazy vs Eager Reading`,80 `## Sniffing an Unknown Format`), not a sentence stating the claim. Each81 opens with one or two sentences saying what the cost is and why, then a82 runnable example; where the sentences would only restate the table, go83 straight to the example. Nest `###` under a `##` topic where a topic has84 several facets.856. Close with, in this order: `## Common Patterns` where a realistic86 read-transform-write or aggregation example helps; `## Performance Best87 Practices` as a ✅ **Do** list and a ❌ **Avoid** list, each item tied to a88 cost on this page; `## Version Notes` as a bulleted list of89 `**Python 3.x+**: ...` entries for changes on supported versions and90 `**All Python 3**: ...` for a caveat that holds on every one; and91 `## Related Modules` as `**[name](name.md)** - why a reader would go there`.92 Omit a closing section only when the module has nothing to put in it.937. Cover all scoped operations at the altitude set by *Document the Common94 Case* below: one bound per operation, with its size variables defined.95 Distinguish best, average, amortized and worst only where they differ96 asymptotically and ordinary use can reach the difference; state eager versus97 lazy work, cache effects, output-sensitive terms, and version boundaries98 where they change the result on a version this project supports.998. Add topic sections only where a non-obvious cost changes a practical100 choice. Exclude generic usage advice unrelated to complexity, and prefer no101 section to one that restates the table in sentences.1029. Include runnable examples that demonstrate the documented operation or a103 performance consequence. Write them the way the csv page does: `import` at104 the top, self-contained inputs (in memory, such as `io.StringIO` or a105 literal, where the API allows; a temporary resource the block creates and106 removes where it does not), a trailing `# O(...)` comment on the107 operations whose cost the example demonstrates (repeated calls and108 incidental setup need not each carry one), and `assert` statements that109 pin the result so the block proves something when the test suite runs it.110 Where the result is an exception, catch it, assert on its message, and111 add an `else` that raises, so a block that stops raising fails. No112 `print()` output to read by eye. Avoid huge allocations or slow113 benchmark-style examples in docs.11410. Link related operations when the comparison helps readers choose between115 different costs.116117Every table row, annotation, caption, example comment, explanatory sentence,118warning, and recommendation that describes cost or behavior is a claim. Make a119claim inventory while writing; do not review only text containing `O(...)`.120121## Document the Common Case122123The page exists so a reader can choose between operations. Its subject is the124Big-O characteristic that governs that choice, not a full account of the CPython125code path that produced it. A row that is correct but exhaustive costs more than126it returns: it reads worse, it goes stale sooner, and every added clause is one127more claim to test.128129Keep these off the page:130131- **Measured constant factors.** "roughly 1,400x dearer", "some 50x", "wins by132 eight times". A ratio is a property of one machine, one input shape and one133 release. The page cannot re-run it, the reader cannot act on it, and nothing134 fails when it drifts. Where a magnitude really does drive a choice, say which135 side wins and why, not by how much; the number stays in the test that guards136 it.137- **Pathological-input costs.** An argument whose `__hash__` scans 100,000138 elements does make hashing dominate a cache hit, but pricing that into the139 cache's row teaches nothing about the cache. Document the cost the operation140 itself controls; where caller-supplied cost dominates, name it once as a141 variable (h, f, the callback) and move on.142- **Per-release micro-changes.** A version boundary earns a mention when it143 changes the bound or the recommendation on a supported version. Shifts in144 constant factors between minor releases do not, and neither does an145 implementation detail stated so precisely that the next release falsifies it.146- **Restated mechanism.** The C function reached, the struct field consulted,147 the order of two statements: that is evidence for the test file, not content148 for the page, unless the reader must do something differently because of it.149150Apply one test to every note: would removing it change how someone uses the151operation? If not, cut it. An empty Notes cell beside a correct bound is a good152outcome, not an unfinished one.153154A deliberately loose bound fails that test even when it is honest about being155loose. Bounding a recursive tree walk by the whole tree's metadata is true, and156tells the reader that shape does not matter - when two trees of equal entry157count differ eightfold by shape. Give the tight bound and its size variables;158"conservative" is a bound no release can ever falsify, which is the same as one159no reader can use.160161## Coverage Is a Claim162163Use the shared public API audit as the completeness gate for the page being164written or reviewed. Run it before the claim review and again on the final page:165166```bash167uv run python scripts/audit_documentation.py --page docs/stdlib/os.md --check --include-review168```169170Replace the path with the actual English page. Scope by page, including submodule171APIs assigned to it (such as `os.path` in `os.md`), rather than filtering output172by a module-name prefix. The audit uses the current interpreter's versioned173Python API inventory and deduplicates aliases across the full audit. Use that174shared inventory instead of writing another `dir(module)` completeness test.175Runtime inspection and official documentation still supplement inventory gaps.176177Resolve every reported miss with substantive documentation or correct an audit178classification/matching defect with a regression test. Group related APIs when179they share a bound. Do not add token mentions to obtain a pass, silently suppress180names, or treat an inspection failure or empty inventory as zero misses.181182The gate checks name coverage, not complexity correctness. Review the scoped183unresolved/unavailable and unclassified diagnostics too; record explicit names184and reasons for intentional exclusions or platform/version limitations in the185module test rationale. A successful exit does not discharge those diagnostics.186Inspect the official inventory for relevant supported-version APIs absent from187the running interpreter; run another version only when resolving a claim about188that version. One platform's successful audit does not establish all-platform189coverage.190191### A Foreign Platform's Gap Is Not This Platform's Blocker192193Some modules cannot be imported where the work is happening: `winreg`, `msvcrt`194and `asyncio.windows_events` on Linux, and their equivalents elsewhere. The195audit reports each as an inspection error, and its exit status counts every196inspection error as a failure. That conflates two different things, and only197one of them is yours to fix.198199Sort each inspection error into one of three classes:200201- **Imports here.** The ordinary case, including your own platform's APIs. A202 miss or a failing test is a blocker.203- **Belongs to another platform.** `winreg` on Linux. Nothing you write makes204 it inspectable, and no build of this interpreter would, so it is not a205 coverage defect. Name it and its reason in the module test rationale, and206 move on.207- **Belongs to this platform but is missing from this build.** `dbm.gnu`208 without `_gdbm`. You cannot inspect it here either, so it does not block209 finishing - but it is *not* discharged, because an interpreter built with it210 would surface real misses. Record it as unresolved, under that name, and do211 not report the module's coverage as established.212213So a `--check` run reporting **zero missing names** whose only inspection214errors are foreign-platform modules has met the coverage bar, whatever its exit215status says. Report it that way - "0 missing; the gate cannot exit clean on216Linux because these two modules are Windows-only" - rather than presenting a217red gate as an open coverage gap, or implying a green one the tool cannot218produce. Never quote the exit status alone as evidence in either direction:219read the missing-name count and the error list. Where a missing-build module is220among the errors, say that the count is provisional on that build.221222What this does not license: a reachable module that fails to import is a real223failure, and an inspection error is never a reason to skip reading the official224inventory for that module's APIs. A page still documents the APIs its module225exposes on platforms you are not running, sourced from the official docs, with226the platform named in the row.227228A full review is complete only when the scoped gate reports no missing names,229every remaining coverage diagnostic is accounted for - fixed if it imports230here, discharged if it belongs to another platform, carried as an explicit231unresolved item if this build simply lacks it - and every documented claim has232evidence.233Report API completeness and claim correctness separately. If the work is an234explicitly scoped correction, report remaining API gaps rather than describing235the whole page as reviewed. Newly documented APIs need the same claim inventory,236behavioral tests, and example verification as the existing rows.237238## Test Every Claim239240Use the `testing-complexity-claims` skill if available. Otherwise apply its core241contract directly:242243- A module-specific `tests/test_<module>_complexity.py` covers the page's table.244- Explanatory claims beyond the table receive focused tests, preferably based on245 observable behavior rather than elapsed time.246- Claims that execution cannot settle are listed with the reason in a relevant247 test module's docstring; do not add a fake or permanently skipped test.248- Test or explicitly account for every fenced code block using the code-section249 rules below.250- Maintain a one-to-one claim inventory showing a test or an explicit251 untestable rationale for each claim.252253Do not write documentation first and defer its evidence to later work.254255## Test Every Code Section256257Account for every fenced code block in the English page, not just blocks that258contain complexity annotations. Test each block when safely and meaningfully259possible; for a block that cannot be executed, record the block's location and260the concrete reason, such as required network access, interactive input,261deliberately incomplete names, destructive behavior, or an intentional262exception without an established marker. Translations do not need duplicate263execution because their code fences must be byte-for-byte identical to English.264265Follow the isolation lessons from repository issue #7 when building or extending266a documentation-code runner:267268- dedent each extracted block so fences nested in admonitions compile correctly;269- run each block independently in a subprocess with a hard timeout, a fresh270 namespace, closed stdin, and a temporary working directory;271- do not rely on text matching for unsafe or interactive calls: `breakpoint()`,272 `help()`, `pdb.set_trace()`, `sys.stdin.read()`, and `getpass.getpass()` are273 pitfalls alongside obvious `input()` calls;274- isolate or explicitly exclude process, thread, network, browser, system,275 signal, destructive filesystem, and indefinitely blocking examples;276- support intentional exceptions through an explicit convention rather than277 treating all raised exceptions as broken examples;278- report every failure with its Markdown file and fence line number, and restore279 captured output before emitting diagnostics;280- assert the expected block count or accounted-for locations so extraction281 cannot silently test nothing;282- mutation-test the runner with a known broken example and first assert that the283 mutation actually changed its target.284285Execution proves only that a block does not crash; it does not prove that the286block demonstrates what its prose, comments, or output claims. Add semantic287assertions for results, exceptions, state changes, operation counts, and288complexity behavior wherever those claims can be tested. Retain claim-specific289unit tests even when a generic code-block runner also executes the example.290291## Integrate the Page2922931. Add the English page to the appropriate alphabetized navigation section in294 `mkdocs.yml`.2952. Run `make audit` to print live coverage without writing files. Coverage tests296 compare the current interpreter with the English documentation tree; CI also297 checks the pinned newest supported Python patch. Preserve navigation targets298 for historical modules even when the current interpreter no longer has them.2993. Look for existing translations at the equivalent `docs/<locale>/...` path.300 If they exist, faithfully mirror the English change and run:301302 ```bash303 uv run python scripts/validate_translations.py --update-hashes <locale>304 ```305306 Never hand-edit `source_sha`. Keep fenced code byte-for-byte identical to307 English, and preserve heading levels, table shape, links, and complexity308 notation. Missing translations may continue to fall back to English.309310## Verify311312Run the narrowest useful checks while iterating, then finish with:313314```bash315make check316```317318Also inspect the final diff for:319320- a scoped public API audit reporting no missing names, with every remaining321 coverage diagnostic accounted for and any unreachable-platform module named322 as such rather than left looking like a gap;323- defined size variables and bounds qualified only where the qualification324 changes a decision;325- notes that survive the removal test, carrying no measured constants,326 pathological-input pricing, or restated mechanism;327- the same section order, heading style, table layout and example shape as328 `docs/stdlib/csv.md`, checked against that page rather than against the329 pages edited most recently;330- every claim mapped to evidence;331- every fenced code section tested or explicitly accounted for, with semantic332 assertions where execution alone is insufficient;333- alphabetized navigation and passing live coverage checks;334- translations updated where an equivalent page exists;335- no unrelated formatting or content changes.336337If a claim remains unverified, describe the missing evidence and do not present338the page as complete.