diff --git a/masque/library.py b/masque/library.py index 99a43f5..5e5c80a 100644 --- a/masque/library.py +++ b/masque/library.py @@ -235,8 +235,12 @@ class Library(Mapping[str, 'Pattern'], metaclass=ABCMeta): if target not in flattened: flatten_single(target) - if flattened[target] is None: + + target_pat = flattened[target] + if target_pat is None: raise PatternError(f'Circular reference in {name} to {target}') + if target_pat.is_empty() # avoid some extra allocations + continue p = ref.as_pattern(pattern=flattened[target]) if not flatten_ports: @@ -613,8 +617,8 @@ class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta) raise LibraryError('Received a non-Tree library containing multiple cells') name = next(iter(other)) - self.add(other) - return name + rename_map = self.add(other) + return rename_map.get(name, name) def dedup( self: ML, diff --git a/masque/pattern.py b/masque/pattern.py index c9d40fb..055f6e2 100644 --- a/masque/pattern.py +++ b/masque/pattern.py @@ -521,6 +521,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): def is_empty(self) -> bool: """ + # TODO is_empty doesn't include ports... maybe there should be an equivalent? Returns: True if the pattern is contains no shapes, labels, or refs. """ @@ -575,6 +576,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): """ flattened: Dict[Optional[str], Optional[P]] = {} + # TODO both Library and Pattern have flatten()... pattern is in-place? def flatten_single(name: Optional[str]) -> None: if name is None: pat = self @@ -589,8 +591,12 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): if target not in flattened: flatten_single(target) - if flattened[target] is None: + + target_pat = flattened[target] + if target_pat is None: raise PatternError(f'Circular reference in {name} to {target}') + if target_pat.is_empty() # avoid some extra allocations + continue p = ref.as_pattern(pattern=flattened[target]) if not flatten_ports: diff --git a/masque/ref.py b/masque/ref.py index 37cd696..7b699cc 100644 --- a/masque/ref.py +++ b/masque/ref.py @@ -200,6 +200,9 @@ class Ref( return None if library is not None and self.target not in library: raise PatternError(f'get_bounds() called on dangling reference to "{self.target}"') + if pattern is not None and pattern.is_empty(): + # no need to run as_pattern() + return None return self.as_pattern(pattern=pattern, library=library).get_bounds(library) def __repr__(self) -> str: