Repository navigation
Conversation
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.
Disclosure: this contribution was written by Árbol, an AI assistant working under the direction of the account holder, who set the acceptance criteria and verified the results before submission.
Problem
A comment that appears inside a variation before its first move is
collected by
GameBuilderas a pending starting comment. If thevariation contains no move at all — an empty variation such as
({lonely}), or a variation whose moves are all skipped after anillegal move — the pending comments are never consumed, and they leak
onto the next move parsed afterwards, wherever that is:
That violates the documented contract of
GameNode.starting_comments("Only nodes that actually start avariation can have a starting comment"). It also breaks export round
trips: the exporter writes the starting comment before
2. Nf3, atwhich position it re-parses as a post-move comment on
e5, so thecomment is silently re-attached to a different node:
Nested variations are affected the same way
(
(2. Bc4 ({lonely}) Bc5 ...)landslonelyinBc5.starting_comments). Related symptoms of the same leak: acomment in an empty variation in front of a sibling variation becomes
that sibling's starting comment, and a comment in an empty variation
at the end of a game is dropped entirely.
The defect is also present in the released 1.11.2
GameBuilder(single-string comment API); this patch is against master.
Fix
Scope the pending starting-comment buffer to the variation it was
collected in:
begin_variation()saves the enclosing buffer and starts a freshone (so nested variations cannot mix buffers).
end_variation()attaches any still-pending comments to thecommentsof the node the variation branched from — the positionthe annotation belongs to — and restores the saved buffer.
With this, the example above parses with
e5.comments == ['lonely']and
Nf3.starting_comments == [], and export round trips are theidentity. Legitimate starting comments (variations that do contain
moves) are unaffected.
Tests
Added regression tests covering: the mainline leak, round-trip
identity, the nested empty variation, end-of-game preservation,
sibling non-contamination, nested buffer scoping, an invariant sweep
(no node carries starting comments without starting a variation),
and legitimate starting comments. Full test suite with this change: 297 tests, OK
(22 skipped, external engine/tablebase binaries unavailable).
Unpatched master runs 296 tests, OK, and the new regression test
fails there.
mypy --strict chesspasses.