[Pattern] make plug/place atomic wrt. annotation conflicts
This commit is contained in:
parent
524503031c
commit
0f2b4d713b
2 changed files with 38 additions and 0 deletions
|
|
@ -1387,6 +1387,10 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
|
|||
if append:
|
||||
if isinstance(other, Abstract):
|
||||
raise PatternError('Must provide a full `Pattern` (not an `Abstract`) when appending!')
|
||||
if other.annotations is not None and self.annotations is not None:
|
||||
annotation_conflicts = set(self.annotations.keys()) & set(other.annotations.keys())
|
||||
if annotation_conflicts:
|
||||
raise PatternError(f'Annotation keys overlap: {annotation_conflicts}')
|
||||
else:
|
||||
if isinstance(other, Pattern):
|
||||
raise PatternError('Must provide an `Abstract` (not a `Pattern`) when creating a reference. '
|
||||
|
|
@ -1562,6 +1566,10 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
|
|||
if append:
|
||||
if isinstance(other, Abstract):
|
||||
raise PatternError('Must provide a full `Pattern` (not an `Abstract`) when appending!')
|
||||
if other.annotations is not None and self.annotations is not None:
|
||||
annotation_conflicts = set(self.annotations.keys()) & set(other.annotations.keys())
|
||||
if annotation_conflicts:
|
||||
raise PatternError(f'Annotation keys overlap: {annotation_conflicts}')
|
||||
elif isinstance(other, Pattern):
|
||||
raise PatternError('Must provide an `Abstract` (not a `Pattern`) when creating a reference. '
|
||||
'Use `append=True` if you intended to append the full geometry.')
|
||||
|
|
|
|||
|
|
@ -148,6 +148,17 @@ def test_pattern_place_append_requires_pattern_atomically() -> None:
|
|||
assert not parent.ports
|
||||
|
||||
|
||||
def test_pattern_place_append_annotation_conflict_is_atomic() -> None:
|
||||
parent = Pattern(annotations={"k": [1]})
|
||||
child = Pattern(annotations={"k": [2]}, ports={"A": Port((1, 2), 0)})
|
||||
|
||||
with pytest.raises(PatternError, match="Annotation keys overlap"):
|
||||
parent.place(child, append=True)
|
||||
|
||||
assert not parent.ports
|
||||
assert parent.annotations == {"k": [1]}
|
||||
|
||||
|
||||
def test_pattern_interface() -> None:
|
||||
source = Pattern()
|
||||
source.ports["A"] = Port((10, 20), 0, ptype="test")
|
||||
|
|
@ -192,6 +203,25 @@ def test_pattern_plug_requires_abstract_for_reference_atomically() -> None:
|
|||
assert set(parent.ports) == {"X"}
|
||||
|
||||
|
||||
def test_pattern_plug_append_annotation_conflict_is_atomic() -> None:
|
||||
parent = Pattern(
|
||||
annotations={"k": [1]},
|
||||
ports={"X": Port((0, 0), 0), "Q": Port((9, 9), 0)},
|
||||
)
|
||||
child = Pattern(
|
||||
annotations={"k": [2]},
|
||||
ports={"A": Port((0, 0), pi), "B": Port((5, 0), 0)},
|
||||
)
|
||||
|
||||
with pytest.raises(PatternError, match="Annotation keys overlap"):
|
||||
parent.plug(child, {"X": "A"}, map_out={"B": "Y"}, append=True)
|
||||
|
||||
assert set(parent.ports) == {"X", "Q"}
|
||||
assert_allclose(parent.ports["X"].offset, (0, 0))
|
||||
assert_allclose(parent.ports["Q"].offset, (9, 9))
|
||||
assert parent.annotations == {"k": [1]}
|
||||
|
||||
|
||||
def test_pattern_append_port_conflict_is_atomic() -> None:
|
||||
pat1 = Pattern()
|
||||
pat1.ports["A"] = Port((0, 0), 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue