Docxodus v12.1.0: drop WmlComparer for DocxDiff (1.0.0) - #32
Merged
Conversation
Docxodus v11.0.0 deleted the WmlComparer engine in favour of DocxDiff, which has been its default since v8.0.0. That removal reaches straight into this project's public API, which has exposed the upstream selector as a keyword argument since 0.3.0. BREAKING CHANGE: engine, detail_threshold and simplify_move_markup are removed from DocxodusEngine.run_redline() and raise ValueError. They are rejected rather than dropped, because dropping them would not be a breaking change but a wrong-answer one. The v12 CLI rejects --engine as an unknown flag and merely warns-and-ignores the other two, so a caller passing engine="wmlcomparer" would have silently received DocxDiff output believing they had selected something else. Unknown keyword arguments are rejected on the same reasoning: a typo used to be discarded in silence, which is indistinguishable from a setting that did nothing. The GitHub Action's `comparison` input maps onto the deleted selector and now fails the run for the same reason. XmlPowerToolsEngine wraps the *original* Open-XML-PowerTools WmlComparer in a separately published wheel. It keeps working and keeps shipping; instantiating it now warns that it is on the way out. Also fixes two bugs in BaseEngine.run_redline's temp-file handling: - #30: the output scratch file was NamedTemporaryFile(delete=False).name, which drops the only reference to the file object. Its finalizer reports a ResourceWarning on CPython 3.13+ and the descriptor stays open until collection. Now mkstemp, which is the right tool when only a path is wanted. - Path inputs were registered for deletion alongside the engine's own scratch files, so passing a path — a documented input mode that the quickstart demonstrates — deleted the caller's source documents. Only files this library creates are cleaned up now. Revision counts on the fixtures are re-pinned to 10, measured against a freshly built v12.1.0 binary. It is neither the 9 the old default reported nor the 11 the old opt-in reported: v11 and v12 changed region arrangement, surplus table cells and section defaults. Fixes #30 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ed9PC7DDco5AFPjsZyy9F
The README described three ways to compare across two engine classes; two of those three are gone. It now describes two engine classes, one algorithm each, and carries an "Upgrading to 1.0.0" section covering the removed keyword arguments, the re-baselined revision count, and the input-revision policy change that this project's fixtures cannot warn anyone about. The Action self-test no longer asserts an exact revision count. That workflow installs python-redlines from PyPI, so the number it sees tracks the published version rather than the branch under test — pinning it to 10 here would fail every run until 1.0.0 ships, and pinning it to 9 would fail every run afterwards. It asserts a positive count, which is what "the action plumbing works" actually means; the exact count is pinned in tests/test_docxodus_engine.py, which runs against the working tree. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ed9PC7DDco5AFPjsZyy9F
Development Status moves from 4 - Beta to 5 - Production/Stable, which is what shipping a 1.0.0 asserts. The `ooxmlpowertools` extra now says in the file that it installs a deprecated engine. `all` deliberately keeps installing it: the extra exists so that anyone who needs the original WmlComparer's output has somewhere to stand, and quietly changing what `all` resolves to would break existing pins to make a point. Drops the brainstorming design doc from the branch — its substance lives in the previous commit message, the PR body, and the README's "Upgrading to 1.0.0" section, and a published package's repo is not the place for a process artifact. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ed9PC7DDco5AFPjsZyy9F
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.
Tracks the Docxodus submodule from v7.0.0 to v12.1.0 and releases the result as 1.0.0.
Docxodus v11.0.0 deleted the
WmlComparerengine in favour ofDocxDiff, its default since v8.0.0 and now mature. That removal reaches straight into this project's public API, which has exposed the upstream selector as a keyword argument since 0.3.0.Breaking changes
Three keyword arguments are removed from
DocxodusEngine.run_redline()and raiseValueError:enginewmlcompareranddocxdiff. There is nothing left to select.detail_thresholdWmlComparer's LCS granularity.DocxDiff's granularity is structural.simplify_move_markupWmlComparer's move markup.DocxDiffrenders moves natively.They raise rather than being ignored, and that is the load-bearing part of this PR. Simply deleting the code path would not have produced a breaking change — it would have produced a wrong-answer change.
_build_commandonly reads keys it knows about, sorun_redline(..., engine="wmlcomparer")would have become a silently-ignored kwarg handing the caller DocxDiff output while they believed they had selected WmlComparer.There is a second, independent reason: the v12 CLI writes a warning to stderr for
--detail-threshold=and--simplify-move-markup.run_redlinesurfaces any non-empty stderr, so passing them through breaks everyassert stderr is Nonein the suite.Unknown keyword arguments are now rejected on the same reasoning —
detial_threshold=0.5used to vanish in silence, which is indistinguishable from a setting that did nothing.The Action's
comparisoninput maps onto the deleted selector and now fails the run.Bug fixes
Issue #30 — leaked
NamedTemporaryFile. The output scratch file wastempfile.NamedTemporaryFile(delete=False).name, which drops the only reference to the file object. Its finalizer reportsResourceWarningon CPython 3.13+, once per call, and under-W errorsurfaces as an unraisable exception attributed to whatever test was running when the collector fired. Nowmkstemp, which is the right tool when only a path is wanted.Data loss on path inputs — found while fixing #30, and the most user-protective change here.
run_redlineappendedoriginal_pathandmodified_pathtotemp_filesunconditionally, and thefinallyblockos.removes every entry. When the caller passed a path — a documented, type-hinted input mode thatdocs/quickstart.mddemonstrates — those entries were the caller's own files:Only byte inputs were safe, which is why the Action (bytes-only) never hit it. Only files this library creates are registered for cleanup now. Anyone who avoided the path API because it ate their documents can use it.
Revision counts: measured, not predicted
The fixture count is now 10. It is neither the 9 the old default reported nor the 11 the 0.3.0 opt-in reported — v11/v12 changed region arrangement, surplus table cells and section defaults. Measured against a freshly built v12.1.0 binary, with
~/.cache/python-redlinescleared first (the extraction cache keys on the installed binary package version, so a rebuilt binary at an unchanged version is otherwise silently ignored).The Action self-test workflow no longer asserts an exact count: it installs python-redlines from PyPI, so its number tracks the published version, not this branch. Pinning it to 10 would fail every run until 1.0.0 ships; pinning it to 9 would fail every run after. It asserts a positive count — which is what "the action plumbing works" means — and the exact count stays pinned in
tests/test_docxodus_engine.py, which runs against the working tree.Deliberately not done
XmlPowerToolsEnginewraps the original Open-XML-PowerTools WmlComparer in a separately published wheel. Retiring a package users have pinned is its own decision with its own migration story, so it keeps shipping and keeps working — it just emits aDeprecationWarningnow. Release notes say "the Docxodus engine no longer carries WmlComparer", not "Python-Redlines is WmlComparer-free", which would be false while that wheel exists.allstill resolves to both engines, so existing pins do not change meaning.Verification
72 passed, 1 skipped— the skip is theResourceWarningassertion, which only fires on CPython 3.13+ (this box is 3.12); a version-independent test asserts the same defect directly.linux-x64, and confirmed--engine=now exits 1 as an unknown flag.win-x64as a cross-RID check — the v7→v12 jump touched 1366 files, sodotnet publish -r <rid> --self-containedneeded re-verifying against something other than the native RID before the six-RID release matrix runs.Not verifiable locally: macOS and Windows runners, and the other four RIDs. CI on this PR is the first real test of the v12 submodule on those.
Closes #30
🤖 Generated with Claude Code
https://claude.ai/code/session_014ed9PC7DDco5AFPjsZyy9F