diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6ea8ef49..9b165e04 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,6 +24,16 @@ repos: - id: ruff-format files: ^gplugins/(femwell|gmsh|meow|sax|tidy3d|klayout|vlsir)/ + - repo: https://github.com/pre-commit/mirrors-mypy + rev: "v1.15.0" + hooks: + - id: mypy + args: [--ignore-missing-imports, --strict, --config-file=pyproject.toml] + additional_dependencies: + - gdsfactory + - pytest + files: ^gplugins/(femwell|gmsh|meow|sax|tidy3d|klayout|vlsir)/ + # - repo: https://github.com/shellcheck-py/shellcheck-py # rev: v0.9.0.5 # hooks: diff --git a/Makefile b/Makefile index 865940b7..8f9171ab 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ venv: install: uv venv --python 3.11 - uv pip install -e .[dev,docs,devsim,femwell,gmsh,klayout,meow,sax,schematic,tidy3d,vlsir] + uv pip install -e .[dev,docs,femwell,gmsh,meow,sax,tidy3d,klayout,vlsir] uv run pre-commit install dev: test-data gmsh elmer install diff --git a/gplugins/common/utils/get_component_with_net_layers.py b/gplugins/common/utils/get_component_with_net_layers.py index 05b63b0e..5a6c5e86 100644 --- a/gplugins/common/utils/get_component_with_net_layers.py +++ b/gplugins/common/utils/get_component_with_net_layers.py @@ -1,6 +1,7 @@ import copy import gdsfactory as gf +import klayout.db as kdb from gdsfactory import Component from gdsfactory.technology import LayerStack, LogicalLayer @@ -35,8 +36,8 @@ def get_component_layer_stack( def get_component_with_net_layers( - component, - layer_stack, + component: Component, + layer_stack: LayerStack, port_names: list[str], delimiter: str = "#", new_layers_init: tuple[int, int] = (10010, 0), @@ -74,7 +75,9 @@ def get_component_with_net_layers( net_component = net_component.remove_layers(layers=(port.layer,)) for polygon in polygons: # If polygon belongs to port, create a unique new layer, and add the polygon to it - if polygon.sized(3 * gf.kcl.dbu).inside(port.center): + if polygon.sized(int(3 * gf.kcl.dbu)).inside( + kdb.Point(*port.to_itype().center) + ): # if gdstk.inside( # [port.center], # gdstk.offset(gdstk.Polygon(polygon), gf.get_active_pdk().grid_size), @@ -111,8 +114,3 @@ def get_component_with_net_layers( net_component.name = f"{component.name}_net_layers" return net_component - - -if __name__ == "__main__": - c = get_component_with_net_layers() - c.show() diff --git a/gplugins/common/utils/get_effective_indices.py b/gplugins/common/utils/get_effective_indices.py index bc93c525..699103fa 100644 --- a/gplugins/common/utils/get_effective_indices.py +++ b/gplugins/common/utils/get_effective_indices.py @@ -2,9 +2,10 @@ from __future__ import annotations -from typing import Literal +from typing import Any, Literal, cast import numpy as np +import numpy.typing as npt from scipy.optimize import fsolve @@ -19,9 +20,9 @@ def get_effective_indices( """Returns the effective refractive indices for a 1D mode. Args: - epsilon_core: Relative permittivity of the film. - epsilon_substrate: Relative permittivity of the substrate. - epsilon_cladding: Relative permittivity of the cladding. + core_material: Refractive index of the core material. + nsubstrate: Refractive index of the substrate. + clad_materialding: Refractive index of the cladding. thickness: Thickness of the film in um. wavelength: Wavelength in um. polarization: Either "te" or "tm". @@ -66,18 +67,20 @@ def get_effective_indices( k_0 = 2 * np.pi / wavelength - def k_f(e_eff): + def k_f(e_eff: npt.NDArray[np.floating[Any]]) -> npt.NDArray[np.floating[Any]]: return k_0 * np.sqrt(epsilon_core - e_eff) / (epsilon_core if tm else 1) - def k_s(e_eff): + def k_s(e_eff: npt.NDArray[np.floating[Any]]) -> npt.NDArray[np.floating[Any]]: return ( k_0 * np.sqrt(e_eff - epsilon_substrate) / (epsilon_substrate if tm else 1) ) - def k_c(e_eff): + def k_c(e_eff: npt.NDArray[np.floating[Any]]) -> npt.NDArray[np.floating[Any]]: return k_0 * np.sqrt(e_eff - epsilon_cladding) / (epsilon_cladding if tm else 1) - def objective(e_eff): + def objective( + e_eff: npt.NDArray[np.floating[Any]], + ) -> npt.NDArray[np.floating[Any]]: return 1 / np.tan(k_f(e_eff) * thickness) - ( k_f(e_eff) ** 2 - k_s(e_eff) * k_c(e_eff) ) / (k_f(e_eff) * (k_s(e_eff) + k_c(e_eff))) @@ -92,14 +95,14 @@ def objective(e_eff): return [] # and then use fsolve to get exact indices - indices_temp = fsolve(objective, indices_temp) + indices_temp = cast(npt.NDArray[np.floating[Any]], fsolve(objective, indices_temp)) - indices = [] + indices: list[float] = [] for index in indices_temp: if not any(np.isclose(index, i, atol=1e-5) for i in indices): indices.append(index) - return np.sqrt(indices).tolist() + return cast(list[float], np.sqrt(indices).tolist()) def test_effective_index() -> None: diff --git a/gplugins/common/utils/parse_layer_stack.py b/gplugins/common/utils/parse_layer_stack.py index 6941015e..ac1830b7 100644 --- a/gplugins/common/utils/parse_layer_stack.py +++ b/gplugins/common/utils/parse_layer_stack.py @@ -26,7 +26,7 @@ def list_unique_layer_stack_z( def map_unique_layer_stack_z( layer_stack: LayerStack, include_zmax: bool = True, -): +) -> dict[str, set[float]]: """Map unique LayerStack z coordinates to various layers. Args: @@ -57,7 +57,7 @@ def map_unique_layer_stack_z( def get_layer_overlaps_z( layer_stack: LayerStack, include_zmax: bool = True, -): +) -> dict[float, set[str]]: """Maps layers to unique LayerStack z coordinates. Args: @@ -67,7 +67,7 @@ def get_layer_overlaps_z( """ z_grid = list_unique_layer_stack_z(layer_stack) unique_z_dict = map_unique_layer_stack_z(layer_stack, include_zmax) - intersection_z_dict = {} + intersection_z_dict: dict[float, set[str]] = {} for z in z_grid: current_layers = { layername for layername, layer_zs in unique_z_dict.items() if z in layer_zs @@ -77,11 +77,12 @@ def get_layer_overlaps_z( return intersection_z_dict -def get_layers_at_z(layer_stack: LayerStack, z: float): +def get_layers_at_z(layer_stack: LayerStack, z: float) -> list[str]: """Returns layers present at a given z-position. Args: layer_stack: LayerStack + z: float Returns: List of layers """ @@ -93,11 +94,11 @@ def get_layers_at_z(layer_stack: LayerStack, z: float): raise ValueError("Requested z-value is above the minimum layer_stack z") for z_unique in intersection_z_dict.keys(): if z <= z_unique: - return intersection_z_dict[z_unique] + return list(intersection_z_dict[z_unique]) raise AssertionError("Could not find z-value in layer_stack z-range.") -def order_layer_stack(layer_stack: LayerStack): +def order_layer_stack(layer_stack: LayerStack) -> list[str]: """Orders layer_stack according to mesh_order. Args: diff --git a/gplugins/common/utils/plot.py b/gplugins/common/utils/plot.py index 86d8fc08..b6e77923 100644 --- a/gplugins/common/utils/plot.py +++ b/gplugins/common/utils/plot.py @@ -4,13 +4,17 @@ from collections.abc import Sequence from functools import partial from itertools import combinations +from typing import Any -import gdsfactory as gf import matplotlib.pyplot as plt import numpy as np +import numpy.typing as npt +from matplotlib.axes import Axes -def _check_ports(sp: dict[str, np.ndarray], ports: Sequence[str]) -> None: +def _check_ports( + sp: dict[str, npt.NDArray[np.floating[Any]]], ports: Sequence[str] +) -> None: """Ensure ports exist in Sparameters.""" for port in ports: if port not in sp: @@ -18,7 +22,7 @@ def _check_ports(sp: dict[str, np.ndarray], ports: Sequence[str]) -> None: def plot_sparameters( - sp: dict[str, np.ndarray], + sp: dict[str, npt.NDArray[np.floating[Any]]], logscale: bool = True, plot_phase: bool = False, keys: tuple[str, ...] | None = None, @@ -39,7 +43,7 @@ def plot_sparameters( """ w = sp["wavelengths"] * units - keys = keys or [key for key in sp if not key.lower().startswith("wav")] + keys = keys or tuple(key for key in sp if not key.lower().startswith("wav")) for key in keys: if with_simpler_input_keys: @@ -74,9 +78,12 @@ def plot_sparameters( def plot_imbalance( - sp: dict[str, np.ndarray], ports: Sequence[str], ax: plt.Axes | None = None + sp: dict[str, npt.NDArray[np.floating[Any]]], + ports: Sequence[str], + ax: Axes | None = None, ) -> None: """Plots imbalance in dB for coupler. + The imbalance is always defined between two ports, so this function plots the imbalance between all unique port combinations. @@ -107,7 +114,9 @@ def plot_imbalance( def plot_loss( - sp: dict[str, np.ndarray], ports: Sequence[str], ax: plt.Axes | None = None + sp: dict[str, npt.NDArray[np.floating[Any]]], + ports: Sequence[str], + ax: Axes | None = None, ) -> None: """Plots loss dB for coupler. @@ -137,7 +146,9 @@ def plot_loss( def plot_reflection( - sp: dict[str, np.ndarray], ports: Sequence[str], ax: plt.Axes | None = None + sp: dict[str, npt.NDArray[np.floating[Any]]], + ports: Sequence[str], + ax: Axes | None = None, ) -> None: """Plots reflection in dB for coupler. @@ -172,11 +183,3 @@ def plot_reflection( plot_imbalance2x2 = partial(plot_imbalance, ports=["o1@0,o3@0", "o1@0,o4@0"]) plot_reflection1x2 = partial(plot_reflection, ports=["o1@0,o1@0"]) plot_reflection2x2 = partial(plot_reflection, ports=["o1@0,o1@0", "o2@0,o1@0"]) - -if __name__ == "__main__": - import gplugins as sim - - sp = sim.get_sparameters_data_tidy3d(component=gf.components.mmi1x2) - # plot_sparameters(sp, logscale=False, keys=["o1@0,o2@0"]) - # plot_sparameters(sp, logscale=False, keys=["S21"]) - # plt.show() diff --git a/gplugins/gmsh/define_polysurfaces.py b/gplugins/gmsh/define_polysurfaces.py index 2cdc1ae7..90d45878 100644 --- a/gplugins/gmsh/define_polysurfaces.py +++ b/gplugins/gmsh/define_polysurfaces.py @@ -6,16 +6,16 @@ def define_polysurfaces( - polygons_dict: dict, + polygons_dict: dict[str, Any], layer_stack: LayerStack, - layer_physical_map: dict, - layer_meshbool_map: dict, + layer_physical_map: dict[str, Any], + layer_meshbool_map: dict[str, Any], model: Any, - resolutions: dict, + resolutions: dict[str, Any] | None = None, scale_factor: float = 1, -): +) -> list[PolySurface]: """Define meshwell polysurfaces dimtags from gdsfactory information.""" - polysurfaces_list = [] + polysurfaces_list: list[PolySurface] = [] if resolutions is None: resolutions = {} @@ -24,6 +24,11 @@ def define_polysurfaces( if polygons_dict[layername].is_empty: continue + layer_stack_ = layer_stack.layers.get(layername) + + if layer_stack_ is None: + continue + polysurfaces_list.append( PolySurface( polygons=scale( @@ -33,7 +38,7 @@ def define_polysurfaces( ), model=model, resolution=resolutions.get(layername, None), - mesh_order=layer_stack.layers.get(layername).mesh_order, + mesh_order=layer_stack_.mesh_order, physical_name=layer_physical_map[layername] if layername in layer_physical_map else layername, diff --git a/gplugins/gmsh/uz_xsection_mesh.py b/gplugins/gmsh/uz_xsection_mesh.py index 9e1d2f17..00af37eb 100644 --- a/gplugins/gmsh/uz_xsection_mesh.py +++ b/gplugins/gmsh/uz_xsection_mesh.py @@ -1,7 +1,7 @@ -# type: ignore from __future__ import annotations from collections.abc import Sequence +from typing import Any import gdsfactory as gf import numpy as np @@ -206,12 +206,12 @@ def uz_xsection_mesh( component: ComponentOrReference, xsection_bounds: tuple[tuple[float, float], tuple[float, float]], layer_stack: LayerStack, - layer_physical_map: dict, - layer_meshbool_map: dict, - resolutions: dict | None = None, + layer_physical_map: dict[str, Any], + layer_meshbool_map: dict[str, Any], + resolutions: dict[str, Any] | None = None, default_characteristic_length: float = 0.5, background_tag: str | None = None, - background_padding: Sequence[float, float, float, float, float, float] = (2.0,) * 6, + background_padding: Sequence[float] = (2.0,) * 6, background_mesh_order: int | float = 2**63 - 1, global_scaling: float = 1, global_scaling_premesh: float = 1, @@ -225,9 +225,9 @@ def uz_xsection_mesh( n_threads: int = get_number_of_cores(), gmsh_version: float | None = None, interface_delimiter: str = "___", - background_remeshing_file=None, + background_remeshing_file: str | None = None, optimization_flags: tuple[tuple[str, int]] | None = None, - **kwargs, + **kwargs: Any, ): """Mesh uz cross-section of component along line u = [[x1,y1] , [x2,y2]]. diff --git a/gplugins/gmsh/xyz_mesh.py b/gplugins/gmsh/xyz_mesh.py index 1504494a..0e229e2f 100644 --- a/gplugins/gmsh/xyz_mesh.py +++ b/gplugins/gmsh/xyz_mesh.py @@ -26,10 +26,10 @@ def define_edgeport( - port, - port_dict, - model, - layerlevel, + port: gf.Port, + port_dict: dict[str, Any], + model: Model, + layerlevel: LayerLevel, ): """Creates an unmeshed box at the port location to tag the edge port surfaces in the final mesh.""" zmin = port_dict.get("zmin") or layerlevel.zmin @@ -73,12 +73,12 @@ def define_edgeport( def define_prisms( - layer_polygons_dict: dict, + layer_polygons_dict: dict[str, Any], layer_stack: LayerStack, - layer_physical_map: dict, - layer_meshbool_map: dict, + layer_physical_map: dict[str, Any], + layer_meshbool_map: dict[str, Any], model: Any, - resolutions: dict, + resolutions: dict[str, Any] | None = None, scale_factor: float = 1, ): """Define meshwell prism dimtags from gdsfactory information. @@ -92,7 +92,7 @@ def define_prisms( resolutions: Pairs {"layername": {"resolution": float, "distance": "float}} to roughly control mesh refinement.. scale_factor: scaling factor to apply to the polygons (default: 1). """ - prisms_list = [] + prisms_list: list[Prism] = [] buffered_layer_stack = bufferize(layer_stack) if resolutions is None: @@ -102,14 +102,19 @@ def define_prisms( if layer_polygons_dict[layername].is_empty: continue - coords = np.array(buffered_layer_stack.layers[layername].z_to_bias[0]) + layer_ = buffered_layer_stack.layers[layername] + + z_to_bias = layer_.z_to_bias + + if z_to_bias is None: + continue + + coords = np.array(z_to_bias[0]) zs = ( coords * buffered_layer_stack.layers[layername].thickness * scale_factor + buffered_layer_stack.layers[layername].zmin * scale_factor ) - buffers = ( - np.array(buffered_layer_stack.layers[layername].z_to_bias[1]) * scale_factor - ) + buffers = np.array(z_to_bias[1]) * scale_factor buffer_dict = dict(zip(zs, buffers)) @@ -137,9 +142,9 @@ def define_prisms( def xyz_mesh( component: ComponentOrReference, layer_stack: LayerStack, - layer_physical_map: dict, - layer_meshbool_map: dict, - resolutions: dict | None = None, + layer_physical_map: dict[str, Any], + layer_meshbool_map: dict[str, Any], + resolutions: dict[str, Any] | None = None, default_characteristic_length: float = 0.5, background_tag: str | None = None, background_padding: tuple[float, float, float, float, float, float] = (2.0,) * 6, diff --git a/gplugins/klayout/get_netlist.py b/gplugins/klayout/get_netlist.py index 31ed5009..388bf84f 100644 --- a/gplugins/klayout/get_netlist.py +++ b/gplugins/klayout/get_netlist.py @@ -1,4 +1,3 @@ -# type: ignore from typing import Any import gdsfactory as gf @@ -35,7 +34,8 @@ def get_l2n( klayout_tech_path = tech_dir / "tech.lyt" # klayout tech path is now assumed to contain a `tech.lyt`` file to use - technology = Tech.load(str(klayout_tech_path)) + Tech.load(str(klayout_tech_path)) + technology = Tech lib.read(filename=str(gdspath)) c = lib.top_kcell() @@ -45,6 +45,7 @@ def get_l2n( reversed_layer_map = {} layers = gf.get_active_pdk().layers + assert layers is not None # Reversed layer map with names as sets in order to support layer aliases for k, v in {layer.name: (layer.layer, layer.datatype) for layer in layers}.items(): diff --git a/gplugins/klayout/netlist_graph.py b/gplugins/klayout/netlist_graph.py index fa7f82bd..20106801 100644 --- a/gplugins/klayout/netlist_graph.py +++ b/gplugins/klayout/netlist_graph.py @@ -8,6 +8,7 @@ import networkx as nx from gdsfactory import logger from gdsfactory.typings import PathType +from klayout.db import NetlistSpiceReaderDelegate import gplugins.vlsir from gplugins.klayout.netlist_spice_reader import ( @@ -109,8 +110,8 @@ def networkx_from_spice( filepath: PathType, include_labels: bool = True, top_cell: str | None = None, - spice_reader: type[NetlistSpiceReaderDelegateWithStrings] - | NetlistSpiceReaderDelegateWithStrings = GdsfactorySpiceReader, + spice_reader: type[NetlistSpiceReaderDelegate] + | NetlistSpiceReaderDelegate = GdsfactorySpiceReader, **kwargs: Any, ) -> nx.Graph: """Returns a networkx Graph from a SPICE netlist file or KLayout LayoutToNetlist. diff --git a/gplugins/klayout/netlist_spice_reader.py b/gplugins/klayout/netlist_spice_reader.py index a9d2e9ce..ccf2d0ba 100644 --- a/gplugins/klayout/netlist_spice_reader.py +++ b/gplugins/klayout/netlist_spice_reader.py @@ -59,7 +59,7 @@ def integer_to_string_map(self, value: MutableMapping[int, str]) -> None: self._integer_to_string_map = value @override - def wants_subcircuit(self, name: str): + def wants_subcircuit(self, name: str) -> bool: """Model all SPICE models that start with `WG` as devices in order to support parameters.""" return "WG" in name or super().wants_subcircuit(name) @@ -105,7 +105,7 @@ def element( value: Any, nets: Sequence[kdb.Net], parameters: dict[str, int | float | str], - ): + ) -> bool: # Handle non-'X' elements with standard KLayout processing if element != "X": # Other devices with standard KLayout @@ -145,6 +145,8 @@ def element( ), ) + return True + class GdsfactorySpiceReader(CalibreSpiceReader): """KLayout Spice reader for Gdsfactory-extracted KLayout LayoutToNetlist. @@ -175,7 +177,7 @@ def __init__( ] @override - def wants_subcircuit(self, name: str): + def wants_subcircuit(self, name: str) -> bool: """Model all basic gdsfactory components as devices in order to support parameters.""" return all( cell not in name.casefold() for cell in self.components_as_subcircuits diff --git a/gplugins/klayout/plot_nets.py b/gplugins/klayout/plot_nets.py index b0e54054..e69c808d 100644 --- a/gplugins/klayout/plot_nets.py +++ b/gplugins/klayout/plot_nets.py @@ -5,6 +5,7 @@ import networkx as nx from gdsfactory.typings import PathType from klayout.db import NetlistSpiceReaderDelegate +from matplotlib.figure import Figure from gplugins.klayout.netlist_graph import networkx_from_spice from gplugins.klayout.netlist_spice_reader import ( @@ -19,7 +20,7 @@ def plot_nets( top_cell: str | None = None, nodes_to_reduce: Collection[str] | None = None, spice_reader: type[NetlistSpiceReaderDelegate] = GdsfactorySpiceReader, -) -> None | plt.Figure: +) -> None | Figure: """Plots the connectivity between the components in the KLayout LayoutToNetlist file from :func:`~get_l2n`. Args: @@ -91,6 +92,7 @@ def _removal_condition(node: str, degree: int) -> bool: font_size=12, ) return fig + return if __name__ == "__main__": diff --git a/gplugins/klayout/tests/test_plot_nets.py b/gplugins/klayout/tests/test_plot_nets.py index 9ebdc933..9d491a14 100644 --- a/gplugins/klayout/tests/test_plot_nets.py +++ b/gplugins/klayout/tests/test_plot_nets.py @@ -10,7 +10,7 @@ @pytest.fixture(scope="session") -def klayout_netlist(tmpdir_factory) -> str: +def klayout_netlist(tmpdir_factory: pytest.TempdirFactory) -> str: """Get KLayout netlist file for `pads_correct`. Cached for session scope.""" tmp_path = tmpdir_factory.mktemp("data") c = pads_correct() @@ -22,7 +22,7 @@ def klayout_netlist(tmpdir_factory) -> str: @pytest.fixture(scope="session") -def spice_netlist(tmpdir_factory) -> str: +def spice_netlist(tmpdir_factory: pytest.TempdirFactory) -> str: """Get SPICE netlist file for `pads_correct`. Cached for session scope.""" tmp_path = tmpdir_factory.mktemp("data") c = pads_correct() @@ -42,10 +42,10 @@ def spice_netlist(tmpdir_factory) -> str: "nodes_to_reduce", [None, {"straight"}, {"straight", "bend_euler"}] ) def test_plot_nets( - klayout_netlist, - interactive, - include_labels, - nodes_to_reduce, + klayout_netlist: str, + interactive: bool, + include_labels: bool, + nodes_to_reduce: list[str] | None, ) -> None: plot_nets( klayout_netlist, @@ -58,5 +58,5 @@ def test_plot_nets( assert Path("connectivity.html").exists() -def test_plot_nets_spice(spice_netlist) -> None: +def test_plot_nets_spice(spice_netlist: str) -> None: plot_nets(spice_netlist) diff --git a/gplugins/vlsir/export_netlist.py b/gplugins/vlsir/export_netlist.py index b267ee59..0f866f22 100644 --- a/gplugins/vlsir/export_netlist.py +++ b/gplugins/vlsir/export_netlist.py @@ -10,8 +10,10 @@ - Thoroughly test the parser with more complex netlists. """ +from collections.abc import Iterator from io import StringIO from itertools import count +from typing import Any import vlsirtools from klayout.db import ( @@ -35,27 +37,27 @@ __SUPPORTED_FORMATS = ["spice", "spectre", "xyce", "verilog"] -def _lref(name) -> Reference: +def _lref(name: str) -> Reference: """Create a local `Reference` to a local `Module` with the given name.""" return Reference(local=name) -def _connections(**kwargs) -> list[Connection]: +def _connections(**kwargs: Any) -> list[Connection]: """Create a list of `Connection`s from keyword args of the form `portname=conn_target`, where `conn_target` is a `ConnectionTarget`.""" return [Connection(portname=key, target=value) for key, value in kwargs.items()] -def _params(**kwargs) -> list[Param]: +def _params(**kwargs: Any) -> list[Param]: """Create a list of `Param`s from keyword args of the form r=ParamValue(double_value=1e3).""" return [Param(name=key, value=value) for key, value in kwargs.items()] -def _temp_net(counter) -> str: +def _temp_net(counter: Iterator[int]) -> str: """Return a new unique net name, Used for naming temporary nets.""" return f"__temp_net_{next(counter)}__" -def _net_name(net: Net, counter) -> str: +def _net_name(net: Net, counter: Iterator[int]) -> str: """Get the name of a `Net`.""" if net.name is None: return _temp_net(counter) @@ -63,7 +65,7 @@ def _net_name(net: Net, counter) -> str: return net_name.replace("$", "") -def _instance_name(instance: SubCircuit, counter) -> str: +def _instance_name(instance: SubCircuit, counter: Iterator[int]) -> str: """Get the name of a `SubCircuit` instance.""" if instance.name is None: return _temp_net(counter) @@ -71,7 +73,9 @@ def _instance_name(instance: SubCircuit, counter) -> str: return instance_name.replace("$", "") -def _subcircuit_instance(instance: SubCircuit, counter, **kwargs) -> Instance: +def _subcircuit_instance( + instance: SubCircuit, counter: Iterator[int], **kwargs: Any +) -> Instance: """Create a new VLSIR Instance from the klayout.db SubCircuit and return it to include in the respective Module (SubCircuit).""" subckt_name = _instance_name(instance, counter) ref = instance.circuit_ref() @@ -103,7 +107,7 @@ def _subcircuit_instance(instance: SubCircuit, counter, **kwargs) -> Instance: def _circuit_module( - circuit: Circuit, counter, verbose: bool = False, **kwargs + circuit: Circuit, counter: Iterator[int], verbose: bool = False, **kwargs: Any ) -> Module: """Convert a Klayout DB `Circuit` to a VLSIR 'Module' and return it to include it in the package. @@ -147,7 +151,9 @@ def _circuit_module( return mod -def kdb_vlsir(kdbnet: Netlist, domain: str, verbose: bool = False, **kwargs) -> Package: +def kdb_vlsir( + kdbnet: Netlist, domain: str, verbose: bool = False, **kwargs: Any +) -> Package: """Create a VLSIR `Package` circuit netlist from a KLayout DB `Netlist`. Args: @@ -164,7 +170,7 @@ def kdb_vlsir(kdbnet: Netlist, domain: str, verbose: bool = False, **kwargs) -> return Package(domain=domain, modules=modules) -def export_netlist(pkg: Package, fmt: str = "spice", dest=None) -> str: +def export_netlist(pkg: Package, fmt: str = "spice", dest: Any = None) -> str: """Export a VLSIR `Package` circuit netlist to a string in the specified format. Args: