@@ -688,7 +688,7 @@ async def set_and_wait_for_value(
688688 )
689689
690690
691- def walk_rw_signals (device : Device , path_prefix : str = "" ) -> dict [str , SignalRW [Any ]]:
691+ def walk_rw_signals (device : Device ) -> dict [str , SignalRW [Any ]]:
692692 """Retrieve all SignalRWs from a device.
693693
694694 Stores retrieved signals with their dotted attribute paths in a dictionary. Used as
@@ -700,48 +700,67 @@ def walk_rw_signals(device: Device, path_prefix: str = "") -> dict[str, SignalRW
700700 A dictionary matching the string attribute path of a SignalRW with the
701701 signal itself.
702702 """
703- signals : dict [str , SignalRW [Any ]] = {}
704-
705- for attr_name , attr in device .children ():
706- dot_path = f"{ path_prefix } { attr_name } "
707- if type (attr ) is SignalRW :
708- signals [dot_path ] = attr
709- attr_signals = walk_rw_signals (attr , path_prefix = dot_path + "." )
710- signals .update (attr_signals )
711- return signals
703+ all_devices = walk_devices (device )
704+ return {path : dev for path , dev in all_devices .items () if type (dev ) is SignalRW }
712705
713706
714707async def walk_config_signals (
715- device : Device , path_prefix : str = ""
708+ device : Device ,
716709) -> dict [str , SignalRW [Any ]]:
717710 """Retrieve all configuration signals from a device.
718711
719712 Stores retrieved signals with their dotted attribute paths in a dictionary. Used as
720713 part of saving and loading a device.
721714
722715 :param device: Device to retrieve configuration signals from.
723- :param path_prefix: For internal use, leave blank when calling the method.
724716 :return:
725717 A dictionary matching the string attribute path of a SignalRW with the
726718 signal itself.
727719 """
728- signals : dict [str , SignalRW [Any ]] = {}
729720 config_names : list [str ] = []
730721 if isinstance (device , Configurable ):
731722 configuration = device .read_configuration ()
732723 if inspect .isawaitable (configuration ):
733724 configuration = await configuration
734725 config_names = list (configuration .keys ())
735- for attr_name , attr in device .children ():
736- dot_path = f"{ path_prefix } { attr_name } "
737- if isinstance (attr , SignalRW ) and attr .name in config_names :
738- signals [dot_path ] = attr
739- signals .update (await walk_config_signals (attr , path_prefix = dot_path + "." ))
740726
741- return signals
727+ all_devices = walk_devices (device )
728+ return {
729+ path : dev
730+ for path , dev in all_devices .items ()
731+ if isinstance (dev , SignalRW ) and dev .name in config_names
732+ }
742733
743734
744735class Ignore :
745736 """Annotation to ignore a signal when connecting a device."""
746737
747738 pass
739+
740+
741+ def walk_devices (device : Device , path_prefix : str = "" ) -> dict [str , Device ]:
742+ """Recursively retrieve all Devices from a device tree.
743+
744+ :param device: Root device to start from.
745+ :param path_prefix: For internal use, leave blank when calling the method.
746+ :return: A dictionary mapping dotted attribute paths to Device instances.
747+ """
748+ devices : dict [str , Device ] = {}
749+ for attr_name , attr in device .children ():
750+ dot_path = f"{ path_prefix } { attr_name } "
751+ devices [dot_path ] = attr
752+ devices .update (walk_devices (attr , path_prefix = dot_path + "." ))
753+ return devices
754+
755+
756+ def walk_signal_sources (device : Device ) -> dict [str , str ]:
757+ """Recursively gather the `source` field from every Signal in a device tree.
758+
759+ :param device: Root device to start from.
760+ :param path_prefix: For internal use, leave blank when calling the method.
761+ :return: A dictionary mapping dotted attribute paths to Signal source strings.
762+ """
763+ all_devices = walk_devices (device )
764+ return {
765+ path : dev .source for path , dev in all_devices .items () if isinstance (dev , Signal )
766+ }
0 commit comments