Make the docstring examples runnable doctests against real LMFDB sample data#129
Merged
Conversation
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>
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The agreed follow-up to #127: every
EXAMPLESblock in the library is now a runnable, verified transcript — plain-Python>>>prompts executed as doctests by a newtests/test_doctests.py, replacing 137sage:prompts of which 21 docstrings didfrom lmfdb import dband 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) — andtest_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')→3is a true fact about ℚ(√−23) — while every printed output is checked. The getting-started block in__init__doubles as a demo of configuration discovery: itsPostgresDatabase()line genuinely connects via$PSYCODICT_CONFIG.Drift the conversion surfaced and fixed:
_parse_special's examples predated itscol_typeargument 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.0saving/record=Trueopt-ins for extra counts;analyzeruns 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. (stageddoes 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 -Wclean,ruffclean, zerosage: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_curvesor derived_tmp/_old*/_counts/_statsnames, detected throughpg_tablesso 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. Thestaged()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 baretest_fields_old1decoy created outside psycodict fails the run with the message and survives untouched.🤖 Generated with Claude Code