Skip to content

Commit 8987814

Browse files
[3.11] pythongh-114392: Improve test_capi.test_structmembers (pythonGH-114393) (pythonGH-115030)
Test all integer member types with extreme values and values outside of the valid range. Test support of integer-like objects. Test warnings for wrapped out values. (cherry picked from commit 15f6f04)
1 parent b3f0108 commit 8987814

File tree

1 file changed

+89
-99
lines changed

1 file changed

+89
-99
lines changed

Lib/test/test_capi/test_structmembers.py

Lines changed: 89 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -37,74 +37,111 @@ def __index__(self):
3737

3838
class ReadWriteTests(unittest.TestCase):
3939

40+
def _test_write(self, name, value, expected=None):
41+
if expected is None:
42+
expected = value
43+
setattr(ts, name, value)
44+
self.assertEqual(getattr(ts, name), expected)
45+
46+
def _test_warn(self, name, value, expected=None):
47+
self.assertWarns(RuntimeWarning, setattr, ts, name, value)
48+
if expected is not None:
49+
self.assertEqual(getattr(ts, name), expected)
50+
51+
def _test_overflow(self, name, value):
52+
self.assertRaises(OverflowError, setattr, ts, name, value)
53+
54+
def _test_int_range(self, name, minval, maxval, *, hardlimit=None,
55+
indexlimit=None):
56+
if hardlimit is None:
57+
hardlimit = (minval, maxval)
58+
self._test_write(name, minval)
59+
self._test_write(name, maxval)
60+
hardminval, hardmaxval = hardlimit
61+
self._test_overflow(name, hardminval-1)
62+
self._test_overflow(name, hardmaxval+1)
63+
self._test_overflow(name, 2**1000)
64+
self._test_overflow(name, -2**1000)
65+
if hardminval < minval:
66+
self._test_warn(name, hardminval)
67+
self._test_warn(name, minval-1, maxval)
68+
if maxval < hardmaxval:
69+
self._test_warn(name, maxval+1, minval)
70+
self._test_warn(name, hardmaxval)
71+
72+
if indexlimit is None:
73+
indexlimit = hardlimit
74+
if not indexlimit:
75+
self.assertRaises(TypeError, setattr, ts, name, Index(minval))
76+
self.assertRaises(TypeError, setattr, ts, name, Index(maxval))
77+
else:
78+
hardminindexval, hardmaxindexval = indexlimit
79+
self._test_write(name, Index(minval), minval)
80+
if minval < hardminindexval:
81+
self._test_write(name, Index(hardminindexval), hardminindexval)
82+
if maxval < hardmaxindexval:
83+
self._test_write(name, Index(maxval), maxval)
84+
else:
85+
self._test_write(name, Index(hardmaxindexval), hardmaxindexval)
86+
self._test_overflow(name, Index(hardminindexval-1))
87+
if name in ('T_UINT', 'T_ULONG'):
88+
self.assertRaises(TypeError, setattr, ts, name,
89+
Index(hardmaxindexval+1))
90+
self.assertRaises(TypeError, setattr, ts, name,
91+
Index(2**1000))
92+
else:
93+
self._test_overflow(name, Index(hardmaxindexval+1))
94+
self._test_overflow(name, Index(2**1000))
95+
self._test_overflow(name, Index(-2**1000))
96+
if hardminindexval < minval and name != 'T_ULONGLONG':
97+
self._test_warn(name, Index(hardminindexval))
98+
self._test_warn(name, Index(minval-1))
99+
if maxval < hardmaxindexval:
100+
self._test_warn(name, Index(maxval+1))
101+
self._test_warn(name, Index(hardmaxindexval))
102+
40103
def test_bool(self):
41104
ts.T_BOOL = True
42-
self.assertEqual(ts.T_BOOL, True)
105+
self.assertIs(ts.T_BOOL, True)
43106
ts.T_BOOL = False
44-
self.assertEqual(ts.T_BOOL, False)
107+
self.assertIs(ts.T_BOOL, False)
45108
self.assertRaises(TypeError, setattr, ts, 'T_BOOL', 1)
109+
self.assertRaises(TypeError, setattr, ts, 'T_BOOL', 0)
110+
self.assertRaises(TypeError, setattr, ts, 'T_BOOL', None)
46111

