From 524503031c0a9f3d2c77a6d5db8b875b54f1f5dc Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Wed, 1 Apr 2026 22:59:18 -0700 Subject: [PATCH] [ILibrary / LazyLibrary] allow mapping a name to itself --- masque/library.py | 12 ++++++++++++ masque/test/test_library.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/masque/library.py b/masque/library.py index 5a60e8d..d7a30af 100644 --- a/masque/library.py +++ b/masque/library.py @@ -828,6 +828,9 @@ class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], metaclass=ABCMeta): """ if old_name not in self: raise LibraryError(f'"{old_name}" does not exist in the library.') + if old_name == new_name: + return self + self[new_name] = self[old_name] del self[old_name] if move_references: @@ -852,6 +855,9 @@ class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], metaclass=ABCMeta): Returns: self """ + if old_target == new_target: + return self + for pattern in self.values(): if old_target in pattern.refs: pattern.refs[new_target].extend(pattern.refs[old_target]) @@ -1483,6 +1489,9 @@ class LazyLibrary(ILibrary): """ if old_name not in self.mapping: raise LibraryError(f'"{old_name}" does not exist in the library.') + if old_name == new_name: + return self + self[new_name] = self.mapping[old_name] # copy over function if old_name in self.cache: self.cache[new_name] = self.cache[old_name] @@ -1504,6 +1513,9 @@ class LazyLibrary(ILibrary): Returns: self """ + if old_target == new_target: + return self + self.precache() for pattern in self.cache.values(): if old_target in pattern.refs: diff --git a/masque/test/test_library.py b/masque/test/test_library.py index 621e703..ce564aa 100644 --- a/masque/test/test_library.py +++ b/masque/test/test_library.py @@ -221,6 +221,28 @@ def test_library_rename() -> None: assert "old" not in lib["parent"].refs +@pytest.mark.parametrize("library_cls", (Library, LazyLibrary)) +def test_library_rename_self_is_noop(library_cls: type[Library] | type[LazyLibrary]) -> None: + lib = library_cls() + lib["top"] = Pattern() + lib["parent"] = Pattern() + lib["parent"].ref("top") + + lib.rename("top", "top", move_references=True) + + assert set(lib.keys()) == {"top", "parent"} + assert "top" in lib["parent"].refs + assert len(lib["parent"].refs["top"]) == 1 + + +@pytest.mark.parametrize("library_cls", (Library, LazyLibrary)) +def test_library_rename_top_self_is_noop(library_cls: type[Library] | type[LazyLibrary]) -> None: + lib = library_cls() + lib["top"] = Pattern() + + lib.rename_top("top") + + assert list(lib.keys()) == ["top"] @pytest.mark.parametrize("library_cls", (Library, LazyLibrary)) @@ -230,6 +252,21 @@ def test_library_rename_missing_raises_library_error(library_cls: type[Library] with pytest.raises(LibraryError, match="does not exist"): lib.rename("missing", "new") + + +@pytest.mark.parametrize("library_cls", (Library, LazyLibrary)) +def test_library_move_references_same_target_is_noop(library_cls: type[Library] | type[LazyLibrary]) -> None: + lib = library_cls() + lib["top"] = Pattern() + lib["parent"] = Pattern() + lib["parent"].ref("top") + + lib.move_references("top", "top") + + assert "top" in lib["parent"].refs + assert len(lib["parent"].refs["top"]) == 1 + + def test_library_dfs_can_replace_existing_patterns() -> None: lib = Library() child = Pattern()