fix(edit_schematic_component): update (reference "...") inside (instances) on rename (#186)
Closes #126. A placed schematic symbol carries its reference designator in two places: (symbol (property "Reference" "R5" …) ← what eeschema renders (instances (project "MyProject" (path "/sheet-uuid/symbol-uuid" (reference "R5") ← what netlist + PCB sync read (unit 1) ))) …) Before this change, `edit_schematic_component` with `newReference` updated only the (property "Reference" …) field. The (reference "…") leaves inside (instances) → (project) → (path) kept the old value. eeschema rendered the new reference correctly and ERC passed, but `kicad-cli sch export netlist` and "Update PCB from Schematic" both read from the (instances) block and silently used the OLD reference — producing destructive PCB-sync diffs on what users thought was a clean rename. Severity was high for anyone running batch renames because the symptom only surfaces at PCB-sync time, by which point many renames may be queued. Walk the (instances) subtree within the matched symbol block after the property update and replace every `(reference "OLD")` leaf with the new value. The regex matches `(reference "X")` specifically (not `(property "Reference" "X"`), and the walk is constrained to the (instances …) range via the existing _find_matching_paren helper so other (reference …) tokens elsewhere in the file can't be affected. Adds tests/test_edit_schematic_component_instances.py covering: - Single-instance rename updates both property and instances leaf - Hierarchical case with multiple (path …) entries all updated atomically - No-instances-block schematics don't crash (older KiCad / partial files) - The regex doesn't clobber (property "Reference" …) on the instances pass - Other field values (Value, Footprint) are left intact - The response payload's updated.reference reflects the new ref All 6 tests fail on main without the fix (3 fully, 3 on the instances assertions only) and pass on this branch. The pre-existing TestAddComponentMirrorParam failures in test_add_schematic_component.py are unrelated and present on main — documented in inktomi's PR #169. Co-authored-by: mixelpixx <11727006+mixelpixx@users.noreply.github.com>
This commit is contained in:
@@ -1471,6 +1471,28 @@ class KiCADInterface:
|
||||
rf'\1"{escaped_r}"',
|
||||
block_text,
|
||||
)
|
||||
# Also update the (reference "...") leaves inside the symbol's
|
||||
# (instances) → (project) → (path) subtree. KiCad reads those
|
||||
# entries — not the (property "Reference" ...) field — when
|
||||
# generating netlists and syncing the PCB via "Update PCB from
|
||||
# Schematic", so leaving them stale produces a silent
|
||||
# reference mismatch where eeschema shows the new ref but ERC
|
||||
# / netlist export / PCB sync all use the old one. See #126.
|
||||
instances_pos = block_text.find("(instances")
|
||||
if instances_pos >= 0:
|
||||
instances_end = self._find_matching_paren(block_text, instances_pos)
|
||||
if instances_end >= 0:
|
||||
instances_block = block_text[instances_pos : instances_end + 1]
|
||||
updated_instances = re.sub(
|
||||
r'(\(reference\s+)"' + re.escape(reference) + r'"',
|
||||
rf'\1"{escaped_r}"',
|
||||
instances_block,
|
||||
)
|
||||
block_text = (
|
||||
block_text[:instances_pos]
|
||||
+ updated_instances
|
||||
+ block_text[instances_end + 1 :]
|
||||
)
|
||||
if field_positions is not None:
|
||||
for field_name, pos in field_positions.items():
|
||||
x = pos.get("x", 0)
|
||||
|
||||
Reference in New Issue
Block a user