]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-43916: Apply Py_TPFLAGS_DISALLOW_INSTANTIATION to selected types (GH-25748)
authorErlend Egeberg Aasland <erlend.aasland@innova.no>
Fri, 30 Apr 2021 14:04:57 +0000 (16:04 +0200)
committerGitHub <noreply@github.com>
Fri, 30 Apr 2021 14:04:57 +0000 (16:04 +0200)
Apply Py_TPFLAGS_DISALLOW_INSTANTIATION to the following types:

* _dbm.dbm
* _gdbm.gdbm
* _multibytecodec.MultibyteCodec
* _sre..SRE_Scanner
* _thread._localdummy
* _thread.lock
* _winapi.Overlapped
* array.arrayiterator
* functools.KeyWrapper
* functools._lru_list_elem
* pyexpat.xmlparser
* re.Match
* re.Pattern
* unicodedata.UCD
* zlib.Compress
* zlib.Decompress

20 files changed:
Lib/test/test_array.py
Lib/test/test_curses.py
Lib/test/test_dbm_gnu.py
Lib/test/test_functools.py
Lib/test/test_re.py
Lib/test/test_tcl.py
Lib/test/test_threading.py
Lib/test/test_unicodedata.py
Lib/test/test_zlib.py
Modules/_dbmmodule.c
Modules/_functoolsmodule.c
Modules/_gdbmmodule.c
Modules/_sre.c
Modules/_threadmodule.c
Modules/_winapi.c
Modules/arraymodule.c
Modules/cjkcodecs/multibytecodec.c
Modules/pyexpat.c
Modules/unicodedata.c
Modules/zlibmodule.c

index 11184add6d399b68da8d256a1f4b3be992fd9858..b18467fb889d8bcd81db48e15851679cc8228f0e 100644 (file)
@@ -40,6 +40,12 @@ class MiscTest(unittest.TestCase):
         self.assertRaises(TypeError, array.array, 'xx')
         self.assertRaises(ValueError, array.array, 'x')
 
+    @support.cpython_only
+    def test_disallow_instantiation(self):
+        # Ensure that the type disallows instantiation (bpo-43916)
+        tp = type(iter(array.array('I')))
+        self.assertRaises(TypeError, tp)
+
     @support.cpython_only
     def test_immutable(self):
         # bpo-43908: check that array.array is immutable
index 280a9dc0eedfcefe48d4ed44c6b477f9749ec7aa..8bf48a6454d691e4ad88098726d526fcf8810940 100644 (file)
@@ -6,7 +6,7 @@ import sys
 import tempfile
 import unittest
 
-from test.support import requires, verbose, SaveSignals
+from test.support import requires, verbose, SaveSignals, cpython_only
 from test.support.import_helper import import_module
 
 # Optionally test curses module.  This currently requires that the
@@ -1046,8 +1046,10 @@ class TestCurses(unittest.TestCase):
         panel.set_userptr(A())
         panel.set_userptr(None)
 
+    @cpython_only
     @requires_curses_func('panel')
-    def test_new_curses_panel(self):
+    def test_disallow_instantiation(self):
+        # Ensure that the type disallows instantiation (bpo-43916)
         w = curses.newwin(10, 10)
         panel = curses.panel.new_panel(w)
         self.assertRaises(TypeError, type(panel))
index 017d0ffa658bd620604b1b06e4a1c2b7847ab0b2..b3e55728c8e70dd80622abbd0cc70c009242f743 100644 (file)
@@ -1,5 +1,5 @@
 from test import support
-from test.support import import_helper
+from test.support import import_helper, cpython_only
 gdbm = import_helper.import_module("dbm.gnu") #skip if not supported
 import unittest
 import os
@@ -27,6 +27,13 @@ class TestGdbm(unittest.TestCase):
             self.g.close()
         unlink(filename)
 
+    @cpython_only
+    def test_disallow_instantiation(self):
+        # Ensure that the type disallows instantiation (bpo-43916)
+        self.g = gdbm.open(filename, 'c')
+        tp = type(self.g)
+        self.assertRaises(TypeError, tp)
+
     def test_key_methods(self):
         self.g = gdbm.open(filename, 'c')
         self.assertEqual(self.g.keys(), [])
index fba9281deb37635c6a69bf16acca29ee3b3458d1..3320ab7ec6649d14f1dc8d39199a5469a4b142c8 100644 (file)
@@ -948,6 +948,12 @@ class TestCmpToKeyC(TestCmpToKey, unittest.TestCase):
     if c_functools:
         cmp_to_key = c_functools.cmp_to_key
 
+    @support.cpython_only
+    def test_disallow_instantiation(self):
+        # Ensure that the type disallows instantiation (bpo-43916)
+        tp = type(c_functools.cmp_to_key(None))
+        self.assertRaises(TypeError, tp)
+
 
 class TestCmpToKeyPy(TestCmpToKey, unittest.TestCase):
     cmp_to_key = staticmethod(py_functools.cmp_to_key)
index 96d0cdb17a7ee3447e452831fa40372688c445e9..e1b2c794291848cf64f9357019c1dd8ef3c24b98 100644 (file)
@@ -2215,6 +2215,15 @@ class ImplementationTest(unittest.TestCase):
         self.assertGreaterEqual(sre_compile.MAXREPEAT, 0)
         self.assertGreaterEqual(sre_compile.MAXGROUPS, 0)
 
+    @cpython_only
+    def test_disallow_instantiation(self):
+        # Ensure that the type disallows instantiation (bpo-43916)
+        self.assertRaises(TypeError, re.Match)
+        self.assertRaises(TypeError, re.Pattern)
+        pat = re.compile("")
+        tp = type(pat.scanner(""))
+        self.assertRaises(TypeError, tp)
+
 
 class ExternalTests(unittest.TestCase):
 
index ee7344c48ed0beb73d00584876bd58c6f18a9b05..cd3aacf6f8844c98749c6e9facbb978adb19b81d 100644 (file)
@@ -736,8 +736,11 @@ class TclTest(unittest.TestCase):
         check('{\n')
         check('}\n')
 
+    @support.cpython_only
     def test_new_tcl_obj(self):
         self.assertRaises(TypeError, _tkinter.Tcl_Obj)
+        self.assertRaises(TypeError, _tkinter.TkttType)
+        self.assertRaises(TypeError, _tkinter.TkappType)
 
 class BigmemTclTest(unittest.TestCase):
 
index f44f17f2978f7b48f72bf98568b1a4b2c866cccb..546773e3329afa1763417260597e569267f14746 100644 (file)
@@ -119,6 +119,13 @@ class ThreadTests(BaseTestCase):
             thread = threading.Thread(target=func)
             self.assertEqual(thread.name, "Thread-5 (func)")
 
+    @cpython_only
+    def test_disallow_instantiation(self):
+        # Ensure that the type disallows instantiation (bpo-43916)
+        lock = threading.Lock()
+        tp = type(lock)
+        self.assertRaises(TypeError, tp)
+
     # Create a bunch of threads, let each do some work, wait until all are
     # done.
     def test_various_ops(self):
index edfd860fd5f12fe0c8e4b13100787066879ae9d3..c6bbe3f5ff2b33a88aca90a48ef7a063a6bc4c8f 100644 (file)
@@ -11,7 +11,8 @@ from http.client import HTTPException
 import sys
 import unicodedata
 import unittest
-from test.support import open_urlresource, requires_resource, script_helper
+from test.support import (open_urlresource, requires_resource, script_helper,
+                          cpython_only)
 
 
 class UnicodeMethodsTest(unittest.TestCase):
@@ -225,6 +226,11 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest):
 
 class UnicodeMiscTest(UnicodeDatabaseTest):
 
+    @cpython_only
+    def test_disallow_instantiation(self):
+        # Ensure that the type disallows instantiation (bpo-43916)
+        self.assertRaises(TypeError, unicodedata.UCD)
+
     def test_failed_import_during_compiling(self):
         # Issue 4367
         # Decoding \N escapes requires the unicodedata module. If it can't be
index 7f30cac64f71b93caceffd536706929372da728e..694ef6e48757b41416229dd7cacd4209ec7045c7 100644 (file)
@@ -129,6 +129,14 @@ class ExceptionTestCase(unittest.TestCase):
         with self.assertRaisesRegex(OverflowError, 'int too large'):
             zlib.decompressobj().flush(sys.maxsize + 1)
 
+    @support.cpython_only
+    def test_disallow_instantiation(self):
+        # Ensure that the type disallows instantiation (bpo-43916)
+        comp_type = type(zlib.compressobj())
+        decomp_type = type(zlib.decompressobj())
+        self.assertRaises(TypeError, comp_type)
+        self.assertRaises(TypeError, decomp_type)
+
 
 class BaseCompressTestCase(object):
     def check_big_compress_buffer(self, size, compress_func):
index 97772a04d08fe08d587d1f8ed5603d9dcde3a451..58f9c2c357b2c69fae3effbfbd9472492dfecde8 100644 (file)
@@ -414,7 +414,7 @@ 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,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
     .slots = dbmtype_spec_slots,
 };
 
index eea542e18c92d222eb5d613460d27ffddfe4d847..19cfa9b07b340d62ee6252a44bdb48cdc9670b70 100644 (file)
@@ -546,7 +546,7 @@ static PyType_Slot keyobject_type_slots[] = {
 static PyType_Spec keyobject_type_spec = {
     .name = "functools.KeyWrapper",
     .basicsize = sizeof(keyobject),
-    .flags = Py_TPFLAGS_DEFAULT,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
     .slots = keyobject_type_slots
 };
 
@@ -766,7 +766,7 @@ 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,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
     .slots = lru_list_elem_type_slots
 };
 
index 9e843acbaa6ba5d78c48469f1bc58c605687ebf4..c52190a7ed2db5d67de8773308b855064231e9f2 100644 (file)
@@ -570,7 +570,7 @@ 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,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
     .slots = gdbmtype_spec_slots,
 };
 
index 59f7551a227cd323bcdd517a6bdc819817e03112..9d0fc4ab7c03ab69de4defd0863d8c45b9501888 100644 (file)
@@ -2690,7 +2690,8 @@ static PyType_Spec pattern_spec = {
     .name = "re.Pattern",
     .basicsize = sizeof(PatternObject),
     .itemsize = sizeof(SRE_CODE),
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
+    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
+              Py_TPFLAGS_DISALLOW_INSTANTIATION),
     .slots = pattern_slots,
 };
 
@@ -2755,7 +2756,8 @@ static PyType_Spec match_spec = {
     .name = "re.Match",
     .basicsize = sizeof(MatchObject),
     .itemsize = sizeof(Py_ssize_t),
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
+    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
+              Py_TPFLAGS_DISALLOW_INSTANTIATION),
     .slots = match_slots,
 };
 
@@ -2781,7 +2783,8 @@ static PyType_Slot scanner_slots[] = {
 static PyType_Spec scanner_spec = {
     .name = "_" SRE_MODULE ".SRE_Scanner",
     .basicsize = sizeof(ScannerObject),
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
+    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
+              Py_TPFLAGS_DISALLOW_INSTANTIATION),
     .slots = scanner_slots,
 };
 
index 7feb0b8a1f1f4d4ee529e562521a1ad40f32390c..6924d6553a1ff8ffec7ef2e78b1008469d8b9b25 100644 (file)
@@ -312,7 +312,8 @@ static PyType_Slot lock_type_slots[] = {
 static PyType_Spec lock_type_spec = {
     .name = "_thread.lock",
     .basicsize = sizeof(lockobject),
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+              Py_TPFLAGS_DISALLOW_INSTANTIATION),
     .slots = lock_type_slots,
 };
 
@@ -683,7 +684,7 @@ static PyType_Slot local_dummy_type_slots[] = {
 static PyType_Spec local_dummy_type_spec = {
     .name = "_thread._localdummy",
     .basicsize = sizeof(localdummyobject),
-    .flags = Py_TPFLAGS_DEFAULT,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
     .slots = local_dummy_type_slots,
 };
 
index 9d5a45adac59d04d8b30ea12b3a8b05c19e38fa5..bc2126c8e2ee99c1c0c8b16fe87073e3daebbe0f 100644 (file)
@@ -331,7 +331,7 @@ static PyType_Slot winapi_overlapped_type_slots[] = {
 static PyType_Spec winapi_overlapped_type_spec = {
     .name = "_winapi.Overlapped",
     .basicsize = sizeof(OverlappedObject),
-    .flags = Py_TPFLAGS_DEFAULT,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
     .slots = winapi_overlapped_type_slots,
 };
 
index d65c1449eb38e5c308c9983d77bab0e3841817f2..aa5886f4af7f69b3c63edd47191a4baff4e8e6ab 100644 (file)
@@ -2987,7 +2987,8 @@ static PyType_Slot arrayiter_slots[] = {
 static PyType_Spec arrayiter_spec = {
     .name = "array.arrayiterator",
     .basicsize = sizeof(arrayiterobject),
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+              Py_TPFLAGS_DISALLOW_INSTANTIATION),
     .slots = arrayiter_slots,
 };
 
index 5070c983d402c32c60ee54ddb83cfb7d2c7c5ac7..cb7182ff21fbcd3ba261d1696d24f7bfad7c02b8 100644 (file)
@@ -748,7 +748,8 @@ static PyType_Slot multibytecodec_slots[] = {
 static PyType_Spec multibytecodec_spec = {
     .name = MODULE_NAME ".MultibyteCodec",
     .basicsize = sizeof(MultibyteCodecObject),
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+              Py_TPFLAGS_DISALLOW_INSTANTIATION),
     .slots = multibytecodec_slots,
 };
 
index a13d340a3ea0f096bcbf78ce9abe66e24045b991..7f727a86f5f47db7810b581842758df2a8150d7f 100644 (file)
@@ -1506,7 +1506,8 @@ static PyType_Slot _xml_parse_type_spec_slots[] = {
 static PyType_Spec _xml_parse_type_spec = {
     .name = "pyexpat.xmlparser",
     .basicsize = sizeof(xmlparseobject),
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+              Py_TPFLAGS_DISALLOW_INSTANTIATION),
     .slots = _xml_parse_type_spec_slots,
 };
 
index aebae7da576561f9b10f59d33ca082328fb72f7c..1a41e1c2c527f48b845c297acbc64f7c1073acbf 100644 (file)
@@ -1454,7 +1454,7 @@ static PyType_Slot ucd_type_slots[] = {
 static PyType_Spec ucd_type_spec = {
     .name = "unicodedata.UCD",
     .basicsize = sizeof(PreviousDBVersion),
-    .flags = Py_TPFLAGS_DEFAULT,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
     .slots = ucd_type_slots
 };
 
index 8a20dfcbf9e27a072a2687aea25e09795b4dbc12..fc63ca9445a8a54c557b8d575421b7012d950216 100644 (file)
@@ -1386,11 +1386,10 @@ static PyType_Slot Comptype_slots[] = {
 };
 
 static PyType_Spec Comptype_spec = {
-    "zlib.Compress",
-    sizeof(compobject),
-    0,
-    Py_TPFLAGS_DEFAULT,
-    Comptype_slots
+    .name = "zlib.Compress",
+    .basicsize = sizeof(compobject),
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
+    .slots= Comptype_slots,
 };
 
 static PyType_Slot Decomptype_slots[] = {
@@ -1401,11 +1400,10 @@ static PyType_Slot Decomptype_slots[] = {
 };
 
 static PyType_Spec Decomptype_spec = {
-    "zlib.Decompress",
-    sizeof(compobject),
-    0,
-    Py_TPFLAGS_DEFAULT,
-    Decomptype_slots
+    .name = "zlib.Decompress",
+    .basicsize = sizeof(compobject),
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
+    .slots = Decomptype_slots,
 };
 
 PyDoc_STRVAR(zlib_module_documentation,