mirror of
https://github.com/python/cpython.git
synced 2025-08-22 01:35:16 +00:00
[3.12] gh-127750: Backport some tests for singledispatchmethod (GH-130309) (GH-130340) (GH-130341)
(cherry picked from commit68c57d6f33
) (cherry picked from commit395335d0ff
) (cherry picked from commit10b32054ad
) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
96a914ad7e
commit
e63ca56e3b
2 changed files with 132 additions and 0 deletions
|
@ -2642,6 +2642,7 @@ class TestSingleDispatch(unittest.TestCase):
|
||||||
"""My function docstring"""
|
"""My function docstring"""
|
||||||
return str(arg)
|
return str(arg)
|
||||||
|
|
||||||
|
prefix = A.__qualname__ + '.'
|
||||||
for meth in (
|
for meth in (
|
||||||
A.func,
|
A.func,
|
||||||
A().func,
|
A().func,
|
||||||
|
@ -2651,6 +2652,7 @@ class TestSingleDispatch(unittest.TestCase):
|
||||||
A().static_func
|
A().static_func
|
||||||
):
|
):
|
||||||
with self.subTest(meth=meth):
|
with self.subTest(meth=meth):
|
||||||
|
self.assertEqual(meth.__qualname__, prefix + meth.__name__)
|
||||||
self.assertEqual(meth.__doc__,
|
self.assertEqual(meth.__doc__,
|
||||||
('My function docstring'
|
('My function docstring'
|
||||||
if support.HAVE_DOCSTRINGS
|
if support.HAVE_DOCSTRINGS
|
||||||
|
@ -2946,6 +2948,115 @@ class TestSingleDispatch(unittest.TestCase):
|
||||||
self.assertEqual(f(""), "default")
|
self.assertEqual(f(""), "default")
|
||||||
self.assertEqual(f(b""), "default")
|
self.assertEqual(f(b""), "default")
|
||||||
|
|
||||||
|
def test_method_equal_instances(self):
|
||||||
|
# gh-127750: Reference to self was cached
|
||||||
|
class A:
|
||||||
|
def __eq__(self, other):
|
||||||
|
return True
|
||||||
|
def __hash__(self):
|
||||||
|
return 1
|
||||||
|
@functools.singledispatchmethod
|
||||||
|
def t(self, arg):
|
||||||
|
return self
|
||||||
|
|
||||||
|
a = A()
|
||||||
|
b = A()
|
||||||
|
self.assertIs(a.t(1), a)
|
||||||
|
self.assertIs(b.t(2), b)
|
||||||
|
|
||||||
|
def test_method_bad_hash(self):
|
||||||
|
class A:
|
||||||
|
def __eq__(self, other):
|
||||||
|
raise AssertionError
|
||||||
|
def __hash__(self):
|
||||||
|
raise AssertionError
|
||||||
|
@functools.singledispatchmethod
|
||||||
|
def t(self, arg):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Should not raise
|
||||||
|
A().t(1)
|
||||||
|
hash(A().t)
|
||||||
|
A().t == A().t
|
||||||
|
|
||||||
|
def test_method_no_reference_loops(self):
|
||||||
|
# gh-127750: Created a strong reference to self
|
||||||
|
class A:
|
||||||
|
@functools.singledispatchmethod
|
||||||
|
def t(self, arg):
|
||||||
|
return weakref.ref(self)
|
||||||
|
|
||||||
|
a = A()
|
||||||
|
r = a.t(1)
|
||||||
|
self.assertIsNotNone(r())
|
||||||
|
del a # delete a after a.t
|
||||||
|
if not support.check_impl_detail(cpython=True):
|
||||||
|
support.gc_collect()
|
||||||
|
self.assertIsNone(r())
|
||||||
|
|
||||||
|
a = A()
|
||||||
|
t = a.t
|
||||||
|
del a # delete a before a.t
|
||||||
|
support.gc_collect()
|
||||||
|
r = t(1)
|
||||||
|
self.assertIsNotNone(r())
|
||||||
|
del t
|
||||||
|
if not support.check_impl_detail(cpython=True):
|
||||||
|
support.gc_collect()
|
||||||
|
self.assertIsNone(r())
|
||||||
|
|
||||||
|
def test_signatures(self):
|
||||||
|
@functools.singledispatch
|
||||||
|
def func(item, arg: int) -> str:
|
||||||
|
return str(item)
|
||||||
|
@func.register
|
||||||
|
def _(item: int, arg: bytes) -> str:
|
||||||
|
return str(item)
|
||||||
|
|
||||||
|
self.assertEqual(str(Signature.from_callable(func)),
|
||||||
|
'(item, arg: int) -> str')
|
||||||
|
|
||||||
|
def test_method_signatures(self):
|
||||||
|
class A:
|
||||||
|
def m(self, item, arg: int) -> str:
|
||||||
|
return str(item)
|
||||||
|
@classmethod
|
||||||
|
def cm(cls, item, arg: int) -> str:
|
||||||
|
return str(item)
|
||||||
|
@functools.singledispatchmethod
|
||||||
|
def func(self, item, arg: int) -> str:
|
||||||
|
return str(item)
|
||||||
|
@func.register
|
||||||
|
def _(self, item, arg: bytes) -> str:
|
||||||
|
return str(item)
|
||||||
|
|
||||||
|
@functools.singledispatchmethod
|
||||||
|
@classmethod
|
||||||
|
def cls_func(cls, item, arg: int) -> str:
|
||||||
|
return str(arg)
|
||||||
|
@func.register
|
||||||
|
@classmethod
|
||||||
|
def _(cls, item, arg: bytes) -> str:
|
||||||
|
return str(item)
|
||||||
|
|
||||||
|
@functools.singledispatchmethod
|
||||||
|
@staticmethod
|
||||||
|
def static_func(item, arg: int) -> str:
|
||||||
|
return str(arg)
|
||||||
|
@func.register
|
||||||
|
@staticmethod
|
||||||
|
def _(item, arg: bytes) -> str:
|
||||||
|
return str(item)
|
||||||
|
|
||||||
|
self.assertEqual(str(Signature.from_callable(A.func)),
|
||||||
|
'(self, item, arg: int) -> str')
|
||||||
|
self.assertEqual(str(Signature.from_callable(A().func)),
|
||||||
|
'(self, item, arg: int) -> str')
|
||||||
|
self.assertEqual(str(Signature.from_callable(A.cls_func)),
|
||||||
|
'(cls, item, arg: int) -> str')
|
||||||
|
self.assertEqual(str(Signature.from_callable(A.static_func)),
|
||||||
|
'(item, arg: int) -> str')
|
||||||
|
|
||||||
|
|
||||||
class CachedCostItem:
|
class CachedCostItem:
|
||||||
_cost = 1
|
_cost = 1
|
||||||
|
|
|
@ -362,6 +362,27 @@ class TestPredicates(IsTestBase):
|
||||||
self.assertFalse(inspect.isroutine(int))
|
self.assertFalse(inspect.isroutine(int))
|
||||||
self.assertFalse(inspect.isroutine(type('some_class', (), {})))
|
self.assertFalse(inspect.isroutine(type('some_class', (), {})))
|
||||||
|
|
||||||
|
def test_isroutine_singledispatch(self):
|
||||||
|
self.assertTrue(inspect.isroutine(functools.singledispatch(mod.spam)))
|
||||||
|
|
||||||
|
class A:
|
||||||
|
@functools.singledispatchmethod
|
||||||
|
def method(self, arg):
|
||||||
|
pass
|
||||||
|
@functools.singledispatchmethod
|
||||||
|
@classmethod
|
||||||
|
def class_method(cls, arg):
|
||||||
|
pass
|
||||||
|
@functools.singledispatchmethod
|
||||||
|
@staticmethod
|
||||||
|
def static_method(arg):
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertTrue(inspect.isroutine(A.method))
|
||||||
|
self.assertTrue(inspect.isroutine(A().method))
|
||||||
|
self.assertTrue(inspect.isroutine(A.static_method))
|
||||||
|
self.assertTrue(inspect.isroutine(A.class_method))
|
||||||
|
|
||||||
def test_isclass(self):
|
def test_isclass(self):
|
||||||
self.istest(inspect.isclass, 'mod.StupidGit')
|
self.istest(inspect.isclass, 'mod.StupidGit')
|
||||||
self.assertTrue(inspect.isclass(list))
|
self.assertTrue(inspect.isclass(list))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue