@@ -888,41 +888,23 @@ def _find_impl(cls, registry):
888888 match = t
889889 return registry .get (match )
890890
891- def _get_dispatch_param (func , * , pos = 0 ):
891+ def _get_positional_param (func , * , pos = 0 ):
892892 if isinstance (func , (MethodType , classmethod , staticmethod )):
893893 func = func .__func__
894- if isinstance (func , FunctionType ):
894+ if isinstance (func , FunctionType ) and not hasattr ( func , "__wrapped__" ) :
895895 func_code = func .__code__
896896 try :
897897 return func_code .co_varnames [:func_code .co_argcount ][pos ]
898898 except IndexError :
899899 pass
900+ # Fallback path for ambiguous callables.
901+ # Follows __wrapped__, checks __signature__, __text_signature__, etc.
900902 import inspect
901903 for insp_param in list (inspect .signature (func ).parameters .values ())[pos :]:
902- if insp_param .KEYWORD_ONLY or insp_param .VAR_KEYWORD :
904+ if insp_param .kind in ( insp_param .KEYWORD_ONLY , insp_param . VAR_KEYWORD ) :
903905 break
904906 return insp_param .name
905- raise TypeError (
906- f"Invalid first argument to `register()`: { func !r} "
907- f"does not accept positional arguments."
908- ) from None
909-
910- def _get_dispatch_annotation (func , param ):
911- import annotationlib , typing
912- annotations = typing .get_type_hints (func , format = annotationlib .Format .FORWARDREF )
913- try :
914- fwdref_or_typeform = annotations [param ]
915- except KeyError :
916- raise TypeError (
917- f"Invalid first argument to `register()`: { param !r} . "
918- f"Add missing annotation to parameter { param !r} of { func !r} "
919- f"or use `@register(some_class)`."
920- ) from None
921- return fwdref_or_typeform
922-
923- def _get_dispatch_arg_from_annotations (func , * , pos = 0 ):
924- param = _get_dispatch_param (func , pos = pos )
925- return param , _get_dispatch_annotation (func , param )
907+ return None
926908
927909def singledispatch (func ):
928910 """Single-dispatch generic function decorator.
@@ -998,9 +980,26 @@ def register(cls, func=None, _func_is_method=False):
998980
999981 # 0 for functions, 1 for methods where first argument should be skipped
1000982 argpos = _func_is_method and not isinstance (func , staticmethod )
1001- argname , cls = _get_dispatch_arg_from_annotations (func , pos = argpos )
1002983
1003- from annotationlib import ForwardRef
984+ argname = _get_positional_param (func , pos = argpos )
985+ if argname is None :
986+ raise TypeError (
987+ f"Invalid first argument to `register()`: { func !r} "
988+ f"does not accept positional arguments."
989+ ) from None
990+
991+ from annotationlib import Format , ForwardRef
992+ import typing
993+ annotations = typing .get_type_hints (func , format = Format .FORWARDREF )
994+
995+ try :
996+ cls = annotations [argname ]
997+ except KeyError :
998+ raise TypeError (
999+ f"Invalid first argument to `register()`: { func !r} . "
1000+ f"Add missing type annotation to parameter { argname !r} "
1001+ "of this function or use `@register(some_class)`."
1002+ ) from None
10041003
10051004 if not _is_valid_dispatch_type (cls ):
10061005 if isinstance (cls , UnionType ):
0 commit comments