|
19 | 19 | # import weakref # Deferred to single_dispatch() |
20 | 20 | from operator import itemgetter |
21 | 21 | from reprlib import recursive_repr |
22 | | -from types import GenericAlias, MethodType, MappingProxyType, UnionType |
| 22 | +from types import FunctionType, GenericAlias, MethodType, MappingProxyType, UnionType |
23 | 23 | from _thread import RLock |
24 | 24 |
|
25 | 25 | ################################################################################ |
@@ -1060,6 +1060,12 @@ def __init__(self, unbound, obj, cls): |
1060 | 1060 | # Set instance attributes which cannot be handled in __getattr__() |
1061 | 1061 | # because they conflict with type descriptors. |
1062 | 1062 | func = unbound.func |
| 1063 | + # Dispatch on the second argument if a generic method turns into |
| 1064 | + # a bound method on instance-level access. |
| 1065 | + if obj is None and isinstance(func, FunctionType): |
| 1066 | + self._skip_bound_arg = True |
| 1067 | + else: |
| 1068 | + self._skip_bound_arg = False |
1063 | 1069 | try: |
1064 | 1070 | self.__module__ = func.__module__ |
1065 | 1071 | except AttributeError: |
@@ -1088,7 +1094,12 @@ def __call__(self, /, *args, **kwargs): |
1088 | 1094 | 'singledispatchmethod method') |
1089 | 1095 | raise TypeError(f'{funcname} requires at least ' |
1090 | 1096 | '1 positional argument') |
1091 | | - method = self._dispatch(args[0].__class__) |
| 1097 | + if self._skip_bound_arg: |
| 1098 | + method = self._dispatch(args[1].__class__) |
| 1099 | + if not isinstance(method, FunctionType): |
| 1100 | + args = args[1:] |
| 1101 | + else: |
| 1102 | + method = self._dispatch(args[0].__class__) |
1092 | 1103 | if hasattr(method, "__get__"): |
1093 | 1104 | method = method.__get__(self._obj, self._cls) |
1094 | 1105 | return method(*args, **kwargs) |
|
0 commit comments