From 5c478f42c92bca4bd48db993273e01ed636d6a34 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Mon, 4 May 2009 13:58:06 +0200 Subject: [PATCH] slicing a builtin type will return the same type --- Cython/Compiler/Builtin.py | 3 +- Cython/Compiler/ExprNodes.py | 19 ++++++++--- tests/run/typed_slice.pyx | 62 ++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 tests/run/typed_slice.pyx diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py index e72a1df8..12823aa9 100644 --- a/Cython/Compiler/Builtin.py +++ b/Cython/Compiler/Builtin.py @@ -368,12 +368,13 @@ def init_builtins(): init_builtin_funcs() init_builtin_types() init_builtin_structs() - global list_type, tuple_type, dict_type, set_type, unicode_type, type_type + global list_type, tuple_type, dict_type, set_type, bytes_type, unicode_type, type_type type_type = builtin_scope.lookup('type').type list_type = builtin_scope.lookup('list').type tuple_type = builtin_scope.lookup('tuple').type dict_type = builtin_scope.lookup('dict').type set_type = builtin_scope.lookup('set').type + bytes_type = builtin_scope.lookup('bytes').type unicode_type = builtin_scope.lookup('unicode').type init_builtins() diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index c1bc8ea4..f248af97 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -13,7 +13,7 @@ import Nodes from Nodes import Node import PyrexTypes from PyrexTypes import py_object_type, c_long_type, typecast, error_type -from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type +from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type, bytes_type import Builtin import Symtab import Options @@ -1998,6 +1998,11 @@ class SliceIndexNode(ExprNode): def analyse_target_declaration(self, env): pass + + def analyse_target_types(self, env): + self.analyse_types(env) + # when assigning, we must accept any Python type + self.type = py_object_type def analyse_types(self, env): self.base.analyse_types(env) @@ -2005,16 +2010,20 @@ class SliceIndexNode(ExprNode): self.start.analyse_types(env) if self.stop: self.stop.analyse_types(env) - if self.base.type.is_string: - self.type = py_object_type - elif self.base.type.is_array or self.base.type.is_ptr: + base_type = self.base.type + if base_type.is_string: + self.type = bytes_type + elif base_type.is_array or base_type.is_ptr: # we need a ptr type here instead of an array type, as # array types can result in invalid type casts in the C # code - self.type = PyrexTypes.CPtrType(self.base.type.base_type) + self.type = PyrexTypes.CPtrType(base_type.base_type) else: self.base = self.base.coerce_to_pyobject(env) self.type = py_object_type + if base_type.is_builtin_type: + # slicing builtin types returns something of the same type + self.type = base_type c_int = PyrexTypes.c_py_ssize_t_type if self.start: self.start = self.start.coerce_to(c_int, env) diff --git a/tests/run/typed_slice.pyx b/tests/run/typed_slice.pyx new file mode 100644 index 00000000..3b5b04b0 --- /dev/null +++ b/tests/run/typed_slice.pyx @@ -0,0 +1,62 @@ +__doc__ = u""" + >>> l = [1,2,3,4] + + >>> slice_list(l) + [2, 3] + >>> slice_tuple(tuple(l)) + (2, 3) + + >>> l2 = l[:] + >>> slice_list_assign_list(l2) + [1, 1, 2, 3, 4, 4] + + >>> l2 = l[:] + >>> slice_list_assign_tuple(l2) + [1, 1, 2, 3, 4, 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] + + >>> slice_charp('abcdefg') + 'bc' + >>> slice_charp_repeat('abcdefg') + 'cd' +""" + +def slice_list(list l): + return l[1:3] + +def slice_list_copy(list l): + cdef list retlist = l[1:3] + return retlist + +def slice_tuple(tuple t): + return t[1:3] + +def slice_list_assign_list(list l): + l[1:3] = [1,2,3,4] + return l + +def slice_list_assign_tuple(list l): + l[1:3] = (1,2,3,4) + return l + +def slice_list_assign(list l, value): + l[1:3] = value + return l + + +def slice_charp(str py_string): + cdef char* s = py_string + return s[1:3] + +def slice_charp_repeat(str py_string): + cdef char* s = py_string + cdef str slice_val = s[1:6] + s = slice_val + return s[1:3] -- 2.26.2