mirror of https://github.com/python/cpython
bpo-37619: update_one_slot() should not ignore wrapper descriptors for wrong type (GH-14836)
This commit is contained in:
parent
f958377b67
commit
57ea335606
|
@ -4649,6 +4649,18 @@ order (MRO) for bases """
|
|||
self.assertEqual(x["y"], 42)
|
||||
self.assertEqual(x, -x)
|
||||
|
||||
def test_wrong_class_slot_wrapper(self):
|
||||
# Check bpo-37619: a wrapper descriptor taken from the wrong class
|
||||
# should raise an exception instead of silently being ignored
|
||||
class A(int):
|
||||
__eq__ = str.__eq__
|
||||
__add__ = str.__add__
|
||||
a = A()
|
||||
with self.assertRaises(TypeError):
|
||||
a == a
|
||||
with self.assertRaises(TypeError):
|
||||
a + a
|
||||
|
||||
def test_slot_shadows_class_variable(self):
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
class X:
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
When adding a wrapper descriptor from one class to a different class
|
||||
(for example, setting ``__add__ = str.__add__`` on an ``int`` subclass),
|
||||
an exception is correctly raised when the operator is called.
|
|
@ -7307,13 +7307,20 @@ update_one_slot(PyTypeObject *type, slotdef *p)
|
|||
if (tptr == NULL || tptr == ptr)
|
||||
generic = p->function;
|
||||
d = (PyWrapperDescrObject *)descr;
|
||||
if (d->d_base->wrapper == p->wrapper &&
|
||||
if ((specific == NULL || specific == d->d_wrapped) &&
|
||||
d->d_base->wrapper == p->wrapper &&
|
||||
PyType_IsSubtype(type, PyDescr_TYPE(d)))
|
||||
{
|
||||
if (specific == NULL ||
|
||||
specific == d->d_wrapped)
|
||||
specific = d->d_wrapped;
|
||||
else
|
||||
}
|
||||
else {
|
||||
/* We cannot use the specific slot function because either
|
||||
- it is not unique: there are multiple methods for this
|
||||
slot and they conflict
|
||||
- the signature is wrong (as checked by the ->wrapper
|
||||
comparison above)
|
||||
- it's wrapping the wrong class
|
||||
*/
|
||||
use_generic = 1;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue