Skip to content

Commit 9746cda

Browse files
author
Erlend Egeberg Aasland
authored
bpo-43916: Apply Py_TPFLAGS_DISALLOW_INSTANTIATION to selected types (GH-25748)
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
1 parent 387397f commit 9746cda

20 files changed

+87
-28
lines changed

Lib/test/test_array.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ def test_bad_constructor(self):
4040
self.assertRaises(TypeError, array.array, 'xx')
4141
self.assertRaises(ValueError, array.array, 'x')
4242

43+
@support.cpython_only
44+
def test_disallow_instantiation(self):
45+
# Ensure that the type disallows instantiation (bpo-43916)
46+
tp = type(iter(array.array('I')))
47+
self.assertRaises(TypeError, tp)
48+
4349
@support.cpython_only
4450
def test_immutable(self):
4551
# bpo-43908: check that array.array is immutable

Lib/test/test_curses.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import tempfile
77
import unittest
88

9-
from test.support import requires, verbose, SaveSignals
9+
from test.support import requires, verbose, SaveSignals, cpython_only
1010
from test.support.import_helper import import_module
1111

1212
# Optionally test curses module. This currently requires that the
@@ -1046,8 +1046,10 @@ def __del__(self):
10461046
panel.set_userptr(A())
10471047
panel.set_userptr(None)
10481048

1049+
@cpython_only
10491050
@requires_curses_func('panel')
1050-
def test_new_curses_panel(self):
1051+
def test_disallow_instantiation(self):
1052+
# Ensure that the type disallows instantiation (bpo-43916)
10511053
w = curses.newwin(10, 10)
10521054
panel = curses.panel.new_panel(w)
10531055
self.assertRaises(TypeError, type(panel))

Lib/test/test_dbm_gnu.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from test import support
2-
from test.support import import_helper
2+
from test.support import import_helper, cpython_only
33
gdbm = import_helper.import_module("dbm.gnu") #skip if not supported
44
import unittest
55
import os
@@ -27,6 +27,13 @@ def tearDown(self):
2727
self.g.close()
2828
unlink(filename)
2929

30+
@cpython_only
31+
def test_disallow_instantiation(self):
32+
# Ensure that the type disallows instantiation (bpo-43916)
33+
self.g = gdbm.open(filename, 'c')
34+
tp = type(self.g)
35+
self.assertRaises(TypeError, tp)
36+
3037
def test_key_methods(self):
3138
self.g = gdbm.open(filename, 'c')
3239
self.assertEqual(self.g.keys(), [])

Lib/test/test_functools.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,12 @@ class TestCmpToKeyC(TestCmpToKey, unittest.TestCase):
948948
if c_functools:
949949
cmp_to_key = c_functools.cmp_to_key
950950

951+
@support.cpython_only
952+
def test_disallow_instantiation(self):
953+
# Ensure that the type disallows instantiation (bpo-43916)
954+
tp = type(c_functools.cmp_to_key(None))
955+
self.assertRaises(TypeError, tp)
956+
951957

952958
class TestCmpToKeyPy(TestCmpToKey, unittest.TestCase):
953959
cmp_to_key = staticmethod(py_functools.cmp_to_key)

Lib/test/test_re.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,15 @@ def test_signedness(self):
22152215
self.assertGreaterEqual(sre_compile.MAXREPEAT, 0)
22162216
self.assertGreaterEqual(sre_compile.MAXGROUPS, 0)
22172217

2218+
@cpython_only
2219+
def test_disallow_instantiation(self):
2220+
# Ensure that the type disallows instantiation (bpo-43916)
2221+
self.assertRaises(TypeError, re.Match)
2222+
self.assertRaises(TypeError, re.Pattern)
2223+
pat = re.compile("")
2224+
tp = type(pat.scanner(""))
2225+
self.assertRaises(TypeError, tp)
2226+
22182227

22192228
class ExternalTests(unittest.TestCase):
22202229

Lib/test/test_tcl.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,8 +736,11 @@ def check(value):
736736
check('{\n')
737737
check('}\n')
738738

739+
@support.cpython_only
739740
def test_new_tcl_obj(self):
740741
self.assertRaises(TypeError, _tkinter.Tcl_Obj)
742+
self.assertRaises(TypeError, _tkinter.TkttType)
743+
self.assertRaises(TypeError, _tkinter.TkappType)
741744

742745
class BigmemTclTest(unittest.TestCase):
743746

Lib/test/test_threading.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ def func(): pass
119119
thread = threading.Thread(target=func)
120120
self.assertEqual(thread.name, "Thread-5 (func)")
121121

122+
@cpython_only
123+
def test_disallow_instantiation(self):
124+
# Ensure that the type disallows instantiation (bpo-43916)
125+
lock = threading.Lock()
126+
tp = type(lock)
127+
self.assertRaises(TypeError, tp)
128+
122129
# Create a bunch of threads, let each do some work, wait until all are
123130
# done.
124131
def test_various_ops(self):

Lib/test/test_unicodedata.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
import sys
1212
import unicodedata
1313
import unittest
14-
from test.support import open_urlresource, requires_resource, script_helper
14+
from test.support import (open_urlresource, requires_resource, script_helper,
15+
cpython_only)
1516

1617

1718
class UnicodeMethodsTest(unittest.TestCase):
@@ -225,6 +226,11 @@ def test_east_asian_width_9_0_changes(self):
225226

226227
class UnicodeMiscTest(UnicodeDatabaseTest):
227228

229+
@cpython_only
230+
def test_disallow_instantiation(self):
231+
# Ensure that the type disallows instantiation (bpo-43916)
232+
self.assertRaises(TypeError, unicodedata.UCD)
233+
228234
def test_failed_import_during_compiling(self):
229235
# Issue 4367
230236
# Decoding \N escapes requires the unicodedata module. If it can't be

Lib/test/test_zlib.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ def test_overflow(self):
129129
with self.assertRaisesRegex(OverflowError, 'int too large'):
130130
zlib.decompressobj().flush(sys.maxsize + 1)
131131

132+
@support.cpython_only
133+
def test_disallow_instantiation(self):
134+
# Ensure that the type disallows instantiation (bpo-43916)
135+
comp_type = type(zlib.compressobj())
136+
decomp_type = type(zlib.decompressobj())
137+
self.assertRaises(TypeError, comp_type)
138+
self.assertRaises(TypeError, decomp_type)
139+
132140

133141
class BaseCompressTestCase(object):
134142
def check_big_compress_buffer(self, size, compress_func):

Modules/_dbmmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ static PyType_Spec dbmtype_spec = {
414414
// dbmtype_spec does not have Py_TPFLAGS_BASETYPE flag
415415
// which prevents to create a subclass.
416416
// So calling PyType_GetModuleState() in this file is always safe.
417-
.flags = Py_TPFLAGS_DEFAULT,
417+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
418418
.slots = dbmtype_spec_slots,
419419
};
420420

Modules/_functoolsmodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ static PyType_Slot keyobject_type_slots[] = {
546546
static PyType_Spec keyobject_type_spec = {
547547
.name = "functools.KeyWrapper",
548548
.basicsize = sizeof(keyobject),
549-
.flags = Py_TPFLAGS_DEFAULT,
549+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
550550
.slots = keyobject_type_slots
551551
};
552552

@@ -766,7 +766,7 @@ static PyType_Slot lru_list_elem_type_slots[] = {
766766
static PyType_Spec lru_list_elem_type_spec = {
767767
.name = "functools._lru_list_elem",
768768
.basicsize = sizeof(lru_list_elem),
769-
.flags = Py_TPFLAGS_DEFAULT,
769+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
770770
.slots = lru_list_elem_type_slots
771771
};
772772

Modules/_gdbmmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ static PyType_Spec gdbmtype_spec = {
570570
// dbmtype_spec does not have Py_TPFLAGS_BASETYPE flag
571571
// which prevents to create a subclass.
572572
// So calling PyType_GetModuleState() in this file is always safe.
573-
.flags = Py_TPFLAGS_DEFAULT,
573+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
574574
.slots = gdbmtype_spec_slots,
575575
};
576576

Modules/_sre.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2690,7 +2690,8 @@ static PyType_Spec pattern_spec = {
26902690
.name = "re.Pattern",
26912691
.basicsize = sizeof(PatternObject),
26922692
.itemsize = sizeof(SRE_CODE),
2693-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
2693+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
2694+
Py_TPFLAGS_DISALLOW_INSTANTIATION),
26942695
.slots = pattern_slots,
26952696
};
26962697

@@ -2755,7 +2756,8 @@ static PyType_Spec match_spec = {
27552756
.name = "re.Match",
27562757
.basicsize = sizeof(MatchObject),
27572758
.itemsize = sizeof(Py_ssize_t),
2758-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
2759+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
2760+
Py_TPFLAGS_DISALLOW_INSTANTIATION),
27592761
.slots = match_slots,
27602762
};
27612763

@@ -2781,7 +2783,8 @@ static PyType_Slot scanner_slots[] = {
27812783
static PyType_Spec scanner_spec = {
27822784
.name = "_" SRE_MODULE ".SRE_Scanner",
27832785
.basicsize = sizeof(ScannerObject),
2784-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
2786+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
2787+
Py_TPFLAGS_DISALLOW_INSTANTIATION),
27852788
.slots = scanner_slots,
27862789
};
27872790

Modules/_threadmodule.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,8 @@ static PyType_Slot lock_type_slots[] = {
312312
static PyType_Spec lock_type_spec = {
313313
.name = "_thread.lock",
314314
.basicsize = sizeof(lockobject),
315-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
315+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
316+
Py_TPFLAGS_DISALLOW_INSTANTIATION),
316317
.slots = lock_type_slots,
317318
};
318319

@@ -683,7 +684,7 @@ static PyType_Slot local_dummy_type_slots[] = {
683684
static PyType_Spec local_dummy_type_spec = {
684685
.name = "_thread._localdummy",
685686
.basicsize = sizeof(localdummyobject),
686-
.flags = Py_TPFLAGS_DEFAULT,
687+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
687688
.slots = local_dummy_type_slots,
688689
};
689690

Modules/_winapi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ static PyType_Slot winapi_overlapped_type_slots[] = {
331331
static PyType_Spec winapi_overlapped_type_spec = {
332332
.name = "_winapi.Overlapped",
333333
.basicsize = sizeof(OverlappedObject),
334-
.flags = Py_TPFLAGS_DEFAULT,
334+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
335335
.slots = winapi_overlapped_type_slots,
336336
};
337337

Modules/arraymodule.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2987,7 +2987,8 @@ static PyType_Slot arrayiter_slots[] = {
29872987
static PyType_Spec arrayiter_spec = {
29882988
.name = "array.arrayiterator",
29892989
.basicsize = sizeof(arrayiterobject),
2990-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
2990+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2991+
Py_TPFLAGS_DISALLOW_INSTANTIATION),
29912992
.slots = arrayiter_slots,
29922993
};
29932994

Modules/cjkcodecs/multibytecodec.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,8 @@ static PyType_Slot multibytecodec_slots[] = {
748748
static PyType_Spec multibytecodec_spec = {
749749
.name = MODULE_NAME ".MultibyteCodec",
750750
.basicsize = sizeof(MultibyteCodecObject),
751-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
751+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
752+
Py_TPFLAGS_DISALLOW_INSTANTIATION),
752753
.slots = multibytecodec_slots,
753754
};
754755

Modules/pyexpat.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1506,7 +1506,8 @@ static PyType_Slot _xml_parse_type_spec_slots[] = {
15061506
static PyType_Spec _xml_parse_type_spec = {
15071507
.name = "pyexpat.xmlparser",
15081508
.basicsize = sizeof(xmlparseobject),
1509-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1509+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1510+
Py_TPFLAGS_DISALLOW_INSTANTIATION),
15101511
.slots = _xml_parse_type_spec_slots,
15111512
};
15121513

Modules/unicodedata.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,7 @@ static PyType_Slot ucd_type_slots[] = {
14541454
static PyType_Spec ucd_type_spec = {
14551455
.name = "unicodedata.UCD",
14561456
.basicsize = sizeof(PreviousDBVersion),
1457-
.flags = Py_TPFLAGS_DEFAULT,
1457+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
14581458
.slots = ucd_type_slots
14591459
};
14601460

Modules/zlibmodule.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,11 +1386,10 @@ static PyType_Slot Comptype_slots[] = {
13861386
};
13871387

13881388
static PyType_Spec Comptype_spec = {
1389-
"zlib.Compress",
1390-
sizeof(compobject),
1391-
0,
1392-
Py_TPFLAGS_DEFAULT,
1393-
Comptype_slots
1389+
.name = "zlib.Compress",
1390+
.basicsize = sizeof(compobject),
1391+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
1392+
.slots= Comptype_slots,
13941393
};
13951394

13961395
static PyType_Slot Decomptype_slots[] = {
@@ -1401,11 +1400,10 @@ static PyType_Slot Decomptype_slots[] = {
14011400
};
14021401

14031402
static PyType_Spec Decomptype_spec = {
1404-
"zlib.Decompress",
1405-
sizeof(compobject),
1406-
0,
1407-
Py_TPFLAGS_DEFAULT,
1408-
Decomptype_slots
1403+
.name = "zlib.Decompress",
1404+
.basicsize = sizeof(compobject),
1405+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
1406+
.slots = Decomptype_slots,
14091407
};
14101408

14111409
PyDoc_STRVAR(zlib_module_documentation,

0 commit comments

Comments
 (0)