@@ -885,15 +885,7 @@ def _find_impl(cls, registry):
885885 match = t
886886 return registry .get (match )
887887
888- def singledispatch (func ):
889- """Single-dispatch generic function decorator.
890-
891- Transforms a function into a generic function, which can have different
892- behaviours depending upon the type of its first argument. The decorated
893- function acts as the default implementation, and additional
894- implementations can be registered using the register() attribute of the
895- generic function.
896- """
888+ def _singledispatchimpl (func , is_method ):
897889 # There are many programs that use functools without singledispatch, so we
898890 # trade-off making singledispatch marginally slower for the benefit of
899891 # making start-up of such applications slightly faster.
@@ -963,9 +955,19 @@ def register(cls, func=None):
963955 func = cls
964956
965957 # only import typing if annotation parsing is necessary
966- from typing import get_type_hints
958+ from typing import get_type_hints , Self
967959 from annotationlib import Format , ForwardRef
968- argname , cls = next (iter (get_type_hints (func , format = Format .FORWARDREF ).items ()))
960+ hints_iter = iter (get_type_hints (func , format = Format .FORWARDREF ).items ())
961+ argname , cls = next (hints_iter )
962+ if cls is Self :
963+ if not is_method :
964+ raise TypeError (
965+ f"Invalid annotation for { argname !r} . " ,
966+ "typing.Self can only be used with singledispatchmethod()"
967+ )
968+ else :
969+ argname , cls = next (hints_iter )
970+
969971 if not _is_valid_dispatch_type (cls ):
970972 if _is_union_type (cls ):
971973 raise TypeError (
@@ -1010,6 +1012,16 @@ def wrapper(*args, **kw):
10101012 update_wrapper (wrapper , func )
10111013 return wrapper
10121014
1015+ def singledispatch (func ):
1016+ """Single-dispatch generic function decorator.
1017+
1018+ Transforms a function into a generic function, which can have different
1019+ behaviours depending upon the type of its first argument. The decorated
1020+ function acts as the default implementation, and additional
1021+ implementations can be registered using the register() attribute of the
1022+ generic function.
1023+ """
1024+ return _singledispatchimpl (func , is_method = False )
10131025
10141026# Descriptor version
10151027class singledispatchmethod :
@@ -1023,7 +1035,7 @@ def __init__(self, func):
10231035 if not callable (func ) and not hasattr (func , "__get__" ):
10241036 raise TypeError (f"{ func !r} is not callable or a descriptor" )
10251037
1026- self .dispatcher = singledispatch (func )
1038+ self .dispatcher = _singledispatchimpl (func , is_method = True )
10271039 self .func = func
10281040
10291041 def register (self , cls , method = None ):
0 commit comments