33from collections .abc import Iterator
44from copy import copy
55from dataclasses import dataclass
6+ from typing import get_type_hints
67
78from .attributes import Attribute
89from .cs_methods import Command , Put , Scan
@@ -19,7 +20,12 @@ class SingleMapping:
1920
2021
2122class BaseController :
23+ #! Attributes passed from the device at runtime.
24+ attributes : dict [str , Attribute ]
25+
2226 def __init__ (self , path : list [str ] | None = None ) -> None :
27+ if not hasattr (self , "attributes" ):
28+ self .attributes = {}
2329 self ._path : list [str ] = path or []
2430 self .__sub_controller_tree : dict [str , BaseController ] = {}
2531
@@ -37,12 +43,25 @@ def set_path(self, path: list[str]):
3743 self ._path = path
3844
3945 def _bind_attrs (self ) -> None :
40- for attr_name in dir (self ):
41- attr = getattr (self , attr_name )
46+ class_dir = {key : None for key in dir (type (self ))}
47+ class_type_hints = get_type_hints (type (self ))
48+
49+ for attr_name in {** class_dir , ** class_type_hints }:
50+ attr = getattr (self , attr_name , None )
4251 if isinstance (attr , Attribute ):
52+ if (
53+ attr_name in self .attributes
54+ and self .attributes [attr_name ] is not attr
55+ ):
56+ raise ValueError (
57+ f"`{ type (self ).__name__ } ` has conflicting attribute "
58+ f"`{ attr_name } ` already present in the attributes dict."
59+ )
4360 new_attribute = copy (attr )
4461 setattr (self , attr_name , new_attribute )
4562
63+ self .attributes [attr_name ] = new_attribute
64+
4665 def register_sub_controller (self , name : str , sub_controller : SubController ):
4766 if name in self .__sub_controller_tree .keys ():
4867 raise ValueError (
@@ -69,7 +88,6 @@ def _get_single_mapping(controller: BaseController) -> SingleMapping:
6988 scan_methods : dict [str , Scan ] = {}
7089 put_methods : dict [str , Put ] = {}
7190 command_methods : dict [str , Command ] = {}
72- attributes : dict [str , Attribute ] = {}
7391 for attr_name in dir (controller ):
7492 attr = getattr (controller , attr_name )
7593 match attr :
@@ -79,11 +97,14 @@ def _get_single_mapping(controller: BaseController) -> SingleMapping:
7997 scan_methods [attr_name ] = scan_method
8098 case WrappedMethod (fastcs_method = Command (enabled = True ) as command_method ):
8199 command_methods [attr_name ] = command_method
82- case Attribute (enabled = True ):
83- attributes [attr_name ] = attr
84100
101+ enabled_attributes = {
102+ name : attribute
103+ for name , attribute in controller .attributes .items ()
104+ if attribute .enabled
105+ }
85106 return SingleMapping (
86- controller , scan_methods , put_methods , command_methods , attributes
107+ controller , scan_methods , put_methods , command_methods , enabled_attributes
87108 )
88109
89110
0 commit comments