for _ in range(1025):
self.assertFalse(f())
+ def test_load_shadowing_slot_should_raise_type_error(self):
+ class Class:
+ __slots__ = ("slot",)
+
+ class Sneaky:
+ __slots__ = ("shadowed",)
+ shadowing = Class.slot
+
+ def f(o):
+ o.shadowing
+
+ o = Sneaky()
+ o.shadowed = 42
+
+ for _ in range(1025):
+ with self.assertRaises(TypeError):
+ f(o)
+
+ def test_store_shadowing_slot_should_raise_type_error(self):
+ class Class:
+ __slots__ = ("slot",)
+
+ class Sneaky:
+ __slots__ = ("shadowed",)
+ shadowing = Class.slot
+
+ def f(o):
+ o.shadowing = 42
+
+ o = Sneaky()
+
+ for _ in range(1025):
+ with self.assertRaises(TypeError):
+ f(o)
+
+ def test_load_borrowed_slot_should_not_crash(self):
+ class Class:
+ __slots__ = ("slot",)
+
+ class Sneaky:
+ borrowed = Class.slot
+
+ def f(o):
+ o.borrowed
+
+ o = Sneaky()
+
+ for _ in range(1025):
+ with self.assertRaises(TypeError):
+ f(o)
+
+ def test_store_borrowed_slot_should_not_crash(self):
+ class Class:
+ __slots__ = ("slot",)
+
+ class Sneaky:
+ borrowed = Class.slot
+
+ def f(o):
+ o.borrowed = 42
+
+ o = Sneaky()
+
+ for _ in range(1025):
+ with self.assertRaises(TypeError):
+ f(o)
+
class TestLoadMethodCache(unittest.TestCase):
def test_descriptor_added_after_optimization(self):
PyMemberDescrObject *member = (PyMemberDescrObject *)descr;
struct PyMemberDef *dmem = member->d_member;
Py_ssize_t offset = dmem->offset;
+ if (!PyObject_TypeCheck(owner, member->d_common.d_type)) {
+ SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR);
+ goto fail;
+ }
if (dmem->flags & PY_AUDIT_READ) {
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_AUDITED_SLOT);
goto fail;
PyMemberDescrObject *member = (PyMemberDescrObject *)descr;
struct PyMemberDef *dmem = member->d_member;
Py_ssize_t offset = dmem->offset;
+ if (!PyObject_TypeCheck(owner, member->d_common.d_type)) {
+ SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_EXPECTED_ERROR);
+ goto fail;
+ }
if (dmem->flags & READONLY) {
SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_READ_ONLY);
goto fail;