From b9848d149c0f5c18a4151d977405cc4d909283a2 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Tue, 31 Jan 2023 12:05:44 -0800 Subject: [PATCH] ergonomics --- masque/__init__.py | 9 +++++++-- masque/library.py | 38 ++++++++++++++++++++++++++++++-------- masque/ref.py | 8 +++++--- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/masque/__init__.py b/masque/__init__.py index c22c18c..f15133b 100644 --- a/masque/__init__.py +++ b/masque/__init__.py @@ -32,9 +32,14 @@ from .error import MasqueError, PatternError, LibraryError, BuildError from .shapes import Shape, Polygon, Path, Circle, Arc, Ellipse from .label import Label from .ref import Ref -from .pattern import Pattern +from .pattern import Pattern, NamedPattern -from .library import Library, MutableLibrary, WrapROLibrary, WrapLibrary, LazyLibrary, AbstractView +from .library import ( + Library, MutableLibrary, + WrapROLibrary, WrapLibrary, LazyLibrary, + AbstractView, + Tree, + ) from .ports import Port, PortList from .abstract import Abstract from .builder import Builder, Tool, FlatBuilder diff --git a/masque/library.py b/masque/library.py index 65512e1..1bb5e90 100644 --- a/masque/library.py +++ b/masque/library.py @@ -445,6 +445,7 @@ class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta) Args: old_name: Current name for the pattern new_name: New name for the pattern + #TODO move_Reference Returns: self @@ -557,27 +558,34 @@ class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta) return self def add_tree( - self: ML, - name: str, + self, tree: 'Tree', + name: Optional[str] = None, rename_theirs: Callable[['Library', str], str] = _rename_patterns, - ) -> ML: + ) -> str: """ Add a `Tree` object into the current library. Args: - name: New name for the top-level pattern. tree: The `Tree` object (a `Library` with a specified `top` Pattern) which will be added into the current library. + name: New name for the top-level pattern. If not given, `tree.top` is used. rename_theirs: Called as rename_theirs(self, name) for each duplicate name encountered in `other`. Should return the new name for the pattern in `other`. Default is effectively `name.split('$')[0] if name.startswith('_') else name` + + Returns: + The new name for the top-level pattern (either `name` or `tree.top`). """ - tree.library.rename(tree.top, name, move_references=True) + if name is None: + name = tree.top + else: + tree.library.rename(tree.top, name, move_references=True) + self.add(tree.library, rename_theirs=rename_theirs) - return self + return name def dedup( self: ML, @@ -987,9 +995,20 @@ class Tree(MutableLibrary): def pattern(self) -> Pattern: return self.library[self.top] - def __init__(self, top: Union[str, NamedPattern], library: MutableLibrary) -> None: + def __init__( + self, + top: Union[str, NamedPattern], + library: Optional[MutableLibrary] = None + ) -> None: self.top = top if isinstance(top, str) else top.name - self.library = library + self.library = library if library is not None else WrapLibrary() + + @classmethod + def mk(cls, top: str) -> Tuple['Tree', 'Pattern']: + tree = cls(top=top) + pat = Pattern() + tree[top] = pat + return tree, pat def __getitem__(self, key: str) -> 'Pattern': return self.library[key] @@ -1006,6 +1025,9 @@ class Tree(MutableLibrary): def __delitem__(self, key: str) -> None: del self.library[key] + def __iadd__(self, other: 'Tree') -> None: + self.add_tree(other) + def _rename_patterns(lib: Library, name: str) -> str: # TODO document rename function diff --git a/masque/ref.py b/masque/ref.py index bcc8412..37ba66a 100644 --- a/masque/ref.py +++ b/masque/ref.py @@ -4,7 +4,7 @@ """ #TODO more top-level documentation -from typing import Dict, Optional, Sequence, Mapping, TYPE_CHECKING, Any, TypeVar +from typing import Dict, Optional, Sequence, Mapping, Union, TYPE_CHECKING, Any, TypeVar, cast import copy import numpy @@ -21,7 +21,7 @@ from .traits import ( if TYPE_CHECKING: - from . import Pattern + from . import Pattern, NamedPattern R = TypeVar('R', bound='Ref') @@ -49,7 +49,7 @@ class Ref( def __init__( self, - target: Optional[str], + target: Union[None, str, NamedPattern], *, offset: ArrayLike = (0.0, 0.0), rotation: float = 0.0, @@ -67,6 +67,8 @@ class Ref( scale: Scaling factor applied to the pattern's geometry. repetition: `Repetition` object, default `None` """ + if hasattr(target, 'name'): + target = cast('NamedPattern', target).name self.target = target self.offset = offset self.rotation = rotation