mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	[3.13] gh-127750: Backport some tests for singledispatchmethod (GH-130309) (GH-130340)
(cherry picked from commit395335d0ff) (cherry picked from commit10b32054ad)
This commit is contained in:
		
							parent
							
								
									270ec26c51
								
							
						
					
					
						commit
						68c57d6f33
					
				
					 2 changed files with 132 additions and 0 deletions
				
			
		|  | @ -2758,6 +2758,7 @@ def static_func(arg: int) -> str: | |||
|                 """My function docstring""" | ||||
|                 return str(arg) | ||||
| 
 | ||||
|         prefix = A.__qualname__ + '.' | ||||
|         for meth in ( | ||||
|             A.func, | ||||
|             A().func, | ||||
|  | @ -2767,6 +2768,7 @@ def static_func(arg: int) -> str: | |||
|             A().static_func | ||||
|         ): | ||||
|             with self.subTest(meth=meth): | ||||
|                 self.assertEqual(meth.__qualname__, prefix + meth.__name__) | ||||
|                 self.assertEqual(meth.__doc__, | ||||
|                                  ('My function docstring' | ||||
|                                   if support.HAVE_DOCSTRINGS | ||||
|  | @ -3077,6 +3079,115 @@ def _(arg: typing.List[float] | bytes): | |||
|         self.assertEqual(f(""), "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: | ||||
|     _cost = 1 | ||||
|  |  | |||
|  | @ -408,6 +408,27 @@ def test_isroutine(self): | |||
|         # partial | ||||
|         self.assertFalse(inspect.isroutine(functools.partial(mod.spam))) | ||||
| 
 | ||||
|     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): | ||||
|         self.istest(inspect.isclass, 'mod.StupidGit') | ||||
|         self.assertTrue(inspect.isclass(list)) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Serhiy Storchaka
						Serhiy Storchaka