@@ -20,14 +20,14 @@ class SingleMapping:
2020
2121
2222class BaseController :
23- #! Attributes passed from the device at runtime.
23+ #: Attributes passed from the device at runtime.
2424 attributes : dict [str , Attribute ]
2525
2626 def __init__ (self , path : list [str ] | None = None ) -> None :
2727 if not hasattr (self , "attributes" ):
2828 self .attributes = {}
2929 self ._path : list [str ] = path or []
30- self .__sub_controller_tree : dict [str , BaseController ] = {}
30+ self .__sub_controller_tree : dict [str , SubController ] = {}
3131
3232 self ._bind_attrs ()
3333
@@ -48,6 +48,9 @@ def _bind_attrs(self) -> None:
4848 class_type_hints = get_type_hints (type (self ))
4949
5050 for attr_name in {** class_dir , ** class_type_hints }:
51+ if attr_name == "root_attribute" :
52+ continue
53+
5154 attr = getattr (self , attr_name , None )
5255 if isinstance (attr , Attribute ):
5356 if (
@@ -60,7 +63,6 @@ def _bind_attrs(self) -> None:
6063 )
6164 new_attribute = copy (attr )
6265 setattr (self , attr_name , new_attribute )
63-
6466 self .attributes [attr_name ] = new_attribute
6567
6668 def register_sub_controller (self , name : str , sub_controller : SubController ):
@@ -72,7 +74,16 @@ def register_sub_controller(self, name: str, sub_controller: SubController):
7274 self .__sub_controller_tree [name ] = sub_controller
7375 sub_controller .set_path (self .path + [name ])
7476
75- def get_sub_controllers (self ) -> dict [str , BaseController ]:
77+ if isinstance (sub_controller .root_attribute , Attribute ):
78+ if name in self .attributes :
79+ raise TypeError (
80+ f"Cannot set SubController `{ name } ` root attribute "
81+ f"on the parent controller `{ type (self ).__name__ } ` "
82+ f"as it already has an attribute of that name."
83+ )
84+ self .attributes [name ] = sub_controller .root_attribute
85+
86+ def get_sub_controllers (self ) -> dict [str , SubController ]:
7687 return self .__sub_controller_tree
7788
7889 def get_controller_mappings (self ) -> list [SingleMapping ]:
@@ -104,6 +115,7 @@ def _get_single_mapping(controller: BaseController) -> SingleMapping:
104115 for name , attribute in controller .attributes .items ()
105116 if attribute .enabled
106117 }
118+
107119 return SingleMapping (
108120 controller , scan_methods , put_methods , command_methods , enabled_attributes
109121 )
@@ -135,5 +147,7 @@ class SubController(BaseController):
135147 it as part of a larger device.
136148 """
137149
150+ root_attribute : Attribute | None = None
151+
138152 def __init__ (self ) -> None :
139153 super ().__init__ ()
0 commit comments