Skip to content
Merged
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: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ Every `.. doctest::` block in one `.rst` file shares a single namespace — the

Don't use the bare `python3 -m doctest <file>.rst` CLI (no `optionflags`) to check files under `docs/` — it ignores each block's `:options:` directive (e.g. `+NORMALIZE_WHITESPACE`, `+ELLIPSIS`) and reports false-positive whitespace failures that look like real regressions. `uv run sphinx-build -b doctest docs <tmpdir>` is the faithful check for those. `README.rst` has no `:options:` directives (plain `::` blocks, not `.. doctest::`), so the bare `python -m doctest README.rst` CLI is fine there — that's what CI actually runs.

`Constants` class attributes (e.g. `patronymic_name_order`, `middle_name_as_last`) document behavior with a bare string literal placed right after the assignment — Sphinx's attribute-docstring convention. That string never becomes a real `__doc__`, so `--doctest-modules` (which walks `__doc__` attributes) never sees any `.. doctest::` examples inside it — this let a stale example slip through CI once (`middle_name_as_last`, #133). `tests/test_config_attribute_docstrings.py` (#195) closes that gap: it parses `nameparser/config/__init__.py` with `ast` to recover those literals and runs any doctest examples through `doctest.DocTestParser`/`DocTestRunner` explicitly, so `pytest -q` now exercises them too. When adding or editing a `.. doctest::` example in a `Constants` attribute's bare-string docstring, this is the mechanism that actually runs it — don't assume `--doctest-modules` covers it.
**A `Constants` attribute docstring is not a place for a doctest, and nothing runs one there (2.0 note; the rest of this paragraph is v1 history).** v1's `Constants` documented attributes like `patronymic_name_order` with a bare string literal after the assignment, Sphinx's attribute-docstring convention. That string never became a real `__doc__`, so `--doctest-modules` (which walks `__doc__` attributes) never saw a `.. doctest::` inside it, and a stale example once slipped through CI (`middle_name_as_last`, #133); `tests/test_config_attribute_docstrings.py` (#195) recovered those literals with `ast` and ran their examples explicitly. Both halves are gone: since the M11 swap the real `Constants` lives in `nameparser/_config_shim.py` with bare type annotations (`patronymic_name_order: bool`) and no attribute docstrings, and the test was deleted in M12 (`a689e1d8`) because its AST walk found no class in the re-export shim and nothing to run in the real one. If an attribute docstring with an example ever returns, remember that `--doctest-modules` will not see it: put the example in a unit test instead, per the lean-docs rule in the 2.0 conventions above.

**`uv run mypy` covers `tests/` too** (`pyproject.toml`'s `[tool.mypy] packages = ["nameparser", "tests"]`, PR #250) — a test that deliberately passes an off-contract value to assert a `TypeError`/`ValueError`, or exercises a documented falsy-disables-the-feature toggle (e.g. `regexes.emoji = False`), needs a `# type: ignore[code]` comment on that line rather than a signature change. Before reaching for an ignore, check whether the "error" is really a source annotation that hasn't caught up with already-supported runtime behavior (e.g. `is_prefix`/`is_conjunction`/`is_suffix` accepting `list[str]`, `add_with_encoding` accepting `bytes`) — widen the annotation instead in that case.

Expand Down
Loading