Skip to content

Commit 6414138

Browse files
Erlend Egeberg Aaslandvstinner
Erlend Egeberg Aasland
andauthored
bpo-43908: check_set_special_type_attr() checks Py_TPFLAGS_IMMUTABLETYPE (GH-25743)
check_set_special_type_attr() and type_set_annotations() now check for immutable flag (Py_TPFLAGS_IMMUTABLETYPE). Co-authored-by: Victor Stinner <[email protected]>
1 parent 9032cf5 commit 6414138

File tree

2 files changed

+15
-9
lines changed

2 files changed

+15
-9
lines changed

Lib/test/test_descr.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -4763,12 +4763,14 @@ class X:
47634763
"elephant"
47644764
X.__doc__ = "banana"
47654765
self.assertEqual(X.__doc__, "banana")
4766+
47664767
with self.assertRaises(TypeError) as cm:
47674768
type(list).__dict__["__doc__"].__set__(list, "blah")
4768-
self.assertIn("can't set list.__doc__", str(cm.exception))
4769+
self.assertIn("cannot set '__doc__' attribute of immutable type 'list'", str(cm.exception))
4770+
47694771
with self.assertRaises(TypeError) as cm:
47704772
type(X).__dict__["__doc__"].__delete__(X)
4771-
self.assertIn("can't delete X.__doc__", str(cm.exception))
4773+
self.assertIn("cannot delete '__doc__' attribute of immutable type 'X'", str(cm.exception))
47724774
self.assertEqual(X.__doc__, "banana")
47734775

47744776
def test_qualname(self):

Objects/typeobject.c

+11-7
Original file line numberDiff line numberDiff line change
@@ -466,14 +466,16 @@ static PyMemberDef type_members[] = {
466466
static int
467467
check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *name)
468468
{
469-
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
469+
if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) {
470470
PyErr_Format(PyExc_TypeError,
471-
"can't set %s.%s", type->tp_name, name);
471+
"cannot set '%s' attribute of immutable type '%s'",
472+
name, type->tp_name);
472473
return 0;
473474
}
474475
if (!value) {
475476
PyErr_Format(PyExc_TypeError,
476-
"can't delete %s.%s", type->tp_name, name);
477+
"cannot delete '%s' attribute of immutable type '%s'",
478+
name, type->tp_name);
477479
return 0;
478480
}
479481

@@ -978,8 +980,10 @@ type_get_annotations(PyTypeObject *type, void *context)
978980
static int
979981
type_set_annotations(PyTypeObject *type, PyObject *value, void *context)
980982
{
981-
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
982-
PyErr_Format(PyExc_TypeError, "can't set attributes of built-in/extension type '%s'", type->tp_name);
983+
if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) {
984+
PyErr_Format(PyExc_TypeError,
985+
"cannot set '__annotations__' attribute of immutable type '%s'",
986+
type->tp_name);
983987
return -1;
984988
}
985989

@@ -3953,8 +3957,8 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
39533957
if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) {
39543958
PyErr_Format(
39553959
PyExc_TypeError,
3956-
"can't set attributes of built-in/extension type '%s'",
3957-
type->tp_name);
3960+
"cannot set %R attribute of immutable type '%s'",
3961+
name, type->tp_name);
39583962
return -1;
39593963
}
39603964
if (PyUnicode_Check(name)) {

0 commit comments

Comments
 (0)