[library / gdsii] more cleanup
This commit is contained in:
parent
7b589e4f44
commit
e7f7cae8b9
4 changed files with 40 additions and 1 deletions
|
|
@ -47,5 +47,9 @@ class IBorrowing(ABC):
|
|||
|
||||
The source may use a different name, which is returned alongside it.
|
||||
Port metadata may differ because ports are not layout-file content.
|
||||
The result is not recursively resolved: consumers must follow further
|
||||
borrowing views themselves and enforce format-specific constraints such
|
||||
as whether the visible and source names must match. `None` means the
|
||||
source cannot be reused safely or no source provenance is available.
|
||||
"""
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class _SubtreeLibraryView(ILibraryView, IMaterializable, IBorrowing):
|
|||
name: set(child_graph.get(name, set()))
|
||||
for name in self._order
|
||||
}
|
||||
|
||||
def __getitem__(self, key: str) -> Pattern:
|
||||
if key not in self._names:
|
||||
raise KeyError(key)
|
||||
|
|
@ -136,6 +137,7 @@ class _SubtreeLibraryView(ILibraryView, IMaterializable, IBorrowing):
|
|||
refs = self._source.find_refs_local(name, parent_graph=parent_graph, dangling=dangling)
|
||||
return {parent: transforms for parent, transforms in refs.items() if parent in self._names}
|
||||
|
||||
|
||||
class Library(ILibrary):
|
||||
"""
|
||||
Default implementation for a writeable library.
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ class PortsLibraryView(ILibraryView, IMaterializable, IBorrowing):
|
|||
self._replace = replace
|
||||
self._cache: dict[str, Pattern] = {}
|
||||
self._lookups_in_progress: list[str] = []
|
||||
|
||||
def __getitem__(self, key: str) -> Pattern:
|
||||
return self.materialize(key, persist=True)
|
||||
|
||||
|
|
@ -160,6 +161,7 @@ class PortsLibraryView(ILibraryView, IMaterializable, IBorrowing):
|
|||
return cast('dict[str, list[NDArray[numpy.float64]]]', finder(name, parent_graph=parent_graph, dangling=dangling))
|
||||
return super().find_refs_local(name, parent_graph=parent_graph, dangling=dangling)
|
||||
|
||||
|
||||
class OverlayLibrary(ILibrary, IMaterializable, IBorrowing):
|
||||
"""
|
||||
Mutable overlay over one or more source libraries.
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ from numpy.testing import assert_allclose
|
|||
|
||||
from ..file import gdsii
|
||||
from ..file.gdsii import lazy as gdsii_lazy
|
||||
from ..file.gdsii import lazy_write as gdsii_lazy_write
|
||||
from ..error import LibraryError
|
||||
from ..pattern import Pattern
|
||||
from ..ports import Port
|
||||
from ..library import IBorrowing, IMaterializable, LazyLibrary, Library, OverlayLibrary, PortsLibraryView
|
||||
from ..library import IBorrowing, IMaterializable, LazyLibrary, Library, LibraryView, OverlayLibrary, PortsLibraryView
|
||||
|
||||
|
||||
def _make_lazy_port_library() -> Library:
|
||||
|
|
@ -76,6 +77,19 @@ def test_gdsii_lazy_write_materializes_transiently() -> None:
|
|||
assert info['name'] == 'transient'
|
||||
|
||||
|
||||
def test_gdsii_raw_copy_provenance_cycle_falls_back() -> None:
|
||||
class SelfBorrowingView(LibraryView, IBorrowing):
|
||||
def borrowed_sources(self) -> tuple['SelfBorrowingView', ...]:
|
||||
return (self,)
|
||||
|
||||
def source_cell(self, name: str) -> tuple['SelfBorrowingView', str] | None:
|
||||
return self, name
|
||||
|
||||
view = SelfBorrowingView({'top': Pattern()})
|
||||
|
||||
assert gdsii_lazy_write._resolve_raw_struct(view, 'top') is None
|
||||
|
||||
|
||||
def test_gdsii_lazy_source_exposes_order_and_graph_without_materializing(tmp_path: Path) -> None:
|
||||
gds_file = tmp_path / 'lazy_source.gds'
|
||||
src = _make_lazy_port_library()
|
||||
|
|
@ -147,6 +161,23 @@ def test_gdsii_lazy_subtree_stays_borrowed_and_preserves_write_metadata(tmp_path
|
|||
assert set(roundtrip) == {'leaf', 'child', 'top'}
|
||||
|
||||
|
||||
def test_gdsii_lazy_borrowed_sources_require_matching_units(tmp_path: Path) -> None:
|
||||
gds_a = tmp_path / 'units_a.gds'
|
||||
gds_b = tmp_path / 'units_b.gds'
|
||||
source = Library({'top': Pattern()})
|
||||
gdsii.writefile(source, gds_a, meters_per_unit=1e-9, library_name='units-a')
|
||||
gdsii.writefile(source, gds_b, meters_per_unit=2e-9, library_name='units-b')
|
||||
|
||||
lazy_a, _ = gdsii_lazy.readfile(gds_a)
|
||||
lazy_b, _ = gdsii_lazy.readfile(gds_b)
|
||||
overlay = OverlayLibrary()
|
||||
overlay.add_source(lazy_a)
|
||||
overlay.add_source(lazy_b, rename_theirs=lambda lib, name: lib.get_name(name))
|
||||
|
||||
with pytest.raises(LibraryError, match='identical units'):
|
||||
gdsii_lazy.write(overlay, io.BytesIO())
|
||||
|
||||
|
||||
def test_gdsii_lazy_overlay_subtree_preserves_source_laziness(tmp_path: Path) -> None:
|
||||
gds_file = tmp_path / 'lazy_overlay_subtree_source.gds'
|
||||
src = _make_lazy_port_library()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue