bpo-39679: Add tests for classmethod/staticmethod singledispatchmethods (GH-29034) (GH-29072)

In Python 3.8 and 3.9, stacking `@functools.singledispatchmethod` on top of
`@classmethod` or `@staticmethod` caused an exception to be raised if the
method was registered using type-annotations rather than
`@method.register(int)`. This was not caught by unit tests, however, as the
tests only tested the `@method.register(int)` way of registering additional
implementations. The bug is no longer present in Python 3.10+, but
`test_functools.py` is still lacking regression tests for these cases. This
commit adds these test cases.
(cherry picked from commit ad6d162e51)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
Miss Islington (bot) 2021-10-19 15:07:13 -07:00 committed by GitHub
parent 5c9cab595e
commit c15ba304f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 0 deletions

View file

@ -2437,6 +2437,48 @@ class TestSingleDispatch(unittest.TestCase):
self.assertEqual(a.t(''), "str")
self.assertEqual(a.t(0.0), "base")
def test_staticmethod_type_ann_register(self):
class A:
@functools.singledispatchmethod
@staticmethod
def t(arg):
return arg
@t.register
@staticmethod
def _(arg: int):
return isinstance(arg, int)
@t.register
@staticmethod
def _(arg: str):
return isinstance(arg, str)
a = A()
self.assertTrue(A.t(0))
self.assertTrue(A.t(''))
self.assertEqual(A.t(0.0), 0.0)
def test_classmethod_type_ann_register(self):
class A:
def __init__(self, arg):
self.arg = arg
@functools.singledispatchmethod
@classmethod
def t(cls, arg):
return cls("base")
@t.register
@classmethod
def _(cls, arg: int):
return cls("int")
@t.register
@classmethod
def _(cls, arg: str):
return cls("str")
self.assertEqual(A.t(0).arg, "int")
self.assertEqual(A.t('').arg, "str")
self.assertEqual(A.t(0.0).arg, "base")
def test_invalid_registrations(self):
msg_prefix = "Invalid first argument to `register()`: "
msg_suffix = (

View file

@ -0,0 +1,2 @@
Add more test cases for `@functools.singledispatchmethod` when combined with
`@classmethod` or `@staticmethod`.