Skip to content

Make the docstring examples runnable doctests against real LMFDB sample data#129

Merged
roed314 merged 3 commits into
roed314:mainfrom
roed-math:doctest-examples
Jul 22, 2026
Merged

Make the docstring examples runnable doctests against real LMFDB sample data#129
roed314 merged 3 commits into
roed314:mainfrom
roed-math:doctest-examples

Conversation

@roed-math

@roed-math roed-math commented Jul 22, 2026

Copy link
Copy Markdown

The agreed follow-up to #127: every EXAMPLES block in the library is now a runnable, verified transcript — plain-Python >>> prompts executed as doctests by a new tests/test_doctests.py, replacing 137 sage: prompts of which 21 docstrings did from lmfdb import db and referenced production tables whose outputs had long drifted (or never held for standalone users).

Stacked on #127 (docstring-polish) — merge that first and this reduces to one commit.

The example data. The runner creates two small fixed-name tables of genuine LMFDB data and drops them afterwards: test_fields — 22 selected number fields of degree ≤ 3: the rationals, twelve quadratic fields, and all nine cubic fields with |disc| ≤ 90 (labels, signatures, ramified primes, class groups) — and test_curves, a dozen elliptic curves over ℚ(√5), ℚ(√2) and ℚ(√13) (the rank-1 curves make the join example work). So the examples keep their number-theoretic flavor — nf.lookup('2.0.23.1', 'class_number')3 is a true fact about ℚ(√−23) — while every printed output is checked. The getting-started block in __init__ doubles as a demo of configuration discovery: its PostgresDatabase() line genuinely connects via $PSYCODICT_CONFIG.

Drift the conversion surfaced and fixed: _parse_special's examples predated its col_type argument and the array-containment typecast ("ramps" @> %s::integer[]); _parse_values' first example showed _parse_dict({}) returning [] (it returns (None, None)); lookup's example used a column deleted long ago (the docstring even apologized for it); search's un-limited form returning an iterator is now shown explicitly; the statistics walkthrough now demonstrates the 1.0 saving/record=True opt-ins for extra counts; analyze runs for real, pinned up to the plan text via ellipsis. Operational walkthroughs (rewrite, compare, show_slow_report) are converted but +SKIP-marked — they illustrate sessions, not reproducible transcripts. (staged does run, after review: it stages the insertion of the first totally real quartic field, an update, and a deletion, landing the table back where it started, with the swap's progress output pinned via ellipses.)

CI: the runner is an ordinary test file, so the database job picks it up with no workflow changes; without a reachable server it skips with the rest of the suite, and the unit job's explicit file list is unaffected. The tables' fixed names mean the file must not run concurrently with itself against one database — the suite runs serially, noted in the module docstring for anyone experimenting with pytest-xdist.

Verified: the 9 doctest module runs pass (128 examples), full suite 866 passed / 36 skipped on a scratch PG 18 cluster, sphinx -W clean, ruff clean, zero sage: prompts and zero lmfdb imports remaining in docstrings.

Review rounds addressed: the fixture never guesses ownership — it refuses to run while anything occupies its namespace (test_fields/test_curves or derived _tmp/_old*/_counts/_stats names, detected through pg_tables so bare debris outside psycodict's meta tables is caught too), with an explicit manual-cleanup recipe in the failure message; recovery from a crashed run is deliberately manual. The staged() example is now a valid, running transcript instead of referencing columns from the old sample table, and the fixture description no longer overclaims completeness (the rationals, twelve quadratics, nine cubics). Verified: doctests pass twice consecutively (any teardown leak would fail the second run's occupancy gate), and a bare test_fields_old1 decoy created outside psycodict fails the run with the message and survives untouched.

🤖 Generated with Claude Code

Every EXAMPLES block in the library is now a real transcript: 128
plain-Python prompts (was 137 sage: prompts, 21 docstrings importing
lmfdb) that tests/test_doctests.py executes as doctests against two
small fixed tables of genuine LMFDB data it creates -- test_fields
(the number fields of degree <= 3 with |disc| <= 90) and test_curves
(a dozen elliptic curves over three of those fields).  Examples keep
their mathematical flavor while every printed output is verified: the
getting-started walkthrough in __init__ (which exercises configuration
discovery via PSYCODICT_CONFIG), the query-parsing internals (whose
old expected outputs had drifted: _parse_special has grown a col_type
argument and array containment now emits a typecast), search/lucky/
lookup/count and the join example, the statistics workflow including
the saving/record opt-ins from the 1.0 changes, analyze (checked up to
the plan text via ellipsis), and the pure helpers.  Operational
walkthroughs (rewrite, staged, compare, show_slow_report) are
converted but marked +SKIP.

The runner is part of the ordinary suite, so the database CI job picks
it up with no workflow changes; without a reachable server it skips
with the rest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@read-the-docs-community

read-the-docs-community Bot commented Jul 22, 2026

Copy link
Copy Markdown

Documentation build overview

📚 psycodict | 🛠️ Build #33703554 | 📁 Comparing 80fdd5f against latest (bac6dc5)

  🔍 Preview build  

17 files changed · ± 17 modified

± Modified

roed314 and others added 2 commits July 22, 2026 04:53
…est census

Three review findings on the doctest examples:

- The fixture force-dropped any existing test_fields/test_curves,
  violating the suite's isolation promise.  It now refuses to touch an
  existing table unless it is recognizably this file's own leftover
  (same columns, same label set), failing with a clear message
  otherwise; verified against a decoy table, which survives untouched
  while all nine tests fail safely.  Setup and teardown also clear
  psycodict's _tmp/_old debris (the staged example creates a
  test_fields_old1 backup, which previously leaked and would have
  broken the second run).

- The +SKIP'd staged() example referenced an undefined variable and
  columns that do not exist in test_fields.  It is now a real, running
  transcript: staging the insertion of the (genuine) first totally
  real quartic field 4.4.725.1, an update, and a deletion, so the
  table ends where it started; the swap's progress output is pinned
  with ellipses for the timings.

- test_fields was described as all fields with degree <= 3 and
  |disc| <= 90; the quadratics are a selection (the LMFDB has 66 such
  fields).  Reworded everywhere to 22 selected fields (the rationals,
  thirteen quadratic fields, and the nine cubic fields with
  |disc| <= 90 -- the cubics actually are complete).

Verified: doctests pass twice in a row against the same database, full
suite 866 passed / 36 skipped, sphinx -W clean, ruff clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The collision guard no longer classifies anything as 'our leftover':
the fixture refuses to run while any table occupies its namespace --
test_fields/test_curves or anything derived from them (_tmp, _old*,
_counts, _stats), found through pg_tables so that bare debris outside
psycodict's meta tables is caught too -- and the failure message gives
the explicit cleanup recipe.  Recovery from a crashed run is manual by
design.  The teardown claim is now load-bearing in both directions:
the namespace was verified empty at setup, so everything present at
teardown is ours, and any teardown leak fails the next run's gate
(verified by running twice consecutively, and by a bare
test_fields_old1 decoy created outside psycodict, which fails the run
with the message and survives untouched).

Also corrects the sample census: the rationals, twelve (not thirteen)
quadratic fields, and the nine cubic fields with |disc| <= 90.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@roed314
roed314 merged commit c3e660c into roed314:main Jul 22, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants