2
# tag: list, tuple, slice, slicing
7
@cython.test_fail_if_path_exists("//CondExprNode")
8
def slice_list(list l, int start, int stop):
10
>>> slice_list([1,2,3,4], 1, 3)
12
>>> slice_list([1,2,3,4], 1, 7)
14
>>> slice_list([], 1, 3)
16
>>> slice_list([1], 1, 3)
18
>>> slice_list([1,2,3,4], -3, -1)
20
>>> slice_list([1,2,3,4], -10, -1)
22
>>> slice_list([], -3, -1)
24
>>> slice_list([1], -3, -1)
29
@cython.test_fail_if_path_exists("//CondExprNode")
30
def slice_list_start(list l, int start):
32
>>> slice_list_start([1,2,3,4], 1)
34
>>> slice_list_start([], 1)
36
>>> slice_list_start([1], 1)
38
>>> slice_list_start([1], 2)
40
>>> slice_list_start([1,2,3,4], -3)
42
>>> slice_list_start([1,2,3,4], -10)
44
>>> slice_list_start([], -3)
46
>>> slice_list_start([1], -3)
52
@cython.test_fail_if_path_exists("//CondExprNode")
53
def slice_list_stop(list l, int stop):
55
>>> slice_list_stop([1,2,3,4], 3)
57
>>> slice_list_stop([1,2,3,4], 7)
59
>>> slice_list_stop([], 3)
61
>>> slice_list_stop([1], 3)
63
>>> slice_list_stop([1,2,3,4], -3)
65
>>> slice_list_stop([1,2,3,4], -10)
67
>>> slice_list_stop([], -1)
69
>>> slice_list_stop([1], -1)
71
>>> slice_list_stop([1, 2], -3)
77
@cython.test_fail_if_path_exists("//CondExprNode")
78
def slice_list_copy(list l):
80
>>> slice_list_copy([])
82
>>> slice_list_copy([1,2,3])
88
@cython.test_fail_if_path_exists("//CondExprNode")
89
def slice_tuple_copy(tuple l):
91
>>> slice_tuple_copy(())
93
>>> slice_tuple_copy((1,2,3))
99
@cython.test_fail_if_path_exists("//CondExprNode")
100
def slice_tuple(tuple t, int start, int stop):
102
>>> slice_tuple((1,2,3,4), 1, 3)
104
>>> slice_tuple((1,2,3,4), 1, 7)
106
>>> slice_tuple((), 1, 3)
108
>>> slice_tuple((1,), 1, 3)
110
>>> slice_tuple((1,2,3,4), -3, -1)
112
>>> slice_tuple((1,2,3,4), -10, -1)
114
>>> slice_tuple((), -3, -1)
116
>>> slice_tuple((1,), -3, -1)
122
@cython.test_fail_if_path_exists("//CondExprNode")
123
def slice_tuple_start(tuple t, int start):
125
>>> slice_tuple_start((1,2,3,4), 1)
127
>>> slice_tuple_start((), 1)
129
>>> slice_tuple_start((1,), 1)
131
>>> slice_tuple_start((1,2,3,4), -3)
133
>>> slice_tuple_start((1,2,3,4), -10)
135
>>> slice_tuple_start((), -3)
137
>>> slice_tuple_start((1,), -3)
143
@cython.test_fail_if_path_exists("//CondExprNode")
144
def slice_tuple_stop(tuple t, int stop):
146
>>> slice_tuple_stop((1,2,3,4), 3)
148
>>> slice_tuple_stop((1,2,3,4), 7)
150
>>> slice_tuple_stop((), 3)
152
>>> slice_tuple_stop((1,), 3)
154
>>> slice_tuple_stop((1,2,3,4), -1)
156
>>> slice_tuple_stop((), -1)
162
@cython.test_fail_if_path_exists("//CondExprNode")
163
def slice_list_assign_list(list l):
167
>>> slice_list_assign_list(l2)
174
@cython.test_fail_if_path_exists("//CondExprNode")
175
def slice_list_assign_tuple(list l):
179
>>> slice_list_assign_tuple(l2)
186
@cython.test_fail_if_path_exists("//CondExprNode")
187
def slice_list_assign(list l, value):
191
>>> slice_list_assign(l2, (1,2,3,4))
194
>>> slice_list_assign(l2, dict(zip(l,l)))
201
def slice_charp(py_string_arg):
203
>>> print("%s" % slice_charp('abcdefg'))
206
cdef bytes py_string = py_string_arg.encode(u'ASCII')
207
cdef char* s = py_string
208
return s[1:3].decode(u'ASCII')
211
def slice_charp_repeat(py_string_arg):
213
>>> print("%s" % slice_charp_repeat('abcdefg'))
216
cdef bytes py_string = py_string_arg.encode(u'ASCII')
217
cdef char* s = py_string
218
cdef bytes slice_val = s[1:6]
220
return s[1:3].decode(u'ASCII')
223
# Readers will find the common boilerplate in the tests below:
226
# >>> b = ''.join(map(str, l)).encode('ASCII')
227
# >>> u = b.decode('ASCII')
228
# >>> o = (l, t, b, u)
229
# >>> n = ('list', 'tuple', 'bytes', 'unicode')
230
# >>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o)
231
# >>> r = lambda i, *a: '%s[%s] -> %s' % (n[i], ':'.join(map(repr, a)), FUNCTION_NAME(o[i], *a))
232
# Originally, this was planned to be a basic iteration over
233
# the various object types contained within the sliceable fused
234
# type, but Python2 -> Python3 semantics changed the class names
235
# and string representations used for raw bytes and unicode.
236
# As a result, we dynamically adjust the printed string output
237
# for each test in order to ensure consistent results when running
238
# both Python2 and Python3.
240
ctypedef fused sliceable:
247
@cython.test_assert_path_exists("//SliceIndexNode//CondExprNode")
248
def slice_fused_type_start(sliceable seq, start):
252
>>> b = ''.join(map(str, l)).encode('ASCII')
253
>>> u = b.decode('ASCII')
255
>>> n = ('list', 'tuple', 'bytes', 'unicode')
256
>>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o)
257
>>> r = lambda i, s: '%s[%r:] -> %s' % (n[i], s, p(slice_fused_type_start(o[i], s)))
258
>>> for i in range(len(o)):
259
... for s in (0, len(l) - 1, len(l), -1, -len(l), None):
262
list[0:] -> [1, 2, 3, 4, 5]
266
list[-5:] -> [1, 2, 3, 4, 5]
267
list[None:] -> [1, 2, 3, 4, 5]
268
tuple[0:] -> (1, 2, 3, 4, 5)
272
tuple[-5:] -> (1, 2, 3, 4, 5)
273
tuple[None:] -> (1, 2, 3, 4, 5)
279
bytes[None:] -> 12345
284
unicode[-5:] -> 12345
285
unicode[None:] -> 12345
291
@cython.test_assert_path_exists("//SliceIndexNode//CondExprNode")
292
def slice_fused_type_stop(sliceable seq, stop):
296
>>> b = ''.join(map(str, l)).encode('ASCII')
297
>>> u = b.decode('ASCII')
299
>>> n = ('list', 'tuple', 'bytes', 'unicode')
300
>>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o)
301
>>> r = lambda i, s: '%s[:%r] -> %s' % (n[i], s, p(slice_fused_type_stop(o[i], s)))
302
>>> for i in range(len(o)):
303
... for s in (0, len(l) - 1, len(l), -1, -len(l), None):
307
list[:4] -> [1, 2, 3, 4]
308
list[:5] -> [1, 2, 3, 4, 5]
309
list[:-1] -> [1, 2, 3, 4]
311
list[:None] -> [1, 2, 3, 4, 5]
313
tuple[:4] -> (1, 2, 3, 4)
314
tuple[:5] -> (1, 2, 3, 4, 5)
315
tuple[:-1] -> (1, 2, 3, 4)
317
tuple[:None] -> (1, 2, 3, 4, 5)
323
bytes[:None] -> 12345
329
unicode[:None] -> 12345
335
@cython.test_assert_path_exists("//SliceIndexNode//CondExprNode")
336
def slice_fused_type_start_and_stop(sliceable seq, start, stop):
340
>>> b = ''.join(map(str, l)).encode('ASCII')
341
>>> u = b.decode('ASCII')
343
>>> n = ('list', 'tuple', 'bytes', 'unicode')
344
>>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o)
345
>>> r = lambda i, t, s: '%s[%r:%r] -> %s' % (n[i], t, s, p(slice_fused_type_start_and_stop(o[i], t, s)))
346
>>> for i in range(len(o)):
347
... for start, stop in ((0, len(l)), (0, None), (None, len(l)),
348
... (-len(l), 0), (1, 0), (0, 1)):
349
... print(r(i, start, stop))
351
list[0:5] -> [1, 2, 3, 4, 5]
352
list[0:None] -> [1, 2, 3, 4, 5]
353
list[None:5] -> [1, 2, 3, 4, 5]
357
tuple[0:5] -> (1, 2, 3, 4, 5)
358
tuple[0:None] -> (1, 2, 3, 4, 5)
359
tuple[None:5] -> (1, 2, 3, 4, 5)
364
bytes[0:None] -> 12345
365
bytes[None:5] -> 12345
369
unicode[0:5] -> 12345
370
unicode[0:None] -> 12345
371
unicode[None:5] -> 12345
376
obj = seq[start:stop]
380
def slice_fused_type_step(sliceable seq, step):
384
>>> b = ''.join(map(str, l)).encode('ASCII')
385
>>> u = b.decode('ASCII')
387
>>> n = ('list', 'tuple', 'bytes', 'unicode')
388
>>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o)
389
>>> r = lambda i, s: '%s[::%r] -> %s' % (n[i], s, p(slice_fused_type_step(o[i], s)))
390
>>> for i in range(len(o)):
391
... for s in (1, -1, 2, -3, 5, -5, None):
394
list[::1] -> [1, 2, 3, 4, 5]
395
list[::-1] -> [5, 4, 3, 2, 1]
396
list[::2] -> [1, 3, 5]
400
list[::None] -> [1, 2, 3, 4, 5]
401
tuple[::1] -> (1, 2, 3, 4, 5)
402
tuple[::-1] -> (5, 4, 3, 2, 1)
403
tuple[::2] -> (1, 3, 5)
404
tuple[::-3] -> (5, 2)
407
tuple[::None] -> (1, 2, 3, 4, 5)
414
bytes[::None] -> 12345
415
unicode[::1] -> 12345
416
unicode[::-1] -> 54321
421
unicode[::None] -> 12345
423
... try: slice_fused_type_step(v, 0)
424
... except ValueError: pass
425
... try: slice_fused_type_step(v, v)
426
... except TypeError: pass
432
def slice_fused_type_start_and_step(sliceable seq, start, step):
436
>>> b = ''.join(map(str, l)).encode('ASCII')
437
>>> u = b.decode('ASCII')
439
>>> n = ('list', 'tuple', 'bytes', 'unicode')
440
>>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o)
441
>>> r = lambda i, s, t: '%s[%r::%r] -> %s' % (n[i], s, t, p(slice_fused_type_start_and_step(o[i], s, t)))
442
>>> for i in range(len(o)):
443
... for start, step in ((0, 1), (0, -1), (1, 1), (1, -1),
444
... (None, 1), (None, -1), (None, None),
445
... (1, 2), (len(l), -2), (len(l), len(l))):
446
... print(r(i, start, step))
448
list[0::1] -> [1, 2, 3, 4, 5]
450
list[1::1] -> [2, 3, 4, 5]
451
list[1::-1] -> [2, 1]
452
list[None::1] -> [1, 2, 3, 4, 5]
453
list[None::-1] -> [5, 4, 3, 2, 1]
454
list[None::None] -> [1, 2, 3, 4, 5]
456
list[5::-2] -> [5, 3, 1]
458
tuple[0::1] -> (1, 2, 3, 4, 5)
460
tuple[1::1] -> (2, 3, 4, 5)
461
tuple[1::-1] -> (2, 1)
462
tuple[None::1] -> (1, 2, 3, 4, 5)
463
tuple[None::-1] -> (5, 4, 3, 2, 1)
464
tuple[None::None] -> (1, 2, 3, 4, 5)
465
tuple[1::2] -> (2, 4)
466
tuple[5::-2] -> (5, 3, 1)
472
bytes[None::1] -> 12345
473
bytes[None::-1] -> 54321
474
bytes[None::None] -> 12345
478
unicode[0::1] -> 12345
480
unicode[1::1] -> 2345
482
unicode[None::1] -> 12345
483
unicode[None::-1] -> 54321
484
unicode[None::None] -> 12345
486
unicode[5::-2] -> 531
488
>>> for o in (l, t, b):
489
... try: slice_fused_type_start_and_step(o, 0, 0)
490
... except ValueError: pass
492
obj = seq[start::step]
496
def slice_fused_type_stop_and_step(sliceable seq, stop, step):
500
>>> b = ''.join(map(str, l)).encode('ASCII')
501
>>> u = b.decode('ASCII')
503
>>> n = ('list', 'tuple', 'bytes', 'unicode')
504
>>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o)
505
>>> r = lambda i, s, t: '%s[:%r:%r] -> %s' % (n[i], s, t, p(slice_fused_type_stop_and_step(o[i], s, t)))
506
>>> for i in range(len(o)):
507
... for stop, step in ((len(l), 1), (len(l), None), (None, 1),
508
... (len(l), -1), (len(l) - 1, 2), (len(l), -2),
509
... (len(l), len(l))):
510
... print(r(i, stop, step))
512
list[:5:1] -> [1, 2, 3, 4, 5]
513
list[:5:None] -> [1, 2, 3, 4, 5]
514
list[:None:1] -> [1, 2, 3, 4, 5]
519
tuple[:5:1] -> (1, 2, 3, 4, 5)
520
tuple[:5:None] -> (1, 2, 3, 4, 5)
521
tuple[:None:1] -> (1, 2, 3, 4, 5)
523
tuple[:4:2] -> (1, 3)
527
bytes[:5:None] -> 12345
528
bytes[:None:1] -> 12345
533
unicode[:5:1] -> 12345
534
unicode[:5:None] -> 12345
535
unicode[:None:1] -> 12345
541
... try: slice_fused_type_stop_and_step(v, len(l), 0)
542
... except ValueError: pass
543
... try: slice_fused_type_stop_and_step(v, len(l), v)
544
... except TypeError: pass
546
obj = seq[:stop:step]
550
def slice_fused_type_all(sliceable seq, start, stop, step):
554
>>> b = ''.join(map(str, l)).encode('ASCII')
555
>>> u = b.decode('ASCII')
557
>>> n = ('list', 'tuple', 'bytes', 'unicode')
558
>>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o)
559
>>> r = lambda i, s, t, e: '%s[%r:%r:%r] -> %s' % (n[i], s, t, e, p(slice_fused_type_all(o[i], s, t, e)))
560
>>> for i in range(len(o)):
561
... for args in ((0, len(l), 1), (len(l), 0, -1), (None, len(l), 1),
562
... (len(l), None, -1), (-len(l), len(l), None), (None, None, None),
563
... (1, 3, 2), (len(l), 1, -3), (len(l), 0, 1)):
564
... print(r(i, *args))
566
list[0:5:1] -> [1, 2, 3, 4, 5]
567
list[5:0:-1] -> [5, 4, 3, 2]
568
list[None:5:1] -> [1, 2, 3, 4, 5]
569
list[5:None:-1] -> [5, 4, 3, 2, 1]
570
list[-5:5:None] -> [1, 2, 3, 4, 5]
571
list[None:None:None] -> [1, 2, 3, 4, 5]
575
tuple[0:5:1] -> (1, 2, 3, 4, 5)
576
tuple[5:0:-1] -> (5, 4, 3, 2)
577
tuple[None:5:1] -> (1, 2, 3, 4, 5)
578
tuple[5:None:-1] -> (5, 4, 3, 2, 1)
579
tuple[-5:5:None] -> (1, 2, 3, 4, 5)
580
tuple[None:None:None] -> (1, 2, 3, 4, 5)
582
tuple[5:1:-3] -> (5,)
584
bytes[0:5:1] -> 12345
585
bytes[5:0:-1] -> 5432
586
bytes[None:5:1] -> 12345
587
bytes[5:None:-1] -> 54321
588
bytes[-5:5:None] -> 12345
589
bytes[None:None:None] -> 12345
593
unicode[0:5:1] -> 12345
594
unicode[5:0:-1] -> 5432
595
unicode[None:5:1] -> 12345
596
unicode[5:None:-1] -> 54321
597
unicode[-5:5:None] -> 12345
598
unicode[None:None:None] -> 12345
603
... try: slice_fused_type_stop_and_step(v, len(l), 0)
604
... except ValueError: pass
605
... try: slice_fused_type_stop_and_step(v, len(l), v)
606
... except TypeError: pass
608
obj = seq[start:stop:step]