Allow library __setitem__ to take in either Pattern or Callable

No longer need it to be Generic!
This commit is contained in:
Jan Petykiewicz 2023-01-26 11:36:27 -08:00
parent 089e5192e3
commit f80c21ed4d
2 changed files with 39 additions and 22 deletions

View File

@ -532,7 +532,7 @@ class Builder(PortList):
in_ptype = self.pattern[portspec].ptype in_ptype = self.pattern[portspec].ptype
pat = tool.path(ccw, length, in_ptype=in_ptype, port_names=tool_port_names, **kwargs) pat = tool.path(ccw, length, in_ptype=in_ptype, port_names=tool_port_names, **kwargs)
name = self.library.get_name(base_name) name = self.library.get_name(base_name)
self.library.set_const(name, pat) self.library[name] = pat
return self.plug(Abstract(name, pat.ports), {portspec: tool_port_names[0]}) return self.plug(Abstract(name, pat.ports), {portspec: tool_port_names[0]})
def path_to( def path_to(
@ -615,7 +615,7 @@ class Builder(PortList):
for port_name, length in extensions.items(): for port_name, length in extensions.items():
bld.path(port_name, ccw, length, tool_port_names=tool_port_names) bld.path(port_name, ccw, length, tool_port_names=tool_port_names)
name = self.library.get_name(base_name) name = self.library.get_name(base_name)
self.library.set_const(name, bld.pattern) self.library[name] = bld.pattern
return self.plug(Abstract(name, bld.pattern.ports), {sp: 'in_' + sp for sp in ports.keys()}) # TODO safe to use 'in_'? return self.plug(Abstract(name, bld.pattern.ports), {sp: 'in_' + sp for sp in ports.keys()}) # TODO safe to use 'in_'?
# TODO def path_join() and def bus_join()? # TODO def path_join() and def bus_join()?

View File

@ -5,7 +5,7 @@ Library classes for managing unique name->pattern mappings and
# TODO documentn all library classes # TODO documentn all library classes
# TODO toplevel documentation of library, classes, and abstracts # TODO toplevel documentation of library, classes, and abstracts
""" """
from typing import List, Dict, Callable, TypeVar, Generic, Type, TYPE_CHECKING, cast from typing import List, Dict, Callable, TypeVar, Type, TYPE_CHECKING, cast
from typing import Tuple, Union, Iterator, Mapping, MutableMapping, Set, Optional, Sequence from typing import Tuple, Union, Iterator, Mapping, MutableMapping, Set, Optional, Sequence
import logging import logging
import base64 import base64
@ -403,32 +403,29 @@ class Library(Mapping[str, 'Pattern'], metaclass=ABCMeta):
raise LibraryError('visit_* functions returned a new `Pattern` object' raise LibraryError('visit_* functions returned a new `Pattern` object'
' but no top-level name was provided in `hierarchy`') ' but no top-level name was provided in `hierarchy`')
cast(MutableLibrary, self).set_const(name, pattern) cast(MutableLibrary, self)[name] = pattern
return self return self
VVV = TypeVar('VVV') class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta):
class MutableLibrary(Library, Generic[VVV], metaclass=ABCMeta):
# inherited abstract functions # inherited abstract functions
#def __getitem__(self, key: str) -> 'Pattern': #def __getitem__(self, key: str) -> 'Pattern':
#def __iter__(self) -> Iterator[str]: #def __iter__(self) -> Iterator[str]:
#def __len__(self) -> int: #def __len__(self) -> int:
@abstractmethod @abstractmethod
def __setitem__(self, key: str, value: VVV) -> None: def __setitem__(
self,
key: str,
value: Union['Pattern', Callable[[], 'Pattern']],
) -> None:
pass pass
@abstractmethod @abstractmethod
def __delitem__(self, key: str) -> None: def __delitem__(self, key: str) -> None:
pass pass
@abstractmethod
def set_const(self, key: str, value: 'Pattern') -> None:
pass
@abstractmethod @abstractmethod
def _merge(self, other: Mapping[str, 'Pattern'], key: str) -> None: def _merge(self, other: Mapping[str, 'Pattern'], key: str) -> None:
pass pass
@ -566,7 +563,7 @@ class MutableLibrary(Library, Generic[VVV], metaclass=ABCMeta):
del pat.shapes[i] del pat.shapes[i]
for ll, pp in shape_pats.items(): for ll, pp in shape_pats.items():
self.set_const(label2name(ll), pp) self[label2name(ll)] = pp
return self return self
@ -601,7 +598,7 @@ class MutableLibrary(Library, Generic[VVV], metaclass=ABCMeta):
continue continue
name = name_func(pat, shape) name = name_func(pat, shape)
self.set_const(name, Pattern(shapes=[shape])) self[name] = Pattern(shapes=[shape])
pat.ref(name, repetition=shape.repetition) pat.ref(name, repetition=shape.repetition)
shape.repetition = None shape.repetition = None
pat.shapes = new_shapes pat.shapes = new_shapes
@ -612,7 +609,7 @@ class MutableLibrary(Library, Generic[VVV], metaclass=ABCMeta):
new_labels.append(label) new_labels.append(label)
continue continue
name = name_func(pat, label) name = name_func(pat, label)
self.set_const(name, Pattern(labels=[label])) self[name] = Pattern(labels=[label])
pat.ref(name, repetition=label.repetition) pat.ref(name, repetition=label.repetition)
label.repetition = None label.repetition = None
pat.labels = new_labels pat.labels = new_labels
@ -688,15 +685,23 @@ class WrapLibrary(MutableLibrary):
def __len__(self) -> int: def __len__(self) -> int:
return len(self.mapping) return len(self.mapping)
def __setitem__(self, key: str, value: 'Pattern') -> None: def __setitem__(
self,
key: str,
value: Union['Pattern', Callable[[], 'Pattern']],
) -> None:
if key in self.mapping:
raise LibraryError(f'"{key}" already exists in the library. Overwriting is not allowed!')
if callable(value):
value = value()
else:
value = value
self.mapping[key] = value self.mapping[key] = value
def __delitem__(self, key: str) -> None: def __delitem__(self, key: str) -> None:
del self.mapping[key] del self.mapping[key]
def set_const(self, key: str, value: 'Pattern') -> None:
self[key] = value
def _merge(self, other: Mapping[str, 'Pattern'], key: str) -> None: def _merge(self, other: Mapping[str, 'Pattern'], key: str) -> None:
self[key] = other[key] self[key] = other[key]
@ -721,8 +726,20 @@ class LazyLibrary(MutableLibrary):
self.cache = {} self.cache = {}
self._lookups_in_progress = set() self._lookups_in_progress = set()
def __setitem__(self, key: str, value: Callable[[], 'Pattern']) -> None: def __setitem__(
self.dict[key] = value self,
key: str,
value: Union['Pattern', Callable[[], 'Pattern']],
) -> None:
if key in self.dict:
raise LibraryError(f'"{key}" already exists in the library. Overwriting is not allowed!')
if callable(value):
value_func = value
else:
value_func = lambda: cast('Pattern', value) # noqa: E731
self.dict[key] = value_func
if key in self.cache: if key in self.cache:
del self.cache[key] del self.cache[key]