8000 bpo-37619: update_one_slot() should not ignore wrapper descriptors fo… · python/cpython@eb1bc48 · GitHub
[go: up one dir, main page]

Skip to content

Commit eb1bc48

Browse files
miss-islingtonjdemeyer
authored andcommitted
bpo-37619: update_one_slot() should not ignore wrapper descriptors for wrong type (GH-15838)
(cherry picked from commit 57ea335) Co-authored-by: Jeroen Demeyer <J.Demeyer@UGent.be>
1 parent 55daf1a commit eb1bc48

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

Lib/test/test_descr.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4649,6 +4649,18 @@ class X(dict):
46494649
self.assertEqual(x["y"], 42)
46504650
self.assertEqual(x, -x)
46514651

4652+
def test_wrong_class_slot_wrapper(self):
4653+
# Check bpo-37619: a wrapper descriptor taken from the wrong class
4654+
# should raise an exception instead of silently being ignored
4655+
class A(int):
4656+
__eq__ = str.__eq__
4657+
__add__ = str.__add__
4658+
a = A()
4659+
with self.assertRaises(TypeError):
4660+
a == a
4661+
with self.assertRaises(TypeError):
4662+
a + a
4663+
46524664
def test_slot_shadows_class_variable(self):
46534665
with self.assertRaises(ValueError) as cm:
46544666
class X:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
When adding a wrapper descriptor from one class to a different class
2+
(for example, setting ``__add__ = str.__add__`` on an ``int`` subclass),
3+
an exception is correctly raised when the operator is called.

Objects/typeobject.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7243,14 +7243,21 @@ update_one_slot(PyTypeObject *type, slotdef *p)
72437243
if (tptr == NULL || tptr == ptr)
72447244
generic = p->function;
72457245
d = (PyWrapperDescrObject *)descr;
7246-
if (d->d_base->wrapper == p->wrapper &&
7246+
if ((specific == NULL || specific == d->d_wrapped) &&
7247+
d->d_base->wrapper == p->wrapper &&
72477248
PyType_IsSubtype(type, PyDescr_TYPE(d)))
72487249
{
7249-
if (specific == NULL ||
7250-
specific == d->d_wrapped)
7251-
specific = d->d_wrapped;
7252-
else
7253-
use_generic = 1;
7250+
specific = d->d_wrapped;
7251+
}
7252+
else {
7253+
/* We cannot use the specific slot function because either
7254+
- it is not unique: there are multiple methods for this
7255+
slot and they conflict
7256+
- the signature is wrong (as checked by the ->wrapper
7257+
comparison above)
7258+
- it's wrapping the wrong class
7259+
*/
7260+
use_generic = 1;
72547261
}
72557262
}
72567263
else if (Py_TYPE(descr) == &PyCFunction_Type &&

0 commit comments

Comments
 (0)
0