From ce4113f277f70dcbd011f62764f29bc63df78047 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 30 Apr 2021 11:54:45 +0200 Subject: [PATCH 1/8] check_set_special_type_attr() now checks for Py_TPFLAGS_IMMUTABLETYPE iso. !Py_TPFLAGS_HEAPTYPE --- Objects/typeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ac4dc1da4411dc..e68538770d72ee 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -461,7 +461,7 @@ static PyMemberDef type_members[] = { static int check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *name) { - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { PyErr_Format(PyExc_TypeError, "can't set %s.%s", type->tp_name, name); return 0; From af09ad663e3b82337e40e8d2c35fe36c8cafa6c1 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 30 Apr 2021 12:37:04 +0200 Subject: [PATCH 2/8] type_set_annotations now check for immutable flag iso. heap type flag --- Objects/typeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e68538770d72ee..8473aab211d6b5 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -973,7 +973,7 @@ type_get_annotations(PyTypeObject *type, void *context) static int type_set_annotations(PyTypeObject *type, PyObject *value, void *context) { - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { PyErr_Format(PyExc_TypeError, "can't set attributes of built-in/extension type '%s'", type->tp_name); return -1; } From 392af9ce44dde2d63b1eabda2ab8ee8a50cd3815 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Fri, 30 Apr 2021 12:43:26 +0200 Subject: [PATCH 3/8] Advertise immutable flag in error message Co-authored-by: Victor Stinner --- Objects/typeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 8473aab211d6b5..d18e82b6778d7b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -463,7 +463,7 @@ check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *nam { if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { PyErr_Format(PyExc_TypeError, - "can't set %s.%s", type->tp_name, name); + "can't set '%r' attribute of immutable type %s", name, type->tp_name); return 0; } if (!value) { From fd929c014bf0620748c25c32378505db69fde58f Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 30 Apr 2021 12:50:05 +0200 Subject: [PATCH 4/8] Address review: improve comments --- Objects/typeobject.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index d18e82b6778d7b..e93e122a93b9e1 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -463,12 +463,14 @@ check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *nam { if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { PyErr_Format(PyExc_TypeError, - "can't set '%r' attribute of immutable type %s", name, type->tp_name); + "cannot set '%r' attribute of immutable type '%s'", + name, type->tp_name); return 0; } if (!value) { PyErr_Format(PyExc_TypeError, - "can't delete %s.%s", type->tp_name, name); + "cannot delete '%r' attribute of immutable type '%s'", + name, type->tp_name); return 0; } @@ -974,7 +976,9 @@ static int type_set_annotations(PyTypeObject *type, PyObject *value, void *context) { if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { - PyErr_Format(PyExc_TypeError, "can't set attributes of built-in/extension type '%s'", type->tp_name); + PyErr_Format(PyExc_TypeError, + "cannot set '__annotations__' attribute of immutable type '%s'", + type->tp_name); return -1; } @@ -3947,7 +3951,7 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { PyErr_Format( PyExc_TypeError, - "can't set attributes of built-in/extension type '%s'", + "cannot set attributes of immutable type '%s'", type->tp_name); return -1; } From 52795a49b2c607be10efca76dfadf686db9f55eb Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 30 Apr 2021 13:17:15 +0200 Subject: [PATCH 5/8] Fix formatting --- Objects/typeobject.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e93e122a93b9e1..d73d548ce92fec 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -463,13 +463,13 @@ check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *nam { if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { PyErr_Format(PyExc_TypeError, - "cannot set '%r' attribute of immutable type '%s'", + "cannot set '%R' attribute of immutable type '%s'", name, type->tp_name); return 0; } if (!value) { PyErr_Format(PyExc_TypeError, - "cannot delete '%r' attribute of immutable type '%s'", + "cannot delete '%R' attribute of immutable type '%s'", name, type->tp_name); return 0; } @@ -3951,8 +3951,8 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { PyErr_Format( PyExc_TypeError, - "cannot set attributes of immutable type '%s'", - type->tp_name); + "cannot set '%R' attribute of immutable type '%s'", + name, type->tp_name); return -1; } if (PyUnicode_Check(name)) { From 817b8cffead36600e61db0edb3bee4408dbbd50f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 30 Apr 2021 13:35:17 +0200 Subject: [PATCH 6/8] Update Objects/typeobject.c --- Objects/typeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index d73d548ce92fec..f155b81124d2cc 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3951,7 +3951,7 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { PyErr_Format( PyExc_TypeError, - "cannot set '%R' attribute of immutable type '%s'", + "cannot set %R attribute of immutable type '%s'", name, type->tp_name); return -1; } From b464ab54daa545f092b315672a6cdf1e4156cb44 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 30 Apr 2021 14:19:23 +0200 Subject: [PATCH 7/8] Don't need quotes when using %R --- Objects/typeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index f155b81124d2cc..ef6b95f8d512b8 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -463,13 +463,13 @@ check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *nam { if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { PyErr_Format(PyExc_TypeError, - "cannot set '%R' attribute of immutable type '%s'", + "cannot set %R attribute of immutable type '%s'", name, type->tp_name); return 0; } if (!value) { PyErr_Format(PyExc_TypeError, - "cannot delete '%R' attribute of immutable type '%s'", + "cannot delete %R attribute of immutable type '%s'", name, type->tp_name); return 0; } From 10b007174482d88ef4b1f486a5277ebc28464256 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 30 Apr 2021 14:53:41 +0200 Subject: [PATCH 8/8] Fix test_descr --- Lib/test/test_descr.py | 6 ++++-- Objects/typeobject.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 79d6c4b5e72328..3cb923ed0520a3 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4763,12 +4763,14 @@ class X: "elephant" X.__doc__ = "banana" self.assertEqual(X.__doc__, "banana") + with self.assertRaises(TypeError) as cm: type(list).__dict__["__doc__"].__set__(list, "blah") - self.assertIn("can't set list.__doc__", str(cm.exception)) + self.assertIn("cannot set '__doc__' attribute of immutable type 'list'", str(cm.exception)) + with self.assertRaises(TypeError) as cm: type(X).__dict__["__doc__"].__delete__(X) - self.assertIn("can't delete X.__doc__", str(cm.exception)) + self.assertIn("cannot delete '__doc__' attribute of immutable type 'X'", str(cm.exception)) self.assertEqual(X.__doc__, "banana") def test_qualname(self): diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ef6b95f8d512b8..13fc295e851f70 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -463,13 +463,13 @@ check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *nam { if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { PyErr_Format(PyExc_TypeError, - "cannot set %R attribute of immutable type '%s'", + "cannot set '%s' attribute of immutable type '%s'", name, type->tp_name); return 0; } if (!value) { PyErr_Format(PyExc_TypeError, - "cannot delete %R attribute of immutable type '%s'", + "cannot delete '%s' attribute of immutable type '%s'", name, type->tp_name); return 0; }