Skip to content

0.4.0 pre-release: quote_blocks without deepcopy; LegaldownDeprecationWarning - #101

Merged
dvejsada merged 1 commit into
mainfrom
claude/jolly-johnson-e3yr9u
Oct 3, 2026
Merged

dvejsada merged 1 commit into
mainfrom
claude/jolly-johnson-e3yr9u

Conversation

@dvejsada

@dvejsada dvejsada commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Two fixes found while migrating PactTrack (ForLegalAI/PactTrack#106) to the unreleased 0.4.0.

quote_blocks RecursionError

  • The bug: legaldown.syntax.quote_blocks deep-copied the cached reading of a quote. copy.deepcopy recurses once per nesting level, so it raised RecursionError for a list nested about 62 levels inside a quote. The parser accepts that input (MAX_LIST_DEPTH is 64).

  • The fix: quote_blocks now reads the quote again without the cache, through _read_quote_content, the uncached body of quote_content. The caller still gets blocks of its own that it may change, and the cache is left alone. drafting_note_blocks is built on quote_blocks, so it is fixed too.

  • Tests: the new tests/test_deep_nesting.py has 100 tests. They run every public path on lists, quotes and mixes of both at and past the parser's limits, from 64 to 70 nested lists and 16 to 20 nested quotes. The paths are:

    • parse, and validate with and without final;
    • serialize, and the dict round trip;
    • layout, line_of and body_layout;
    • iter_document_directives, find_markers and block_fragments;
    • the quote readers and code_content;
    • template assembly.

    Before the fix only quote_blocks and drafting_note_blocks failed. Every path also passes with the recursion limit lowered to 600.

One warning category for every deprecation

  • The change: every deprecation legaldown raises is now a LegaldownDeprecationWarning, a DeprecationWarning subclass exported from legaldown. That covers parse_document, serialize_document, validate_document, the importer keyword arguments, assemble, template_questions and needed_questions.
  • Why: with stacklevel=2 the warnings are attributed to the caller's module, and their messages don't share a prefix, so no single filter caught them all. Existing DeprecationWarning filters still match.
  • Docs: the README shows the two filters that work: warnings.simplefilter("error", LegaldownDeprecationWarning) and pytest's filterwarnings = ["error::legaldown.LegaldownDeprecationWarning"]. Python's own -W option and PYTHONWARNINGS cannot name a category defined in a package. That was checked on Python 3.11, 3.12 and 3.13.

Verification

  • 3169 tests pass with the spec fixtures corpus, 121 of them new. ruff is clean.
  • All 160 spec fixture documents give byte-identical validation results to main.

🤖 Generated with Claude Code

https://claude.ai/code/session_013WmBAc5T7UCKVdpUmg9qxz


Generated by Claude Code

…nWarning

quote_blocks deep-copied the cached reading of a quote, which recursed
once per nesting level and raised RecursionError for a list nested about
62 deep inside a quote — input the parser accepts (MAX_LIST_DEPTH 64).
Found by PactTrack's migration to 0.4.0. It now reads the quote again,
uncached (_read_quote_content), so the blocks are still the caller's to
change and the cache is untouched; drafting_note_blocks builds on it.
tests/test_deep_nesting.py runs every public path (parse, validate with
and without final, serialize, the dict round trip, layout, line_of,
body_layout, iter_document_directives, find_markers, block_fragments,
the quote readers, code_content, template assembly) on lists, quotes and
their mixes at and past the parser's limits.

Every deprecation legaldown raises is now a LegaldownDeprecationWarning
(a DeprecationWarning subclass, exported from legaldown), so one filter
catches them all; the README says how (warnings.simplefilter, or pytest
filterwarnings — Python's -W cannot name a package's category).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013WmBAc5T7UCKVdpUmg9qxz
@dvejsada dvejsada added the ci label Oct 3, 2026 — with Claude
@dvejsada
dvejsada merged commit be91622 into main Oct 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants