88from typing import TYPE_CHECKING , Any , Protocol , Self , overload , runtime_checkable
99
1010import injection
11- from type_analyzer import MatchingTypesConfig , matching_types
11+ from type_analyzer import MatchingTypesConfig , iter_matching_types , matching_types
1212
1313type HandlerType [** P , T ] = type [Handler [P , T ]]
1414type HandlerFactory [** P , T ] = Callable [..., Awaitable [Handler [P , T ]]]
@@ -50,12 +50,14 @@ def handlers_from(
5050 self ,
5151 input_type : type [I ],
5252 ) -> Iterator [Callable [[I ], Awaitable [O ]]]:
53- for it in _standardize_input_type (input_type ):
54- for factory in self .__factories .get (it , ()):
53+ for key_type in _iter_key_types (input_type ):
54+ for factory in self .__factories .get (key_type , ()):
5555 yield _make_handle_function (factory )
5656
5757 def subscribe (self , input_type : type [I ], factory : HandlerFactory [[I ], O ]) -> Self :
58- self .__factories [input_type ].append (factory )
58+ for key_type in _build_key_types (input_type ):
59+ self .__factories [key_type ].append (factory )
60+
5961 return self
6062
6163
@@ -70,18 +72,20 @@ def handlers_from(
7072 self ,
7173 input_type : type [I ],
7274 ) -> Iterator [Callable [[I ], Awaitable [O ]]]:
73- for it in _standardize_input_type (input_type ):
74- factory = self .__factories .get (it , None )
75+ for key_type in _iter_key_types (input_type ):
76+ factory = self .__factories .get (key_type , None )
7577 if factory is not None :
7678 yield _make_handle_function (factory )
7779
7880 def subscribe (self , input_type : type [I ], factory : HandlerFactory [[I ], O ]) -> Self :
79- if input_type in self .__factories :
80- raise RuntimeError (
81- f"A handler is already registered for the input type: `{ input_type } `."
82- )
81+ for key_type in _build_key_types (input_type ):
82+ if key_type in self .__factories :
83+ raise RuntimeError (
84+ f"A handler is already registered for the input type: `{ key_type } `."
85+ )
86+
87+ self .__factories [key_type ] = factory
8388
84- self .__factories [input_type ] = factory
8589 return self
8690
8791
@@ -153,6 +157,20 @@ def __decorator(
153157 return wrapped
154158
155159
160+ def _build_key_types (input_type : Any ) -> tuple [Any , ...]:
161+ config = MatchingTypesConfig (ignore_none = True )
162+ return matching_types (input_type , config )
163+
164+
165+ def _iter_key_types (input_type : Any ) -> Iterator [Any ]:
166+ config = MatchingTypesConfig (
167+ with_bases = True ,
168+ with_origin = True ,
169+ with_type_alias_value = True ,
170+ )
171+ return iter_matching_types (input_type , config )
172+
173+
156174def _resolve_input_type [I , O ](handler_type : HandlerType [[I ], O ]) -> type [I ]:
157175 fake_method = handler_type .handle .__get__ (NotImplemented , handler_type )
158176 signature = inspect_signature (fake_method , eval_str = True )
@@ -171,15 +189,6 @@ def _resolve_input_type[I, O](handler_type: HandlerType[[I], O]) -> type[I]:
171189 )
172190
173191
174- def _standardize_input_type (input_type : Any ) -> tuple [Any , ...]:
175- config = MatchingTypesConfig (
176- with_bases = True ,
177- with_origin = True ,
178- with_type_alias_value = True ,
179- )
180- return matching_types (input_type , config )
181-
182-
183192def _make_handle_function [I , O ](
184193 factory : HandlerFactory [[I ], O ],
185194) -> Callable [[I ], Awaitable [O ]]:
0 commit comments