@@ -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
@@ -47,6 +47,9 @@ def _bind_attrs(self) -> None:
4747 class_type_hints = get_type_hints (type (self ))
4848
4949 for attr_name in {** class_dir , ** class_type_hints }:
50+ if attr_name == "root_attribute" :
51+ continue
52+
5053 attr = getattr (self , attr_name , None )
5154 if isinstance (attr , Attribute ):
5255 if (
@@ -59,7 +62,6 @@ def _bind_attrs(self) -> None:
5962 )
6063 new_attribute = copy (attr )
6164 setattr (self , attr_name , new_attribute )
62-
6365 self .attributes [attr_name ] = new_attribute
6466
6567 def register_sub_controller (self , name : str , sub_controller : SubController ):
@@ -71,7 +73,16 @@ def register_sub_controller(self, name: str, sub_controller: SubController):
7173 self .__sub_controller_tree [name ] = sub_controller
7274 sub_controller .set_path (self .path + [name ])
7375
74- def get_sub_controllers (self ) -> dict [str , BaseController ]:
76+ if isinstance (sub_controller .root_attribute , Attribute ):
77+ if name in self .attributes :
78+ raise TypeError (
79+ f"Cannot set SubController `{ name } ` root attribute "
80+ f"on the parent controller `{ type (self ).__name__ } ` "
81+ f"as it already has an attribute of that name."
82+ )
83+ self .attributes [name ] = sub_controller .root_attribute
84+
85+ def get_sub_controllers (self ) -> dict [str , SubController ]:
7586 return self .__sub_controller_tree
7687
7788 def get_controller_mappings (self ) -> list [SingleMapping ]:
@@ -103,6 +114,7 @@ def _get_single_mapping(controller: BaseController) -> SingleMapping:
103114 for name , attribute in controller .attributes .items ()
104115 if attribute .enabled
105116 }
117+
106118 return SingleMapping (
107119 controller , scan_methods , put_methods , command_methods , enabled_attributes
108120 )
@@ -134,5 +146,7 @@ class SubController(BaseController):
134146 it as part of a larger device.
135147 """
136148
149+ root_attribute : Attribute | None = None
150+
137151 def __init__ (self ) -> None :
138152 super ().__init__ ()
0 commit comments