[PatherMixin] add thru arg to path_into and rework portlist inheritance

This commit is contained in:
jan 2025-11-19 01:24:02 -08:00
parent 334bcade31
commit 184168f623
2 changed files with 38 additions and 13 deletions

View File

@ -1,5 +1,5 @@
from typing import Self, TYPE_CHECKING from typing import Self, TYPE_CHECKING
from collections.abc import Sequence, Iterator from collections.abc import Sequence, Iterator, Iterable
import logging import logging
from contextlib import contextmanager from contextlib import contextmanager
from abc import abstractmethod, ABCMeta from abc import abstractmethod, ABCMeta
@ -9,22 +9,19 @@ from numpy import pi
from numpy.typing import ArrayLike from numpy.typing import ArrayLike
from ..pattern import Pattern from ..pattern import Pattern
from ..library import ILibrary from ..library import ILibrary, TreeView
from ..error import PortError, BuildError from ..error import PortError, BuildError
from ..utils import SupportsBool from ..utils import SupportsBool
from ..abstract import Abstract from ..abstract import Abstract
from .tools import Tool from .tools import Tool
from .utils import ell from .utils import ell
from ..ports import PortList
if TYPE_CHECKING:
from .pather import Pather
from .renderpather import RenderPather
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class PatherMixin(metaclass=ABCMeta): class PatherMixin(PortList, metaclass=ABCMeta):
pattern: Pattern pattern: Pattern
""" Layout of this device """ """ Layout of this device """
@ -64,6 +61,21 @@ class PatherMixin(metaclass=ABCMeta):
) -> Self: ) -> Self:
pass pass
@abstractmethod
def plug(
self,
other: Abstract | str | Pattern | TreeView,
map_in: dict[str, str],
map_out: dict[str, str | None] | None = None,
*,
mirrored: bool = False,
thru: bool | str = True,
set_rotation: bool | None = None,
append: bool = False,
ok_connections: Iterable[tuple[str, str]] = (),
) -> Self:
pass
def retool( def retool(
self, self,
tool: Tool, tool: Tool,
@ -221,6 +233,7 @@ class PatherMixin(metaclass=ABCMeta):
*, *,
out_ptype: str | None = None, out_ptype: str | None = None,
plug_destination: bool = True, plug_destination: bool = True,
thru: str | None = None,
**kwargs, **kwargs,
) -> Self: ) -> Self:
""" """
@ -244,6 +257,8 @@ class PatherMixin(metaclass=ABCMeta):
out_ptype: Passed to the pathing tool in order to specify the desired port type out_ptype: Passed to the pathing tool in order to specify the desired port type
to be generated at the destination end. If `None` (default), the destination to be generated at the destination end. If `None` (default), the destination
port's `ptype` will be used. port's `ptype` will be used.
thru: If not `None`, the port by this name will be rename to `portspec_src`.
This can be used when routing a signal through a pre-placed 2-port device.
Returns: Returns:
self self
@ -312,6 +327,9 @@ class PatherMixin(metaclass=ABCMeta):
else: else:
raise BuildError(f'Don\'t know how to route ports with relative angle {angle}') raise BuildError(f'Don\'t know how to route ports with relative angle {angle}')
if thru is not None:
self.rename_ports({thru: portspec_src})
return self return self
def mpath( def mpath(
@ -453,9 +471,9 @@ class PortPather:
port without needing to repeatedly pass its name. port without needing to repeatedly pass its name.
""" """
port: str port: str
pather: 'Pather | RenderPather' pather: PatherMixin
def __init__(self, port: str, pather: 'Pather | RenderPather') -> None: def __init__(self, port: str, pather: PatherMixin) -> None:
self.port = port self.port = port
self.pather = pather self.pather = pather

View File

@ -2,7 +2,7 @@
Pather with batched (multi-step) rendering Pather with batched (multi-step) rendering
""" """
from typing import Self from typing import Self
from collections.abc import Sequence, Mapping, MutableMapping from collections.abc import Sequence, Mapping, MutableMapping, Iterable
import copy import copy
import logging import logging
from collections import defaultdict from collections import defaultdict
@ -13,7 +13,7 @@ from numpy import pi
from numpy.typing import ArrayLike from numpy.typing import ArrayLike
from ..pattern import Pattern from ..pattern import Pattern
from ..library import ILibrary from ..library import ILibrary, TreeView
from ..error import BuildError from ..error import BuildError
from ..ports import PortList, Port from ..ports import PortList, Port
from ..abstract import Abstract from ..abstract import Abstract
@ -25,7 +25,7 @@ from .pather_mixin import PatherMixin
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class RenderPather(PortList, PatherMixin): class RenderPather(PatherMixin):
""" """
`RenderPather` is an alternative to `Pather` which uses the `path`/`path_to`/`mpath` `RenderPather` is an alternative to `Pather` which uses the `path`/`path_to`/`mpath`
functions to plan out wire paths without incrementally generating the layout. Instead, functions to plan out wire paths without incrementally generating the layout. Instead,
@ -188,7 +188,7 @@ class RenderPather(PortList, PatherMixin):
def plug( def plug(
self, self,
other: Abstract | str, other: Abstract | str | Pattern | TreeView,
map_in: dict[str, str], map_in: dict[str, str],
map_out: dict[str, str | None] | None = None, map_out: dict[str, str | None] | None = None,
*, *,
@ -196,6 +196,7 @@ class RenderPather(PortList, PatherMixin):
thru: bool | str = True, thru: bool | str = True,
set_rotation: bool | None = None, set_rotation: bool | None = None,
append: bool = False, append: bool = False,
ok_connections: Iterable[tuple[str, str]] = (),
) -> Self: ) -> Self:
""" """
Wrapper for `Pattern.plug` which adds a `RenderStep` with opcode 'P' Wrapper for `Pattern.plug` which adds a `RenderStep` with opcode 'P'
@ -229,6 +230,12 @@ class RenderPather(PortList, PatherMixin):
append: If `True`, `other` is appended instead of being referenced. append: If `True`, `other` is appended instead of being referenced.
Note that this does not flatten `other`, so its refs will still Note that this does not flatten `other`, so its refs will still
be refs (now inside `self`). be refs (now inside `self`).
ok_connections: Set of "allowed" ptype combinations. Identical
ptypes are always allowed to connect, as is `'unk'` with
any other ptypte. Non-allowed ptype connections will emit a
warning. Order is ignored, i.e. `(a, b)` is equivalent to
`(b, a)`.
Returns: Returns:
self self