[plug()] rename inherit_name arg to thru and allow passing a string

Breaking change

Affects Pattern, Builder, Pather, RenderPather
This commit is contained in:
jan 2025-11-19 00:06:57 -08:00
parent 8d91fb4915
commit 8a0c985e36
3 changed files with 51 additions and 31 deletions

View File

@ -67,7 +67,7 @@ class Builder(PortList):
- `my_device.plug(wire, {'myport': 'A'})` places port 'A' of `wire` at 'myport' - `my_device.plug(wire, {'myport': 'A'})` places port 'A' of `wire` at 'myport'
of `my_device`. If `wire` has only two ports (e.g. 'A' and 'B'), no `map_out`, of `my_device`. If `wire` has only two ports (e.g. 'A' and 'B'), no `map_out`,
argument is provided, and the `inherit_name` argument is not explicitly argument is provided, and the `thru` argument is not explicitly
set to `False`, the unconnected port of `wire` is automatically renamed to set to `False`, the unconnected port of `wire` is automatically renamed to
'myport'. This allows easy extension of existing ports without changing 'myport'. This allows easy extension of existing ports without changing
their names or having to provide `map_out` each time `plug` is called. their names or having to provide `map_out` each time `plug` is called.
@ -223,7 +223,7 @@ class Builder(PortList):
map_out: dict[str, str | None] | None = None, map_out: dict[str, str | None] | None = None,
*, *,
mirrored: bool = False, mirrored: bool = False,
inherit_name: bool = 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]] = (), ok_connections: Iterable[tuple[str, str]] = (),
@ -246,11 +246,15 @@ class Builder(PortList):
new names for ports in `other`. new names for ports in `other`.
mirrored: Enables mirroring `other` across the x axis prior to mirrored: Enables mirroring `other` across the x axis prior to
connecting any ports. connecting any ports.
inherit_name: If `True`, and `map_in` specifies only a single port, thru: If map_in specifies only a single port, `thru` provides a mechainsm
and `map_out` is `None`, and `other` has only two ports total, to avoid repeating the port name. Eg, for `map_in={'myport': 'A'}`,
then automatically renames the output port of `other` to the - If True (default), and `other` has only two ports total, and map_out
name of the port from `self` that appears in `map_in`. This doesn't specify a name for the other port, its name is set to the key
makes it easy to extend a device with simple 2-port devices in `map_in`, i.e. 'myport'.
- If a string, `map_out[thru]` is set to the key in `map_in` (i.e. 'myport').
An error is raised if that entry already exists.
This makes it easy to extend a pattern with simple 2-port devices
(e.g. wires) without providing `map_out` each time `plug` is (e.g. wires) without providing `map_out` each time `plug` is
called. See "Examples" above for more info. Default `True`. called. See "Examples" above for more info. Default `True`.
set_rotation: If the necessary rotation cannot be determined from set_rotation: If the necessary rotation cannot be determined from
@ -296,7 +300,7 @@ class Builder(PortList):
map_in = map_in, map_in = map_in,
map_out = map_out, map_out = map_out,
mirrored = mirrored, mirrored = mirrored,
inherit_name = inherit_name, thru = thru,
set_rotation = set_rotation, set_rotation = set_rotation,
append = append, append = append,
ok_connections = ok_connections, ok_connections = ok_connections,

View File

@ -193,7 +193,7 @@ class RenderPather(PortList, PatherMixin):
map_out: dict[str, str | None] | None = None, map_out: dict[str, str | None] | None = None,
*, *,
mirrored: bool = False, mirrored: bool = False,
inherit_name: bool = True, thru: bool | str = True,
set_rotation: bool | None = None, set_rotation: bool | None = None,
append: bool = False, append: bool = False,
) -> Self: ) -> Self:
@ -210,11 +210,15 @@ class RenderPather(PortList, PatherMixin):
new names for ports in `other`. new names for ports in `other`.
mirrored: Enables mirroring `other` across the x axis prior to mirrored: Enables mirroring `other` across the x axis prior to
connecting any ports. connecting any ports.
inherit_name: If `True`, and `map_in` specifies only a single port, thru: If map_in specifies only a single port, `thru` provides a mechainsm
and `map_out` is `None`, and `other` has only two ports total, to avoid repeating the port name. Eg, for `map_in={'myport': 'A'}`,
then automatically renames the output port of `other` to the - If True (default), and `other` has only two ports total, and map_out
name of the port from `self` that appears in `map_in`. This doesn't specify a name for the other port, its name is set to the key
makes it easy to extend a device with simple 2-port devices in `map_in`, i.e. 'myport'.
- If a string, `map_out[thru]` is set to the key in `map_in` (i.e. 'myport').
An error is raised if that entry already exists.
This makes it easy to extend a pattern with simple 2-port devices
(e.g. wires) without providing `map_out` each time `plug` is (e.g. wires) without providing `map_out` each time `plug` is
called. See "Examples" above for more info. Default `True`. called. See "Examples" above for more info. Default `True`.
set_rotation: If the necessary rotation cannot be determined from set_rotation: If the necessary rotation cannot be determined from

