add ok_connections arg to allow plugging mismatched ports without warnings

This commit is contained in:
Jan Petykiewicz 2024-10-05 14:29:02 -07:00
parent 4e862d6853
commit 93471a221c
3 changed files with 30 additions and 2 deletions

View File

@ -2,7 +2,7 @@
Simplified Pattern assembly (`Builder`) Simplified Pattern assembly (`Builder`)
""" """
from typing import Self from typing import Self
from collections.abc import Sequence, Mapping from collections.abc import Iterable, Sequence, Mapping
import copy import copy
import logging import logging
from functools import wraps from functools import wraps
@ -226,6 +226,7 @@ class Builder(PortList):
inherit_name: bool = True, inherit_name: bool = 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 around `Pattern.plug` which allows a string for `other`. Wrapper around `Pattern.plug` which allows a string for `other`.
@ -260,6 +261,11 @@ class Builder(PortList):
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
@ -293,6 +299,7 @@ class Builder(PortList):
inherit_name=inherit_name, inherit_name=inherit_name,
set_rotation=set_rotation, set_rotation=set_rotation,
append=append, append=append,
ok_connections=ok_connections,
) )
return self return self

View File

@ -1225,6 +1225,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
inherit_name: bool = True, inherit_name: bool = 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:
""" """
Instantiate or append a pattern into the current pattern, connecting Instantiate or append a pattern into the current pattern, connecting
@ -1270,6 +1271,11 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
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
@ -1300,6 +1306,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
map_in, map_in,
mirrored=mirrored, mirrored=mirrored,
set_rotation=set_rotation, set_rotation=set_rotation,
ok_connections=ok_connections,
) )
# get rid of plugged ports # get rid of plugged ports

View File

@ -419,6 +419,7 @@ class PortList(metaclass=ABCMeta):
*, *,
mirrored: bool = False, mirrored: bool = False,
set_rotation: bool | None = None, set_rotation: bool | None = None,
ok_connections: Iterable[tuple[str, str]] = (),
) -> tuple[NDArray[numpy.float64], float, NDArray[numpy.float64]]: ) -> tuple[NDArray[numpy.float64], float, NDArray[numpy.float64]]:
""" """
Given a device `other` and a mapping `map_in` specifying port connections, Given a device `other` and a mapping `map_in` specifying port connections,
@ -435,6 +436,11 @@ class PortList(metaclass=ABCMeta):
port with `rotation=None`), `set_rotation` must be provided port with `rotation=None`), `set_rotation` must be provided
to indicate how much `other` should be rotated. Otherwise, to indicate how much `other` should be rotated. Otherwise,
`set_rotation` must remain `None`. `set_rotation` must remain `None`.
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:
- The (x, y) translation (performed last) - The (x, y) translation (performed last)
@ -451,6 +457,7 @@ class PortList(metaclass=ABCMeta):
map_in=map_in, map_in=map_in,
mirrored=mirrored, mirrored=mirrored,
set_rotation=set_rotation, set_rotation=set_rotation,
ok_connections=ok_connections,
) )
@staticmethod @staticmethod
@ -461,6 +468,7 @@ class PortList(metaclass=ABCMeta):
*, *,
mirrored: bool = False, mirrored: bool = False,
set_rotation: bool | None = None, set_rotation: bool | None = None,
ok_connections: Iterable[tuple[str, str]] = (),
) -> tuple[NDArray[numpy.float64], float, NDArray[numpy.float64]]: ) -> tuple[NDArray[numpy.float64], float, NDArray[numpy.float64]]:
""" """
Given two sets of ports (s_ports and o_ports) and a mapping `map_in` Given two sets of ports (s_ports and o_ports) and a mapping `map_in`
@ -479,6 +487,11 @@ class PortList(metaclass=ABCMeta):
port with `rotation=None`), `set_rotation` must be provided port with `rotation=None`), `set_rotation` must be provided
to indicate how much `o_ports` should be rotated. Otherwise, to indicate how much `o_ports` should be rotated. Otherwise,
`set_rotation` must remain `None`. `set_rotation` must remain `None`.
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:
- The (x, y) translation (performed last) - The (x, y) translation (performed last)
@ -502,7 +515,8 @@ class PortList(metaclass=ABCMeta):
o_offsets[:, 1] *= -1 o_offsets[:, 1] *= -1
o_rotations *= -1 o_rotations *= -1
type_conflicts = numpy.array([st != ot and 'unk' not in (st, ot) ok_pairs = {tuple(sorted(pair)) for pair in ok_connections if pair[0] != pair[1]}
type_conflicts = numpy.array([(st != ot) and ('unk' not in (st, ot)) and (tuple(sorted((st, ot))) not in ok_pairs)
for st, ot in zip(s_types, o_types, strict=True)]) for st, ot in zip(s_types, o_types, strict=True)])
if type_conflicts.any(): if type_conflicts.any():
msg = 'Ports have conflicting types:\n' msg = 'Ports have conflicting types:\n'