[PortLoadView / LayerMappedView] rename/add new views
This commit is contained in:
parent
412133533a
commit
cbf75319ad
9 changed files with 287 additions and 87 deletions
|
|
@ -23,7 +23,8 @@ from .mapping import (
|
|||
)
|
||||
from .overlay import (
|
||||
OverlayLibrary as OverlayLibrary,
|
||||
PortsLibraryView as PortsLibraryView,
|
||||
PortLoadView as PortLoadView,
|
||||
LayerMappedView as LayerMappedView,
|
||||
)
|
||||
from .build import (
|
||||
LibraryBuilder as LibraryBuilder,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
"""Overlay and ports-importing library views."""
|
||||
"""Overlay and lazily processed library views."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import defaultdict
|
||||
|
|
@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Literal, Self, cast
|
|||
import copy
|
||||
|
||||
from ..error import LibraryError
|
||||
from ..pattern import Pattern, map_targets
|
||||
from ..pattern import Pattern, map_layers, map_targets
|
||||
from .base import ILibrary, ILibraryView
|
||||
from .capabilities import IBorrowing, IMaterializable
|
||||
from .utils import INameView, dangling_mode_t, _plan_source_names, _source_rename_map, _validate_dangling_mode
|
||||
|
|
@ -44,39 +44,17 @@ def _materialize_detached_pattern(view: ILibraryView, name: str) -> Pattern:
|
|||
return view[name].deepcopy()
|
||||
|
||||
|
||||
class PortsLibraryView(ILibraryView, IMaterializable, IBorrowing):
|
||||
"""
|
||||
Read-only view which imports or applies ports on first materialization.
|
||||
|
||||
The wrapped source remains untouched; this view owns a separate processed
|
||||
cache so direct-copy workflows can continue to use the raw source view.
|
||||
The view borrows its source: callers must keep the source open for the
|
||||
lifetime of the view and close the source themselves.
|
||||
|
||||
Graph queries and source ordering are delegated to the wrapped source,
|
||||
while `source_cell()` exposes unchanged layout provenance and `__getitem__`
|
||||
and `materialize_many()` return port-imported patterns.
|
||||
"""
|
||||
class _ProcessedLibraryView(ILibraryView, IMaterializable, IBorrowing):
|
||||
"""Shared detached-materialization behavior for read-only processing views."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
source: ILibraryView,
|
||||
*,
|
||||
layers: Sequence[layer_t] = (),
|
||||
max_depth: int = 0,
|
||||
skip_subcells: bool = True,
|
||||
ports: Mapping[str, Mapping[str, Port]] | None = None,
|
||||
replace: bool = False,
|
||||
copy_through: bool,
|
||||
) -> None:
|
||||
self._source = source
|
||||
self._layers = tuple(layers)
|
||||
self._max_depth = max_depth
|
||||
self._skip_subcells = skip_subcells
|
||||
self._ports = {
|
||||
name: copy.deepcopy(dict(cell_ports))
|
||||
for name, cell_ports in (ports or {}).items()
|
||||
}
|
||||
self._replace = replace
|
||||
self._copy_through = copy_through
|
||||
self._cache: dict[str, Pattern] = {}
|
||||
self._lookups_in_progress: list[str] = []
|
||||
|
||||
|
|
@ -92,9 +70,11 @@ class PortsLibraryView(ILibraryView, IMaterializable, IBorrowing):
|
|||
def __contains__(self, key: object) -> bool:
|
||||
return key in self._source
|
||||
|
||||
def materialize(self, name: str, *, persist: bool = True) -> Pattern:
|
||||
from ..utils.ports2data import data_to_ports # noqa: PLC0415
|
||||
def _process_pattern(self, name: str, pattern: Pattern) -> Pattern:
|
||||
"""Apply this view's processing to one detached source pattern."""
|
||||
raise NotImplementedError
|
||||
|
||||
def materialize(self, name: str, *, persist: bool = True) -> Pattern:
|
||||
if name in self._cache:
|
||||
return self._cache[name]
|
||||
|
||||
|
|
@ -108,28 +88,14 @@ class PortsLibraryView(ILibraryView, IMaterializable, IBorrowing):
|
|||
|
||||
self._lookups_in_progress.append(name)
|
||||
try:
|
||||
pat = _materialize_detached_pattern(self._source, name)
|
||||
if self._layers:
|
||||
pat = data_to_ports(
|
||||
layers=self._layers,
|
||||
library=self,
|
||||
pattern=pat,
|
||||
name=name,
|
||||
max_depth=self._max_depth,
|
||||
skip_subcells=self._skip_subcells,
|
||||
)
|
||||
if name in self._ports:
|
||||
ports = copy.deepcopy(self._ports[name])
|
||||
if self._replace:
|
||||
pat.ports = ports
|
||||
else:
|
||||
pat.ports.update(ports)
|
||||
pattern = _materialize_detached_pattern(self._source, name)
|
||||
pattern = self._process_pattern(name, pattern)
|
||||
finally:
|
||||
self._lookups_in_progress.pop()
|
||||
|
||||
if persist:
|
||||
self._cache[name] = pat
|
||||
return pat
|
||||
self._cache[name] = pattern
|
||||
return pattern
|
||||
|
||||
def source_order(self) -> tuple[str, ...]:
|
||||
return self._source.source_order()
|
||||
|
|
@ -138,7 +104,7 @@ class PortsLibraryView(ILibraryView, IMaterializable, IBorrowing):
|
|||
return (self._source,)
|
||||
|
||||
def source_cell(self, name: str) -> tuple[ILibraryView, str] | None:
|
||||
if name not in self._source or name in self._cache:
|
||||
if not self._copy_through or name not in self._source or name in self._cache:
|
||||
return None
|
||||
return self._source, name
|
||||
|
||||
|
|
@ -162,6 +128,88 @@ class PortsLibraryView(ILibraryView, IMaterializable, IBorrowing):
|
|||
return super().find_refs_local(name, parent_graph=parent_graph, dangling=dangling)
|
||||
|
||||
|
||||
class PortLoadView(_ProcessedLibraryView):
|
||||
"""
|
||||
Read-only view which loads or applies ports on first materialization.
|
||||
|
||||
The wrapped source remains untouched; this view owns a separate processed
|
||||
cache so direct-copy workflows can continue to use the raw source view.
|
||||
The view borrows its source: callers must keep the source open for the
|
||||
lifetime of the view and close the source themselves.
|
||||
|
||||
Graph queries and source ordering are delegated to the wrapped source,
|
||||
while `source_cell()` exposes unchanged layout provenance and `__getitem__`
|
||||
and `materialize_many()` return port-imported patterns.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
source: ILibraryView,
|
||||
*,
|
||||
layers: Sequence[layer_t] = (),
|
||||
max_depth: int = 0,
|
||||
skip_subcells: bool = True,
|
||||
ports: Mapping[str, Mapping[str, Port]] | None = None,
|
||||
replace: bool = False,
|
||||
) -> None:
|
||||
super().__init__(source, copy_through=True)
|
||||
self._layers = tuple(layers)
|
||||
self._max_depth = max_depth
|
||||
self._skip_subcells = skip_subcells
|
||||
self._ports = {
|
||||
name: copy.deepcopy(dict(cell_ports))
|
||||
for name, cell_ports in (ports or {}).items()
|
||||
}
|
||||
self._replace = replace
|
||||
|
||||
def _process_pattern(self, name: str, pattern: Pattern) -> Pattern:
|
||||
from ..utils.ports2data import data_to_ports # noqa: PLC0415
|
||||
|
||||
if self._layers:
|
||||
pattern = data_to_ports(
|
||||
layers=self._layers,
|
||||
library=self,
|
||||
pattern=pattern,
|
||||
name=name,
|
||||
max_depth=self._max_depth,
|
||||
skip_subcells=self._skip_subcells,
|
||||
)
|
||||
if name in self._ports:
|
||||
ports = copy.deepcopy(self._ports[name])
|
||||
if self._replace:
|
||||
pattern.ports = ports
|
||||
else:
|
||||
pattern.ports.update(ports)
|
||||
return pattern
|
||||
|
||||
|
||||
class LayerMappedView(_ProcessedLibraryView):
|
||||
"""
|
||||
Read-only view which remaps shape and label layers on materialization.
|
||||
|
||||
The wrapped source remains untouched. By default, source-aware writers
|
||||
must materialize and serialize every mapped cell. With `copy_through=True`,
|
||||
unmaterialized cells may instead be copied unchanged from their source;
|
||||
persistent access maps and caches a cell, disabling copy-through for it.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
source: ILibraryView,
|
||||
map_layer: Callable[[layer_t], layer_t],
|
||||
*,
|
||||
copy_through: bool = False,
|
||||
) -> None:
|
||||
super().__init__(source, copy_through=copy_through)
|
||||
self._map_layer = map_layer
|
||||
|
||||
def _process_pattern(self, name: str, pattern: Pattern) -> Pattern:
|
||||
_ = name
|
||||
pattern.shapes = map_layers(pattern.shapes, self._map_layer)
|
||||
pattern.labels = map_layers(pattern.labels, self._map_layer)
|
||||
return pattern
|
||||
|
||||
|
||||
class OverlayLibrary(ILibrary, IMaterializable, IBorrowing):
|
||||
"""
|
||||
Mutable overlay over one or more source libraries.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue