# mode: run # tag: list, tuple, slice, slicing cimport cython @cython.test_fail_if_path_exists("//CondExprNode") def slice_list(list l, int start, int stop): """ >>> slice_list([1,2,3,4], 1, 3) [2, 3] >>> slice_list([1,2,3,4], 1, 7) [2, 3, 4] >>> slice_list([], 1, 3) [] >>> slice_list([1], 1, 3) [] >>> slice_list([1,2,3,4], -3, -1) [2, 3] >>> slice_list([1,2,3,4], -10, -1) [1, 2, 3] >>> slice_list([], -3, -1) [] >>> slice_list([1], -3, -1) [] """ return l[start:stop] @cython.test_fail_if_path_exists("//CondExprNode") def slice_list_start(list l, int start): """ >>> slice_list_start([1,2,3,4], 1) [2, 3, 4] >>> slice_list_start([], 1) [] >>> slice_list_start([1], 1) [] >>> slice_list_start([1], 2) [] >>> slice_list_start([1,2,3,4], -3) [2, 3, 4] >>> slice_list_start([1,2,3,4], -10) [1, 2, 3, 4] >>> slice_list_start([], -3) [] >>> slice_list_start([1], -3) [1] """ return l[start:] @cython.test_fail_if_path_exists("//CondExprNode") def slice_list_stop(list l, int stop): """ >>> slice_list_stop([1,2,3,4], 3) [1, 2, 3] >>> slice_list_stop([1,2,3,4], 7) [1, 2, 3, 4] >>> slice_list_stop([], 3) [] >>> slice_list_stop([1], 3) [1] >>> slice_list_stop([1,2,3,4], -3) [1] >>> slice_list_stop([1,2,3,4], -10) [] >>> slice_list_stop([], -1) [] >>> slice_list_stop([1], -1) [] >>> slice_list_stop([1, 2], -3) [] """ return l[:stop] @cython.test_fail_if_path_exists("//CondExprNode") def slice_list_copy(list l): """ >>> slice_list_copy([]) [] >>> slice_list_copy([1,2,3]) [1, 2, 3] """ return l[:] @cython.test_fail_if_path_exists("//CondExprNode") def slice_tuple_copy(tuple l): """ >>> slice_tuple_copy(()) () >>> slice_tuple_copy((1,2,3)) (1, 2, 3) """ return l[:] @cython.test_fail_if_path_exists("//CondExprNode") def slice_tuple(tuple t, int start, int stop): """ >>> slice_tuple((1,2,3,4), 1, 3) (2, 3) >>> slice_tuple((1,2,3,4), 1, 7) (2, 3, 4) >>> slice_tuple((), 1, 3) () >>> slice_tuple((1,), 1, 3) () >>> slice_tuple((1,2,3,4), -3, -1) (2, 3) >>> slice_tuple((1,2,3,4), -10, -1) (1, 2, 3) >>> slice_tuple((), -3, -1) () >>> slice_tuple((1,), -3, -1) () """ return t[start:stop] @cython.test_fail_if_path_exists("//CondExprNode") def slice_tuple_start(tuple t, int start): """ >>> slice_tuple_start((1,2,3,4), 1) (2, 3, 4) >>> slice_tuple_start((), 1) () >>> slice_tuple_start((1,), 1) () >>> slice_tuple_start((1,2,3,4), -3) (2, 3, 4) >>> slice_tuple_start((1,2,3,4), -10) (1, 2, 3, 4) >>> slice_tuple_start((), -3) () >>> slice_tuple_start((1,), -3) (1,) """ return t[start:] @cython.test_fail_if_path_exists("//CondExprNode") def slice_tuple_stop(tuple t, int stop): """ >>> slice_tuple_stop((1,2,3,4), 3) (1, 2, 3) >>> slice_tuple_stop((1,2,3,4), 7) (1, 2, 3, 4) >>> slice_tuple_stop((), 3) () >>> slice_tuple_stop((1,), 3) (1,) >>> slice_tuple_stop((1,2,3,4), -1) (1, 2, 3) >>> slice_tuple_stop((), -1) () """ return t[:stop] @cython.test_fail_if_path_exists("//CondExprNode") def slice_list_assign_list(list l): """ >>> l = [1,2,3,4] >>> l2 = l[:] >>> slice_list_assign_list(l2) [1, 1, 2, 3, 4, 4] """ l[1:3] = [1,2,3,4] return l @cython.test_fail_if_path_exists("//CondExprNode") def slice_list_assign_tuple(list l): """ >>> l = [1,2,3,4] >>> l2 = l[:] >>> slice_list_assign_tuple(l2) [1, 1, 2, 3, 4, 4] """ l[1:3] = (1,2,3,4) return l @cython.test_fail_if_path_exists("//CondExprNode") def slice_list_assign(list l, value): """ >>> l = [1,2,3,4] >>> l2 = l[:] >>> slice_list_assign(l2, (1,2,3,4)) [1, 1, 2, 3, 4, 4] >>> l2 = l[:] >>> slice_list_assign(l2, dict(zip(l,l))) [1, 1, 2, 3, 4, 4] """ l[1:3] = value return l def slice_charp(py_string_arg): """ >>> print("%s" % slice_charp('abcdefg')) bc """ cdef bytes py_string = py_string_arg.encode(u'ASCII') cdef char* s = py_string return s[1:3].decode(u'ASCII') def slice_charp_repeat(py_string_arg): """ >>> print("%s" % slice_charp_repeat('abcdefg')) cd """ cdef bytes py_string = py_string_arg.encode(u'ASCII') cdef char* s = py_string cdef bytes slice_val = s[1:6] s = slice_val return s[1:3].decode(u'ASCII') # Readers will find the common boilerplate in the tests below: # >>> l = [1,2,3,4,5] # >>> t = tuple(l) # >>> b = ''.join(map(str, l)).encode('ASCII') # >>> u = b.decode('ASCII') # >>> o = (l, t, b, u) # >>> n = ('list', 'tuple', 'bytes', 'unicode') # >>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o) # >>> r = lambda i, *a: '%s[%s] -> %s' % (n[i], ':'.join(map(repr, a)), FUNCTION_NAME(o[i], *a)) # Originally, this was planned to be a basic iteration over # the various object types contained within the slicable fused # type, but Python2 -> Python3 semantics changed the class names # and string representations used for raw bytes and unicode. # As a result, we dynamically adjust the printed string output # for each test in order to ensure consistent results when running # both Python2 and Python3. ctypedef fused slicable: list tuple bytes unicode @cython.test_assert_path_exists("//SliceIndexNode//CondExprNode") def slice_fused_type_start(slicable seq, start): """ >>> l = [1,2,3,4,5] >>> t = tuple(l) >>> b = ''.join(map(str, l)).encode('ASCII') >>> u = b.decode('ASCII') >>> o = (l, t, b, u) >>> n = ('list', 'tuple', 'bytes', 'unicode') >>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o) >>> r = lambda i, s: '%s[%r:] -> %s' % (n[i], s, p(slice_fused_type_start(o[i], s))) >>> for i in range(len(o)): ... for s in (0, len(l) - 1, len(l), -1, -len(l), None): ... print(r(i, s)) ... list[0:] -> [1, 2, 3, 4, 5] list[4:] -> [5] list[5:] -> [] list[-1:] -> [5] list[-5:] -> [1, 2, 3, 4, 5] list[None:] -> [1, 2, 3, 4, 5] tuple[0:] -> (1, 2, 3, 4, 5) tuple[4:] -> (5,) tuple[5:] -> () tuple[-1:] -> (5,) tuple[-5:] -> (1, 2, 3, 4, 5) tuple[None:] -> (1, 2, 3, 4, 5) bytes[0:] -> 12345 bytes[4:] -> 5 bytes[5:] -> bytes[-1:] -> 5 bytes[-5:] -> 12345 bytes[None:] -> 12345 unicode[0:] -> 12345 unicode[4:] -> 5 unicode[5:] -> unicode[-1:] -> 5 unicode[-5:] -> 12345 unicode[None:] -> 12345 """ obj = seq[start:] return obj @cython.test_assert_path_exists("//SliceIndexNode//CondExprNode") def slice_fused_type_stop(slicable seq, stop): """ >>> l = [1,2,3,4,5] >>> t = tuple(l) >>> b = ''.join(map(str, l)).encode('ASCII') >>> u = b.decode('ASCII') >>> o = (l, t, b, u) >>> n = ('list', 'tuple', 'bytes', 'unicode') >>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o) >>> r = lambda i, s: '%s[:%r] -> %s' % (n[i], s, p(slice_fused_type_stop(o[i], s))) >>> for i in range(len(o)): ... for s in (0, len(l) - 1, len(l), -1, -len(l), None): ... print(r(i, s)) ... list[:0] -> [] list[:4] -> [1, 2, 3, 4] list[:5] -> [1, 2, 3, 4, 5] list[:-1] -> [1, 2, 3, 4] list[:-5] -> [] list[:None] -> [1, 2, 3, 4, 5] tuple[:0] -> () tuple[:4] -> (1, 2, 3, 4) tuple[:5] -> (1, 2, 3, 4, 5) tuple[:-1] -> (1, 2, 3, 4) tuple[:-5] -> () tuple[:None] -> (1, 2, 3, 4, 5) bytes[:0] -> bytes[:4] -> 1234 bytes[:5] -> 12345 bytes[:-1] -> 1234 bytes[:-5] -> bytes[:None] -> 12345 unicode[:0] -> unicode[:4] -> 1234 unicode[:5] -> 12345 unicode[:-1] -> 1234 unicode[:-5] -> unicode[:None] -> 12345 """ obj = seq[:stop] return obj @cython.test_assert_path_exists("//SliceIndexNode//CondExprNode") def slice_fused_type_start_and_stop(slicable seq, start, stop): """ >>> l = [1,2,3,4,5] >>> t = tuple(l) >>> b = ''.join(map(str, l)).encode('ASCII') >>> u = b.decode('ASCII') >>> o = (l, t, b, u) >>> n = ('list', 'tuple', 'bytes', 'unicode') >>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o) >>> r = lambda i, t, s: '%s[%r:%r] -> %s' % (n[i], t, s, p(slice_fused_type_start_and_stop(o[i], t, s))) >>> for i in range(len(o)): ... for start, stop in ((0, len(l)), (0, None), (None, len(l)), ... (-len(l), 0), (1, 0), (0, 1)): ... print(r(i, start, stop)) ... list[0:5] -> [1, 2, 3, 4, 5] list[0:None] -> [1, 2, 3, 4, 5] list[None:5] -> [1, 2, 3, 4, 5] list[-5:0] -> [] list[1:0] -> [] list[0:1] -> [1] tuple[0:5] -> (1, 2, 3, 4, 5) tuple[0:None] -> (1, 2, 3, 4, 5) tuple[None:5] -> (1, 2, 3, 4, 5) tuple[-5:0] -> () tuple[1:0] -> () tuple[0:1] -> (1,) bytes[0:5] -> 12345 bytes[0:None] -> 12345 bytes[None:5] -> 12345 bytes[-5:0] -> bytes[1:0] -> bytes[0:1] -> 1 unicode[0:5] -> 12345 unicode[0:None] -> 12345 unicode[None:5] -> 12345 unicode[-5:0] -> unicode[1:0] -> unicode[0:1] -> 1 """ obj = seq[start:stop] return obj def slice_fused_type_step(slicable seq, step): """ >>> l = [1,2,3,4,5] >>> t = tuple(l) >>> b = ''.join(map(str, l)).encode('ASCII') >>> u = b.decode('ASCII') >>> o = (l, t, b, u) >>> n = ('list', 'tuple', 'bytes', 'unicode') >>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o) >>> r = lambda i, s: '%s[::%r] -> %s' % (n[i], s, p(slice_fused_type_step(o[i], s))) >>> for i in range(len(o)): ... for s in (1, -1, 2, -3, 5, -5, None): ... print(r(i, s)) ... list[::1] -> [1, 2, 3, 4, 5] list[::-1] -> [5, 4, 3, 2, 1] list[::2] -> [1, 3, 5] list[::-3] -> [5, 2] list[::5] -> [1] list[::-5] -> [5] list[::None] -> [1, 2, 3, 4, 5] tuple[::1] -> (1, 2, 3, 4, 5) tuple[::-1] -> (5, 4, 3, 2, 1) tuple[::2] -> (1, 3, 5) tuple[::-3] -> (5, 2) tuple[::5] -> (1,) tuple[::-5] -> (5,) tuple[::None] -> (1, 2, 3, 4, 5) bytes[::1] -> 12345 bytes[::-1] -> 54321 bytes[::2] -> 135 bytes[::-3] -> 52 bytes[::5] -> 1 bytes[::-5] -> 5 bytes[::None] -> 12345 unicode[::1] -> 12345 unicode[::-1] -> 54321 unicode[::2] -> 135 unicode[::-3] -> 52 unicode[::5] -> 1 unicode[::-5] -> 5 unicode[::None] -> 12345 >>> for v in o: ... try: slice_fused_type_step(v, 0) ... except ValueError: pass ... try: slice_fused_type_step(v, v) ... except TypeError: pass """ obj = seq[::step] return obj def slice_fused_type_start_and_step(slicable seq, start, step): """ >>> l = [1,2,3,4,5] >>> t = tuple(l) >>> b = ''.join(map(str, l)).encode('ASCII') >>> u = b.decode('ASCII') >>> o = (l, t, b, u) >>> n = ('list', 'tuple', 'bytes', 'unicode') >>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o) >>> r = lambda i, s, t: '%s[%r::%r] -> %s' % (n[i], s, t, p(slice_fused_type_start_and_step(o[i], s, t))) >>> for i in range(len(o)): ... for start, step in ((0, 1), (0, -1), (1, 1), (1, -1), ... (None, 1), (None, -1), (None, None), ... (1, 2), (len(l), -2), (len(l), len(l))): ... print(r(i, start, step)) ... list[0::1] -> [1, 2, 3, 4, 5] list[0::-1] -> [1] list[1::1] -> [2, 3, 4, 5] list[1::-1] -> [2, 1] list[None::1] -> [1, 2, 3, 4, 5] list[None::-1] -> [5, 4, 3, 2, 1] list[None::None] -> [1, 2, 3, 4, 5] list[1::2] -> [2, 4] list[5::-2] -> [5, 3, 1] list[5::5] -> [] tuple[0::1] -> (1, 2, 3, 4, 5) tuple[0::-1] -> (1,) tuple[1::1] -> (2, 3, 4, 5) tuple[1::-1] -> (2, 1) tuple[None::1] -> (1, 2, 3, 4, 5) tuple[None::-1] -> (5, 4, 3, 2, 1) tuple[None::None] -> (1, 2, 3, 4, 5) tuple[1::2] -> (2, 4) tuple[5::-2] -> (5, 3, 1) tuple[5::5] -> () bytes[0::1] -> 12345 bytes[0::-1] -> 1 bytes[1::1] -> 2345 bytes[1::-1] -> 21 bytes[None::1] -> 12345 bytes[None::-1] -> 54321 bytes[None::None] -> 12345 bytes[1::2] -> 24 bytes[5::-2] -> 531 bytes[5::5] -> unicode[0::1] -> 12345 unicode[0::-1] -> 1 unicode[1::1] -> 2345 unicode[1::-1] -> 21 unicode[None::1] -> 12345 unicode[None::-1] -> 54321 unicode[None::None] -> 12345 unicode[1::2] -> 24 unicode[5::-2] -> 531 unicode[5::5] -> >>> for o in (l, t, b): ... try: slice_fused_type_start_and_step(o, 0, 0) ... except ValueError: pass """ obj = seq[start::step] return obj def slice_fused_type_stop_and_step(slicable seq, stop, step): """ >>> l = [1,2,3,4,5] >>> t = tuple(l) >>> b = ''.join(map(str, l)).encode('ASCII') >>> u = b.decode('ASCII') >>> o = (l, t, b, u) >>> n = ('list', 'tuple', 'bytes', 'unicode') >>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o) >>> r = lambda i, s, t: '%s[:%r:%r] -> %s' % (n[i], s, t, p(slice_fused_type_stop_and_step(o[i], s, t))) >>> for i in range(len(o)): ... for stop, step in ((len(l), 1), (len(l), None), (None, 1), ... (len(l), -1), (len(l) - 1, 2), (len(l), -2), ... (len(l), len(l))): ... print(r(i, stop, step)) ... list[:5:1] -> [1, 2, 3, 4, 5] list[:5:None] -> [1, 2, 3, 4, 5] list[:None:1] -> [1, 2, 3, 4, 5] list[:5:-1] -> [] list[:4:2] -> [1, 3] list[:5:-2] -> [] list[:5:5] -> [1] tuple[:5:1] -> (1, 2, 3, 4, 5) tuple[:5:None] -> (1, 2, 3, 4, 5) tuple[:None:1] -> (1, 2, 3, 4, 5) tuple[:5:-1] -> () tuple[:4:2] -> (1, 3) tuple[:5:-2] -> () tuple[:5:5] -> (1,) bytes[:5:1] -> 12345 bytes[:5:None] -> 12345 bytes[:None:1] -> 12345 bytes[:5:-1] -> bytes[:4:2] -> 13 bytes[:5:-2] -> bytes[:5:5] -> 1 unicode[:5:1] -> 12345 unicode[:5:None] -> 12345 unicode[:None:1] -> 12345 unicode[:5:-1] -> unicode[:4:2] -> 13 unicode[:5:-2] -> unicode[:5:5] -> 1 >>> for v in o: ... try: slice_fused_type_stop_and_step(v, len(l), 0) ... except ValueError: pass ... try: slice_fused_type_stop_and_step(v, len(l), v) ... except TypeError: pass """ obj = seq[:stop:step] return obj def slice_fused_type_all(slicable seq, start, stop, step): """ >>> l = [1,2,3,4,5] >>> t = tuple(l) >>> b = ''.join(map(str, l)).encode('ASCII') >>> u = b.decode('ASCII') >>> o = (l, t, b, u) >>> n = ('list', 'tuple', 'bytes', 'unicode') >>> p = lambda o: o.decode() if isinstance(o, type(b)) else str(o) >>> 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))) >>> for i in range(len(o)): ... for args in ((0, len(l), 1), (len(l), 0, -1), (None, len(l), 1), ... (len(l), None, -1), (-len(l), len(l), None), (None, None, None), ... (1, 3, 2), (len(l), 1, -3), (len(l), 0, 1)): ... print(r(i, *args)) ... list[0:5:1] -> [1, 2, 3, 4, 5] list[5:0:-1] -> [5, 4, 3, 2] list[None:5:1] -> [1, 2, 3, 4, 5] list[5:None:-1] -> [5, 4, 3, 2, 1] list[-5:5:None] -> [1, 2, 3, 4, 5] list[None:None:None] -> [1, 2, 3, 4, 5] list[1:3:2] -> [2] list[5:1:-3] -> [5] list[5:0:1] -> [] tuple[0:5:1] -> (1, 2, 3, 4, 5) tuple[5:0:-1] -> (5, 4, 3, 2) tuple[None:5:1] -> (1, 2, 3, 4, 5) tuple[5:None:-1] -> (5, 4, 3, 2, 1) tuple[-5:5:None] -> (1, 2, 3, 4, 5) tuple[None:None:None] -> (1, 2, 3, 4, 5) tuple[1:3:2] -> (2,) tuple[5:1:-3] -> (5,) tuple[5:0:1] -> () bytes[0:5:1] -> 12345 bytes[5:0:-1] -> 5432 bytes[None:5:1] -> 12345 bytes[5:None:-1] -> 54321 bytes[-5:5:None] -> 12345 bytes[None:None:None] -> 12345 bytes[1:3:2] -> 2 bytes[5:1:-3] -> 5 bytes[5:0:1] -> unicode[0:5:1] -> 12345 unicode[5:0:-1] -> 5432 unicode[None:5:1] -> 12345 unicode[5:None:-1] -> 54321 unicode[-5:5:None] -> 12345 unicode[None:None:None] -> 12345 unicode[1:3:2] -> 2 unicode[5:1:-3] -> 5 unicode[5:0:1] -> >>> for v in o: ... try: slice_fused_type_stop_and_step(v, len(l), 0) ... except ValueError: pass ... try: slice_fused_type_stop_and_step(v, len(l), v) ... except TypeError: pass """ obj = seq[start:stop:step] return obj