mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	gh-93021: Fix __text_signature__ for __get__ (GH-93023)
Because of the way wrap_descr_get is written, the second argument to __get__ methods implemented through the wrapper is always optional.
This commit is contained in:
		
							parent
							
								
									dd5cf84f24
								
							
						
					
					
						commit
						4e08fbcfdf
					
				
					 3 changed files with 10 additions and 2 deletions
				
			
		|  | @ -597,6 +597,12 @@ def test_slot_wrapper_types(self): | ||||||
|         self.assertIsInstance(object.__lt__, types.WrapperDescriptorType) |         self.assertIsInstance(object.__lt__, types.WrapperDescriptorType) | ||||||
|         self.assertIsInstance(int.__lt__, types.WrapperDescriptorType) |         self.assertIsInstance(int.__lt__, types.WrapperDescriptorType) | ||||||
| 
 | 
 | ||||||
|  |     def test_dunder_get_signature(self): | ||||||
|  |         sig = inspect.signature(object.__init__.__get__) | ||||||
|  |         self.assertEqual(list(sig.parameters), ["instance", "owner"]) | ||||||
|  |         # gh-93021: Second parameter is optional | ||||||
|  |         self.assertIs(sig.parameters["owner"].default, None) | ||||||
|  | 
 | ||||||
|     def test_method_wrapper_types(self): |     def test_method_wrapper_types(self): | ||||||
|         self.assertIsInstance(object().__init__, types.MethodWrapperType) |         self.assertIsInstance(object().__init__, types.MethodWrapperType) | ||||||
|         self.assertIsInstance(object().__str__, types.MethodWrapperType) |         self.assertIsInstance(object().__str__, types.MethodWrapperType) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,2 @@ | ||||||
|  | Fix the :attr:`__text_signature__` for :meth:`__get__` methods implemented | ||||||
|  | in C. Patch by Jelle Zijlstra. | ||||||
|  | @ -7184,7 +7184,7 @@ wrap_descr_get(PyObject *self, PyObject *args, void *wrapped) | ||||||
|         obj = NULL; |         obj = NULL; | ||||||
|     if (type == Py_None) |     if (type == Py_None) | ||||||
|         type = NULL; |         type = NULL; | ||||||
|     if (type == NULL &&obj == NULL) { |     if (type == NULL && obj == NULL) { | ||||||
|         PyErr_SetString(PyExc_TypeError, |         PyErr_SetString(PyExc_TypeError, | ||||||
|                         "__get__(None, None) is invalid"); |                         "__get__(None, None) is invalid"); | ||||||
|         return NULL; |         return NULL; | ||||||
|  | @ -8209,7 +8209,7 @@ static slotdef slotdefs[] = { | ||||||
|     TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next, |     TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next, | ||||||
|            "__next__($self, /)\n--\n\nImplement next(self)."), |            "__next__($self, /)\n--\n\nImplement next(self)."), | ||||||
|     TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, |     TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, | ||||||
|            "__get__($self, instance, owner, /)\n--\n\nReturn an attribute of instance, which is of type owner."), |            "__get__($self, instance, owner=None, /)\n--\n\nReturn an attribute of instance, which is of type owner."), | ||||||
|     TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, |     TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, | ||||||
|            "__set__($self, instance, value, /)\n--\n\nSet an attribute of instance to value."), |            "__set__($self, instance, value, /)\n--\n\nSet an attribute of instance to value."), | ||||||
|     TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, |     TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jelle Zijlstra
						Jelle Zijlstra