This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients Mark.Shannon, corona10, erlendaasland, gvanrossum, shihai1991, vstinner
Date 2021-04-22.12:50:51
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1619095852.0.0.349001683209.issue43908@roundup.psfhosted.org>
In-reply-to
Content
Let me propose a flag name: Py_TPFLAGS_IMMUTABLE.

Py_TPFLAGS_IMMUTABLE implies that setattr(type, name, value) fails. A type has a dictionary, but it cannot be modified with type.__dict__[name] = value, since type.__dict__ returns a read-only mapping proxy.


Currently, the limitation of not being able to modify a built-in type is arbitrary, it's not a technical limitation. It is implemented in type_setattro() which is the default implementation of tp_setattro: PyType_Type.tp_setattro = type_setattro.


Not having Py_TPFLAGS_HEAPTYPE flag implies "immutable". I suggest to add a new Py_TPFLAGS_IMMUTABLE flag and modify PyType_Ready() to use the flag if Py_TPFLAGS_HEAPTYPE is not set:

if (!(flags & Py_TPFLAGS_HEAPTYPE)) {
   flags |= Py_TPFLAGS_IMMUTABLE;
}


You can try with this change:

diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 254d12cc97..4bd02d40c1 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -3875,13 +3875,6 @@ static int
 type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
 {
     int res;
-    if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
-        PyErr_Format(
-            PyExc_TypeError,
-            "can't set attributes of built-in/extension type '%s'",
-            type->tp_name);
-        return -1;
-    }
     if (PyUnicode_Check(name)) {
         if (PyUnicode_CheckExact(name)) {
             if (PyUnicode_READY(name) == -1)


It becomes possible to modify built-in types:

$ ./python
Python 3.10.0a7+ (heads/master-dirty:cdad2724e6, Apr 22 2021, 14:44:44) [GCC 10.2.1 20201125 (Red Hat 10.2.1-9)] on linux
>>> str.x=1
>>> str.x
1
>>> del str.x

>>> del str.__repr__

>>> del str.__repr__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: __repr__
History
Date User Action Args
2021-04-22 12:50:52vstinnersetrecipients: + vstinner, gvanrossum, Mark.Shannon, corona10, shihai1991, erlendaasland
2021-04-22 12:50:52vstinnersetmessageid: <1619095852.0.0.349001683209.issue43908@roundup.psfhosted.org>
2021-04-22 12:50:52vstinnerlinkissue43908 messages
2021-04-22 12:50:51vstinnercreate