Skip to content

Commit 3b52c8d

Browse files
Erlend Egeberg Aaslandvstinner
Erlend Egeberg Aasland
andauthored
bpo-43908: Add Py_TPFLAGS_IMMUTABLETYPE flag (GH-25520)
Introduce Py_TPFLAGS_IMMUTABLETYPE flag for immutable type objects, and modify PyType_Ready() to set it for static types. Co-authored-by: Victor Stinner <[email protected]>
1 parent 3cc481b commit 3b52c8d

File tree

4 files changed

+24
-1
lines changed

4 files changed

+24
-1
lines changed

Doc/c-api/typeobj.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,18 @@ and :c:type:`PyType_Type` effectively act as defaults.)
11771177

11781178
.. versionadded:: 3.10
11791179

1180+
.. data:: Py_TPFLAGS_IMMUTABLETYPE
1181+
1182+
This bit is set for type objects that are immutable: type attributes cannot be set nor deleted.
1183+
1184+
:c:func:`PyType_Ready` automatically applies this flag to static types.
1185+
1186+
**Inheritance:**
1187+
1188+
This flag is not inherited.
1189+
1190+
.. versionadded:: 3.10
1191+
11801192

11811193
.. c:member:: const char* PyTypeObject.tp_doc
11821194

Include/object.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,9 @@ Code can use PyType_HasFeature(type_ob, flag_value) to test whether the
320320
given type object has a specified feature.
321321
*/
322322

323+
/* Set if the type object is immutable: type attributes cannot be set nor deleted */
324+
#define Py_TPFLAGS_IMMUTABLETYPE (1UL << 8)
325+
323326
/* Set if the type object is dynamically allocated */
324327
#define Py_TPFLAGS_HEAPTYPE (1UL << 9)
325328

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Introduce :const:`Py_TPFLAGS_IMMUTABLETYPE` flag for immutable type objects, and
2+
modify :c:func:`PyType_Ready` to set it for static types. Patch by
3+
Erlend E. Aasland.

Objects/typeobject.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3875,7 +3875,7 @@ static int
38753875
type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
38763876
{
38773877
int res;
3878-
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
3878+
if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) {
38793879
PyErr_Format(
38803880
PyExc_TypeError,
38813881
"can't set attributes of built-in/extension type '%s'",
@@ -6229,6 +6229,11 @@ PyType_Ready(PyTypeObject *type)
62296229

62306230
type->tp_flags |= Py_TPFLAGS_READYING;
62316231

6232+
/* Historically, all static types were immutable. See bpo-43908 */
6233+
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
6234+
type->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
6235+
}
6236+
62326237
if (type_ready(type) < 0) {
62336238
type->tp_flags &= ~Py_TPFLAGS_READYING;
62346239
return -1;

0 commit comments

Comments
 (0)