diff --git a/masque/__init__.py b/masque/__init__.py index 4ad7e69..9dbf233 100644 --- a/masque/__init__.py +++ b/masque/__init__.py @@ -80,7 +80,6 @@ from .builder import ( SimpleTool as SimpleTool, AutoTool as AutoTool, PathTool as PathTool, - PortPather as PortPather, ) from .utils import ( ports2data as ports2data, diff --git a/masque/builder/__init__.py b/masque/builder/__init__.py index 2fd00a4..eb5047f 100644 --- a/masque/builder/__init__.py +++ b/masque/builder/__init__.py @@ -1,7 +1,6 @@ from .builder import Builder as Builder from .pather import Pather as Pather from .renderpather import RenderPather as RenderPather -from .pather_mixin import PortPather as PortPather from .utils import ell as ell from .tools import ( Tool as Tool, diff --git a/masque/builder/builder.py b/masque/builder/builder.py index ee1d277..4494751 100644 --- a/masque/builder/builder.py +++ b/masque/builder/builder.py @@ -67,7 +67,7 @@ class Builder(PortList): - `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`, - argument is provided, and the `thru` argument is not explicitly + argument is provided, and the `inherit_name` argument is not explicitly set to `False`, the unconnected port of `wire` is automatically renamed to 'myport'. This allows easy extension of existing ports without changing 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, *, mirrored: bool = False, - thru: bool | str = True, + inherit_name: bool = True, set_rotation: bool | None = None, append: bool = False, ok_connections: Iterable[tuple[str, str]] = (), @@ -246,15 +246,11 @@ class Builder(PortList): new names for ports in `other`. mirrored: Enables mirroring `other` across the x axis prior to connecting any ports. - thru: If map_in specifies only a single port, `thru` provides a mechainsm - to avoid repeating the port name. Eg, for `map_in={'myport': 'A'}`, - - If True (default), and `other` has only two ports total, and map_out - doesn't specify a name for the other port, its name is set to the key - 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 + inherit_name: If `True`, and `map_in` specifies only a single port, + and `map_out` is `None`, and `other` has only two ports total, + then automatically renames the output port of `other` to the + name of the port from `self` that appears in `map_in`. This + makes it easy to extend a device with simple 2-port devices (e.g. wires) without providing `map_out` each time `plug` is called. See "Examples" above for more info. Default `True`. set_rotation: If the necessary rotation cannot be determined from @@ -300,7 +296,7 @@ class Builder(PortList): map_in = map_in, map_out = map_out, mirrored = mirrored, - thru = thru, + inherit_name = inherit_name, set_rotation = set_rotation, append = append, ok_connections = ok_connections, diff --git a/masque/builder/pather_mixin.py b/masque/builder/pather_mixin.py index 571f0bb..477c8aa 100644 --- a/masque/builder/pather_mixin.py +++ b/masque/builder/pather_mixin.py @@ -1,4 +1,4 @@ -from typing import Self, TYPE_CHECKING +from typing import Self from collections.abc import Sequence, Iterator import logging from contextlib import contextmanager @@ -11,15 +11,11 @@ from numpy.typing import ArrayLike from ..pattern import Pattern from ..library import ILibrary from ..error import PortError, BuildError -from ..utils import SupportsBool -from ..abstract import Abstract +from ..utils import rotation_matrix_2d, SupportsBool +#from ..abstract import Abstract from .tools import Tool from .utils import ell -if TYPE_CHECKING: - from .pather import Pather - from .renderpather import RenderPather - logger = logging.getLogger(__name__) @@ -439,88 +435,3 @@ class PatherMixin(metaclass=ABCMeta): """ self.pattern.flatten(self.library) return self - - - -class PortPather: - """ - Single-port state manager - - This class provides a convenient way to perform multiple pathing operations on a - port without needing to repeatedly pass its name. - """ - port: str - pather: 'Pather | RenderPather' - - def __init__(self, port: str, pather: 'Pather | RenderPather') -> None: - self.port = port - self.pather = pather - - # - # Delegate to pather - # - def retool(self, tool: Tool) -> Self: - self.pather.retool(tool, keys=[self.port]) - return self - - @contextmanager - def toolctx(self, tool: Tool) -> Iterator[Self]: - with self.pather.toolctx(tool, keys=[self.port]): - yield self - - def path(self, *args, **kwargs) -> Self: - self.pather.path(self.port, *args, **kwargs) - return self - - def pathS(self, *args, **kwargs) -> Self: - self.pather.pathS(self.port, *args, **kwargs) - return self - - def path_to(self, *args, **kwargs) -> Self: - self.pather.path_to(self.port, *args, **kwargs) - return self - - def path_into(self, *args, **kwargs) -> Self: - self.pather.path_into(self.port, *args, **kwargs) - return self - - def path_from(self, *args, **kwargs) -> Self: - self.pather.path_into(args[0], self.port, *args[1:], **kwargs) - return self - - def mpath(self, *args, **kwargs) -> Self: - self.pather.mpath([self.port], *args, **kwargs) - return self - - def plug( - self, - other: Abstract | str, - other_port: str, - *args, - **kwargs, - ) -> Self: - self.pather.plug(other, {self.port: other_port}, *args, **kwargs) - return self - - def plugged(self, other_port: str) -> Self: - self.pather.plugged({self.port: other_port}) - return self - - # - # Delegate to port - # - def set_ptype(self, ptype: str) -> Self: - self.pather[self.port].set_ptype(ptype) - return self - - def mirror(self, *args, **kwargs) -> Self: - self.pather[self.port].mirror(*args, **kwargs) - return self - - def rotate(self, rotation: float) -> Self: - self.pather[self.port].rotate(rotation) - return self - - def set_rotation(self, rotation: float | None) -> Self: - self.pather[self.port].set_rotation(rotation) - return self diff --git a/masque/builder/renderpather.py b/masque/builder/renderpather.py index 682f9ec..eb78cb8 100644 --- a/masque/builder/renderpather.py +++ b/masque/builder/renderpather.py @@ -193,7 +193,7 @@ class RenderPather(PortList, PatherMixin): map_out: dict[str, str | None] | None = None, *, mirrored: bool = False, - thru: bool | str = True, + inherit_name: bool = True, set_rotation: bool | None = None, append: bool = False, ) -> Self: @@ -210,15 +210,11 @@ class RenderPather(PortList, PatherMixin): new names for ports in `other`. mirrored: Enables mirroring `other` across the x axis prior to connecting any ports. - thru: If map_in specifies only a single port, `thru` provides a mechainsm - to avoid repeating the port name. Eg, for `map_in={'myport': 'A'}`, - - If True (default), and `other` has only two ports total, and map_out - doesn't specify a name for the other port, its name is set to the key - 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 + inherit_name: If `True`, and `map_in` specifies only a single port, + and `map_out` is `None`, and `other` has only two ports total, + then automatically renames the output port of `other` to the + name of the port from `self` that appears in `map_in`. This + makes it easy to extend a device with simple 2-port devices (e.g. wires) without providing `map_out` each time `plug` is called. See "Examples" above for more info. Default `True`. set_rotation: If the necessary rotation cannot be determined from @@ -265,13 +261,13 @@ class RenderPather(PortList, PatherMixin): self.paths[new_name].append(RenderStep('P', None, port.copy(), port.copy(), None)) self.pattern.plug( - other = other_tgt, - map_in = map_in, - map_out = map_out, - mirrored = mirrored, - thru = thru, - set_rotation = set_rotation, - append = append, + other=other_tgt, + map_in=map_in, + map_out=map_out, + mirrored=mirrored, + inherit_name=inherit_name, + set_rotation=set_rotation, + append=append, ) return self @@ -337,14 +333,14 @@ class RenderPather(PortList, PatherMixin): self.paths[new_name].append(RenderStep('P', None, port.copy(), port.copy(), None)) self.pattern.place( - other = other_tgt, - offset = offset, - rotation = rotation, - pivot = pivot, - mirrored = mirrored, - port_map = port_map, - skip_port_check = skip_port_check, - append = append, + other=other_tgt, + offset=offset, + rotation=rotation, + pivot=pivot, + mirrored=mirrored, + port_map=port_map, + skip_port_check=skip_port_check, + append=append, ) return self diff --git a/masque/pattern.py b/masque/pattern.py index 4a401b6..fd29d5f 100644 --- a/masque/pattern.py +++ b/masque/pattern.py @@ -1202,7 +1202,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): # map_out: dict[str, str | None] | None, # *, # mirrored: bool, -# thru: bool | str, +# inherit_name: bool, # set_rotation: bool | None, # append: Literal[False], # ) -> Self: @@ -1216,7 +1216,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): # map_out: dict[str, str | None] | None, # *, # mirrored: bool, -# thru: bool | str, +# inherit_name: bool, # set_rotation: bool | None, # append: bool, # ) -> Self: @@ -1229,7 +1229,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): map_out: dict[str, str | None] | None = None, *, mirrored: bool = False, - thru: bool | str = True, + inherit_name: bool = True, set_rotation: bool | None = None, append: bool = False, 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' of `my_pat`. If `wire` has only two ports (e.g. 'A' and 'B'), no `map_out` argument is - provided, and the `thru` argument is not explicitly set to `False`, + provided, and the `inherit_name` argument is not explicitly set to `False`, the unconnected port of `wire` is automatically renamed to 'myport'. This allows easy extension of existing ports without changing their names or having to provide `map_out` each time `plug` is called. @@ -1263,15 +1263,11 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): new names for ports in `other`. mirrored: Enables mirroring `other` across the x axis prior to connecting any ports. - thru: If map_in specifies only a single port, `thru` provides a mechainsm - to avoid repeating the port name. Eg, for `map_in={'myport': 'A'}`, - - If True (default), and `other` has only two ports total, and map_out - doesn't specify a name for the other port, its name is set to the key - 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 + inherit_name: If `True`, and `map_in` specifies only a single port, + and `map_out` is `None`, and `other` has only two ports total, + then automatically renames the output port of `other` to the + name of the port from `self` that appears in `map_in`. This + makes it easy to extend a pattern with simple 2-port devices (e.g. wires) without providing `map_out` each time `plug` is called. See "Examples" above for more info. Default `True`. set_rotation: If the necessary rotation cannot be determined from @@ -1299,25 +1295,18 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): `PortError` if the specified port mapping is not achieveable (the ports 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: 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) translation, rotation, pivot = self.find_transform( other, diff --git a/pyproject.toml b/pyproject.toml index 9a29065..062098d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,6 @@ dxf = ["ezdxf~=1.0.2"] svg = ["svgwrite"] visualize = ["matplotlib"] text = ["matplotlib", "freetype-py"] -manhatanize_slow = ["float_raster"] [tool.ruff]