Skip to content

Preserve node syntax when printing data class edits - #162

Merged
ESultanik merged 1 commit into
masterfrom
150-dataclass-edit-print
Sep 9, 2026
Merged

ESultanik merged 1 commit into
masterfrom
150-dataclass-edit-print

Conversation

@ESultanik

Copy link
Copy Markdown
Collaborator

Closes #150

DataClassEdit had no print() override, so an edited DataClassNode was rendered by
AbstractCompoundEdit.print, which prints each slot edit back to back. That drops whatever syntax the
node's formatter writes between the slots.

SequenceEdit, the other container edit type, already hands control back to the node's formatter, which
writes the syntax and reaches the sub-edits as it prints each child. DataClassEdit now does the same.
This affects any DataClassNode whose rendering needs punctuation between its slots, so it is a
prerequisite for correct diff rendering in #151 and #154.

A print_DataClassEdit formatter method would be the wrong place for this: print_StringEdit is the only
print_<Edit> formatter in the package, and it exists because a character-level string diff has no
node-level rendering. get_formatter always resolves here, because DataClassNode is a ContainerNode
and formatters find print_ContainerNode through the MRO.

Diff Before After
x = foo(1, 2) -> x = foo(1, 2, 3) [x]foo[1,2,++3++] x = foo(1, 2, ++3++)
x = foo(1, 2) -> y = foo(1, 2) [x -> y]foo[1,2] x -> y = foo(1, 2)
x = foo(1, 2) -> x = bar(1, 2) [x]x = ~~foo~~++bar++(1, 2) x = ~~foo~~++bar++(1, 2)
x = a.b.c -> x = a.b.d [x]abc -> d x = a.b.c -> d

Validation

  • Two new tests in test/test_pydiff.py cover Assignment, Call, and PyObjAttribute. Both fail
    against the unfixed code with the "Before" strings above, and pass with the fix.
  • ruff check graphtage test docs bindist: passes.
  • pytest: 142 passed.
  • make -C docs html SPHINXOPTS="-W --keep-going": build succeeded.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GypKU5KdLfs2Cf8kS2TzJa

`DataClassEdit` had no `print()` override, so an edited `DataClassNode`
fell back to `AbstractCompoundEdit.print`, which prints each slot edit
back to back. That drops whatever syntax the node's formatter writes
between the slots: an edited `Assignment` lost its ` = `, an edited
`PyObjAttribute` lost its dots, and `x = foo(1, 2)` against
`x = foo(1, 2, 3)` rendered as `[x]foo[1,2,++3++]`.

`SequenceEdit`, the other container edit type, already hands control
back to the node's formatter, which writes the syntax and reaches the
sub-edits as it prints each child. `DataClassEdit` now does the same.
A `print_DataClassEdit` formatter method would be the wrong place for
this, because the syntax and the per-child edits both live in the node
formatter. `get_formatter` always resolves, because `DataClassNode` is
a `ContainerNode` and formatters find `print_ContainerNode` through the
MRO.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GypKU5KdLfs2Cf8kS2TzJa
@ESultanik
ESultanik merged commit 82f6619 into master Sep 9, 2026
11 checks passed
@ESultanik
ESultanik deleted the 150-dataclass-edit-print branch September 9, 2026 14:27
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.

DataClassEdit does not override print(), so edited data class nodes lose their syntax

1 participant