gh-140873: Add support of non-descriptor callables in functools.singledispatchmethod() (GH-140884)

This commit is contained in:
Serhiy Storchaka 2025-11-13 19:48:52 +02:00 committed by GitHub
parent b99db92dde
commit b2b68d40f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 52 additions and 3 deletions

View file

@ -2785,7 +2785,7 @@ class Slot:
@functools.singledispatchmethod
@classmethod
def go(cls, item, arg):
pass
return item - arg
@go.register
@classmethod
@ -2794,7 +2794,9 @@ def _(cls, item: int, arg):
s = Slot()
self.assertEqual(s.go(1, 1), 2)
self.assertEqual(s.go(1.5, 1), 0.5)
self.assertEqual(Slot.go(1, 1), 2)
self.assertEqual(Slot.go(1.5, 1), 0.5)
def test_staticmethod_slotted_class(self):
class A:
@ -3485,6 +3487,37 @@ def _(item, arg: bytes) -> str:
self.assertEqual(str(Signature.from_callable(A.static_func)),
'(item, arg: int) -> str')
def test_method_non_descriptor(self):
class Callable:
def __init__(self, value):
self.value = value
def __call__(self, arg):
return self.value, arg
class A:
t = functools.singledispatchmethod(Callable('general'))
t.register(int, Callable('special'))
@functools.singledispatchmethod
def u(self, arg):
return 'general', arg
u.register(int, Callable('special'))
v = functools.singledispatchmethod(Callable('general'))
@v.register(int)
def _(self, arg):
return 'special', arg
a = A()
self.assertEqual(a.t(0), ('special', 0))
self.assertEqual(a.t(2.5), ('general', 2.5))
self.assertEqual(A.t(0), ('special', 0))
self.assertEqual(A.t(2.5), ('general', 2.5))
self.assertEqual(a.u(0), ('special', 0))
self.assertEqual(a.u(2.5), ('general', 2.5))
self.assertEqual(a.v(0), ('special', 0))
self.assertEqual(a.v(2.5), ('general', 2.5))
class CachedCostItem:
_cost = 1