redo library class naming
This commit is contained in:
parent
c7505a12b0
commit
9c9d3c3928
@ -7,7 +7,7 @@ from skimage.measure import find_contours
|
|||||||
from matplotlib import pyplot
|
from matplotlib import pyplot
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
from masque import Pattern, Library, Polygon
|
from masque import Pattern, Polygon
|
||||||
from masque.file.gdsii import writefile
|
from masque.file.gdsii import writefile
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -5,14 +5,14 @@ import numpy
|
|||||||
from numpy import pi
|
from numpy import pi
|
||||||
|
|
||||||
import masque
|
import masque
|
||||||
from masque import Pattern, Ref, Arc, WrapLibrary
|
from masque import Pattern, Ref, Arc, Library
|
||||||
from masque.repetition import Grid
|
from masque.repetition import Grid
|
||||||
from masque.file import gdsii, dxf, oasis
|
from masque.file import gdsii, dxf, oasis
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
lib = WrapLibrary()
|
lib = Library()
|
||||||
|
|
||||||
cell_name = 'ellip_grating'
|
cell_name = 'ellip_grating'
|
||||||
pat = masque.Pattern()
|
pat = masque.Pattern()
|
||||||
@ -115,7 +115,7 @@ def main():
|
|||||||
|
|
||||||
print(f'Read back and rewrite to {dxf2}')
|
print(f'Read back and rewrite to {dxf2}')
|
||||||
dxf_lib, _info = dxf.readfile(dxf1)
|
dxf_lib, _info = dxf.readfile(dxf1)
|
||||||
print(WrapLibrary(dxf_lib))
|
print(Library(dxf_lib))
|
||||||
dxf.writefile(dxf_lib, 'Model', dxf2)
|
dxf.writefile(dxf_lib, 'Model', dxf2)
|
||||||
|
|
||||||
layer_map = {'base': (0,0), 'mylabel': (1,2)}
|
layer_map = {'base': (0,0), 'mylabel': (1,2)}
|
||||||
|
@ -6,7 +6,7 @@ from numpy import pi
|
|||||||
|
|
||||||
from masque import (
|
from masque import (
|
||||||
layer_t, Pattern, Ref, Label, Builder, Port, Polygon,
|
layer_t, Pattern, Ref, Label, Builder, Port, Polygon,
|
||||||
WrapLibrary, Library,
|
Library, ILibraryView,
|
||||||
)
|
)
|
||||||
from masque.utils import ports2data
|
from masque.utils import ports2data
|
||||||
from masque.file.gdsii import writefile, check_valid_names
|
from masque.file.gdsii import writefile, check_valid_names
|
||||||
@ -247,7 +247,7 @@ def main(interactive: bool = True) -> None:
|
|||||||
devices['l3cav'] = perturbed_l3(lattice_constant=a, hole='smile', hole_lib=shape_lib, xy_size=(4, 10)) # uses smile :)
|
devices['l3cav'] = perturbed_l3(lattice_constant=a, hole='smile', hole_lib=shape_lib, xy_size=(4, 10)) # uses smile :)
|
||||||
|
|
||||||
# Turn our dict of devices into a Library -- useful for getting abstracts
|
# Turn our dict of devices into a Library -- useful for getting abstracts
|
||||||
lib = WrapLibrary(devices)
|
lib = Library(devices)
|
||||||
abv = lib.abstract_view() # lets us use abv[cell] instead of lib.abstract(cell)
|
abv = lib.abstract_view() # lets us use abv[cell] instead of lib.abstract(cell)
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -4,7 +4,7 @@ from pprint import pformat
|
|||||||
import numpy
|
import numpy
|
||||||
from numpy import pi
|
from numpy import pi
|
||||||
|
|
||||||
from masque import Pattern, Builder, WrapLibrary, LazyLibrary, Library
|
from masque import Pattern, Builder, LazyLibrary
|
||||||
from masque.file.gdsii import writefile, load_libraryfile
|
from masque.file.gdsii import writefile, load_libraryfile
|
||||||
|
|
||||||
import pcgen
|
import pcgen
|
||||||
|
@ -35,8 +35,8 @@ from .ref import Ref
|
|||||||
from .pattern import Pattern
|
from .pattern import Pattern
|
||||||
|
|
||||||
from .library import (
|
from .library import (
|
||||||
Library, MutableLibrary,
|
ILibraryView, ILibrary,
|
||||||
WrapROLibrary, WrapLibrary, LazyLibrary,
|
LibraryView, Library, LazyLibrary,
|
||||||
AbstractView,
|
AbstractView,
|
||||||
Tree,
|
Tree,
|
||||||
)
|
)
|
||||||
|
@ -11,7 +11,7 @@ from .utils import rotation_matrix_2d, normalize_mirror
|
|||||||
|
|
||||||
#if TYPE_CHECKING:
|
#if TYPE_CHECKING:
|
||||||
# from .builder import Builder, Tool
|
# from .builder import Builder, Tool
|
||||||
# from .library import MutableLibrary
|
# from .library import ILibrary
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -44,7 +44,7 @@ class Abstract(PortList):
|
|||||||
|
|
||||||
# def build(
|
# def build(
|
||||||
# self,
|
# self,
|
||||||
# library: 'MutableLibrary',
|
# library: 'ILibrary',
|
||||||
# tools: 'None | Tool | MutableMapping[str | None, Tool]' = None,
|
# tools: 'None | Tool | MutableMapping[str | None, Tool]' = None,
|
||||||
# ) -> 'Builder':
|
# ) -> 'Builder':
|
||||||
# """
|
# """
|
||||||
|
@ -8,7 +8,7 @@ from numpy.typing import ArrayLike
|
|||||||
|
|
||||||
from ..pattern import Pattern
|
from ..pattern import Pattern
|
||||||
from ..ref import Ref
|
from ..ref import Ref
|
||||||
from ..library import MutableLibrary
|
from ..library import ILibrary
|
||||||
from ..error import PortError, BuildError
|
from ..error import PortError, BuildError
|
||||||
from ..ports import PortList, Port
|
from ..ports import PortList, Port
|
||||||
from ..abstract import Abstract
|
from ..abstract import Abstract
|
||||||
@ -79,7 +79,7 @@ class Builder(PortList):
|
|||||||
pattern: Pattern
|
pattern: Pattern
|
||||||
""" Layout of this device """
|
""" Layout of this device """
|
||||||
|
|
||||||
library: MutableLibrary | None
|
library: ILibrary | None
|
||||||
"""
|
"""
|
||||||
Library from which existing patterns should be referenced, and to which
|
Library from which existing patterns should be referenced, and to which
|
||||||
new ones should be added
|
new ones should be added
|
||||||
@ -98,7 +98,7 @@ class Builder(PortList):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
library: MutableLibrary | None = None,
|
library: ILibrary | None = None,
|
||||||
*,
|
*,
|
||||||
pattern: Pattern | None = None,
|
pattern: Pattern | None = None,
|
||||||
ports: str | Mapping[str, Port] | None = None,
|
ports: str | Mapping[str, Port] | None = None,
|
||||||
@ -140,7 +140,7 @@ class Builder(PortList):
|
|||||||
cls,
|
cls,
|
||||||
source: PortList | Mapping[str, Port] | str,
|
source: PortList | Mapping[str, Port] | str,
|
||||||
*,
|
*,
|
||||||
library: MutableLibrary | None = None,
|
library: ILibrary | None = None,
|
||||||
in_prefix: str = 'in_',
|
in_prefix: str = 'in_',
|
||||||
out_prefix: str = '',
|
out_prefix: str = '',
|
||||||
port_map: dict[str, str] | Sequence[str] | None = None,
|
port_map: dict[str, str] | Sequence[str] | None = None,
|
||||||
@ -194,7 +194,7 @@ class Builder(PortList):
|
|||||||
names.
|
names.
|
||||||
"""
|
"""
|
||||||
if library is None:
|
if library is None:
|
||||||
if hasattr(source, 'library') and isinstance(source.library, MutableLibrary):
|
if hasattr(source, 'library') and isinstance(source.library, ILibrary):
|
||||||
library = source.library
|
library = source.library
|
||||||
|
|
||||||
if isinstance(source, str):
|
if isinstance(source, str):
|
||||||
@ -541,7 +541,7 @@ class Pather(Builder):
|
|||||||
"""
|
"""
|
||||||
__slots__ = ('tools',)
|
__slots__ = ('tools',)
|
||||||
|
|
||||||
library: MutableLibrary
|
library: ILibrary
|
||||||
"""
|
"""
|
||||||
Library from which existing patterns should be referenced, and to which
|
Library from which existing patterns should be referenced, and to which
|
||||||
new ones should be added
|
new ones should be added
|
||||||
@ -555,7 +555,7 @@ class Pather(Builder):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
library: MutableLibrary,
|
library: ILibrary,
|
||||||
*,
|
*,
|
||||||
pattern: Pattern | None = None,
|
pattern: Pattern | None = None,
|
||||||
ports: str | Mapping[str, Port] | None = None,
|
ports: str | Mapping[str, Port] | None = None,
|
||||||
@ -599,7 +599,7 @@ class Pather(Builder):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def mk(
|
def mk(
|
||||||
cls,
|
cls,
|
||||||
library: MutableLibrary,
|
library: ILibrary,
|
||||||
name: str,
|
name: str,
|
||||||
*,
|
*,
|
||||||
ports: str | Mapping[str, Port] | None = None,
|
ports: str | Mapping[str, Port] | None = None,
|
||||||
@ -614,7 +614,7 @@ class Pather(Builder):
|
|||||||
cls,
|
cls,
|
||||||
builder: Builder,
|
builder: Builder,
|
||||||
*,
|
*,
|
||||||
library: MutableLibrary | None = None,
|
library: ILibrary | None = None,
|
||||||
tools: Tool | MutableMapping[str | None, Tool] | None = None,
|
tools: Tool | MutableMapping[str | None, Tool] | None = None,
|
||||||
) -> 'Pather':
|
) -> 'Pather':
|
||||||
"""TODO from_builder docs"""
|
"""TODO from_builder docs"""
|
||||||
@ -629,7 +629,7 @@ class Pather(Builder):
|
|||||||
cls,
|
cls,
|
||||||
source: PortList | Mapping[str, Port] | str,
|
source: PortList | Mapping[str, Port] | str,
|
||||||
*,
|
*,
|
||||||
library: MutableLibrary | None = None,
|
library: ILibrary | None = None,
|
||||||
tools: Tool | MutableMapping[str | None, Tool] | None = None,
|
tools: Tool | MutableMapping[str | None, Tool] | None = None,
|
||||||
in_prefix: str = 'in_',
|
in_prefix: str = 'in_',
|
||||||
out_prefix: str = '',
|
out_prefix: str = '',
|
||||||
@ -640,7 +640,7 @@ class Pather(Builder):
|
|||||||
TODO doc pather.interface
|
TODO doc pather.interface
|
||||||
"""
|
"""
|
||||||
if library is None:
|
if library is None:
|
||||||
if hasattr(source, 'library') and isinstance(source.library, MutableLibrary):
|
if hasattr(source, 'library') and isinstance(source.library, ILibrary):
|
||||||
library = source.library
|
library = source.library
|
||||||
else:
|
else:
|
||||||
raise BuildError('No library provided (and not present in `source.library`')
|
raise BuildError('No library provided (and not present in `source.library`')
|
||||||
|
@ -105,8 +105,8 @@ class FlatBuilder(PortList):
|
|||||||
Args:
|
Args:
|
||||||
source: A collection of ports (e.g. Pattern, Builder, or dict)
|
source: A collection of ports (e.g. Pattern, Builder, or dict)
|
||||||
from which to create the interface.
|
from which to create the interface.
|
||||||
library: Used for buildin functions; if not passed and the source
|
library: Used for buildin functions; if not passed and the source TODO
|
||||||
library: Library from which existing patterns should be referenced,
|
library: Library from which existing patterns should be referenced, TODO
|
||||||
and to which new ones should be added. If not provided,
|
and to which new ones should be added. If not provided,
|
||||||
the source's library will be used (if available).
|
the source's library will be used (if available).
|
||||||
tools: Tool objects are used to dynamically generate new single-use
|
tools: Tool objects are used to dynamically generate new single-use
|
||||||
|
@ -18,7 +18,7 @@ from ezdxf.enums import TextEntityAlignment
|
|||||||
|
|
||||||
from .utils import is_gzipped, tmpfile
|
from .utils import is_gzipped, tmpfile
|
||||||
from .. import Pattern, Ref, PatternError, Label
|
from .. import Pattern, Ref, PatternError, Label
|
||||||
from ..library import Library, WrapROLibrary, WrapLibrary
|
from ..library import ILibraryView, LibraryView, Library
|
||||||
from ..shapes import Shape, Polygon, Path
|
from ..shapes import Shape, Polygon, Path
|
||||||
from ..repetition import Grid
|
from ..repetition import Grid
|
||||||
from ..utils import rotation_matrix_2d, layer_t
|
from ..utils import rotation_matrix_2d, layer_t
|
||||||
@ -75,9 +75,9 @@ def write(
|
|||||||
#TODO consider supporting DXF arcs?
|
#TODO consider supporting DXF arcs?
|
||||||
if not isinstance(library, Library):
|
if not isinstance(library, Library):
|
||||||
if isinstance(library, dict):
|
if isinstance(library, dict):
|
||||||
library = WrapROLibrary(library)
|
library = LibraryView(library)
|
||||||
else:
|
else:
|
||||||
library = WrapROLibrary(dict(library))
|
library = LibraryView(dict(library))
|
||||||
|
|
||||||
pattern = library[top_name]
|
pattern = library[top_name]
|
||||||
subtree = library.subtree(top_name)
|
subtree = library.subtree(top_name)
|
||||||
@ -148,7 +148,7 @@ def readfile(
|
|||||||
filename: str | pathlib.Path,
|
filename: str | pathlib.Path,
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> tuple[WrapLibrary, dict[str, Any]]:
|
) -> tuple[Library, dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Wrapper for `dxf.read()` that takes a filename or path instead of a stream.
|
Wrapper for `dxf.read()` that takes a filename or path instead of a stream.
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ def readfile(
|
|||||||
|
|
||||||
def read(
|
def read(
|
||||||
stream: TextIO,
|
stream: TextIO,
|
||||||
) -> tuple[WrapLibrary, dict[str, Any]]:
|
) -> tuple[Library, dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Read a dxf file and translate it into a dict of `Pattern` objects. DXF `Block`s are
|
Read a dxf file and translate it into a dict of `Pattern` objects. DXF `Block`s are
|
||||||
translated into `Pattern` objects; `LWPolyline`s are translated into polygons, and `Insert`s
|
translated into `Pattern` objects; `LWPolyline`s are translated into polygons, and `Insert`s
|
||||||
@ -190,7 +190,7 @@ def read(
|
|||||||
msp = lib.modelspace()
|
msp = lib.modelspace()
|
||||||
|
|
||||||
top_name, top_pat = _read_block(msp)
|
top_name, top_pat = _read_block(msp)
|
||||||
mlib = WrapLibrary({top_name: top_pat})
|
mlib = Library({top_name: top_pat})
|
||||||
for bb in lib.blocks:
|
for bb in lib.blocks:
|
||||||
if bb.name == '*Model_Space':
|
if bb.name == '*Model_Space':
|
||||||
continue
|
continue
|
||||||
|
@ -38,7 +38,7 @@ from .. import Pattern, Ref, PatternError, LibraryError, Label, Shape
|
|||||||
from ..shapes import Polygon, Path
|
from ..shapes import Polygon, Path
|
||||||
from ..repetition import Grid
|
from ..repetition import Grid
|
||||||
from ..utils import layer_t, normalize_mirror, annotations_t
|
from ..utils import layer_t, normalize_mirror, annotations_t
|
||||||
from ..library import LazyLibrary, WrapLibrary, MutableLibrary, Library
|
from ..library import LazyLibrary, Library, ILibrary, ILibraryView
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -97,11 +97,11 @@ def write(
|
|||||||
library_name: Library name written into the GDSII file.
|
library_name: Library name written into the GDSII file.
|
||||||
Default 'masque-klamath'.
|
Default 'masque-klamath'.
|
||||||
"""
|
"""
|
||||||
if not isinstance(library, MutableLibrary):
|
if not isinstance(library, ILibrary):
|
||||||
if isinstance(library, dict):
|
if isinstance(library, dict):
|
||||||
library = WrapLibrary(library)
|
library = Library(library)
|
||||||
else:
|
else:
|
||||||
library = WrapLibrary(dict(library))
|
library = Library(dict(library))
|
||||||
|
|
||||||
# Create library
|
# Create library
|
||||||
header = klamath.library.FileHeader(
|
header = klamath.library.FileHeader(
|
||||||
@ -160,7 +160,7 @@ def readfile(
|
|||||||
filename: str | pathlib.Path,
|
filename: str | pathlib.Path,
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> tuple[WrapLibrary, dict[str, Any]]:
|
) -> tuple[Library, dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Wrapper for `read()` that takes a filename or path instead of a stream.
|
Wrapper for `read()` that takes a filename or path instead of a stream.
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ def readfile(
|
|||||||
def read(
|
def read(
|
||||||
stream: IO[bytes],
|
stream: IO[bytes],
|
||||||
raw_mode: bool = True,
|
raw_mode: bool = True,
|
||||||
) -> tuple[WrapLibrary, dict[str, Any]]:
|
) -> tuple[Library, dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
# TODO check GDSII file for cycles!
|
# TODO check GDSII file for cycles!
|
||||||
Read a gdsii file and translate it into a dict of Pattern objects. GDSII structures are
|
Read a gdsii file and translate it into a dict of Pattern objects. GDSII structures are
|
||||||
@ -208,7 +208,7 @@ def read(
|
|||||||
"""
|
"""
|
||||||
library_info = _read_header(stream)
|
library_info = _read_header(stream)
|
||||||
|
|
||||||
mlib = WrapLibrary()
|
mlib = Library()
|
||||||
found_struct = records.BGNSTR.skip_past(stream)
|
found_struct = records.BGNSTR.skip_past(stream)
|
||||||
while found_struct:
|
while found_struct:
|
||||||
name = records.STRNAME.skip_and_read(stream)
|
name = records.STRNAME.skip_and_read(stream)
|
||||||
@ -511,7 +511,7 @@ def load_library(
|
|||||||
stream: IO[bytes],
|
stream: IO[bytes],
|
||||||
*,
|
*,
|
||||||
full_load: bool = False,
|
full_load: bool = False,
|
||||||
postprocess: Callable[[Library, str, Pattern], Pattern] | None = None
|
postprocess: Callable[[ILibraryView, str, Pattern], Pattern] | None = None
|
||||||
) -> tuple[LazyLibrary, dict[str, Any]]:
|
) -> tuple[LazyLibrary, dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Scan a GDSII stream to determine what structures are present, and create
|
Scan a GDSII stream to determine what structures are present, and create
|
||||||
@ -571,7 +571,7 @@ def load_libraryfile(
|
|||||||
*,
|
*,
|
||||||
use_mmap: bool = True,
|
use_mmap: bool = True,
|
||||||
full_load: bool = False,
|
full_load: bool = False,
|
||||||
postprocess: Callable[[Library, str, Pattern], Pattern] | None = None
|
postprocess: Callable[[ILibraryView, str, Pattern], Pattern] | None = None
|
||||||
) -> tuple[LazyLibrary, dict[str, Any]]:
|
) -> tuple[LazyLibrary, dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Wrapper for `load_library()` that takes a filename or path instead of a stream.
|
Wrapper for `load_library()` that takes a filename or path instead of a stream.
|
||||||
|
@ -29,7 +29,7 @@ from fatamorgana.basic import PathExtensionScheme, AString, NString, PropStringR
|
|||||||
|
|
||||||
from .utils import is_gzipped, tmpfile
|
from .utils import is_gzipped, tmpfile
|
||||||
from .. import Pattern, Ref, PatternError, LibraryError, Label, Shape
|
from .. import Pattern, Ref, PatternError, LibraryError, Label, Shape
|
||||||
from ..library import WrapLibrary, MutableLibrary
|
from ..library import Library, ILibrary
|
||||||
from ..shapes import Polygon, Path, Circle
|
from ..shapes import Polygon, Path, Circle
|
||||||
from ..repetition import Grid, Arbitrary, Repetition
|
from ..repetition import Grid, Arbitrary, Repetition
|
||||||
from ..utils import layer_t, normalize_mirror, annotations_t
|
from ..utils import layer_t, normalize_mirror, annotations_t
|
||||||
@ -98,11 +98,11 @@ def build(
|
|||||||
Returns:
|
Returns:
|
||||||
`fatamorgana.OasisLayout`
|
`fatamorgana.OasisLayout`
|
||||||
"""
|
"""
|
||||||
if not isinstance(library, MutableLibrary):
|
if not isinstance(library, ILibrary):
|
||||||
if isinstance(library, dict):
|
if isinstance(library, dict):
|
||||||
library = WrapLibrary(library)
|
library = Library(library)
|
||||||
else:
|
else:
|
||||||
library = WrapLibrary(dict(library))
|
library = Library(dict(library))
|
||||||
|
|
||||||
if layer_map is None:
|
if layer_map is None:
|
||||||
layer_map = {}
|
layer_map = {}
|
||||||
@ -205,7 +205,7 @@ def readfile(
|
|||||||
filename: str | pathlib.Path,
|
filename: str | pathlib.Path,
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> tuple[WrapLibrary, dict[str, Any]]:
|
) -> tuple[Library, dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Wrapper for `oasis.read()` that takes a filename or path instead of a stream.
|
Wrapper for `oasis.read()` that takes a filename or path instead of a stream.
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ def readfile(
|
|||||||
|
|
||||||
def read(
|
def read(
|
||||||
stream: IO[bytes],
|
stream: IO[bytes],
|
||||||
) -> tuple[WrapLibrary, dict[str, Any]]:
|
) -> tuple[Library, dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Read a OASIS file and translate it into a dict of Pattern objects. OASIS cells are
|
Read a OASIS file and translate it into a dict of Pattern objects. OASIS cells are
|
||||||
translated into Pattern objects; Polygons are translated into polygons, and Placements
|
translated into Pattern objects; Polygons are translated into polygons, and Placements
|
||||||
@ -260,7 +260,7 @@ def read(
|
|||||||
layer_map[str(layer_name.nstring)] = layer_name
|
layer_map[str(layer_name.nstring)] = layer_name
|
||||||
library_info['layer_map'] = layer_map
|
library_info['layer_map'] = layer_map
|
||||||
|
|
||||||
mlib = WrapLibrary()
|
mlib = Library()
|
||||||
for cell in lib.cells:
|
for cell in lib.cells:
|
||||||
if isinstance(cell.name, int):
|
if isinstance(cell.name, int):
|
||||||
cell_name = lib.cellnames[cell.name].nstring.string
|
cell_name = lib.cellnames[cell.name].nstring.string
|
||||||
|
@ -35,7 +35,7 @@ logger = logging.getLogger(__name__)
|
|||||||
visitor_function_t = Callable[..., 'Pattern']
|
visitor_function_t = Callable[..., 'Pattern']
|
||||||
|
|
||||||
|
|
||||||
def _rename_patterns(lib: 'Library', name: str) -> str:
|
def _rename_patterns(lib: 'ILibraryView', name: str) -> str:
|
||||||
# TODO document rename function
|
# TODO document rename function
|
||||||
if not name.startswith('_'):
|
if not name.startswith('_'):
|
||||||
return name
|
return name
|
||||||
@ -44,7 +44,7 @@ def _rename_patterns(lib: 'Library', name: str) -> str:
|
|||||||
return lib.get_name(stem)
|
return lib.get_name(stem)
|
||||||
|
|
||||||
|
|
||||||
class Library(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
class ILibraryView(Mapping[str, 'Pattern'], 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]:
|
||||||
@ -68,7 +68,7 @@ class Library(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||||||
return Abstract(name=name, ports=self[name].ports)
|
return Abstract(name=name, ports=self[name].ports)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return '<Library with keys\n' + pformat(list(self.keys())) + '>'
|
return '<ILibraryView with keys\n' + pformat(list(self.keys())) + '>'
|
||||||
|
|
||||||
def dangling_refs(
|
def dangling_refs(
|
||||||
self,
|
self,
|
||||||
@ -138,9 +138,9 @@ class Library(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||||||
def subtree(
|
def subtree(
|
||||||
self,
|
self,
|
||||||
tops: str | Sequence[str],
|
tops: str | Sequence[str],
|
||||||
) -> 'Library':
|
) -> 'ILibraryView':
|
||||||
"""
|
"""
|
||||||
Return a new `Library`, containing only the specified patterns and the patterns they
|
Return a new `ILibraryView`, containing only the specified patterns and the patterns they
|
||||||
reference (recursively).
|
reference (recursively).
|
||||||
Dangling references do not cause an error.
|
Dangling references do not cause an error.
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ class Library(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||||||
tops: Name(s) of patterns to keep
|
tops: Name(s) of patterns to keep
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A `WrapROLibrary` containing only `tops` and the patterns they reference.
|
A `LibraryView` containing only `tops` and the patterns they reference.
|
||||||
"""
|
"""
|
||||||
if isinstance(tops, str):
|
if isinstance(tops, str):
|
||||||
tops = (tops,)
|
tops = (tops,)
|
||||||
@ -157,7 +157,7 @@ class Library(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||||||
keep |= set(tops)
|
keep |= set(tops)
|
||||||
|
|
||||||
filtered = {kk: vv for kk, vv in self.items() if kk in keep}
|
filtered = {kk: vv for kk, vv in self.items() if kk in keep}
|
||||||
new = WrapROLibrary(filtered)
|
new = LibraryView(filtered)
|
||||||
return new
|
return new
|
||||||
|
|
||||||
def polygonize(
|
def polygonize(
|
||||||
@ -415,19 +415,19 @@ class Library(Mapping[str, 'Pattern'], metaclass=ABCMeta):
|
|||||||
|
|
||||||
if pattern is not original_pattern:
|
if pattern is not original_pattern:
|
||||||
name = hierarchy[-1] # TODO what is name=None?
|
name = hierarchy[-1] # TODO what is name=None?
|
||||||
if not isinstance(self, MutableLibrary):
|
if not isinstance(self, ILibrary):
|
||||||
raise LibraryError('visit_* functions returned a new `Pattern` object'
|
raise LibraryError('visit_* functions returned a new `Pattern` object'
|
||||||
' but the library is immutable')
|
' but the library is immutable')
|
||||||
if name is None:
|
if name is None:
|
||||||
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)[name] = pattern
|
cast(ILibrary, self)[name] = pattern
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta):
|
class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], 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]:
|
||||||
@ -510,7 +510,7 @@ class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta)
|
|||||||
def add(
|
def add(
|
||||||
self,
|
self,
|
||||||
other: Mapping[str, 'Pattern'],
|
other: Mapping[str, 'Pattern'],
|
||||||
rename_theirs: Callable[['Library', str], str] = _rename_patterns,
|
rename_theirs: Callable[['ILibraryView', str], str] = _rename_patterns,
|
||||||
) -> dict[str, str]:
|
) -> dict[str, str]:
|
||||||
"""
|
"""
|
||||||
Add keys from another library into this one.
|
Add keys from another library into this one.
|
||||||
@ -534,7 +534,7 @@ class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta)
|
|||||||
self._merge(key, other, key)
|
self._merge(key, other, key)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
temp = WrapLibrary(copy.deepcopy(dict(other))) # TODO maybe add a `mutate` arg? Might want to keep the same patterns
|
temp = Library(copy.deepcopy(dict(other))) # TODO maybe add a `mutate` arg? Might want to keep the same patterns
|
||||||
rename_map = {}
|
rename_map = {}
|
||||||
for old_name in temp:
|
for old_name in temp:
|
||||||
if old_name in self:
|
if old_name in self:
|
||||||
@ -559,13 +559,13 @@ class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta)
|
|||||||
self,
|
self,
|
||||||
tree: 'Tree',
|
tree: 'Tree',
|
||||||
name: str | None = None,
|
name: str | None = None,
|
||||||
rename_theirs: Callable[['Library', str], str] = _rename_patterns,
|
rename_theirs: Callable[['ILibraryView', str], str] = _rename_patterns,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Add a `Tree` object into the current library.
|
Add a `Tree` object into the current library.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
tree: The `Tree` object (a `Library` with a specified `top` Pattern)
|
tree: The `Tree` object (an `ILibraryView` with a specified `top` Pattern)
|
||||||
which will be added into the current library.
|
which will be added into the current library.
|
||||||
name: New name for the top-level pattern. If not given, `tree.top` is used.
|
name: New name for the top-level pattern. If not given, `tree.top` is used.
|
||||||
rename_theirs: Called as rename_theirs(self, name) for each duplicate name
|
rename_theirs: Called as rename_theirs(self, name) for each duplicate name
|
||||||
@ -593,8 +593,8 @@ class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta)
|
|||||||
if len(other) == 1:
|
if len(other) == 1:
|
||||||
name = next(iter(other))
|
name = next(iter(other))
|
||||||
else:
|
else:
|
||||||
if not isinstance(other, Library):
|
if not isinstance(other, ILibraryView):
|
||||||
other = WrapROLibrary(other)
|
other = LibraryView(other)
|
||||||
|
|
||||||
tops = other.tops()
|
tops = other.tops()
|
||||||
if len(tops) > 1:
|
if len(tops) > 1:
|
||||||
@ -764,7 +764,7 @@ class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta)
|
|||||||
tops: str | Sequence[str],
|
tops: str | Sequence[str],
|
||||||
) -> Self:
|
) -> Self:
|
||||||
"""
|
"""
|
||||||
Return a new `Library`, containing only the specified patterns and the patterns they
|
Return a new `ILibraryView`, containing only the specified patterns and the patterns they
|
||||||
reference (recursively).
|
reference (recursively).
|
||||||
Dangling references do not cause an error.
|
Dangling references do not cause an error.
|
||||||
|
|
||||||
@ -772,7 +772,7 @@ class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta)
|
|||||||
tops: Name(s) of patterns to keep
|
tops: Name(s) of patterns to keep
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A `Library` containing only `tops` and the patterns they reference.
|
An object of the same type as `self` containing only `tops` and the patterns they reference.
|
||||||
"""
|
"""
|
||||||
if isinstance(tops, str):
|
if isinstance(tops, str):
|
||||||
tops = (tops,)
|
tops = (tops,)
|
||||||
@ -815,7 +815,7 @@ class MutableLibrary(Library, MutableMapping[str, 'Pattern'], metaclass=ABCMeta)
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
class WrapROLibrary(Library):
|
class LibraryView(ILibraryView):
|
||||||
mapping: Mapping[str, 'Pattern']
|
mapping: Mapping[str, 'Pattern']
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -837,10 +837,10 @@ class WrapROLibrary(Library):
|
|||||||
return key in self.mapping
|
return key in self.mapping
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f'<WrapROLibrary ({type(self.mapping)}) with keys\n' + pformat(list(self.keys())) + '>'
|
return f'<LibraryView ({type(self.mapping)}) with keys\n' + pformat(list(self.keys())) + '>'
|
||||||
|
|
||||||
|
|
||||||
class WrapLibrary(MutableLibrary):
|
class Library(ILibrary):
|
||||||
mapping: MutableMapping[str, 'Pattern']
|
mapping: MutableMapping[str, 'Pattern']
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -885,10 +885,10 @@ class WrapLibrary(MutableLibrary):
|
|||||||
self[key_self] = other[key_other]
|
self[key_self] = other[key_other]
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f'<WrapLibrary ({type(self.mapping)}) with keys\n' + pformat(list(self.keys())) + '>'
|
return f'<Library ({type(self.mapping)}) with keys\n' + pformat(list(self.keys())) + '>'
|
||||||
|
|
||||||
|
|
||||||
class LazyLibrary(MutableLibrary):
|
class LazyLibrary(ILibrary):
|
||||||
"""
|
"""
|
||||||
This class is usually used to create a library of Patterns by mapping names to
|
This class is usually used to create a library of Patterns by mapping names to
|
||||||
functions which generate or load the relevant `Pattern` object as-needed.
|
functions which generate or load the relevant `Pattern` object as-needed.
|
||||||
@ -1027,9 +1027,9 @@ class LazyLibrary(MutableLibrary):
|
|||||||
|
|
||||||
|
|
||||||
class AbstractView(Mapping[str, Abstract]):
|
class AbstractView(Mapping[str, Abstract]):
|
||||||
library: Library
|
library: ILibraryView
|
||||||
|
|
||||||
def __init__(self, library: Library) -> None:
|
def __init__(self, library: ILibraryView) -> None:
|
||||||
self.library = library
|
self.library = library
|
||||||
|
|
||||||
def __getitem__(self, key: str) -> Abstract:
|
def __getitem__(self, key: str) -> Abstract:
|
||||||
@ -1042,9 +1042,9 @@ class AbstractView(Mapping[str, Abstract]):
|
|||||||
return self.library.__len__()
|
return self.library.__len__()
|
||||||
|
|
||||||
|
|
||||||
class Tree(MutableLibrary):
|
class Tree(ILibrary):
|
||||||
top: str
|
top: str
|
||||||
library: MutableLibrary
|
library: ILibrary
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pattern(self) -> 'Pattern':
|
def pattern(self) -> 'Pattern':
|
||||||
@ -1053,10 +1053,10 @@ class Tree(MutableLibrary):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
top: str,
|
top: str,
|
||||||
library: MutableLibrary | None = None
|
library: ILibrary | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
self.top = top
|
self.top = top
|
||||||
self.library = library if library is not None else WrapLibrary()
|
self.library = library if library is not None else Library()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def mk(cls, top: str) -> tuple['Tree', 'Pattern']:
|
def mk(cls, top: str) -> tuple['Tree', 'Pattern']:
|
||||||
|
@ -16,7 +16,7 @@ from ..label import Label
|
|||||||
from ..utils import layer_t
|
from ..utils import layer_t
|
||||||
from ..ports import Port
|
from ..ports import Port
|
||||||
from ..error import PatternError
|
from ..error import PatternError
|
||||||
from ..library import Library, WrapROLibrary
|
from ..library import ILibraryView, LibraryView
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -88,8 +88,8 @@ def data_to_ports(
|
|||||||
logger.warning(f'Pattern {name if name else pattern} already had ports, skipping data_to_ports')
|
logger.warning(f'Pattern {name if name else pattern} already had ports, skipping data_to_ports')
|
||||||
return pattern
|
return pattern
|
||||||
|
|
||||||
if not isinstance(library, Library):
|
if not isinstance(library, ILibraryView):
|
||||||
library = WrapROLibrary(library)
|
library = LibraryView(library)
|
||||||
|
|
||||||
data_to_ports_flat(layers, pattern, name)
|
data_to_ports_flat(layers, pattern, name)
|
||||||
if (skip_subcells and pattern.ports) or max_depth == 0:
|
if (skip_subcells and pattern.ports) or max_depth == 0:
|
||||||
|
Loading…
Reference in New Issue
Block a user