View File

@ -1202,7 +1202,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
# map_out: dict[str, str | None] | None, # map_out: dict[str, str | None] | None,
# *, # *,
# mirrored: bool, # mirrored: bool,
# inherit_name: bool, # thru: bool | str,
# set_rotation: bool | None, # set_rotation: bool | None,
# append: Literal[False], # append: Literal[False],
# ) -> Self: # ) -> Self:
@ -1216,7 +1216,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
# map_out: dict[str, str | None] | None, # map_out: dict[str, str | None] | None,
# *, # *,
# mirrored: bool, # mirrored: bool,
# inherit_name: bool, # thru: bool | str,
# set_rotation: bool | None, # set_rotation: bool | None,
# append: bool, # append: bool,
# ) -> Self: # ) -> Self:
@ -1229,7 +1229,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
map_out: dict[str, str | None] | None = None, map_out: dict[str, str | None] | None = None,
*, *,
mirrored: bool = False, mirrored: bool = False,
inherit_name: bool = 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]] = (), ok_connections: Iterable[tuple[str, str]] = (),
@ -1250,7 +1250,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
- `my_pat.plug(wire, {'myport': 'A'})` places port 'A' of `wire` at 'myport' - `my_pat.plug(wire, {'myport': 'A'})` places port 'A' of `wire` at 'myport'
of `my_pat`. of `my_pat`.
If `wire` has only two ports (e.g. 'A' and 'B'), no `map_out` argument is If `wire` has only two ports (e.g. 'A' and 'B'), no `map_out` argument is
provided, and the `inherit_name` argument is not explicitly set to `False`, provided, and the `thru` argument is not explicitly set to `False`,
the unconnected port of `wire` is automatically renamed to 'myport'. This the unconnected port of `wire` is automatically renamed to 'myport'. This
allows easy extension of existing ports without changing their names or allows easy extension of existing ports without changing their names or
having to provide `map_out` each time `plug` is called. having to provide `map_out` each time `plug` is called.
@ -1263,11 +1263,15 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
new names for ports in `other`. new names for ports in `other`.
mirrored: Enables mirroring `other` across the x axis prior to connecting mirrored: Enables mirroring `other` across the x axis prior to connecting
any ports. any ports.
inherit_name: If `True`, and `map_in` specifies only a single port, thru: If map_in specifies only a single port, `thru` provides a mechainsm
and `map_out` is `None`, and `other` has only two ports total, to avoid repeating the port name. Eg, for `map_in={'myport': 'A'}`,
then automatically renames the output port of `other` to the - If True (default), and `other` has only two ports total, and map_out
name of the port from `self` that appears in `map_in`. This doesn't specify a name for the other port, its name is set to the key
makes it easy to extend a pattern with simple 2-port devices in `map_in`, i.e. 'myport'.
- If a string, `map_out[thru]` is set to the key in `map_in` (i.e. 'myport').
An error is raised if that entry already exists.
This makes it easy to extend a pattern with simple 2-port devices
(e.g. wires) without providing `map_out` each time `plug` is (e.g. wires) without providing `map_out` each time `plug` is
called. See "Examples" above for more info. Default `True`. called. See "Examples" above for more info. Default `True`.
set_rotation: If the necessary rotation cannot be determined from set_rotation: If the necessary rotation cannot be determined from
@ -1295,18 +1299,26 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable):
`PortError` if the specified port mapping is not achieveable (the ports `PortError` if the specified port mapping is not achieveable (the ports
do not line up) do not line up)
""" """
# If asked to inherit a name, check that all conditions are met
if (inherit_name
and not map_out
and len(map_in) == 1
and len(other.ports) == 2):
out_port_name = next(iter(set(other.ports.keys()) - set(map_in.values())))
map_out = {out_port_name: next(iter(map_in.keys()))}
if map_out is None: if map_out is None:
map_out = {} map_out = {}
map_out = copy.deepcopy(map_out) map_out = copy.deepcopy(map_out)
# If asked to inherit a name, check that all conditions are met
if isinstance(thru, str):
if not len(map_in == 1):
raise PatternError(f'Got {thru=} but have multiple map_in entries; don\'t know which one to use')
if thru in map_out:
raise PatternError(f'Got {thru=} but tha port already exists in map_out')
map_out[thru] = next(iter(map_in.keys()))
elif (bool(thru)
and len(map_in) == 1
and not map_out
and len(other.ports) == 2
):
out_port_name = next(iter(set(other.ports.keys()) - set(map_in.values())))
map_out = {out_port_name: next(iter(map_in.keys()))}
self.check_ports(other.ports.keys(), map_in, map_out) self.check_ports(other.ports.keys(), map_in, map_out)
translation, rotation, pivot = self.find_transform( translation, rotation, pivot = self.find_transform(
other, other,