Skip to content

Commit c497857

Browse files
committed
Specialcase bound methods in singledispatchmethods
Removed _dispatchmethod=False from register property, because it was an incorrect assumption.
1 parent 62088c7 commit c497857

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

Lib/functools.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -888,21 +888,24 @@ def _find_impl(cls, registry):
888888
match = t
889889
return registry.get(match)
890890

891-
def _get_dispatch_param(func, *, _insideclass=False):
891+
def _get_dispatch_param(func, *, _dispatchmethod=False):
892892
"""Finds the first positional and user-specified parameter in a callable
893893
or descriptor.
894894
895895
Used by singledispatch for registration by type annotation of the parameter.
896896
"""
897897
# Fast path for typical callables and descriptors.
898898
# idx is 0 when singledispatch() and 1 when singledispatchmethod().
899-
idx = _insideclass
900899
if isinstance(func, staticmethod):
901900
idx = 0
902901
func = func.__func__
903902
elif isinstance(func, classmethod):
904903
func = func.__func__
905904
idx = 1
905+
elif _dispatchmethod and isinstance(func, MethodType):
906+
idx = 0
907+
else:
908+
idx = _dispatchmethod
906909
if isinstance(func, FunctionType) and not hasattr(func, "__wrapped__"):
907910
# Method from inspect._signature_from_function.
908911
func_code = func.__code__
@@ -967,7 +970,7 @@ def _is_valid_dispatch_type(cls):
967970
return (isinstance(cls, UnionType) and
968971
all(isinstance(arg, type) for arg in cls.__args__))
969972

970-
def register(cls, func=None, _insideclass=False):
973+
def register(cls, func=None, _dispatchmethod=False):
971974
"""generic_func.register(cls, func) -> func
972975
973976
Registers a new implementation for the given *cls* on a *generic_func*.
@@ -992,7 +995,7 @@ def register(cls, func=None, _insideclass=False):
992995
)
993996
func = cls
994997

995-
argname = _get_dispatch_param(func, _insideclass=_insideclass)
998+
argname = _get_dispatch_param(func, _dispatchmethod=_dispatchmethod)
996999
if argname is None:
9971000
raise TypeError(
9981001
f"Invalid first argument to `register()`: {func!r} "
@@ -1071,12 +1074,12 @@ def __init__(self, func):
10711074
self.dispatcher = singledispatch(func)
10721075
self.func = func
10731076

1074-
def register(self, cls, method=None, _insideclass=True):
1077+
def register(self, cls, method=None, _dispatchmethod=True):
10751078
"""generic_method.register(cls, func) -> func
10761079
10771080
Registers a new implementation for the given *cls* on a *generic_method*.
10781081
"""
1079-
return self.dispatcher.register(cls, func=method, _insideclass=_insideclass)
1082+
return self.dispatcher.register(cls, func=method, _dispatchmethod=_dispatchmethod)
10801083

10811084
def __get__(self, obj, cls=None):
10821085
return _singledispatchmethod_get(self, obj, cls)
@@ -1151,8 +1154,7 @@ def __wrapped__(self):
11511154

11521155
@property
11531156
def register(self):
1154-
# This is called from outside of the class with singledispatchmethod.
1155-
return partial(self._unbound.register, _insideclass=False)
1157+
return self._unbound.register
11561158

11571159

11581160
################################################################################

0 commit comments

Comments
 (0)