47112
def test_byte(self):
48-
ts.T_BYTE = CHAR_MAX
49-
self.assertEqual(ts.T_BYTE, CHAR_MAX)
50-
ts.T_BYTE = CHAR_MIN
51-
self.assertEqual(ts.T_BYTE, CHAR_MIN)
52-
ts.T_UBYTE = UCHAR_MAX
53-
self.assertEqual(ts.T_UBYTE, UCHAR_MAX)
113+
self._test_int_range('T_BYTE', CHAR_MIN, CHAR_MAX,
114+
hardlimit=(LONG_MIN, LONG_MAX))
115+
self._test_int_range('T_UBYTE', 0, UCHAR_MAX,
116+
hardlimit=(LONG_MIN, LONG_MAX))
54117

55118
def test_short(self):
56-
ts.T_SHORT = SHRT_MAX
57-
self.assertEqual(ts.T_SHORT, SHRT_MAX)
58-
ts.T_SHORT = SHRT_MIN
59-
self.assertEqual(ts.T_SHORT, SHRT_MIN)
60-
ts.T_USHORT = USHRT_MAX
61-
self.assertEqual(ts.T_USHORT, USHRT_MAX)
119+
self._test_int_range('T_SHORT', SHRT_MIN, SHRT_MAX,
120+
hardlimit=(LONG_MIN, LONG_MAX))
121+
self._test_int_range('T_USHORT', 0, USHRT_MAX,
122+
hardlimit=(LONG_MIN, LONG_MAX))
62123

63124
def test_int(self):
64-
ts.T_INT = INT_MAX
65-
self.assertEqual(ts.T_INT, INT_MAX)
66-
ts.T_INT = INT_MIN
67-
self.assertEqual(ts.T_INT, INT_MIN)
68-
ts.T_UINT = UINT_MAX
69-
self.assertEqual(ts.T_UINT, UINT_MAX)
70-
ts.T_UINT = Index(0)
71-
self.assertEqual(ts.T_UINT, 0)
72-
ts.T_UINT = Index(INT_MAX)
73-
self.assertEqual(ts.T_UINT, INT_MAX)
125+
self._test_int_range('T_INT', INT_MIN, INT_MAX,
126+
hardlimit=(LONG_MIN, LONG_MAX))
127+
self._test_int_range('T_UINT', 0, UINT_MAX,
128+
hardlimit=(LONG_MIN, ULONG_MAX),
129+
indexlimit=(LONG_MIN, LONG_MAX))
74130

75131
def test_long(self):
76-
ts.T_LONG = LONG_MAX
77-
self.assertEqual(ts.T_LONG, LONG_MAX)
78-
ts.T_LONG = LONG_MIN
79-
self.assertEqual(ts.T_LONG, LONG_MIN)
80-
ts.T_ULONG = ULONG_MAX
81-
self.assertEqual(ts.T_ULONG, ULONG_MAX)
82-
ts.T_ULONG = Index(0)
83-
self.assertEqual(ts.T_ULONG, 0)
84-
ts.T_ULONG = Index(LONG_MAX)
85-
self.assertEqual(ts.T_ULONG, LONG_MAX)
132+
self._test_int_range('T_LONG', LONG_MIN, LONG_MAX)
133+
self._test_int_range('T_ULONG', 0, ULONG_MAX,
134+
hardlimit=(LONG_MIN, ULONG_MAX),
135+
indexlimit=(LONG_MIN, LONG_MAX))
86136

87137
def test_py_ssize_t(self):
88-
ts.T_PYSSIZET = PY_SSIZE_T_MAX
89-
self.assertEqual(ts.T_PYSSIZET, PY_SSIZE_T_MAX)
90-
ts.T_PYSSIZET = PY_SSIZE_T_MIN
91-
self.assertEqual(ts.T_PYSSIZET, PY_SSIZE_T_MIN)
138+
self._test_int_range('T_PYSSIZET', PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, indexlimit=False)
92139

