From b3559728d0fcff23fec90995f28f1f53e162fafd Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:35:05 +0200 Subject: [PATCH 01/18] Make functools types immutable --- Modules/_functoolsmodule.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 19cfa9b07b340d..058ca9214a60ce 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -481,7 +481,8 @@ static PyType_Spec partial_type_spec = { .name = "functools.partial", .basicsize = sizeof(partialobject), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL | + Py_TPFLAGS_IMMUTABLETYPE, .slots = partial_type_slots }; @@ -546,7 +547,8 @@ static PyType_Slot keyobject_type_slots[] = { static PyType_Spec keyobject_type_spec = { .name = "functools.KeyWrapper", .basicsize = sizeof(keyobject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE, .slots = keyobject_type_slots }; @@ -766,7 +768,8 @@ static PyType_Slot lru_list_elem_type_slots[] = { static PyType_Spec lru_list_elem_type_spec = { .name = "functools._lru_list_elem", .basicsize = sizeof(lru_list_elem), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE, .slots = lru_list_elem_type_slots }; @@ -1400,7 +1403,7 @@ static PyType_Spec lru_cache_type_spec = { .name = "functools._lru_cache_wrapper", .basicsize = sizeof(lru_cache_object), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_METHOD_DESCRIPTOR, + Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_IMMUTABLETYPE, .slots = lru_cache_type_slots }; From a5e0d3ab5e4675b59744d943e35b86311310467b Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:37:10 +0200 Subject: [PATCH 02/18] Multibyte codec types are now immutable --- Modules/cjkcodecs/multibytecodec.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index cb7182ff21fbcd..ba558d0dbf2f1d 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -749,7 +749,7 @@ static PyType_Spec multibytecodec_spec = { .name = MODULE_NAME ".MultibyteCodec", .basicsize = sizeof(MultibyteCodecObject), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_DISALLOW_INSTANTIATION), + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), .slots = multibytecodec_slots, }; @@ -1111,7 +1111,8 @@ static PyType_Slot encoder_slots[] = { static PyType_Spec encoder_spec = { .name = MODULE_NAME ".MultibyteIncrementalEncoder", .basicsize = sizeof(MultibyteIncrementalEncoderObject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = encoder_slots, }; @@ -1384,7 +1385,8 @@ static PyType_Slot decoder_slots[] = { static PyType_Spec decoder_spec = { .name = MODULE_NAME ".MultibyteIncrementalDecoder", .basicsize = sizeof(MultibyteIncrementalDecoderObject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = decoder_slots, }; @@ -1705,7 +1707,8 @@ static PyType_Slot reader_slots[] = { static PyType_Spec reader_spec = { .name = MODULE_NAME ".MultibyteStreamReader", .basicsize = sizeof(MultibyteStreamReaderObject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = reader_slots, }; @@ -1925,7 +1928,8 @@ static PyType_Slot writer_slots[] = { static PyType_Spec writer_spec = { .name = MODULE_NAME ".MultibyteStreamWriter", .basicsize = sizeof(MultibyteStreamWriterObject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = writer_slots, }; From 06f51ffcd5acb870f74db98fd782407678d5ca09 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:37:58 +0200 Subject: [PATCH 03/18] pyexpat.xmlparser is now immutable --- Modules/pyexpat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 7f727a86f5f47d..7ea43a0359383d 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1507,7 +1507,7 @@ static PyType_Spec _xml_parse_type_spec = { .name = "pyexpat.xmlparser", .basicsize = sizeof(xmlparseobject), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_DISALLOW_INSTANTIATION), + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), .slots = _xml_parse_type_spec_slots, }; From 2fdee5a659cc8b49b1edfb0ac54c1b8dcf0809ac Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:38:39 +0200 Subject: [PATCH 04/18] array.arrayiterator is now immutable --- Modules/arraymodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index aa5886f4af7f69..b905dc6fdbd421 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -2988,7 +2988,7 @@ static PyType_Spec arrayiter_spec = { .name = "array.arrayiterator", .basicsize = sizeof(arrayiterobject), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_DISALLOW_INSTANTIATION), + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), .slots = arrayiter_slots, }; From be80315ab3c954ed74c1d3bc775a47ba446dabe5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:39:41 +0200 Subject: [PATCH 05/18] _thread types are now immutable --- Modules/_threadmodule.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 6924d6553a1ff8..2ce48e1c97126f 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -313,7 +313,7 @@ static PyType_Spec lock_type_spec = { .name = "_thread.lock", .basicsize = sizeof(lockobject), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_DISALLOW_INSTANTIATION), + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), .slots = lock_type_slots, }; @@ -585,7 +585,8 @@ static PyType_Slot rlock_type_slots[] = { static PyType_Spec rlock_type_spec = { .name = "_thread.RLock", .basicsize = sizeof(rlockobject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = rlock_type_slots, }; @@ -684,7 +685,8 @@ static PyType_Slot local_dummy_type_slots[] = { static PyType_Spec local_dummy_type_spec = { .name = "_thread._localdummy", .basicsize = sizeof(localdummyobject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE), .slots = local_dummy_type_slots, }; @@ -968,7 +970,8 @@ static PyType_Slot local_type_slots[] = { static PyType_Spec local_type_spec = { .name = "_thread._local", .basicsize = sizeof(localobject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), .slots = local_type_slots, }; From 53c32945db331a69ea913cceb7f0a10c30e65457 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:40:41 +0200 Subject: [PATCH 06/18] _csv types are now immutable --- Modules/_csv.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Modules/_csv.c b/Modules/_csv.c index a213734f508068..78855b871352c5 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -537,7 +537,8 @@ static PyType_Slot Dialect_Type_slots[] = { PyType_Spec Dialect_Type_spec = { .name = "_csv.Dialect", .basicsize = sizeof(DialectObj), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), .slots = Dialect_Type_slots, }; @@ -958,7 +959,8 @@ static PyType_Slot Reader_Type_slots[] = { PyType_Spec Reader_Type_spec = { .name = "_csv.reader", .basicsize = sizeof(ReaderObj), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), .slots = Reader_Type_slots }; @@ -1382,7 +1384,8 @@ static PyType_Slot Writer_Type_slots[] = { PyType_Spec Writer_Type_spec = { .name = "_csv.writer", .basicsize = sizeof(WriterObj), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), .slots = Writer_Type_slots, }; From 1bc65696941732bda3a14240aaa1281ddeed0b6e Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:41:19 +0200 Subject: [PATCH 07/18] _queue.SimpleQueue is now immutable --- Modules/_queuemodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index c27fb1a001d21e..e247221d76dcdf 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -371,7 +371,8 @@ static PyType_Slot simplequeue_slots[] = { static PyType_Spec simplequeue_spec = { .name = "_queue.SimpleQueue", .basicsize = sizeof(simplequeueobject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), .slots = simplequeue_slots, }; From e38cafcd28ac2410909b27588b9c94f7ced872c3 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:41:47 +0200 Subject: [PATCH 08/18] mmap.mmap is now immutable --- Modules/mmapmodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 9a2542f824c5c4..485a4d5166f386 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1114,7 +1114,8 @@ static PyType_Slot mmap_object_slots[] = { static PyType_Spec mmap_object_spec = { .name = "mmap.mmap", .basicsize = sizeof(mmap_object), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = mmap_object_slots, }; From 5ee3460962aee803d50c5afb2b98fe2959a7e3dd Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:42:14 +0200 Subject: [PATCH 09/18] unicodedata.UCD is now immutable --- Modules/unicodedata.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 2e8d199de86ca8..9bf54598ab95dc 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -1454,7 +1454,8 @@ static PyType_Slot ucd_type_slots[] = { static PyType_Spec ucd_type_spec = { .name = "unicodedata.UCD", .basicsize = sizeof(PreviousDBVersion), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE), .slots = ucd_type_slots }; From 783f71dedee71150d92156d5914f409297ba5e22 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:44:55 +0200 Subject: [PATCH 10/18] sqlite3 types are now immutable --- Modules/_sqlite/cache.c | 6 ++++-- Modules/_sqlite/connection.c | 3 ++- Modules/_sqlite/cursor.c | 3 ++- Modules/_sqlite/prepare_protocol.c | 2 +- Modules/_sqlite/row.c | 3 ++- Modules/_sqlite/statement.c | 2 +- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 8da0a64a3f90a4..7f59d0317b6e2a 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -267,7 +267,8 @@ static PyType_Slot node_slots[] = { static PyType_Spec node_spec = { .name = MODULE_NAME ".Node", .basicsize = sizeof(pysqlite_Node), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = node_slots, }; PyTypeObject *pysqlite_NodeType = NULL; @@ -291,7 +292,8 @@ static PyType_Slot cache_slots[] = { static PyType_Spec cache_spec = { .name = MODULE_NAME ".Cache", .basicsize = sizeof(pysqlite_Cache), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = cache_slots, }; PyTypeObject *pysqlite_CacheType = NULL; diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 28932726b74257..a5ef8d77b60ea1 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1923,7 +1923,8 @@ static PyType_Slot connection_slots[] = { static PyType_Spec connection_spec = { .name = MODULE_NAME ".Connection", .basicsize = sizeof(pysqlite_Connection), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = connection_slots, }; diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index b71f780a0b4dfd..fc97eae5e252b2 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -1020,7 +1020,8 @@ static PyType_Slot cursor_slots[] = { static PyType_Spec cursor_spec = { .name = MODULE_NAME ".Cursor", .basicsize = sizeof(pysqlite_Cursor), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = cursor_slots, }; diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index 7d2d7ade591467..2dd1b3e2c5e7d2 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -49,7 +49,7 @@ static PyType_Slot type_slots[] = { static PyType_Spec type_spec = { .name = MODULE_NAME ".PrepareProtocol", .basicsize = sizeof(pysqlite_PrepareProtocol), - .flags = Py_TPFLAGS_DEFAULT, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), .slots = type_slots, }; diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index f9dfcbd5d615e5..08c1a4b6353171 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -237,7 +237,8 @@ static PyType_Slot row_slots[] = { static PyType_Spec row_spec = { .name = MODULE_NAME ".Row", .basicsize = sizeof(pysqlite_Row), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = row_slots, }; diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 57026270e1eeb5..1394cf2c5e0f9f 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -475,7 +475,7 @@ static PyType_Slot stmt_slots[] = { static PyType_Spec stmt_spec = { .name = MODULE_NAME ".Statement", .basicsize = sizeof(pysqlite_Statement), - .flags = Py_TPFLAGS_DEFAULT, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), .slots = stmt_slots, }; PyTypeObject *pysqlite_StatementType = NULL; From b50c5b91628f07012752a21728fc24f19fbcc3e3 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:45:25 +0200 Subject: [PATCH 11/18] _lsprof.Profiler is now immutable --- Modules/_lsprof.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index c32699cb8ad580..d0861b1d745fce 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -807,7 +807,8 @@ static PyType_Slot _lsprof_profiler_type_spec_slots[] = { static PyType_Spec _lsprof_profiler_type_spec = { .name = "_lsprof.Profiler", .basicsize = sizeof(ProfilerObject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), .slots = _lsprof_profiler_type_spec_slots, }; From 7ee4d337421a02aa782d5c974e4eccb296aa12c5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:45:53 +0200 Subject: [PATCH 12/18] _overlapped.Overlapped is now immutable --- Modules/overlapped.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 38dd98f084849e..7c4570896bc591 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -1876,7 +1876,7 @@ static PyType_Slot overlapped_type_slots[] = { static PyType_Spec overlapped_type_spec = { .name = "_overlapped.Overlapped", .basicsize = sizeof(OverlappedObject), - .flags = Py_TPFLAGS_DEFAULT, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), .slots = overlapped_type_slots }; From 261767c478659f17ab92a57ae6c12fae467fd19b Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:46:47 +0200 Subject: [PATCH 13/18] _operator types are now immutable --- Modules/_operator.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Modules/_operator.c b/Modules/_operator.c index f55c2f1d1f415e..c7bfef0de5e972 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -1124,7 +1124,8 @@ static PyType_Spec itemgetter_type_spec = { .name = "operator.itemgetter", .basicsize = sizeof(itemgetterobject), .itemsize = 0, - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), .slots = itemgetter_type_slots, }; @@ -1446,7 +1447,8 @@ static PyType_Spec attrgetter_type_spec = { .name = "operator.attrgetter", .basicsize = sizeof(attrgetterobject), .itemsize = 0, - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), .slots = attrgetter_type_slots, }; @@ -1691,7 +1693,8 @@ static PyType_Spec methodcaller_type_spec = { .name = "operator.methodcaller", .basicsize = sizeof(methodcallerobject), .itemsize = 0, - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), .slots = methodcaller_type_slots, }; From 8a9290d7d54c10db7be46d4e2ac2f853f9ff3531 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:47:14 +0200 Subject: [PATCH 14/18] winapi__overlapped.Overlapped is now immutable --- Modules/_winapi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_winapi.c b/Modules/_winapi.c index bc2126c8e2ee99..0263472dd907e2 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -331,7 +331,8 @@ static PyType_Slot winapi_overlapped_type_slots[] = { static PyType_Spec winapi_overlapped_type_spec = { .name = "_winapi.Overlapped", .basicsize = sizeof(OverlappedObject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE), .slots = winapi_overlapped_type_slots, }; From d5fac8338df44828742bcf24c58600c3361e1f17 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:48:03 +0200 Subject: [PATCH 15/18] _lzma types are now immutable --- Modules/_lzmamodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index 2f80bf0496bb3f..915c0c918f6443 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -915,7 +915,7 @@ static PyType_Spec lzma_compressor_type_spec = { // lzma_compressor_type_spec does not have Py_TPFLAGS_BASETYPE flag // which prevents to create a subclass. // So calling PyType_GetModuleState() in this file is always safe. - .flags = Py_TPFLAGS_DEFAULT, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), .slots = lzma_compressor_type_slots, }; @@ -1359,7 +1359,7 @@ static PyType_Spec lzma_decompressor_type_spec = { // lzma_decompressor_type_spec does not have Py_TPFLAGS_BASETYPE flag // which prevents to create a subclass. // So calling PyType_GetModuleState() in this file is always safe. - .flags = Py_TPFLAGS_DEFAULT, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), .slots = lzma_decompressor_type_slots, }; From 5dcfbce1e40bfb4583bc3b978bd915805f15d6f5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:48:36 +0200 Subject: [PATCH 16/18] _bz2 types are now immutable --- Modules/_bz2module.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index d75bb32d2fc5eb..798e9efc628f05 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -422,7 +422,7 @@ static PyType_Spec bz2_compressor_type_spec = { // bz2_compressor_type_spec does not have Py_TPFLAGS_BASETYPE flag // which prevents to create a subclass. // So calling PyType_GetModuleState() in this file is always safe. - .flags = Py_TPFLAGS_DEFAULT, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), .slots = bz2_compressor_type_slots, }; @@ -766,7 +766,7 @@ static PyType_Spec bz2_decompressor_type_spec = { // bz2_decompressor_type_spec does not have Py_TPFLAGS_BASETYPE flag // which prevents to create a subclass. // So calling PyType_GetModuleState() in this file is always safe. - .flags = Py_TPFLAGS_DEFAULT, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), .slots = bz2_decompressor_type_slots, }; From 758dec220bda9d6f9a1cc02a487472e5e57a127c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 12:49:44 +0200 Subject: [PATCH 17/18] _dbm.dbm and _gdbm.gdbm are now immutable --- Modules/_dbmmodule.c | 3 ++- Modules/_gdbmmodule.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 96d0b0a5cfe6a5..11c979720aa732 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -413,7 +413,8 @@ static PyType_Spec dbmtype_spec = { // dbmtype_spec does not have Py_TPFLAGS_BASETYPE flag // which prevents to create a subclass. // So calling PyType_GetModuleState() in this file is always safe. - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE), .slots = dbmtype_spec_slots, }; diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index dc8b8b692c1a3f..7af2daceccdc23 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -570,7 +570,8 @@ static PyType_Spec gdbmtype_spec = { // dbmtype_spec does not have Py_TPFLAGS_BASETYPE flag // which prevents to create a subclass. // So calling PyType_GetModuleState() in this file is always safe. - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE), .slots = gdbmtype_spec_slots, }; From 5b8acb6da67762b5a989420b0966db24c0f5ddcf Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 5 Jun 2021 20:49:24 +0200 Subject: [PATCH 18/18] Fix merge --- Modules/_sqlite/cache.c | 314 ---------------------------------------- 1 file changed, 314 deletions(-) delete mode 100644 Modules/_sqlite/cache.c diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c deleted file mode 100644 index 7f59d0317b6e2a..00000000000000 --- a/Modules/_sqlite/cache.c +++ /dev/null @@ -1,314 +0,0 @@ -/* cache .c - a LRU cache - * - * Copyright (C) 2004-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "cache.h" -#include - -/* only used internally */ -static pysqlite_Node * -pysqlite_new_node(PyObject *key, PyObject *data) -{ - pysqlite_Node* node; - - node = (pysqlite_Node*) (pysqlite_NodeType->tp_alloc(pysqlite_NodeType, 0)); - if (!node) { - return NULL; - } - - node->key = Py_NewRef(key); - node->data = Py_NewRef(data); - - node->prev = NULL; - node->next = NULL; - - return node; -} - -static void -pysqlite_node_dealloc(pysqlite_Node *self) -{ - PyTypeObject *tp = Py_TYPE(self); - - Py_DECREF(self->key); - Py_DECREF(self->data); - - tp->tp_free(self); - Py_DECREF(tp); -} - -static int -pysqlite_cache_init(pysqlite_Cache *self, PyObject *args, PyObject *kwargs) -{ - PyObject* factory; - int size = 10; - - self->factory = NULL; - - if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) { - return -1; - } - - /* minimum cache size is 5 entries */ - if (size < 5) { - size = 5; - } - self->size = size; - self->first = NULL; - self->last = NULL; - - self->mapping = PyDict_New(); - if (!self->mapping) { - return -1; - } - - self->factory = Py_NewRef(factory); - - self->decref_factory = 1; - - return 0; -} - -static void -pysqlite_cache_dealloc(pysqlite_Cache *self) -{ - PyTypeObject *tp = Py_TYPE(self); - pysqlite_Node* node; - pysqlite_Node* delete_node; - - if (!self->factory) { - /* constructor failed, just get out of here */ - return; - } - - /* iterate over all nodes and deallocate them */ - node = self->first; - while (node) { - delete_node = node; - node = node->next; - Py_DECREF(delete_node); - } - - if (self->decref_factory) { - Py_DECREF(self->factory); - } - Py_DECREF(self->mapping); - - tp->tp_free(self); - Py_DECREF(tp); -} - -PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) -{ - pysqlite_Node* node; - pysqlite_Node* ptr; - PyObject* data; - - node = (pysqlite_Node*)PyDict_GetItemWithError(self->mapping, key); - if (node) { - /* an entry for this key already exists in the cache */ - - /* increase usage counter of the node found */ - if (node->count < LONG_MAX) { - node->count++; - } - - /* if necessary, reorder entries in the cache by swapping positions */ - if (node->prev && node->count > node->prev->count) { - ptr = node->prev; - - while (ptr->prev && node->count > ptr->prev->count) { - ptr = ptr->prev; - } - - if (node->next) { - node->next->prev = node->prev; - } else { - self->last = node->prev; - } - if (node->prev) { - node->prev->next = node->next; - } - if (ptr->prev) { - ptr->prev->next = node; - } else { - self->first = node; - } - - node->next = ptr; - node->prev = ptr->prev; - if (!node->prev) { - self->first = node; - } - ptr->prev = node; - } - } - else if (PyErr_Occurred()) { - return NULL; - } - else { - /* There is no entry for this key in the cache, yet. We'll insert a new - * entry in the cache, and make space if necessary by throwing the - * least used item out of the cache. */ - - if (PyDict_GET_SIZE(self->mapping) == self->size) { - if (self->last) { - node = self->last; - - if (PyDict_DelItem(self->mapping, self->last->key) != 0) { - return NULL; - } - - if (node->prev) { - node->prev->next = NULL; - } - self->last = node->prev; - node->prev = NULL; - - Py_DECREF(node); - } - } - - /* We cannot replace this by PyObject_CallOneArg() since - * PyObject_CallFunction() has a special case when using a - * single tuple as argument. */ - data = PyObject_CallFunction(self->factory, "O", key); - - if (!data) { - return NULL; - } - - node = pysqlite_new_node(key, data); - if (!node) { - return NULL; - } - node->prev = self->last; - - Py_DECREF(data); - - if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) { - Py_DECREF(node); - return NULL; - } - - if (self->last) { - self->last->next = node; - } else { - self->first = node; - } - self->last = node; - } - - return Py_NewRef(node->data); -} - -static PyObject * -pysqlite_cache_display(pysqlite_Cache *self, PyObject *args) -{ - pysqlite_Node* ptr; - PyObject* prevkey; - PyObject* nextkey; - PyObject* display_str; - - ptr = self->first; - - while (ptr) { - if (ptr->prev) { - prevkey = ptr->prev->key; - } else { - prevkey = Py_None; - } - - if (ptr->next) { - nextkey = ptr->next->key; - } else { - nextkey = Py_None; - } - - display_str = PyUnicode_FromFormat("%S <- %S -> %S\n", - prevkey, ptr->key, nextkey); - if (!display_str) { - return NULL; - } - PyObject_Print(display_str, stdout, Py_PRINT_RAW); - Py_DECREF(display_str); - - ptr = ptr->next; - } - - Py_RETURN_NONE; -} - -static PyType_Slot node_slots[] = { - {Py_tp_dealloc, pysqlite_node_dealloc}, - {Py_tp_new, PyType_GenericNew}, - {0, NULL}, -}; - -static PyType_Spec node_spec = { - .name = MODULE_NAME ".Node", - .basicsize = sizeof(pysqlite_Node), - .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_IMMUTABLETYPE), - .slots = node_slots, -}; -PyTypeObject *pysqlite_NodeType = NULL; - -static PyMethodDef cache_methods[] = { - {"get", (PyCFunction)pysqlite_cache_get, METH_O, - PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")}, - {"display", (PyCFunction)pysqlite_cache_display, METH_NOARGS, - PyDoc_STR("For debugging only.")}, - {NULL, NULL} -}; - -static PyType_Slot cache_slots[] = { - {Py_tp_dealloc, pysqlite_cache_dealloc}, - {Py_tp_methods, cache_methods}, - {Py_tp_new, PyType_GenericNew}, - {Py_tp_init, pysqlite_cache_init}, - {0, NULL}, -}; - -static PyType_Spec cache_spec = { - .name = MODULE_NAME ".Cache", - .basicsize = sizeof(pysqlite_Cache), - .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_IMMUTABLETYPE), - .slots = cache_slots, -}; -PyTypeObject *pysqlite_CacheType = NULL; - -int -pysqlite_cache_setup_types(PyObject *mod) -{ - pysqlite_NodeType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &node_spec, NULL); - if (pysqlite_NodeType == NULL) { - return -1; - } - - pysqlite_CacheType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &cache_spec, NULL); - if (pysqlite_CacheType == NULL) { - return -1; - } - return 0; -}