From 836a7ea2dac4d41f67bdce503c0e2e22ed69a28c Mon Sep 17 00:00:00 2001 From: PONS Date: Thu, 11 Jun 2026 13:24:36 +0200 Subject: [PATCH 1/2] Removed unused line --- tests/dummy_cs/tango-pyaml/tango/pyaml/controlsystem.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/dummy_cs/tango-pyaml/tango/pyaml/controlsystem.py b/tests/dummy_cs/tango-pyaml/tango/pyaml/controlsystem.py index d39c57724..292305690 100644 --- a/tests/dummy_cs/tango-pyaml/tango/pyaml/controlsystem.py +++ b/tests/dummy_cs/tango-pyaml/tango/pyaml/controlsystem.py @@ -85,8 +85,5 @@ def name(self) -> str: def get_aggregator(self) -> str | None: return MultiAttribute() - def vector_aggregator(self) -> str | None: - return self._cfg.vector_aggregator - def __repr__(self): return repr(self._cfg).replace("ConfigModel", self.__class__.__name__) From 24c632f3e695180f435cea18d609becf8bff3081 Mon Sep 17 00:00:00 2001 From: PONS Date: Thu, 11 Jun 2026 15:20:44 +0200 Subject: [PATCH 2/2] Removed list behavior of DeviceAccessList --- pyaml/control/abstract_impl.py | 16 +++++------ pyaml/control/deviceaccesslist.py | 19 ++++++++----- .../tango/pyaml/multi_attribute.py | 28 +++++++++---------- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/pyaml/control/abstract_impl.py b/pyaml/control/abstract_impl.py index 30afc024d..4dd26228c 100644 --- a/pyaml/control/abstract_impl.py +++ b/pyaml/control/abstract_impl.py @@ -95,21 +95,21 @@ def _iter_devices_and_ranges(devs: DeviceAccess | DeviceAccessList): - DeviceAccessList: yields N items based on get_devices() and get_range() flattening """ # Single device - if hasattr(devs, "get") and hasattr(devs, "get_range") and not hasattr(devs, "get_devices"): + if isinstance(devs, DeviceAccess): r = devs.get_range() if r is None: r = [None, None] return [(devs, [r[0], r[1]])] - # Device list (expects get_devices() + get_range() flat list) - devices = devs.get_devices() - flat = np.asarray(devs.get_range(), dtype=object).ravel() - if (flat.size % 2) != 0: + # get_range() return a flat list + flat = devs.get_range() + if (len(flat) % 2) != 0: raise ValueError(f"dev_range must have an even length, got {flat.size}") + # Reshape pairs = [] - for i, d in enumerate(devices): - pairs.append((d, [flat[2 * i], flat[2 * i + 1]])) + for i in range(devs.len()): + pairs.append((devs.get_device_at(i), [flat[2 * i], flat[2 * i + 1]])) return pairs @@ -196,7 +196,7 @@ def unit(self) -> str: return self._devs.unit() def nb_device(self) -> int: - return self._devs.__len__() + return self._devs.len() # ------------------------------------------------------------------------------ diff --git a/pyaml/control/deviceaccesslist.py b/pyaml/control/deviceaccesslist.py index e913389ec..d1dc7cfc3 100644 --- a/pyaml/control/deviceaccesslist.py +++ b/pyaml/control/deviceaccesslist.py @@ -4,22 +4,27 @@ import numpy.typing as npt from .deviceaccess import DeviceAccess -from .readback_value import Value -class DeviceAccessList(list[DeviceAccess], metaclass=ABCMeta): +class DeviceAccessList(metaclass=ABCMeta): """ - Abstract class providing access to a list of control system float variable + Abstract class providing access to a list of control system variales. + Internal structure depends on the backend and might not be trivially iterable. """ @abstractmethod def add_devices(self, devices: DeviceAccess | list[DeviceAccess]): - """Add a DeviceAccess to this list""" + """Add a DeviceAccess (or a list) to this list""" pass @abstractmethod - def get_devices(self) -> DeviceAccess | list[DeviceAccess]: - """Get the DeviceAccess list""" + def get_device_at(self, index: int) -> DeviceAccess: + """Returns the device at the given index""" + pass + + @abstractmethod + def len(self) -> int: + """Get the DeviceAccessList length""" pass @abstractmethod @@ -56,7 +61,7 @@ def get_range(self) -> list[float]: Returns ------- list[float] - List containing [min, max] values + List containing [min0, max0, min1, max1, ...] values """ pass diff --git a/tests/dummy_cs/tango-pyaml/tango/pyaml/multi_attribute.py b/tests/dummy_cs/tango-pyaml/tango/pyaml/multi_attribute.py index 611850a33..9235fd4a1 100644 --- a/tests/dummy_cs/tango-pyaml/tango/pyaml/multi_attribute.py +++ b/tests/dummy_cs/tango-pyaml/tango/pyaml/multi_attribute.py @@ -12,7 +12,7 @@ class MultiAttribute(DeviceAccessList): def __init__(self): - super().__init__() + self._items = [] def add_devices(self, devices: DeviceAccess | list[DeviceAccess]): if isinstance(devices, list): @@ -23,7 +23,7 @@ def add_devices(self, devices: DeviceAccess | list[DeviceAccess]): (tango.pyaml.attribute) but got ({device.__class__.__name__})""" ) - super().extend(devices) + self._items.extend(devices) else: if not isinstance(devices, Attribute): raise pyaml.PyAMLException( @@ -31,46 +31,46 @@ def add_devices(self, devices: DeviceAccess | list[DeviceAccess]): (tango.pyaml.attribute) but got ({devices.__class__.__name__})""" ) - super().append(devices) + self._items.append(devices) - def get_devices(self) -> DeviceAccess | list[DeviceAccess]: - if len(self) == 1: - return self[0] - else: - return self + def len(self) -> int: + return len(self._items) + + def get_device_at(self, index: int) -> DeviceAccess: + return self._items[index] def set(self, value: npt.NDArray[np.float64]): print(f"MultiAttribute.set({len(value)} values)") global LAST_NB_WRITTEN LAST_NB_WRITTEN += len(value) - for idx, a in enumerate(self): + for idx, a in enumerate(self._items): a.set(value[idx]) def set_and_wait(self, value: npt.NDArray[np.float64]): pass def get(self) -> npt.NDArray[np.float64]: - print(f"MultiAttribute.get({len(self)} values)") - return np.array([a.get() for a in self]) + print(f"MultiAttribute.get({len(self._items)} values)") + return np.array([a.get() for a in self._items]) def readback(self) -> np.array: return np.array([]) def unit(self) -> list[str]: - return [a.unit() for a in self] + return [a.unit() for a in self._items] def get_last_nb_written(self) -> int: return self.__last_nb_written def get_range(self) -> list[float]: attr_range: list[float] = [] - for device in self: + for device in self._items: attr_range.extend(device.get_range()) return attr_range def check_device_availability(self) -> bool: available = False - for device in self: + for device in self._items: available = device.check_device_availability() if not available: break