Skip to content

Commit 5479e0f

Browse files
committed
Dispatch on the second argument if generic method is instance-bindable
1 parent d736349 commit 5479e0f

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

Lib/functools.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
# import weakref # Deferred to single_dispatch()
2020
from operator import itemgetter
2121
from reprlib import recursive_repr
22-
from types import GenericAlias, MethodType, MappingProxyType, UnionType
22+
from types import FunctionType, GenericAlias, MethodType, MappingProxyType, UnionType
2323
from _thread import RLock
2424

2525
################################################################################
@@ -1060,6 +1060,12 @@ def __init__(self, unbound, obj, cls):
10601060
# Set instance attributes which cannot be handled in __getattr__()
10611061
# because they conflict with type descriptors.
10621062
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
10631069
try:
10641070
self.__module__ = func.__module__
10651071
except AttributeError:
@@ -1088,7 +1094,12 @@ def __call__(self, /, *args, **kwargs):
10881094
'singledispatchmethod method')
10891095
raise TypeError(f'{funcname} requires at least '
10901096
'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__)
10921103
if hasattr(method, "__get__"):
10931104
method = method.__get__(self._obj, self._cls)
10941105
return method(*args, **kwargs)

0 commit comments

Comments
 (0)