Skip to content

Linear-time rendering of deep nesting; html5ever 0.40.1; Python 3.15t wheels - #2

Merged
jaredlynskey merged 6 commits into
mainfrom
housekeeping
Oct 30, 2026
Merged

jaredlynskey merged 6 commits into
mainfrom
housekeeping

Conversation

@jaredlynskey

Copy link
Copy Markdown
Owner

Summary

  • Fix: 0.4.0's plain-text renderer was quadratic on deeply nested lists, definitions, paragraphs and emphasis (400,000 nested lists took 49 s). Now 0.5 s, with unchanged output. New regression test.
  • html5ever 0.40.1 (vendored), still with Fix quadratic parsing of deeply nested markup servo/html5ever#800. Trees, quirks mode and parse errors match stock 0.40.1 on 76,597 inputs and the single-page HTML standard. pyhtml2text's output is unchanged. Building from source now needs Rust 1.85.
  • unicode-width 0.2.3 (Unicode 18): the halfwidth katakana sound marks ゙ ゚ now count one column. Characters new in Unicode 18 get their widths. Nothing else changes.
  • Free-threaded Python 3.15: cp315t wheels on every platform. CI tests on 3.10, 3.14t, 3.15 and 3.15t via .github/pytest.sh.
  • Smaller changes:
    • setup-uv 10.3.3
    • The release job drops contents: write
    • New classifiers
    • README fixes
    • Changelog

Test plan

  • pytest (62) on 3.10, 3.15 and 3.15t locally. cargo test, clippy and fmt pass.
  • Output compared with 0.4.0 on 39 real pages × 11 option sets and 13,000 random documents, plus 7,688 deep-nesting cases.
  • sdist builds a wheel offline.
  • CI: 3.15t wheels build on manylinux, musllinux, Windows and macOS, and the new test matrix passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UAcwbHeVLzMGEur9Rwxt7S

jaredlynskey and others added 6 commits October 30, 2026 13:50
0.4.0's renderer did work for every enclosing level at each level:
mark() flagged every open frame, each prefixed block copied its lines to
put its prefix in front, and each character compared the whole stack of
open styles. 400,000 nested lists took 49 s.

Frames are now flagged from the innermost out until one already is, lines
keep their prefixes back to front until they leave the renderer, and each
distinct style stack has a number. The lists now take 0.5 s. Output is
unchanged: the same as before on 39 real pages with every option set and
on 13,000 random documents with six, and the same as 0.4.0 on 31 nesting
patterns at 62 depths with four.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UAcwbHeVLzMGEur9Rwxt7S
The vendored html5ever is now 0.40.1, with servo/html5ever#800 applied as
it is (the PR is against 0.40.1). html5ever's own tests and all html5lib
tree-construction and tokenizer tests pass in release and debug builds;
trees, quirks mode and exact parse errors match stock 0.40.1 on every
html5lib input, 73,000 random documents (a third as fragments), 39 real
pages and the single-page HTML standard; and pyhtml2text's output is the
same as with the previous copy. Stock 0.40.1 takes 18 s to parse 40,000
nested lists; the patched copy 0.04 s.

unicode-width 0.2.3 has Unicode 18's widths. It changes the width of 1,029
characters: the halfwidth katakana sound marks U+FF9E and U+FF9F (now one
column, as terminals show them, rather than none) and characters new in
Unicode 18. No other string's width changes (1.5 million random strings of
Arabic, Kirat Rai, Hangul jamo, Devanagari, emoji and joiners compared).

Also cc 1.10.0 and smallvec 1.16.4.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UAcwbHeVLzMGEur9Rwxt7S
- Build cp315t wheels alongside cp314t on every platform. The abi3 wheels
  already cover 3.15.
- CI runs the tests on 3.10, 3.14t, 3.15 and 3.15t (3.11 rather than 3.10
  on Windows arm64, which has no uv-managed 3.10) through one script,
  .github/pytest.sh, instead of on whichever Python the runner had.
- setup-uv 10.3.3. The release job no longer asks for contents: write,
  which it doesn't use.
- Python version, free-threading, Markdown and Typed classifiers.
- README: label the Markdown example's output, and mention 3.15t.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UAcwbHeVLzMGEur9Rwxt7S
sccache before 0.19 can't parse the `-Tp <path>` that cc 1.9 and later
pass cl.exe for mimalloc's C++ source, so every Windows build failed
(rust-lang/cc-rs#2063, merged but not released). Tag builds already ran
without sccache.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UAcwbHeVLzMGEur9Rwxt7S
On macOS and Windows, uv took the free-threaded 3.15t set up for the build
for "3.15", so the abi3 wheel wasn't tested on 3.15 there.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UAcwbHeVLzMGEur9Rwxt7S
@jaredlynskey
jaredlynskey merged commit 70b038c into main Oct 30, 2026
17 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.

1 participant