93140
@unittest.skipUnless(hasattr(ts, "T_LONGLONG"), "long long not present")
94141
def test_longlong(self):
95-
ts.T_LONGLONG = LLONG_MAX
96-
self.assertEqual(ts.T_LONGLONG, LLONG_MAX)
97-
ts.T_LONGLONG = LLONG_MIN
98-
self.assertEqual(ts.T_LONGLONG, LLONG_MIN)
99-
100-
ts.T_ULONGLONG = ULLONG_MAX
101-
self.assertEqual(ts.T_ULONGLONG, ULLONG_MAX)
102-
103-
## make sure these will accept a plain int as well as a long
104-
ts.T_LONGLONG = 3
105-
self.assertEqual(ts.T_LONGLONG, 3)
106-
ts.T_ULONGLONG = 4
107-
self.assertEqual(ts.T_ULONGLONG, 4)
142+
self._test_int_range('T_LONGLONG', LLONG_MIN, LLONG_MAX)
143+
self._test_int_range('T_ULONGLONG', 0, ULLONG_MAX,
144+
indexlimit=(LONG_MIN, LONG_MAX))
108145

109146
def test_bad_assignments(self):
110147
integer_attributes = [
@@ -113,10 +150,9 @@ def test_bad_assignments(self):
113150
'T_SHORT', 'T_USHORT',
114151
'T_INT', 'T_UINT',
115152
'T_LONG', 'T_ULONG',
153+
'T_LONGLONG', 'T_ULONGLONG',
116154
'T_PYSSIZET'
117155
]
118-
if hasattr(ts, 'T_LONGLONG'):
119-
integer_attributes.extend(['T_LONGLONG', 'T_ULONGLONG'])
120156

121157
# issue8014: this produced 'bad argument to internal function'
122158
# internal error
@@ -130,51 +166,5 @@ def test_inplace_string(self):
130166
self.assertRaises(TypeError, delattr, ts, "T_STRING_INPLACE")
131167

132168

133-
class TestWarnings(unittest.TestCase):
134-
135-
def test_byte_max(self):
136-
with warnings_helper.check_warnings(('', RuntimeWarning)):
137-
ts.T_BYTE = CHAR_MAX+1
138-
139-
def test_byte_min(self):
140-
with warnings_helper.check_warnings(('', RuntimeWarning)):
141-
ts.T_BYTE = CHAR_MIN-1
142-
143-
def test_ubyte_max(self):
144-
with warnings_helper.check_warnings(('', RuntimeWarning)):
145-
ts.T_UBYTE = UCHAR_MAX+1
146-
147-
def test_short_max(self):
148-
with warnings_helper.check_warnings(('', RuntimeWarning)):
149-
ts.T_SHORT = SHRT_MAX+1
150-
151-
def test_short_min(self):
152-
with warnings_helper.check_warnings(('', RuntimeWarning)):
153-
ts.T_SHORT = SHRT_MIN-1
154-
155-
def test_ushort_max(self):
156-
with warnings_helper.check_warnings(('', RuntimeWarning)):
157-
ts.T_USHORT = USHRT_MAX+1
158-
159-
def test_int(self):
160-
if LONG_MIN < INT_MIN:
161-
with self.assertWarns(RuntimeWarning):
162-
ts.T_INT = INT_MIN-1
163-
if LONG_MAX > INT_MAX:
164-
with self.assertWarns(RuntimeWarning):
165-
ts.T_INT = INT_MAX+1
166-
167-
def test_uint(self):
168-
with self.assertWarns(RuntimeWarning):
169-
ts.T_UINT = -1
170-
if ULONG_MAX > UINT_MAX:
171-
with self.assertWarns(RuntimeWarning):
172-
ts.T_UINT = UINT_MAX+1
173-
174-
def test_ulong(self):
175-
with self.assertWarns(RuntimeWarning):
176-
ts.T_ULONG = -1
177-
178-
179169
if __name__ == "__main__":
180170
unittest.main()

0 commit comments

Comments
 (0)