python (3.12.0)
1 import unittest
2 import sys
3 from collections import OrderedDict
4 from test import support
5 from test.support import import_helper
6 import _testcapi
7
8
9 NULL = None
10
11 class ESC[4;38;5;81mTestObject:
12 @property
13 def evil(self):
14 raise RuntimeError('do not get evil')
15 @evil.setter
16 def evil(self, value):
17 raise RuntimeError('do not set evil')
18 @evil.deleter
19 def evil(self):
20 raise RuntimeError('do not del evil')
21
22 class ESC[4;38;5;81mProxyGetItem:
23 def __init__(self, obj):
24 self.obj = obj
25 def __getitem__(self, key):
26 return self.obj[key]
27
28 class ESC[4;38;5;81mProxySetItem:
29 def __init__(self, obj):
30 self.obj = obj
31 def __setitem__(self, key, value):
32 self.obj[key] = value
33
34 class ESC[4;38;5;81mProxyDelItem:
35 def __init__(self, obj):
36 self.obj = obj
37 def __delitem__(self, key):
38 del self.obj[key]
39
40 def gen():
41 yield 'a'
42 yield 'b'
43 yield 'c'
44
45
46 class ESC[4;38;5;81mCAPITest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
47
48 def test_object_getattr(self):
49 xgetattr = _testcapi.object_getattr
50 obj = TestObject()
51 obj.a = 11
52 setattr(obj, '\U0001f40d', 22)
53 self.assertEqual(xgetattr(obj, 'a'), 11)
54 self.assertRaises(AttributeError, xgetattr, obj, 'b')
55 self.assertEqual(xgetattr(obj, '\U0001f40d'), 22)
56
57 self.assertRaises(RuntimeError, xgetattr, obj, 'evil')
58 self.assertRaises(TypeError, xgetattr, obj, 1)
59 # CRASHES xgetattr(obj, NULL)
60 # CRASHES xgetattr(NULL, 'a')
61
62 def test_object_getattrstring(self):
63 getattrstring = _testcapi.object_getattrstring
64 obj = TestObject()
65 obj.a = 11
66 setattr(obj, '\U0001f40d', 22)
67 self.assertEqual(getattrstring(obj, b'a'), 11)
68 self.assertRaises(AttributeError, getattrstring, obj, b'b')
69 self.assertEqual(getattrstring(obj, '\U0001f40d'.encode()), 22)
70
71 self.assertRaises(RuntimeError, getattrstring, obj, b'evil')
72 self.assertRaises(UnicodeDecodeError, getattrstring, obj, b'\xff')
73 # CRASHES getattrstring(obj, NULL)
74 # CRASHES getattrstring(NULL, b'a')
75
76 def test_object_hasattr(self):
77 xhasattr = _testcapi.object_hasattr
78 obj = TestObject()
79 obj.a = 1
80 setattr(obj, '\U0001f40d', 2)
81 self.assertTrue(xhasattr(obj, 'a'))
82 self.assertFalse(xhasattr(obj, 'b'))
83 self.assertTrue(xhasattr(obj, '\U0001f40d'))
84
85 self.assertFalse(xhasattr(obj, 'evil'))
86 self.assertFalse(xhasattr(obj, 1))
87 # CRASHES xhasattr(obj, NULL)
88 # CRASHES xhasattr(NULL, 'a')
89
90 def test_object_hasattrstring(self):
91 hasattrstring = _testcapi.object_hasattrstring
92 obj = TestObject()
93 obj.a = 1
94 setattr(obj, '\U0001f40d', 2)
95 self.assertTrue(hasattrstring(obj, b'a'))
96 self.assertFalse(hasattrstring(obj, b'b'))
97 self.assertTrue(hasattrstring(obj, '\U0001f40d'.encode()))
98
99 self.assertFalse(hasattrstring(obj, b'evil'))
100 self.assertFalse(hasattrstring(obj, b'\xff'))
101 # CRASHES hasattrstring(obj, NULL)
102 # CRASHES hasattrstring(NULL, b'a')
103
104 def test_object_setattr(self):
105 xsetattr = _testcapi.object_setattr
106 obj = TestObject()
107 xsetattr(obj, 'a', 5)
108 self.assertEqual(obj.a, 5)
109 xsetattr(obj, '\U0001f40d', 8)
110 self.assertEqual(getattr(obj, '\U0001f40d'), 8)
111
112 # PyObject_SetAttr(obj, attr_name, NULL) removes the attribute
113 xsetattr(obj, 'a', NULL)
114 self.assertFalse(hasattr(obj, 'a'))
115 self.assertRaises(AttributeError, xsetattr, obj, 'b', NULL)
116 self.assertRaises(RuntimeError, xsetattr, obj, 'evil', NULL)
117
118 self.assertRaises(RuntimeError, xsetattr, obj, 'evil', 'good')
119 self.assertRaises(AttributeError, xsetattr, 42, 'a', 5)
120 self.assertRaises(TypeError, xsetattr, obj, 1, 5)
121 # CRASHES xsetattr(obj, NULL, 5)
122 # CRASHES xsetattr(NULL, 'a', 5)
123
124 def test_object_setattrstring(self):
125 setattrstring = _testcapi.object_setattrstring
126 obj = TestObject()
127 setattrstring(obj, b'a', 5)
128 self.assertEqual(obj.a, 5)
129 setattrstring(obj, '\U0001f40d'.encode(), 8)
130 self.assertEqual(getattr(obj, '\U0001f40d'), 8)
131
132 # PyObject_SetAttrString(obj, attr_name, NULL) removes the attribute
133 setattrstring(obj, b'a', NULL)
134 self.assertFalse(hasattr(obj, 'a'))
135 self.assertRaises(AttributeError, setattrstring, obj, b'b', NULL)
136 self.assertRaises(RuntimeError, setattrstring, obj, b'evil', NULL)
137
138 self.assertRaises(RuntimeError, setattrstring, obj, b'evil', 'good')
139 self.assertRaises(AttributeError, setattrstring, 42, b'a', 5)
140 self.assertRaises(TypeError, setattrstring, obj, 1, 5)
141 self.assertRaises(UnicodeDecodeError, setattrstring, obj, b'\xff', 5)
142 # CRASHES setattrstring(obj, NULL, 5)
143 # CRASHES setattrstring(NULL, b'a', 5)
144
145 def test_object_delattr(self):
146 xdelattr = _testcapi.object_delattr
147 obj = TestObject()
148 obj.a = 1
149 setattr(obj, '\U0001f40d', 2)
150 xdelattr(obj, 'a')
151 self.assertFalse(hasattr(obj, 'a'))
152 self.assertRaises(AttributeError, xdelattr, obj, 'b')
153 xdelattr(obj, '\U0001f40d')
154 self.assertFalse(hasattr(obj, '\U0001f40d'))
155
156 self.assertRaises(AttributeError, xdelattr, 42, 'numerator')
157 self.assertRaises(RuntimeError, xdelattr, obj, 'evil')
158 self.assertRaises(TypeError, xdelattr, obj, 1)
159 # CRASHES xdelattr(obj, NULL)
160 # CRASHES xdelattr(NULL, 'a')
161
162 def test_object_delattrstring(self):
163 delattrstring = _testcapi.object_delattrstring
164 obj = TestObject()
165 obj.a = 1
166 setattr(obj, '\U0001f40d', 2)
167 delattrstring(obj, b'a')
168 self.assertFalse(hasattr(obj, 'a'))
169 self.assertRaises(AttributeError, delattrstring, obj, b'b')
170 delattrstring(obj, '\U0001f40d'.encode())
171 self.assertFalse(hasattr(obj, '\U0001f40d'))
172
173 self.assertRaises(AttributeError, delattrstring, 42, b'numerator')
174 self.assertRaises(RuntimeError, delattrstring, obj, b'evil')
175 self.assertRaises(UnicodeDecodeError, delattrstring, obj, b'\xff')
176 # CRASHES delattrstring(obj, NULL)
177 # CRASHES delattrstring(NULL, b'a')
178
179
180 def test_mapping_check(self):
181 check = _testcapi.mapping_check
182 self.assertTrue(check({1: 2}))
183 self.assertTrue(check([1, 2]))
184 self.assertTrue(check((1, 2)))
185 self.assertTrue(check('abc'))
186 self.assertTrue(check(b'abc'))
187 self.assertFalse(check(42))
188 self.assertFalse(check(object()))
189 self.assertFalse(check(NULL))
190
191 def test_mapping_size(self):
192 for size in _testcapi.mapping_size, _testcapi.mapping_length:
193 self.assertEqual(size({1: 2}), 1)
194 self.assertEqual(size([1, 2]), 2)
195 self.assertEqual(size((1, 2)), 2)
196 self.assertEqual(size('abc'), 3)
197 self.assertEqual(size(b'abc'), 3)
198
199 self.assertRaises(TypeError, size, 42)
200 self.assertRaises(TypeError, size, object())
201 self.assertRaises(SystemError, size, NULL)
202
203 def test_object_getitem(self):
204 getitem = _testcapi.object_getitem
205 dct = {'a': 1, '\U0001f40d': 2}
206 self.assertEqual(getitem(dct, 'a'), 1)
207 self.assertRaises(KeyError, getitem, dct, 'b')
208 self.assertEqual(getitem(dct, '\U0001f40d'), 2)
209
210 dct2 = ProxyGetItem(dct)
211 self.assertEqual(getitem(dct2, 'a'), 1)
212 self.assertRaises(KeyError, getitem, dct2, 'b')
213
214 self.assertEqual(getitem(['a', 'b', 'c'], 1), 'b')
215
216 self.assertRaises(TypeError, getitem, 42, 'a')
217 self.assertRaises(TypeError, getitem, {}, []) # unhashable
218 self.assertRaises(SystemError, getitem, {}, NULL)
219 self.assertRaises(IndexError, getitem, [], 1)
220 self.assertRaises(TypeError, getitem, [], 'a')
221 self.assertRaises(SystemError, getitem, NULL, 'a')
222
223 def test_mapping_getitemstring(self):
224 getitemstring = _testcapi.mapping_getitemstring
225 dct = {'a': 1, '\U0001f40d': 2}
226 self.assertEqual(getitemstring(dct, b'a'), 1)
227 self.assertRaises(KeyError, getitemstring, dct, b'b')
228 self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2)
229
230 dct2 = ProxyGetItem(dct)
231 self.assertEqual(getitemstring(dct2, b'a'), 1)
232 self.assertRaises(KeyError, getitemstring, dct2, b'b')
233
234 self.assertRaises(TypeError, getitemstring, 42, b'a')
235 self.assertRaises(UnicodeDecodeError, getitemstring, {}, b'\xff')
236 self.assertRaises(SystemError, getitemstring, {}, NULL)
237 self.assertRaises(TypeError, getitemstring, [], b'a')
238 self.assertRaises(SystemError, getitemstring, NULL, b'a')
239
240 def test_mapping_haskey(self):
241 haskey = _testcapi.mapping_haskey
242 dct = {'a': 1, '\U0001f40d': 2}
243 self.assertTrue(haskey(dct, 'a'))
244 self.assertFalse(haskey(dct, 'b'))
245 self.assertTrue(haskey(dct, '\U0001f40d'))
246
247 dct2 = ProxyGetItem(dct)
248 self.assertTrue(haskey(dct2, 'a'))
249 self.assertFalse(haskey(dct2, 'b'))
250
251 self.assertTrue(haskey(['a', 'b', 'c'], 1))
252
253 self.assertFalse(haskey(42, 'a'))
254 self.assertFalse(haskey({}, [])) # unhashable
255 self.assertFalse(haskey({}, NULL))
256 self.assertFalse(haskey([], 1))
257 self.assertFalse(haskey([], 'a'))
258 self.assertFalse(haskey(NULL, 'a'))
259
260 def test_mapping_haskeystring(self):
261 haskeystring = _testcapi.mapping_haskeystring
262 dct = {'a': 1, '\U0001f40d': 2}
263 self.assertTrue(haskeystring(dct, b'a'))
264 self.assertFalse(haskeystring(dct, b'b'))
265 self.assertTrue(haskeystring(dct, '\U0001f40d'.encode()))
266
267 dct2 = ProxyGetItem(dct)
268 self.assertTrue(haskeystring(dct2, b'a'))
269 self.assertFalse(haskeystring(dct2, b'b'))
270
271 self.assertFalse(haskeystring(42, b'a'))
272 self.assertFalse(haskeystring({}, b'\xff'))
273 self.assertFalse(haskeystring({}, NULL))
274 self.assertFalse(haskeystring([], b'a'))
275 self.assertFalse(haskeystring(NULL, b'a'))
276
277 def test_object_setitem(self):
278 setitem = _testcapi.object_setitem
279 dct = {}
280 setitem(dct, 'a', 5)
281 self.assertEqual(dct, {'a': 5})
282 setitem(dct, '\U0001f40d', 8)
283 self.assertEqual(dct, {'a': 5, '\U0001f40d': 8})
284
285 dct = {}
286 dct2 = ProxySetItem(dct)
287 setitem(dct2, 'a', 5)
288 self.assertEqual(dct, {'a': 5})
289
290 lst = ['a', 'b', 'c']
291 setitem(lst, 1, 'x')
292 self.assertEqual(lst, ['a', 'x', 'c'])
293
294 self.assertRaises(TypeError, setitem, 42, 'a', 5)
295 self.assertRaises(TypeError, setitem, {}, [], 5) # unhashable
296 self.assertRaises(SystemError, setitem, {}, NULL, 5)
297 self.assertRaises(SystemError, setitem, {}, 'a', NULL)
298 self.assertRaises(IndexError, setitem, [], 1, 5)
299 self.assertRaises(TypeError, setitem, [], 'a', 5)
300 self.assertRaises(TypeError, setitem, (), 1, 5)
301 self.assertRaises(SystemError, setitem, NULL, 'a', 5)
302
303 def test_mapping_setitemstring(self):
304 setitemstring = _testcapi.mapping_setitemstring
305 dct = {}
306 setitemstring(dct, b'a', 5)
307 self.assertEqual(dct, {'a': 5})
308 setitemstring(dct, '\U0001f40d'.encode(), 8)
309 self.assertEqual(dct, {'a': 5, '\U0001f40d': 8})
310
311 dct = {}
312 dct2 = ProxySetItem(dct)
313 setitemstring(dct2, b'a', 5)
314 self.assertEqual(dct, {'a': 5})
315
316 self.assertRaises(TypeError, setitemstring, 42, b'a', 5)
317 self.assertRaises(UnicodeDecodeError, setitemstring, {}, b'\xff', 5)
318 self.assertRaises(SystemError, setitemstring, {}, NULL, 5)
319 self.assertRaises(SystemError, setitemstring, {}, b'a', NULL)
320 self.assertRaises(TypeError, setitemstring, [], b'a', 5)
321 self.assertRaises(SystemError, setitemstring, NULL, b'a', 5)
322
323 def test_object_delitem(self):
324 for delitem in _testcapi.object_delitem, _testcapi.mapping_delitem:
325 dct = {'a': 1, 'c': 2, '\U0001f40d': 3}
326 delitem(dct, 'a')
327 self.assertEqual(dct, {'c': 2, '\U0001f40d': 3})
328 self.assertRaises(KeyError, delitem, dct, 'b')
329 delitem(dct, '\U0001f40d')
330 self.assertEqual(dct, {'c': 2})
331
332 dct = {'a': 1, 'c': 2}
333 dct2 = ProxyDelItem(dct)
334 delitem(dct2, 'a')
335 self.assertEqual(dct, {'c': 2})
336 self.assertRaises(KeyError, delitem, dct2, 'b')
337
338 lst = ['a', 'b', 'c']
339 delitem(lst, 1)
340 self.assertEqual(lst, ['a', 'c'])
341
342 self.assertRaises(TypeError, delitem, 42, 'a')
343 self.assertRaises(TypeError, delitem, {}, []) # unhashable
344 self.assertRaises(SystemError, delitem, {}, NULL)
345 self.assertRaises(IndexError, delitem, [], 1)
346 self.assertRaises(TypeError, delitem, [], 'a')
347 self.assertRaises(SystemError, delitem, NULL, 'a')
348
349 def test_mapping_delitemstring(self):
350 delitemstring = _testcapi.mapping_delitemstring
351 dct = {'a': 1, 'c': 2, '\U0001f40d': 3}
352 delitemstring(dct, b'a')
353 self.assertEqual(dct, {'c': 2, '\U0001f40d': 3})
354 self.assertRaises(KeyError, delitemstring, dct, b'b')
355 delitemstring(dct, '\U0001f40d'.encode())
356 self.assertEqual(dct, {'c': 2})
357
358 dct = {'a': 1, 'c': 2}
359 dct2 = ProxyDelItem(dct)
360 delitemstring(dct2, b'a')
361 self.assertEqual(dct, {'c': 2})
362 self.assertRaises(KeyError, delitemstring, dct2, b'b')
363
364 self.assertRaises(TypeError, delitemstring, 42, b'a')
365 self.assertRaises(UnicodeDecodeError, delitemstring, {}, b'\xff')
366 self.assertRaises(SystemError, delitemstring, {}, NULL)
367 self.assertRaises(TypeError, delitemstring, [], b'a')
368 self.assertRaises(SystemError, delitemstring, NULL, b'a')
369
370 def test_mapping_keys_valuesitems(self):
371 class ESC[4;38;5;81mMapping1(ESC[4;38;5;149mdict):
372 def keys(self):
373 return list(super().keys())
374 def values(self):
375 return list(super().values())
376 def items(self):
377 return list(super().items())
378 class ESC[4;38;5;81mMapping2(ESC[4;38;5;149mdict):
379 def keys(self):
380 return tuple(super().keys())
381 def values(self):
382 return tuple(super().values())
383 def items(self):
384 return tuple(super().items())
385 dict_obj = {'foo': 1, 'bar': 2, 'spam': 3}
386
387 for mapping in [{}, OrderedDict(), Mapping1(), Mapping2(),
388 dict_obj, OrderedDict(dict_obj),
389 Mapping1(dict_obj), Mapping2(dict_obj)]:
390 self.assertListEqual(_testcapi.mapping_keys(mapping),
391 list(mapping.keys()))
392 self.assertListEqual(_testcapi.mapping_values(mapping),
393 list(mapping.values()))
394 self.assertListEqual(_testcapi.mapping_items(mapping),
395 list(mapping.items()))
396
397 def test_mapping_keys_valuesitems_bad_arg(self):
398 self.assertRaises(AttributeError, _testcapi.mapping_keys, object())
399 self.assertRaises(AttributeError, _testcapi.mapping_values, object())
400 self.assertRaises(AttributeError, _testcapi.mapping_items, object())
401 self.assertRaises(AttributeError, _testcapi.mapping_keys, [])
402 self.assertRaises(AttributeError, _testcapi.mapping_values, [])
403 self.assertRaises(AttributeError, _testcapi.mapping_items, [])
404 self.assertRaises(SystemError, _testcapi.mapping_keys, NULL)
405 self.assertRaises(SystemError, _testcapi.mapping_values, NULL)
406 self.assertRaises(SystemError, _testcapi.mapping_items, NULL)
407
408 class ESC[4;38;5;81mBadMapping:
409 def keys(self):
410 return None
411 def values(self):
412 return None
413 def items(self):
414 return None
415 bad_mapping = BadMapping()
416 self.assertRaises(TypeError, _testcapi.mapping_keys, bad_mapping)
417 self.assertRaises(TypeError, _testcapi.mapping_values, bad_mapping)
418 self.assertRaises(TypeError, _testcapi.mapping_items, bad_mapping)
419
420 def test_sequence_check(self):
421 check = _testcapi.sequence_check
422 self.assertFalse(check({1: 2}))
423 self.assertTrue(check([1, 2]))
424 self.assertTrue(check((1, 2)))
425 self.assertTrue(check('abc'))
426 self.assertTrue(check(b'abc'))
427 self.assertFalse(check(42))
428 self.assertFalse(check(object()))
429 # CRASHES check(NULL)
430
431 def test_sequence_size(self):
432 for size in _testcapi.sequence_size, _testcapi.sequence_length:
433 self.assertEqual(size([1, 2]), 2)
434 self.assertEqual(size((1, 2)), 2)
435 self.assertEqual(size('abc'), 3)
436 self.assertEqual(size(b'abc'), 3)
437
438 self.assertRaises(TypeError, size, {})
439 self.assertRaises(TypeError, size, 42)
440 self.assertRaises(TypeError, size, object())
441 self.assertRaises(SystemError, size, NULL)
442
443 def test_sequence_getitem(self):
444 getitem = _testcapi.sequence_getitem
445 lst = ['a', 'b', 'c']
446 self.assertEqual(getitem(lst, 1), 'b')
447 self.assertEqual(getitem(lst, -1), 'c')
448 self.assertRaises(IndexError, getitem, lst, 3)
449
450 self.assertRaises(TypeError, getitem, 42, 1)
451 self.assertRaises(TypeError, getitem, {}, 1)
452 self.assertRaises(SystemError, getitem, NULL, 1)
453
454 def test_sequence_concat(self):
455 concat = _testcapi.sequence_concat
456 self.assertEqual(concat(['a', 'b'], [1, 2]), ['a', 'b', 1, 2])
457 self.assertEqual(concat(('a', 'b'), (1, 2)), ('a', 'b', 1, 2))
458
459 self.assertRaises(TypeError, concat, [], ())
460 self.assertRaises(TypeError, concat, (), [])
461 self.assertRaises(TypeError, concat, [], 42)
462 self.assertRaises(TypeError, concat, 42, [])
463 self.assertRaises(TypeError, concat, 42, 43)
464 self.assertRaises(SystemError, concat, [], NULL)
465 self.assertRaises(SystemError, concat, NULL, [])
466
467 def test_sequence_repeat(self):
468 repeat = _testcapi.sequence_repeat
469 self.assertEqual(repeat(['a', 'b'], 2), ['a', 'b', 'a', 'b'])
470 self.assertEqual(repeat(('a', 'b'), 2), ('a', 'b', 'a', 'b'))
471 self.assertEqual(repeat(['a', 'b'], 0), [])
472 self.assertEqual(repeat(['a', 'b'], -1), [])
473
474 self.assertRaises(TypeError, repeat, set(), 2)
475 self.assertRaises(TypeError, repeat, 42, 2)
476 self.assertRaises(SystemError, repeat, NULL, 2)
477
478 def test_sequence_inplaceconcat(self):
479 inplaceconcat = _testcapi.sequence_inplaceconcat
480 lst = ['a', 'b']
481 res = inplaceconcat(lst, [1, 2])
482 self.assertEqual(res, ['a', 'b', 1, 2])
483 self.assertIs(res, lst)
484 lst = ['a', 'b']
485 res = inplaceconcat(lst, (1, 2))
486 self.assertEqual(res, ['a', 'b', 1, 2])
487 self.assertIs(res, lst)
488 self.assertEqual(inplaceconcat(('a', 'b'), (1, 2)), ('a', 'b', 1, 2))
489
490 self.assertRaises(TypeError, inplaceconcat, (), [])
491 self.assertRaises(TypeError, inplaceconcat, [], 42)
492 self.assertRaises(TypeError, inplaceconcat, 42, [])
493 self.assertRaises(TypeError, inplaceconcat, 42, 43)
494 self.assertRaises(SystemError, inplaceconcat, [], NULL)
495 self.assertRaises(SystemError, inplaceconcat, NULL, [])
496
497 def test_sequence_inplacerepeat(self):
498 inplacerepeat = _testcapi.sequence_inplacerepeat
499 lst = ['a', 'b']
500 res = inplacerepeat(lst, 2)
501 self.assertEqual(res, ['a', 'b', 'a', 'b'])
502 self.assertIs(res, lst)
503 self.assertEqual(inplacerepeat(('a', 'b'), 2), ('a', 'b', 'a', 'b'))
504 self.assertEqual(inplacerepeat(['a', 'b'], 0), [])
505 self.assertEqual(inplacerepeat(['a', 'b'], -1), [])
506
507 self.assertRaises(TypeError, inplacerepeat, set(), 2)
508 self.assertRaises(TypeError, inplacerepeat, 42, 2)
509 self.assertRaises(SystemError, inplacerepeat, NULL, 2)
510
511 def test_sequence_setitem(self):
512 setitem = _testcapi.sequence_setitem
513 lst = ['a', 'b', 'c']
514 setitem(lst, 1, 'x')
515 self.assertEqual(lst, ['a', 'x', 'c'])
516 setitem(lst, -1, 'y')
517 self.assertEqual(lst, ['a', 'x', 'y'])
518
519 setitem(lst, 0, NULL)
520 self.assertEqual(lst, ['x', 'y'])
521 self.assertRaises(IndexError, setitem, lst, 3, 'x')
522
523 self.assertRaises(TypeError, setitem, 42, 1, 'x')
524 self.assertRaises(TypeError, setitem, {}, 1, 'x')
525 self.assertRaises(SystemError, setitem, NULL, 1, 'x')
526
527 def test_sequence_delitem(self):
528 delitem = _testcapi.sequence_delitem
529 lst = ['a', 'b', 'c']
530 delitem(lst, 1)
531 self.assertEqual(lst, ['a', 'c'])
532 delitem(lst, -1)
533 self.assertEqual(lst, ['a'])
534 self.assertRaises(IndexError, delitem, lst, 3)
535
536 self.assertRaises(TypeError, delitem, 42, 1)
537 self.assertRaises(TypeError, delitem, {}, 1)
538 self.assertRaises(SystemError, delitem, NULL, 1)
539
540 def test_sequence_setslice(self):
541 setslice = _testcapi.sequence_setslice
542
543 # Correct case:
544 data = [1, 2, 3, 4, 5]
545 data_copy = data.copy()
546
547 setslice(data, 1, 3, [8, 9])
548 data_copy[1:3] = [8, 9]
549 self.assertEqual(data, data_copy)
550 self.assertEqual(data, [1, 8, 9, 4, 5])
551
552 # Custom class:
553 class ESC[4;38;5;81mCustom:
554 def __setitem__(self, index, value):
555 self.index = index
556 self.value = value
557
558 c = Custom()
559 setslice(c, 0, 5, 'abc')
560 self.assertEqual(c.index, slice(0, 5))
561 self.assertEqual(c.value, 'abc')
562
563 # Immutable sequences must raise:
564 bad_seq1 = (1, 2, 3, 4)
565 self.assertRaises(TypeError, setslice, bad_seq1, 1, 3, (8, 9))
566 self.assertEqual(bad_seq1, (1, 2, 3, 4))
567
568 bad_seq2 = 'abcd'
569 self.assertRaises(TypeError, setslice, bad_seq2, 1, 3, 'xy')
570 self.assertEqual(bad_seq2, 'abcd')
571
572 # Not a sequence:
573 self.assertRaises(TypeError, setslice, object(), 1, 3, 'xy')
574 self.assertRaises(SystemError, setslice, NULL, 1, 3, 'xy')
575
576 data_copy = data.copy()
577 setslice(data_copy, 1, 3, NULL)
578 self.assertEqual(data_copy, [1, 4, 5])
579
580 def test_sequence_delslice(self):
581 delslice = _testcapi.sequence_delslice
582
583 # Correct case:
584 data = [1, 2, 3, 4, 5]
585 data_copy = data.copy()
586
587 delslice(data, 1, 3)
588 del data_copy[1:3]
589 self.assertEqual(data, data_copy)
590 self.assertEqual(data, [1, 4, 5])
591
592 # Custom class:
593 class ESC[4;38;5;81mCustom:
594 def __delitem__(self, index):
595 self.index = index
596
597 c = Custom()
598 delslice(c, 0, 5)
599 self.assertEqual(c.index, slice(0, 5))
600
601 # Immutable sequences must raise:
602 bad_seq1 = (1, 2, 3, 4)
603 self.assertRaises(TypeError, delslice, bad_seq1, 1, 3)
604 self.assertEqual(bad_seq1, (1, 2, 3, 4))
605
606 bad_seq2 = 'abcd'
607 self.assertRaises(TypeError, delslice, bad_seq2, 1, 3)
608 self.assertEqual(bad_seq2, 'abcd')
609
610 # Not a sequence:
611 self.assertRaises(TypeError, delslice, object(), 1, 3)
612 self.assertRaises(SystemError, delslice, NULL, 1, 3)
613
614 mapping = {1: 'a', 2: 'b', 3: 'c'}
615 self.assertRaises(KeyError, delslice, mapping, 1, 3)
616 self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'})
617
618 def test_sequence_count(self):
619 count = _testcapi.sequence_count
620
621 lst = ['a', 'b', 'a']
622 self.assertEqual(count(lst, 'a'), 2)
623 self.assertEqual(count(lst, 'c'), 0)
624 self.assertEqual(count(iter(lst), 'a'), 2)
625 self.assertEqual(count(iter(lst), 'c'), 0)
626 self.assertEqual(count({'a': 2}, 'a'), 1)
627
628 self.assertRaises(TypeError, count, 42, 'a')
629 self.assertRaises(SystemError, count, [], NULL)
630 self.assertRaises(SystemError, count, [1], NULL)
631 self.assertRaises(SystemError, count, NULL, 'a')
632
633 def test_sequence_contains(self):
634 contains = _testcapi.sequence_contains
635
636 lst = ['a', 'b', 'a']
637 self.assertEqual(contains(lst, 'a'), 1)
638 self.assertEqual(contains(lst, 'c'), 0)
639 self.assertEqual(contains(iter(lst), 'a'), 1)
640 self.assertEqual(contains(iter(lst), 'c'), 0)
641 self.assertEqual(contains({'a': 2}, 'a'), 1)
642
643 # XXX Only for empty sequences. Should be SystemError?
644 self.assertEqual(contains([], NULL), 0)
645
646 self.assertRaises(TypeError, contains, 42, 'a')
647 self.assertRaises(SystemError, contains, [1], NULL)
648 # CRASHES contains({}, NULL)
649 # CRASHES contains(set(), NULL)
650 # CRASHES contains(NULL, 'a')
651
652 def test_sequence_index(self):
653 index = _testcapi.sequence_index
654
655 lst = ['a', 'b', 'a']
656 self.assertEqual(index(lst, 'a'), 0)
657 self.assertEqual(index(lst, 'b'), 1)
658 self.assertRaises(ValueError, index, lst, 'c')
659 self.assertEqual(index(iter(lst), 'a'), 0)
660 self.assertEqual(index(iter(lst), 'b'), 1)
661 self.assertRaises(ValueError, index, iter(lst), 'c')
662 dct = {'a': 2, 'b': 3}
663 self.assertEqual(index(dct, 'a'), 0)
664 self.assertEqual(index(dct, 'b'), 1)
665 self.assertRaises(ValueError, index, dct, 'c')
666
667 self.assertRaises(TypeError, index, 42, 'a')
668 self.assertRaises(SystemError, index, [], NULL)
669 self.assertRaises(SystemError, index, [1], NULL)
670 self.assertRaises(SystemError, index, NULL, 'a')
671
672 def test_sequence_list(self):
673 xlist = _testcapi.sequence_list
674 self.assertEqual(xlist(['a', 'b', 'c']), ['a', 'b', 'c'])
675 self.assertEqual(xlist(('a', 'b', 'c')), ['a', 'b', 'c'])
676 self.assertEqual(xlist(iter(['a', 'b', 'c'])), ['a', 'b', 'c'])
677 self.assertEqual(xlist(gen()), ['a', 'b', 'c'])
678
679 self.assertRaises(TypeError, xlist, 42)
680 self.assertRaises(SystemError, xlist, NULL)
681
682 def test_sequence_tuple(self):
683 xtuple = _testcapi.sequence_tuple
684 self.assertEqual(xtuple(['a', 'b', 'c']), ('a', 'b', 'c'))
685 self.assertEqual(xtuple(('a', 'b', 'c')), ('a', 'b', 'c'))
686 self.assertEqual(xtuple(iter(['a', 'b', 'c'])), ('a', 'b', 'c'))
687 self.assertEqual(xtuple(gen()), ('a', 'b', 'c'))
688
689 self.assertRaises(TypeError, xtuple, 42)
690 self.assertRaises(SystemError, xtuple, NULL)
691
692
693 if __name__ == "__main__":
694 unittest.main()