@@ -929,6 +929,32 @@ def _is_valid_dispatch_type(cls):
929929 return (_is_union_type (cls ) and
930930 all (isinstance (arg , type ) for arg in get_args (cls )))
931931
932+ def _skip_self_type (argname , cls , hints_iter ):
933+ # GH-130827: Methods are sometimes annotated with
934+ # typing.Self. We should skip that when it's a valid type.
935+ from typing import Self
936+ if cls is not Self :
937+ return argname , cls
938+ if not is_method :
939+ # typing.Self is not valid in a normal function
940+ raise TypeError (
941+ f"Invalid annotation for { argname !r} . "
942+ "typing.Self can only be used with singledispatchmethod()"
943+ )
944+ try :
945+ argname , cls = next (hints_iter )
946+ return argname , cls
947+ except StopIteration :
948+ # The method is one of some invalid edge cases:
949+ # 1. method(self: Self) -> ...
950+ # 2. method(self, weird: Self) -> ...
951+ # 3. method(self: Self, unannotated) -> ...
952+ raise TypeError (
953+ f"Invalid annotation for { argname !r} . "
954+ "typing.Self must be the first annotation and must "
955+ "have a second parameter with an annotation"
956+ ) from None
957+
932958 def register (cls , func = None ):
933959 """generic_func.register(cls, func) -> func
934960
@@ -955,18 +981,11 @@ def register(cls, func=None):
955981 func = cls
956982
957983 # only import typing if annotation parsing is necessary
958- from typing import get_type_hints , Self
984+ from typing import get_type_hints
959985 from annotationlib import Format , ForwardRef
960986 hints_iter = iter (get_type_hints (func , format = Format .FORWARDREF ).items ())
961987 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 )
988+ argname , cls = _skip_self_type (argname , cls , hints_iter )
970989
971990 if not _is_valid_dispatch_type (cls ):
972991 if _is_union_type (cls ):
0 commit comments