diff --git a/backends/ezdxf_backend.py b/backends/ezdxf_backend.py index 73f9acd..2e49151 100644 --- a/backends/ezdxf_backend.py +++ b/backends/ezdxf_backend.py @@ -4453,6 +4453,13 @@ class EzdxfBackend(AutoCADBackend): } if layer: attribs["layer"] = layer + # `add_blockref` never checks the name, and `add_auto_attribs` + # silently skips autofill when `Insert.block()` resolves to None, + # so a typo'd name used to yield a dangling INSERT that dropped its + # attribute values and that `doc.audit()` later deletes. Refuse + # before writing, as COM's `InsertBlock` does for an unknown name. + if name not in self._doc.blocks: + raise ValueError(f"block {name!r} is not defined") ref = msp.add_blockref(name, (float(x), float(y)), dxfattribs=attribs) if attributes: # `add_auto_blockref` wraps the INSERT in an anonymous *U block, diff --git a/tests/test_block_insert_attributes.py b/tests/test_block_insert_attributes.py index b334f8f..59a69f7 100644 --- a/tests/test_block_insert_attributes.py +++ b/tests/test_block_insert_attributes.py @@ -41,3 +41,15 @@ async def test_insert_without_attributes_is_unchanged(backend): info = await backend.entity_get(ref.handle) assert info.properties["block_name"] == "TB" assert await backend.block_get_attributes(ref.handle) == {} + + +@pytest.mark.parametrize("attributes", [{"TAG": "P-101"}, None], ids=["with-attrs", "no-attrs"]) +async def test_insert_of_undefined_block_is_refused_before_writing(backend, attributes): + # `add_blockref` never checks the name and `add_auto_attribs` skips autofill + # when the definition is missing, so a typo'd name used to return a handle + # whose attribute values were dropped and which `doc.audit()` later deletes. + before = len(list(backend._msp())) + with pytest.raises(ValueError, match="'NO_SUCH_BLOCK' is not defined"): + await backend.block_insert("NO_SUCH_BLOCK", 5, 5, attributes=attributes) + assert len(list(backend._msp())) == before, "a refused insert must not write" + assert [b.name for b in backend._doc.blocks if b.name == "NO_SUCH_BLOCK"] == []