mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	Add a refinement to SLOT1BINFULL() that fixes the problem reported in
SF bug #623669: only try (e.g.) __rdiv__ before __div__ if the right class actually overrides it.
This commit is contained in:
		
							parent
							
								
									0a2f849b79
								
							
						
					
					
						commit
						cd118803b5
					
				
					 1 changed files with 36 additions and 1 deletions
				
			
		| 
						 | 
					@ -3494,6 +3494,40 @@ FUNCNAME(PyObject *self, ARG1TYPE arg1) \
 | 
				
			||||||
	return call_method(self, OPSTR, &cache_str, "(" ARGCODES ")", arg1); \
 | 
						return call_method(self, OPSTR, &cache_str, "(" ARGCODES ")", arg1); \
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Boolean helper for SLOT1BINFULL().
 | 
				
			||||||
 | 
					   right.__class__ is a nontrivial subclass of left.__class__. */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					method_is_overloaded(PyObject *left, PyObject *right, char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *a, *b;
 | 
				
			||||||
 | 
						int ok;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b = PyObject_GetAttrString((PyObject *)(right->ob_type), name);
 | 
				
			||||||
 | 
						if (b == NULL) {
 | 
				
			||||||
 | 
							PyErr_Clear();
 | 
				
			||||||
 | 
							/* If right doesn't have it, it's not overloaded */
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						a = PyObject_GetAttrString((PyObject *)(left->ob_type), name);
 | 
				
			||||||
 | 
						if (a == NULL) {
 | 
				
			||||||
 | 
							PyErr_Clear();
 | 
				
			||||||
 | 
							Py_DECREF(b);
 | 
				
			||||||
 | 
							/* If right has it but left doesn't, it's overloaded */
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ok = PyObject_RichCompareBool(a, b, Py_NE);
 | 
				
			||||||
 | 
						Py_DECREF(a);
 | 
				
			||||||
 | 
						Py_DECREF(b);
 | 
				
			||||||
 | 
						if (ok < 0) {
 | 
				
			||||||
 | 
							PyErr_Clear();
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ok;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \
 | 
					#define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \
 | 
				
			||||||
static PyObject * \
 | 
					static PyObject * \
 | 
				
			||||||
| 
						 | 
					@ -3507,7 +3541,8 @@ FUNCNAME(PyObject *self, PyObject *other) \
 | 
				
			||||||
	    self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
 | 
						    self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
 | 
				
			||||||
		PyObject *r; \
 | 
							PyObject *r; \
 | 
				
			||||||
		if (do_other && \
 | 
							if (do_other && \
 | 
				
			||||||
		    PyType_IsSubtype(other->ob_type, self->ob_type)) { \
 | 
							    PyType_IsSubtype(other->ob_type, self->ob_type) && \
 | 
				
			||||||
 | 
							    method_is_overloaded(self, other, ROPSTR)) { \
 | 
				
			||||||
			r = call_maybe( \
 | 
								r = call_maybe( \
 | 
				
			||||||
				other, ROPSTR, &rcache_str, "(O)", self); \
 | 
									other, ROPSTR, &rcache_str, "(O)", self); \
 | 
				
			||||||
			if (r != Py_NotImplemented) \
 | 
								if (r != Py_NotImplemented) \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue