fix(task-2): find_replace rewrites every surface of a multi-line attribute; COM explode propagates a failing read and undoes a failed burst
Headless text_find_replace matched and wrote only dxf.text of an ATTRIB/ATTDEF, so on a multi-line attribute it reported replaced: 1 while block_get_attributes and block_explode still carried the old embedded MTEXT (and a needle on the second line was never found). The ATTRIB/ATTDEF branch now reads through _attrib_value and writes through _write_attrib_value, the same pair block_get_attributes / block_set_attributes use. COM block_explode swallowed a failing GetAttributes() (attrs = ()), GetConstantAttributes() and Invisible, then exploded, deleted every ATTDEF placeholder and the reference and returned ok: True with no attribute text -- every value destroyed silently on a transient RPC_E_CALL_REJECTED. Those reads now happen before Explode() and propagate with nothing written; a failure after the explode deletes the members it added and the TEXTs written so far and leaves the reference in place (_undo_explode), so the drawing is never left half-burst under an exception. The fakes gain the members a live AcadBlockReference / AcadAttributeDefinition always expose (GetConstantAttributes, Constant, Invisible) instead of relying on the swallow. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
co-authored by
Claude Opus 5
parent
5f33613460
commit
b753a12bb6
@@ -3958,13 +3958,27 @@ class EzdxfBackend(AutoCADBackend):
|
||||
seen.add(key)
|
||||
if layer and entity.dxf.get("layer", "0") != layer:
|
||||
continue
|
||||
current = entity.text if dxftype == "MTEXT" else entity.dxf.get("text", "")
|
||||
# An ATTRIB/ATTDEF is read and written through the attribute
|
||||
# helpers: a multi-line one keeps its content in an embedded
|
||||
# MTEXT and ``dxf.text`` is only the first line, so matching
|
||||
# and writing ``dxf.text`` alone reported ``replaced: 1`` while
|
||||
# ``block_get_attributes`` and ``block_explode`` still carried
|
||||
# the old value. One value, every surface -- the same rule
|
||||
# ``block_set_attributes`` follows.
|
||||
if dxftype == "MTEXT":
|
||||
current = entity.text
|
||||
elif dxftype in ("ATTRIB", "ATTDEF"):
|
||||
current = self._attrib_value(entity)
|
||||
else:
|
||||
current = entity.dxf.get("text", "")
|
||||
if not current or not pattern.search(current):
|
||||
continue
|
||||
updated = pattern.sub(replace, current)
|
||||
if not dry_run:
|
||||
if dxftype == "MTEXT":
|
||||
entity.text = updated
|
||||
elif dxftype in ("ATTRIB", "ATTDEF"):
|
||||
self._write_attrib_value(entity, updated)
|
||||
else:
|
||||
entity.dxf.text = updated
|
||||
changed.append(
|
||||
|
||||
Reference in New Issue
Block a user