diff --git a/masque/builder/renderpather.py b/masque/builder/renderpather.py index 29a8173..4bc3b5f 100644 --- a/masque/builder/renderpather.py +++ b/masque/builder/renderpather.py @@ -430,6 +430,7 @@ class RenderPather(PatherMixin): self.paths[portspec].append(step) self.pattern.ports[portspec] = out_port.copy() + self._log_port_update(portspec) if plug_into is not None: self.plugged({portspec: plug_into}) @@ -506,6 +507,7 @@ class RenderPather(PatherMixin): step = RenderStep('S', tool, port.copy(), out_port.copy(), data) self.paths[portspec].append(step) self.pattern.ports[portspec] = out_port.copy() + self._log_port_update(portspec) if plug_into is not None: self.plugged({portspec: plug_into}) diff --git a/masque/pattern.py b/masque/pattern.py index 94555cc..05a8962 100644 --- a/masque/pattern.py +++ b/masque/pattern.py @@ -638,6 +638,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): """ for entry in chain(chain_elements(self.shapes, self.labels, self.refs), self.ports.values()): cast('Positionable', entry).translate(offset) + self._log_bulk_update(f"translate({offset})") return self def scale_elements(self, c: float) -> Self: @@ -705,6 +706,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): self.rotate_elements(rotation) self.rotate_element_centers(rotation) self.translate_elements(+pivot) + self._log_bulk_update(f"rotate_around({pivot}, {rotation})") return self def rotate_element_centers(self, rotation: float) -> Self: @@ -761,6 +763,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): """ for entry in chain(chain_elements(self.shapes, self.refs, self.labels), self.ports.values()): cast('Flippable', entry).flip_across(axis=axis) + self._log_bulk_update(f"mirror({axis})") return self def copy(self) -> Self: @@ -1160,6 +1163,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): pp.rotate_around(pivot, rotation) pp.translate(offset) self.ports[name] = pp + self._log_port_update(name) if append: if isinstance(other, Abstract): @@ -1315,6 +1319,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): # get rid of plugged ports for ki, vi in map_in.items(): del self.ports[ki] + self._log_port_removal(ki) map_out[vi] = None if isinstance(other, Pattern): diff --git a/masque/ports.py b/masque/ports.py index 45aedb5..5260b19 100644 --- a/masque/ports.py +++ b/masque/ports.py @@ -17,6 +17,7 @@ from .error import PortError, format_stacktrace logger = logging.getLogger(__name__) +port_logger = logging.getLogger('masque.ports') @functools.total_ordering @@ -207,6 +208,19 @@ class PortList(metaclass=ABCMeta): def ports(self, value: dict[str, Port]) -> None: pass + def _log_port_update(self, name: str) -> None: + """ Log the current state of the named port """ + port_logger.info("Port %s: %s", name, self.ports[name]) + + def _log_port_removal(self, name: str) -> None: + """ Log that the named port has been removed """ + port_logger.info("Port %s: removed", name) + + def _log_bulk_update(self, label: str) -> None: + """ Log all current ports at DEBUG level """ + for name, port in self.ports.items(): + port_logger.debug("%s: Port %s: %s", label, name, port) + @overload def __getitem__(self, key: str) -> Port: pass @@ -260,6 +274,7 @@ class PortList(metaclass=ABCMeta): raise PortError(f'Port {name} already exists.') assert name not in self.ports self.ports[name] = value + self._log_port_update(name) return self def rename_ports( @@ -286,11 +301,22 @@ class PortList(metaclass=ABCMeta): if duplicates: raise PortError(f'Unrenamed ports would be overwritten: {duplicates}') + for kk, vv in mapping.items(): + if vv is None: + self._log_port_removal(kk) + elif vv != kk: + self._log_port_removal(kk) + renamed = {vv: self.ports.pop(kk) for kk, vv in mapping.items()} if None in renamed: del renamed[None] self.ports.update(renamed) # type: ignore + + for vv in mapping.values(): + if vv is not None: + self._log_port_update(vv) + return self def add_port_pair( @@ -319,6 +345,8 @@ class PortList(metaclass=ABCMeta): } self.check_ports(names) self.ports.update(new_ports) + self._log_port_update(names[0]) + self._log_port_update(names[1]) return self def plugged( @@ -388,6 +416,7 @@ class PortList(metaclass=ABCMeta): for pp in chain(a_names, b_names): del self.ports[pp] + self._log_port_removal(pp) return self def check_ports(