ereader_layout.py defined _add_page_methods() and called it at import
time, attaching can_fit_line and available_width to the Page class if
they were absent. Page defines both, so the patch never fired - but the
two definitions of can_fit_line disagreed:
Page can_fit_line(baseline_spacing, ascent=0, descent=0)
monkey patch can_fit_line(line_height)
The patched version had no way to express descent, which is exactly the
clipping bug S2 fixed. Had Page.can_fit_line ever been renamed or moved,
this would have silently reinstated pre-S2 behaviour as a side effect of
importing a module in a different package.
Import-time patching of another module's class has no place here. If the
layout engine needs something from Page, it belongs on Page.
Tests pin the outcome: the module exposes no patcher, Page owns both
attributes, and can_fit_line still rejects a line whose descender would
hang past the content box.
894 passed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>