diff --git a/canopen/pdo/__init__.py b/canopen/pdo/__init__.py index b749dfee..a48831ea 100644 --- a/canopen/pdo/__init__.py +++ b/canopen/pdo/__init__.py @@ -19,6 +19,35 @@ logger = logging.getLogger(__name__) +class _CombinedPdoMaps(Mapping[int, PdoMap]): + """Combine RPDO and TPDO :class:`PdoMaps` without dummy zero offsets. + + Avoids ``PdoMaps(0, 0, …)`` where ``__getitem__`` fallbacks would alias + ``key`` to ``key + 1`` (see discussion on PR #613). + """ + + def __init__(self, rx: PdoMaps, tx: PdoMaps): + self.rx = rx + self.tx = tx + + def __getitem__(self, key: int) -> PdoMap: + for maps in (self.rx, self.tx): + try: + return maps[key] + except KeyError: + continue + raise KeyError(key) + + def __iter__(self) -> Iterator[int]: + return itertools.chain( + (self.rx.map_offset + i - 1 for i in self.rx), + (self.tx.map_offset + i - 1 for i in self.tx), + ) + + def __len__(self) -> int: + return len(self.rx) + len(self.tx) + + class PDO(PdoBase): """PDO Class for backwards compatibility.