From d03fafcaf6718d9af4bb9d23667d92c961a17507 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Mon, 30 Mar 2026 23:34:31 -0700 Subject: [PATCH] [ILibraryView] don't fail on nested dangling ref --- masque/library.py | 5 +++-- masque/test/test_library.py | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/masque/library.py b/masque/library.py index cb50139..bb2e3d2 100644 --- a/masque/library.py +++ b/masque/library.py @@ -294,8 +294,9 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta): def flatten_single(name: str) -> None: flattened[name] = None pat = self[name].deepcopy() + refs_by_target = tuple((target, tuple(refs)) for target, refs in pat.refs.items()) - for target in pat.refs: + for target, refs in refs_by_target: if target is None: continue if dangling_ok and target not in self: @@ -310,7 +311,7 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta): if target_pat.is_empty() and not ports_only: # avoid some extra allocations continue - for ref in pat.refs[target]: + for ref in refs: if flatten_ports and ref.repetition is not None and target_pat.ports: raise PatternError( f'Cannot flatten ports from repeated ref to {target!r}; ' diff --git a/masque/test/test_library.py b/masque/test/test_library.py index 1f65595..0a04d98 100644 --- a/masque/test/test_library.py +++ b/masque/test/test_library.py @@ -166,6 +166,24 @@ def test_library_flatten_repeated_ref_with_ports_raises() -> None: lib.flatten("parent", flatten_ports=True) +def test_library_flatten_dangling_ok_nested_preserves_dangling_refs() -> None: + lib = Library() + child = Pattern() + child.ref("missing") + lib["child"] = child + + parent = Pattern() + parent.ref("child") + lib["parent"] = parent + + flat = lib.flatten("parent", dangling_ok=True) + + assert set(flat["child"].refs) == {"missing"} + assert flat["child"].has_refs() + assert set(flat["parent"].refs) == {"missing"} + assert flat["parent"].has_refs() + + def test_lazy_library() -> None: lib = LazyLibrary() called = 0