1 | import unittest
|
---|
2 | from test import test_support
|
---|
3 | from _testcapi import getargs_keywords
|
---|
4 | import warnings
|
---|
5 |
|
---|
6 | """
|
---|
7 | > How about the following counterproposal. This also changes some of
|
---|
8 | > the other format codes to be a little more regular.
|
---|
9 | >
|
---|
10 | > Code C type Range check
|
---|
11 | >
|
---|
12 | > b unsigned char 0..UCHAR_MAX
|
---|
13 | > h signed short SHRT_MIN..SHRT_MAX
|
---|
14 | > B unsigned char none **
|
---|
15 | > H unsigned short none **
|
---|
16 | > k * unsigned long none
|
---|
17 | > I * unsigned int 0..UINT_MAX
|
---|
18 |
|
---|
19 |
|
---|
20 | > i int INT_MIN..INT_MAX
|
---|
21 | > l long LONG_MIN..LONG_MAX
|
---|
22 |
|
---|
23 | > K * unsigned long long none
|
---|
24 | > L long long LLONG_MIN..LLONG_MAX
|
---|
25 |
|
---|
26 | > Notes:
|
---|
27 | >
|
---|
28 | > * New format codes.
|
---|
29 | >
|
---|
30 | > ** Changed from previous "range-and-a-half" to "none"; the
|
---|
31 | > range-and-a-half checking wasn't particularly useful.
|
---|
32 |
|
---|
33 | Plus a C API or two, e.g. PyInt_AsLongMask() ->
|
---|
34 | unsigned long and PyInt_AsLongLongMask() -> unsigned
|
---|
35 | long long (if that exists).
|
---|
36 | """
|
---|
37 |
|
---|
38 | LARGE = 0x7FFFFFFF
|
---|
39 | VERY_LARGE = 0xFF0000121212121212121242L
|
---|
40 |
|
---|
41 | from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, INT_MAX, \
|
---|
42 | INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \
|
---|
43 | SHRT_MIN, SHRT_MAX
|
---|
44 |
|
---|
45 | # fake, they are not defined in Python's header files
|
---|
46 | LLONG_MAX = 2**63-1
|
---|
47 | LLONG_MIN = -2**63
|
---|
48 | ULLONG_MAX = 2**64-1
|
---|
49 |
|
---|
50 | class Long:
|
---|
51 | def __int__(self):
|
---|
52 | return 99L
|
---|
53 |
|
---|
54 | class Int:
|
---|
55 | def __int__(self):
|
---|
56 | return 99
|
---|
57 |
|
---|
58 | class Unsigned_TestCase(unittest.TestCase):
|
---|
59 | def test_b(self):
|
---|
60 | from _testcapi import getargs_b
|
---|
61 | # b returns 'unsigned char', and does range checking (0 ... UCHAR_MAX)
|
---|
62 | self.assertRaises(TypeError, getargs_b, 3.14)
|
---|
63 | self.assertEqual(99, getargs_b(Long()))
|
---|
64 | self.assertEqual(99, getargs_b(Int()))
|
---|
65 |
|
---|
66 | self.assertRaises(OverflowError, getargs_b, -1)
|
---|
67 | self.assertEqual(0, getargs_b(0))
|
---|
68 | self.assertEqual(UCHAR_MAX, getargs_b(UCHAR_MAX))
|
---|
69 | self.assertRaises(OverflowError, getargs_b, UCHAR_MAX + 1)
|
---|
70 |
|
---|
71 | self.assertEqual(42, getargs_b(42))
|
---|
72 | self.assertEqual(42, getargs_b(42L))
|
---|
73 | self.assertRaises(OverflowError, getargs_b, VERY_LARGE)
|
---|
74 |
|
---|
75 | def test_B(self):
|
---|
76 | from _testcapi import getargs_B
|
---|
77 | # B returns 'unsigned char', no range checking
|
---|
78 | self.assertRaises(TypeError, getargs_B, 3.14)
|
---|
79 | self.assertEqual(99, getargs_B(Long()))
|
---|
80 | self.assertEqual(99, getargs_B(Int()))
|
---|
81 |
|
---|
82 | self.assertEqual(UCHAR_MAX, getargs_B(-1))
|
---|
83 | self.assertEqual(UCHAR_MAX, getargs_B(-1L))
|
---|
84 | self.assertEqual(0, getargs_B(0))
|
---|
85 | self.assertEqual(UCHAR_MAX, getargs_B(UCHAR_MAX))
|
---|
86 | self.assertEqual(0, getargs_B(UCHAR_MAX+1))
|
---|
87 |
|
---|
88 | self.assertEqual(42, getargs_B(42))
|
---|
89 | self.assertEqual(42, getargs_B(42L))
|
---|
90 | self.assertEqual(UCHAR_MAX & VERY_LARGE, getargs_B(VERY_LARGE))
|
---|
91 |
|
---|
92 | def test_H(self):
|
---|
93 | from _testcapi import getargs_H
|
---|
94 | # H returns 'unsigned short', no range checking
|
---|
95 | self.assertRaises(TypeError, getargs_H, 3.14)
|
---|
96 | self.assertEqual(99, getargs_H(Long()))
|
---|
97 | self.assertEqual(99, getargs_H(Int()))
|
---|
98 |
|
---|
99 | self.assertEqual(USHRT_MAX, getargs_H(-1))
|
---|
100 | self.assertEqual(0, getargs_H(0))
|
---|
101 | self.assertEqual(USHRT_MAX, getargs_H(USHRT_MAX))
|
---|
102 | self.assertEqual(0, getargs_H(USHRT_MAX+1))
|
---|
103 |
|
---|
104 | self.assertEqual(42, getargs_H(42))
|
---|
105 | self.assertEqual(42, getargs_H(42L))
|
---|
106 |
|
---|
107 | self.assertEqual(VERY_LARGE & USHRT_MAX, getargs_H(VERY_LARGE))
|
---|
108 |
|
---|
109 | def test_I(self):
|
---|
110 | from _testcapi import getargs_I
|
---|
111 | # I returns 'unsigned int', no range checking
|
---|
112 | self.assertRaises(TypeError, getargs_I, 3.14)
|
---|
113 | self.assertEqual(99, getargs_I(Long()))
|
---|
114 | self.assertEqual(99, getargs_I(Int()))
|
---|
115 |
|
---|
116 | self.assertEqual(UINT_MAX, getargs_I(-1))
|
---|
117 | self.assertEqual(0, getargs_I(0))
|
---|
118 | self.assertEqual(UINT_MAX, getargs_I(UINT_MAX))
|
---|
119 | self.assertEqual(0, getargs_I(UINT_MAX+1))
|
---|
120 |
|
---|
121 | self.assertEqual(42, getargs_I(42))
|
---|
122 | self.assertEqual(42, getargs_I(42L))
|
---|
123 |
|
---|
124 | self.assertEqual(VERY_LARGE & UINT_MAX, getargs_I(VERY_LARGE))
|
---|
125 |
|
---|
126 | def test_k(self):
|
---|
127 | from _testcapi import getargs_k
|
---|
128 | # k returns 'unsigned long', no range checking
|
---|
129 | # it does not accept float, or instances with __int__
|
---|
130 | self.assertRaises(TypeError, getargs_k, 3.14)
|
---|
131 | self.assertRaises(TypeError, getargs_k, Long())
|
---|
132 | self.assertRaises(TypeError, getargs_k, Int())
|
---|
133 |
|
---|
134 | self.assertEqual(ULONG_MAX, getargs_k(-1))
|
---|
135 | self.assertEqual(0, getargs_k(0))
|
---|
136 | self.assertEqual(ULONG_MAX, getargs_k(ULONG_MAX))
|
---|
137 | self.assertEqual(0, getargs_k(ULONG_MAX+1))
|
---|
138 |
|
---|
139 | self.assertEqual(42, getargs_k(42))
|
---|
140 | self.assertEqual(42, getargs_k(42L))
|
---|
141 |
|
---|
142 | self.assertEqual(VERY_LARGE & ULONG_MAX, getargs_k(VERY_LARGE))
|
---|
143 |
|
---|
144 | class Signed_TestCase(unittest.TestCase):
|
---|
145 | def test_h(self):
|
---|
146 | from _testcapi import getargs_h
|
---|
147 | # h returns 'short', and does range checking (SHRT_MIN ... SHRT_MAX)
|
---|
148 | self.assertRaises(TypeError, getargs_h, 3.14)
|
---|
149 | self.assertEqual(99, getargs_h(Long()))
|
---|
150 | self.assertEqual(99, getargs_h(Int()))
|
---|
151 |
|
---|
152 | self.assertRaises(OverflowError, getargs_h, SHRT_MIN-1)
|
---|
153 | self.assertEqual(SHRT_MIN, getargs_h(SHRT_MIN))
|
---|
154 | self.assertEqual(SHRT_MAX, getargs_h(SHRT_MAX))
|
---|
155 | self.assertRaises(OverflowError, getargs_h, SHRT_MAX+1)
|
---|
156 |
|
---|
157 | self.assertEqual(42, getargs_h(42))
|
---|
158 | self.assertEqual(42, getargs_h(42L))
|
---|
159 | self.assertRaises(OverflowError, getargs_h, VERY_LARGE)
|
---|
160 |
|
---|
161 | def test_i(self):
|
---|
162 | from _testcapi import getargs_i
|
---|
163 | # i returns 'int', and does range checking (INT_MIN ... INT_MAX)
|
---|
164 | self.assertRaises(TypeError, getargs_i, 3.14)
|
---|
165 | self.assertEqual(99, getargs_i(Long()))
|
---|
166 | self.assertEqual(99, getargs_i(Int()))
|
---|
167 |
|
---|
168 | self.assertRaises(OverflowError, getargs_i, INT_MIN-1)
|
---|
169 | self.assertEqual(INT_MIN, getargs_i(INT_MIN))
|
---|
170 | self.assertEqual(INT_MAX, getargs_i(INT_MAX))
|
---|
171 | self.assertRaises(OverflowError, getargs_i, INT_MAX+1)
|
---|
172 |
|
---|
173 | self.assertEqual(42, getargs_i(42))
|
---|
174 | self.assertEqual(42, getargs_i(42L))
|
---|
175 | self.assertRaises(OverflowError, getargs_i, VERY_LARGE)
|
---|
176 |
|
---|
177 | def test_l(self):
|
---|
178 | from _testcapi import getargs_l
|
---|
179 | # l returns 'long', and does range checking (LONG_MIN ... LONG_MAX)
|
---|
180 | self.assertRaises(TypeError, getargs_l, 3.14)
|
---|
181 | self.assertEqual(99, getargs_l(Long()))
|
---|
182 | self.assertEqual(99, getargs_l(Int()))
|
---|
183 |
|
---|
184 | self.assertRaises(OverflowError, getargs_l, LONG_MIN-1)
|
---|
185 | self.assertEqual(LONG_MIN, getargs_l(LONG_MIN))
|
---|
186 | self.assertEqual(LONG_MAX, getargs_l(LONG_MAX))
|
---|
187 | self.assertRaises(OverflowError, getargs_l, LONG_MAX+1)
|
---|
188 |
|
---|
189 | self.assertEqual(42, getargs_l(42))
|
---|
190 | self.assertEqual(42, getargs_l(42L))
|
---|
191 | self.assertRaises(OverflowError, getargs_l, VERY_LARGE)
|
---|
192 |
|
---|
193 | def test_n(self):
|
---|
194 | from _testcapi import getargs_n
|
---|
195 | # n returns 'Py_ssize_t', and does range checking
|
---|
196 | # (PY_SSIZE_T_MIN ... PY_SSIZE_T_MAX)
|
---|
197 | self.assertRaises(TypeError, getargs_n, 3.14)
|
---|
198 | self.assertEqual(99, getargs_n(Long()))
|
---|
199 | self.assertEqual(99, getargs_n(Int()))
|
---|
200 |
|
---|
201 | self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MIN-1)
|
---|
202 | self.assertEqual(PY_SSIZE_T_MIN, getargs_n(PY_SSIZE_T_MIN))
|
---|
203 | self.assertEqual(PY_SSIZE_T_MAX, getargs_n(PY_SSIZE_T_MAX))
|
---|
204 | self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MAX+1)
|
---|
205 |
|
---|
206 | self.assertEqual(42, getargs_n(42))
|
---|
207 | self.assertEqual(42, getargs_n(42L))
|
---|
208 | self.assertRaises(OverflowError, getargs_n, VERY_LARGE)
|
---|
209 |
|
---|
210 |
|
---|
211 | class LongLong_TestCase(unittest.TestCase):
|
---|
212 | def test_L(self):
|
---|
213 | from _testcapi import getargs_L
|
---|
214 | # L returns 'long long', and does range checking (LLONG_MIN
|
---|
215 | # ... LLONG_MAX)
|
---|
216 | with warnings.catch_warnings():
|
---|
217 | warnings.filterwarnings(
|
---|
218 | "ignore",
|
---|
219 | category=DeprecationWarning,
|
---|
220 | message=".*integer argument expected, got float",
|
---|
221 | module=__name__)
|
---|
222 | self.assertEqual(3, getargs_L(3.14))
|
---|
223 | with warnings.catch_warnings():
|
---|
224 | warnings.filterwarnings(
|
---|
225 | "error",
|
---|
226 | category=DeprecationWarning,
|
---|
227 | message=".*integer argument expected, got float",
|
---|
228 | module="unittest")
|
---|
229 | self.assertRaises(DeprecationWarning, getargs_L, 3.14)
|
---|
230 |
|
---|
231 | self.assertRaises(TypeError, getargs_L, "Hello")
|
---|
232 | self.assertEqual(99, getargs_L(Long()))
|
---|
233 | self.assertEqual(99, getargs_L(Int()))
|
---|
234 |
|
---|
235 | self.assertRaises(OverflowError, getargs_L, LLONG_MIN-1)
|
---|
236 | self.assertEqual(LLONG_MIN, getargs_L(LLONG_MIN))
|
---|
237 | self.assertEqual(LLONG_MAX, getargs_L(LLONG_MAX))
|
---|
238 | self.assertRaises(OverflowError, getargs_L, LLONG_MAX+1)
|
---|
239 |
|
---|
240 | self.assertEqual(42, getargs_L(42))
|
---|
241 | self.assertEqual(42, getargs_L(42L))
|
---|
242 | self.assertRaises(OverflowError, getargs_L, VERY_LARGE)
|
---|
243 |
|
---|
244 | def test_K(self):
|
---|
245 | from _testcapi import getargs_K
|
---|
246 | # K return 'unsigned long long', no range checking
|
---|
247 | self.assertRaises(TypeError, getargs_K, 3.14)
|
---|
248 | self.assertRaises(TypeError, getargs_K, Long())
|
---|
249 | self.assertRaises(TypeError, getargs_K, Int())
|
---|
250 | self.assertEqual(ULLONG_MAX, getargs_K(ULLONG_MAX))
|
---|
251 | self.assertEqual(0, getargs_K(0))
|
---|
252 | self.assertEqual(0, getargs_K(ULLONG_MAX+1))
|
---|
253 |
|
---|
254 | self.assertEqual(42, getargs_K(42))
|
---|
255 | self.assertEqual(42, getargs_K(42L))
|
---|
256 |
|
---|
257 | self.assertEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE))
|
---|
258 |
|
---|
259 |
|
---|
260 | class Tuple_TestCase(unittest.TestCase):
|
---|
261 | def test_tuple(self):
|
---|
262 | from _testcapi import getargs_tuple
|
---|
263 |
|
---|
264 | ret = getargs_tuple(1, (2, 3))
|
---|
265 | self.assertEqual(ret, (1,2,3))
|
---|
266 |
|
---|
267 | # make sure invalid tuple arguments are handled correctly
|
---|
268 | class seq:
|
---|
269 | def __len__(self):
|
---|
270 | return 2
|
---|
271 | def __getitem__(self, n):
|
---|
272 | raise ValueError
|
---|
273 | self.assertRaises(TypeError, getargs_tuple, 1, seq())
|
---|
274 |
|
---|
275 | class Keywords_TestCase(unittest.TestCase):
|
---|
276 | def test_positional_args(self):
|
---|
277 | # using all positional args
|
---|
278 | self.assertEqual(
|
---|
279 | getargs_keywords((1,2), 3, (4,(5,6)), (7,8,9), 10),
|
---|
280 | (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
---|
281 | )
|
---|
282 | def test_mixed_args(self):
|
---|
283 | # positional and keyword args
|
---|
284 | self.assertEqual(
|
---|
285 | getargs_keywords((1,2), 3, (4,(5,6)), arg4=(7,8,9), arg5=10),
|
---|
286 | (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
---|
287 | )
|
---|
288 | def test_keyword_args(self):
|
---|
289 | # all keywords
|
---|
290 | self.assertEqual(
|
---|
291 | getargs_keywords(arg1=(1,2), arg2=3, arg3=(4,(5,6)), arg4=(7,8,9), arg5=10),
|
---|
292 | (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
---|
293 | )
|
---|
294 | def test_optional_args(self):
|
---|
295 | # missing optional keyword args, skipping tuples
|
---|
296 | self.assertEqual(
|
---|
297 | getargs_keywords(arg1=(1,2), arg2=3, arg5=10),
|
---|
298 | (1, 2, 3, -1, -1, -1, -1, -1, -1, 10)
|
---|
299 | )
|
---|
300 | def test_required_args(self):
|
---|
301 | # required arg missing
|
---|
302 | try:
|
---|
303 | getargs_keywords(arg1=(1,2))
|
---|
304 | except TypeError, err:
|
---|
305 | self.assertEqual(str(err), "Required argument 'arg2' (pos 2) not found")
|
---|
306 | else:
|
---|
307 | self.fail('TypeError should have been raised')
|
---|
308 | def test_too_many_args(self):
|
---|
309 | try:
|
---|
310 | getargs_keywords((1,2),3,(4,(5,6)),(7,8,9),10,111)
|
---|
311 | except TypeError, err:
|
---|
312 | self.assertEqual(str(err), "function takes at most 5 arguments (6 given)")
|
---|
313 | else:
|
---|
314 | self.fail('TypeError should have been raised')
|
---|
315 | def test_invalid_keyword(self):
|
---|
316 | # extraneous keyword arg
|
---|
317 | try:
|
---|
318 | getargs_keywords((1,2),3,arg5=10,arg666=666)
|
---|
319 | except TypeError, err:
|
---|
320 | self.assertEqual(str(err), "'arg666' is an invalid keyword argument for this function")
|
---|
321 | else:
|
---|
322 | self.fail('TypeError should have been raised')
|
---|
323 |
|
---|
324 | def test_main():
|
---|
325 | tests = [Signed_TestCase, Unsigned_TestCase, Tuple_TestCase, Keywords_TestCase]
|
---|
326 | try:
|
---|
327 | from _testcapi import getargs_L, getargs_K
|
---|
328 | except ImportError:
|
---|
329 | pass # PY_LONG_LONG not available
|
---|
330 | else:
|
---|
331 | tests.append(LongLong_TestCase)
|
---|
332 | test_support.run_unittest(*tests)
|
---|
333 |
|
---|
334 | if __name__ == "__main__":
|
---|
335 | test_main()
|
---|