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