[BuildLibrary / OverlayLibrary] further simplifications 2
This commit is contained in:
parent
1723212424
commit
1b83034b7e
3 changed files with 26 additions and 89 deletions
|
|
@ -32,7 +32,7 @@ from numpy.typing import NDArray
|
|||
from . import gdsii
|
||||
from .utils import tmpfile
|
||||
from ..error import LibraryError
|
||||
from ..library import ILibrary, ILibraryView, LibraryView, _plan_source_names, dangling_mode_t
|
||||
from ..library import ILibrary, ILibraryView, LibraryView, _plan_source_names, _source_rename_map, dangling_mode_t
|
||||
from ..pattern import Pattern, map_targets
|
||||
from ..utils import apply_transforms
|
||||
from ..utils.ports2data import data_to_ports
|
||||
|
|
@ -319,7 +319,7 @@ class OverlayLibrary(ILibrary):
|
|||
source_order = list(view.source_order())
|
||||
child_graph = view.child_graph(dangling='include')
|
||||
|
||||
source_to_visible, rename_map = _plan_source_names(
|
||||
source_to_visible = _plan_source_names(
|
||||
self,
|
||||
source_order,
|
||||
self._entries,
|
||||
|
|
@ -343,7 +343,7 @@ class OverlayLibrary(ILibrary):
|
|||
if visible_name not in self._order:
|
||||
self._order.append(visible_name)
|
||||
|
||||
return rename_map
|
||||
return _source_rename_map(source_to_visible)
|
||||
|
||||
def rename(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ def _plan_source_names(
|
|||
*,
|
||||
rename_theirs: Callable[['ILibraryView', str], str] | None = None,
|
||||
rename_when: Literal['conflict', 'always'] = 'conflict',
|
||||
) -> tuple[dict[str, str], dict[str, str]]:
|
||||
) -> dict[str, str]:
|
||||
if rename_when not in ('conflict', 'always'):
|
||||
raise ValueError(f'Unknown source rename mode: {rename_when!r}')
|
||||
if rename_when == 'always' and rename_theirs is None:
|
||||
|
|
@ -164,7 +164,6 @@ def _plan_source_names(
|
|||
|
||||
source_to_visible: dict[str, str] = {}
|
||||
visible_names: set[str] = set()
|
||||
rename_map: dict[str, str] = {}
|
||||
|
||||
for name in source_order:
|
||||
visible = name
|
||||
|
|
@ -182,12 +181,18 @@ def _plan_source_names(
|
|||
if not renamed:
|
||||
raise LibraryError(f'Conflicting name while adding source: {name!r}')
|
||||
raise LibraryError(f'Unresolved duplicate key encountered while adding source: {name!r} -> {visible!r}')
|
||||
if visible != name:
|
||||
rename_map[name] = visible
|
||||
source_to_visible[name] = visible
|
||||
visible_names.add(visible)
|
||||
|
||||
return source_to_visible, rename_map
|
||||
return source_to_visible
|
||||
|
||||
|
||||
def _source_rename_map(source_to_visible: Mapping[str, str]) -> dict[str, str]:
|
||||
return {
|
||||
source_name: visible_name
|
||||
for source_name, visible_name in source_to_visible.items()
|
||||
if source_name != visible_name
|
||||
}
|
||||
|
||||
|
||||
class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
||||
|
|
@ -1675,12 +1680,11 @@ class BuildLibrary(ILibrary):
|
|||
move_references: bool = False,
|
||||
) -> Self:
|
||||
"""
|
||||
Rename an imported source-backed visible name during authoring.
|
||||
Rename a helper cell during an active build session.
|
||||
|
||||
Only imported source-backed cells may be renamed on the builder itself.
|
||||
Declared/generated cells must be registered under their intended final
|
||||
names. `move_references=True` is intentionally unsupported here because
|
||||
deferred recipes and declaration internals cannot be rewritten safely.
|
||||
During authoring, declared cells must be registered under their
|
||||
intended final names and imported source cells must be renamed through
|
||||
`add_source(...)`.
|
||||
"""
|
||||
session = self._active_session()
|
||||
if session is not None:
|
||||
|
|
@ -1697,41 +1701,10 @@ class BuildLibrary(ILibrary):
|
|||
)
|
||||
if old_name not in self._names:
|
||||
raise LibraryError(f'"{old_name}" does not exist in the builder.')
|
||||
if new_name in self._names:
|
||||
raise LibraryError(f'"{new_name}" already exists in the builder.')
|
||||
if move_references:
|
||||
raise BuildError(
|
||||
'BuildLibrary.rename(..., move_references=True) is not supported for imported source cells. '
|
||||
'Builder-level renames only change the visible imported name.'
|
||||
)
|
||||
|
||||
source_index: int | None = None
|
||||
source_name: str | None = None
|
||||
for idx, (_source, source_to_visible) in enumerate(self._sources):
|
||||
for candidate_source, candidate_visible in source_to_visible.items():
|
||||
if candidate_visible == old_name:
|
||||
source_index = idx
|
||||
source_name = candidate_source
|
||||
break
|
||||
if source_index is not None:
|
||||
break
|
||||
if source_index is None:
|
||||
raise BuildError(
|
||||
f'Cannot rename "{old_name}" during authoring because only imported source-backed '
|
||||
'cells may be renamed on a BuildLibrary.'
|
||||
)
|
||||
|
||||
source_library, source_to_visible = self._sources[source_index]
|
||||
source_to_visible = dict(source_to_visible)
|
||||
assert source_name is not None
|
||||
|
||||
source_to_visible[source_name] = new_name
|
||||
|
||||
self._sources[source_index] = (source_library, source_to_visible)
|
||||
self._names.remove(old_name)
|
||||
self._names.add(new_name)
|
||||
self._order[self._order.index(old_name)] = new_name
|
||||
return self
|
||||
raise BuildError(
|
||||
f'Cannot rename imported source cell "{old_name}" during authoring. '
|
||||
'Choose visible source names with add_source(..., rename_theirs=..., rename_when=...).'
|
||||
)
|
||||
|
||||
def abstract(self, name: str) -> Abstract:
|
||||
return self._require_active_session('abstract').abstract(name)
|
||||
|
|
@ -1777,7 +1750,7 @@ class BuildLibrary(ILibrary):
|
|||
|
||||
view = source if isinstance(source, ILibraryView) else LibraryView(source)
|
||||
source_order = tuple(view.source_order())
|
||||
source_to_visible, rename_map = _plan_source_names(
|
||||
source_to_visible = _plan_source_names(
|
||||
self,
|
||||
source_order,
|
||||
self._names,
|
||||
|
|
@ -1790,7 +1763,7 @@ class BuildLibrary(ILibrary):
|
|||
visible = source_to_visible[source_name]
|
||||
self._names.add(visible)
|
||||
self._order.append(visible)
|
||||
return rename_map
|
||||
return _source_rename_map(source_to_visible)
|
||||
|
||||
def validate(
|
||||
self,
|
||||
|
|
@ -2011,8 +1984,7 @@ class _BuildSessionLibrary(ILibrary):
|
|||
else:
|
||||
kind = 'helper'
|
||||
|
||||
self._record_provenance(
|
||||
name = key,
|
||||
self._provenance[key] = CellProvenance(
|
||||
requested_name = key,
|
||||
kind = kind,
|
||||
owner_declared_name = current if kind == 'helper' else key,
|
||||
|
|
@ -2054,22 +2026,6 @@ class _BuildSessionLibrary(ILibrary):
|
|||
)
|
||||
return rename_map
|
||||
|
||||
def _record_provenance(
|
||||
self,
|
||||
*,
|
||||
name: str,
|
||||
requested_name: str,
|
||||
kind: Literal['declared', 'helper'],
|
||||
owner_declared_name: str | None,
|
||||
build_chain: tuple[str, ...],
|
||||
) -> None:
|
||||
self._provenance[name] = CellProvenance(
|
||||
requested_name = requested_name,
|
||||
kind = kind,
|
||||
owner_declared_name = owner_declared_name,
|
||||
build_chain = build_chain,
|
||||
)
|
||||
|
||||
def _wrap_error(self, name: str, exc: Exception) -> BuildError:
|
||||
chain = tuple(self._declared_stack)
|
||||
msg = [f'Failed while building declared cell "{name}"']
|
||||
|
|
|
|||
|
|
@ -239,30 +239,11 @@ def test_build_library_rejects_add_source_during_build() -> None:
|
|||
builder.build()
|
||||
|
||||
|
||||
def test_build_library_can_rename_imported_source_cells_during_authoring() -> None:
|
||||
source = Library()
|
||||
source["child"] = Pattern()
|
||||
parent = Pattern()
|
||||
parent.ref("child")
|
||||
source["parent"] = parent
|
||||
|
||||
builder = BuildLibrary()
|
||||
builder.add_source(source)
|
||||
builder.rename("child", "renamed_child")
|
||||
|
||||
built, report = builder.build()
|
||||
|
||||
assert "renamed_child" in built
|
||||
assert "child" not in built
|
||||
assert "renamed_child" in built["parent"].refs
|
||||
assert report.provenance["renamed_child"].requested_name == "child"
|
||||
|
||||
|
||||
def test_build_library_rejects_move_references_for_source_rename() -> None:
|
||||
def test_build_library_rejects_renaming_imported_source_cells_during_authoring() -> None:
|
||||
builder = BuildLibrary()
|
||||
builder.add_source(Library({"src": Pattern()}))
|
||||
|
||||
with pytest.raises(BuildError, match="move_references=True"):
|
||||
with pytest.raises(BuildError, match="add_source"):
|
||||
builder.rename("src", "renamed_src", move_references=True)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue