Update comments
This commit is contained in:
parent
e47f9b76b1
commit
f7f5a62f54
6 changed files with 136 additions and 23 deletions
|
|
@ -36,7 +36,21 @@ visitor_function_t = Callable[..., 'Pattern']
|
|||
|
||||
|
||||
def _rename_patterns(lib: 'ILibraryView', name: str) -> str:
|
||||
# TODO document rename function
|
||||
"""
|
||||
The default `rename_theirs` function for `ILibrary.add`.
|
||||
|
||||
Treats names starting with an underscore as "one-offs" for which name conflicts
|
||||
should be automatically resolved. Conflicts are resolved by calling
|
||||
`lib.get_name(name.split('$')[0])`.
|
||||
Names without a leading underscore are directly returned.
|
||||
|
||||
Args:
|
||||
lib: The library into which `name` is to be added (but is presumed to conflict)
|
||||
name: The original name, to be modified
|
||||
|
||||
Returns:
|
||||
The new name, not guaranteed to be conflict-free!
|
||||
"""
|
||||
if not name.startswith('_'): # TODO what are the consequences of making '_' special? maybe we can make this decision everywhere?
|
||||
return name
|
||||
|
||||
|
|
@ -45,6 +59,11 @@ def _rename_patterns(lib: 'ILibraryView', name: str) -> str:
|
|||
|
||||
|
||||
class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
||||
"""
|
||||
Interface for a read-only library.
|
||||
|
||||
A library is a mapping from unique names (str) to collections of geometry (`Pattern`).
|
||||
"""
|
||||
# inherited abstract functions
|
||||
#def __getitem__(self, key: str) -> 'Pattern':
|
||||
#def __iter__(self) -> Iterator[str]:
|
||||
|
|
@ -53,6 +72,10 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
#__contains__, keys, items, values, get, __eq__, __ne__ supplied by Mapping
|
||||
|
||||
def abstract_view(self) -> 'AbstractView':
|
||||
"""
|
||||
Returns:
|
||||
An AbstractView into this library
|
||||
"""
|
||||
return AbstractView(self)
|
||||
|
||||
def abstract(self, name: str) -> Abstract:
|
||||
|
|
@ -205,14 +228,19 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
def flatten(
|
||||
self,
|
||||
tops: str | Sequence[str],
|
||||
flatten_ports: bool = False, # TODO document
|
||||
flatten_ports: bool = False,
|
||||
) -> dict[str, 'Pattern']:
|
||||
"""
|
||||
Removes all refs and adds equivalent shapes.
|
||||
Also flattens all referenced patterns.
|
||||
Returns copies of all `tops` patterns with all refs
|
||||
removed and replaced with equivalent shapes.
|
||||
Also returns flattened copies of all referenced patterns.
|
||||
The originals in the calling `Library` are not modified.
|
||||
For an in-place variant, see `Pattern.flatten`.
|
||||
|
||||
Args:
|
||||
tops: The pattern(s) to flattern.
|
||||
flatten_ports: If `True`, keep ports from any referenced
|
||||
patterns; otherwise discard them.
|
||||
|
||||
Returns:
|
||||
{name: flat_pattern} mapping for all flattened patterns.
|
||||
|
|
@ -222,7 +250,7 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
|
||||
flattened: dict[str, 'Pattern | None'] = {}
|
||||
|
||||
def flatten_single(name) -> None:
|
||||
def flatten_single(name: str) -> None:
|
||||
flattened[name] = None
|
||||
pat = self[name].deepcopy()
|
||||
|
||||
|
|
@ -428,11 +456,12 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
pattern = visit_after(pattern, hierarchy=hierarchy, memo=memo, transform=transform)
|
||||
|
||||
if pattern is not original_pattern:
|
||||
name = hierarchy[-1] # TODO what is name=None?
|
||||
name = hierarchy[-1]
|
||||
if not isinstance(self, ILibrary):
|
||||
raise LibraryError('visit_* functions returned a new `Pattern` object'
|
||||
' but the library is immutable')
|
||||
if name is None:
|
||||
# The top pattern is not the original pattern, but we don't know what to call it!
|
||||
raise LibraryError('visit_* functions returned a new `Pattern` object'
|
||||
' but no top-level name was provided in `hierarchy`')
|
||||
|
||||
|
|
@ -442,6 +471,11 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
|
||||
|
||||
class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], metaclass=ABCMeta):
|
||||
"""
|
||||
Interface for a writeable library.
|
||||
|
||||
A library is a mapping from unique names (str) to collections of geometry (`Pattern`).
|
||||
"""
|
||||
# inherited abstract functions
|
||||
#def __getitem__(self, key: str) -> 'Pattern':
|
||||
#def __iter__(self) -> Iterator[str]:
|
||||
|
|
@ -477,7 +511,8 @@ class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
Args:
|
||||
old_name: Current name for the pattern
|
||||
new_name: New name for the pattern
|
||||
#TODO move_Reference
|
||||
move_references: If `True`, any refs in this library pointing to `old_name`
|
||||
will be updated to point to `new_name`.
|
||||
|
||||
Returns:
|
||||
self
|
||||
|
|
@ -534,19 +569,31 @@ class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
rename_theirs: Callable[['ILibraryView', str], str] = _rename_patterns,
|
||||
) -> dict[str, str]:
|
||||
"""
|
||||
Add keys from another library into this one.
|
||||
Add items from another library into this one.
|
||||
|
||||
# TODO explain reference renaming and return
|
||||
If any name in `other` is already present in `self`, `rename_theirs(self, name)` is called
|
||||
to pick a new name for the newly-added pattern. If the new name still conflicts with a name
|
||||
in `self` a `LibraryError` is raised. All references to the original name (within `other)`
|
||||
are updated to the new name.
|
||||
|
||||
By default, `rename_theirs` makes no changes to the name (causing a `LibraryError`) unless the
|
||||
name starts with an underscore. Underscored names are truncated to before their first '$'
|
||||
and then passed to `self.get_name()` to create a new unique name.
|
||||
|
||||
Args:
|
||||
other: The library to insert keys from
|
||||
other: The library to insert keys from.
|
||||
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`
|
||||
`self.get_name(name.split('$')[0]) if name.startswith('_') else name`
|
||||
|
||||
Returns:
|
||||
self
|
||||
A mapping of `{old_name: new_name}` for all `old_name`s in `other`. Unchanged
|
||||
names map to themselves.
|
||||
|
||||
Raises:
|
||||
`LibraryError` if a duplicate name is encountered even after applying `rename_theirs()`.
|
||||
"""
|
||||
from .pattern import map_targets
|
||||
duplicates = set(self.keys()) & set(other.keys())
|
||||
|
|
@ -785,7 +832,15 @@ class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
self,
|
||||
repeat: bool = True,
|
||||
) -> set[str]:
|
||||
# TODO doc prune_empty
|
||||
"""
|
||||
Delete any empty patterns (i.e. where `Pattern.is_empty` returns `True`).
|
||||
|
||||
Args:
|
||||
repeat: Also recursively delete any patterns which only contain(ed) empty patterns.
|
||||
|
||||
Returns:
|
||||
A set containing the names of all deleted patterns
|
||||
"""
|
||||
trimmed = set()
|
||||
while empty := set(name for name, pat in self.items() if pat.is_empty()):
|
||||
for name in empty:
|
||||
|
|
@ -807,7 +862,13 @@ class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
key: str,
|
||||
delete_refs: bool = True,
|
||||
) -> Self:
|
||||
# TODO doc delete()
|
||||
"""
|
||||
Delete a pattern and (optionally) all refs pointing to that pattern.
|
||||
|
||||
Args:
|
||||
key: Name of the pattern to be deleted.
|
||||
delete_refs: If `True` (default), also delete all refs pointing to the pattern.
|
||||
"""
|
||||
del self[key]
|
||||
if delete_refs:
|
||||
for pat in self.values():
|
||||
|
|
@ -817,6 +878,12 @@ class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||
|
||||
|
||||
class LibraryView(ILibraryView):
|
||||
"""
|
||||
Default implementation for a read-only library.
|
||||
|
||||
A library is a mapping from unique names (str) to collections of geometry (`Pattern`).
|
||||
This library is backed by an arbitrary python object which implements the `Mapping` interface.
|
||||
"""
|
||||
mapping: Mapping[str, 'Pattern']
|
||||
|
||||
def __init__(
|
||||
|
|
@ -842,6 +909,12 @@ class LibraryView(ILibraryView):
|
|||
|
||||
|
||||
class Library(ILibrary):
|
||||
"""
|
||||
Default implementation for a writeable library.
|
||||
|
||||
A library is a mapping from unique names (str) to collections of geometry (`Pattern`).
|
||||
This library is backed by an arbitrary python object which implements the `MutableMapping` interface.
|
||||
"""
|
||||
mapping: MutableMapping[str, 'Pattern']
|
||||
|
||||
def __init__(
|
||||
|
|
@ -892,6 +965,12 @@ class Library(ILibrary):
|
|||
def mktree(cls, name: str) -> tuple[Self, 'Pattern']:
|
||||
"""
|
||||
Create a new Library and immediately add a pattern
|
||||
|
||||
Args:
|
||||
name: The name for the new pattern (usually the name of the topcell).
|
||||
|
||||
Returns:
|
||||
The newly created `Library` and the newly created `Pattern`
|
||||
"""
|
||||
from .pattern import Pattern
|
||||
tree = cls()
|
||||
|
|
@ -1041,6 +1120,11 @@ class LazyLibrary(ILibrary):
|
|||
|
||||
|
||||
class AbstractView(Mapping[str, Abstract]):
|
||||
"""
|
||||
A read-only mapping from names to `Abstract` objects.
|
||||
|
||||
This is usually just used as a shorthand for repeated calls to `library.abstract()`.
|
||||
"""
|
||||
library: ILibraryView
|
||||
|
||||
def __init__(self, library: ILibraryView) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue