From 850c831d133aa1acfd9719e41dcd710de241c5f2 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 15 May 2010 15:57:56 +0200 Subject: [PATCH] infer plain object for bytes_string[i] and str/unicode for indexed unicode/str objects --- Cython/Compiler/ExprNodes.py | 7 +++++-- tests/run/type_inference.pyx | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index c5fe0f75..b7228de0 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1892,12 +1892,12 @@ class IndexNode(ExprNode): return self.base.type_dependencies(env) def infer_type(self, env): - if isinstance(self.base, StringNode): # FIXME: BytesNode? + if isinstance(self.base, BytesNode): return py_object_type base_type = self.base.infer_type(env) if base_type.is_ptr or base_type.is_array: return base_type.base_type - elif base_type is Builtin.unicode_type and self.index.infer_type(env).is_int: + elif base_type is unicode_type and self.index.infer_type(env).is_int: # Py_UNICODE will automatically coerce to a unicode string # if required, so this is safe. We only infer Py_UNICODE # when the index is a C integer type. Otherwise, we may @@ -1906,6 +1906,9 @@ class IndexNode(ExprNode): # to receive it, throw it away, and potentially rebuild it # on a subsequent PyObject coercion. return PyrexTypes.c_py_unicode_type + elif base_type in (str_type, unicode_type): + # these types will always return themselves on Python indexing + return base_type else: # TODO: Handle buffers (hopefully without too much redundancy). return py_object_type diff --git a/tests/run/type_inference.pyx b/tests/run/type_inference.pyx index 0abc0526..96021075 100644 --- a/tests/run/type_inference.pyx +++ b/tests/run/type_inference.pyx @@ -71,6 +71,27 @@ def slicing(): t1 = t[1:2] assert typeof(t1) == "tuple object", typeof(t1) +def indexing(): + """ + >>> indexing() + """ + b = b"abc" + assert typeof(b) == "char *", typeof(b) + b1 = b[1] + assert typeof(b1) == "char", typeof(b1) # FIXME: bytes object ?? + u = u"xyz" + assert typeof(u) == "unicode object", typeof(u) + u1 = u[1] + assert typeof(u1) == "Py_UNICODE", typeof(u1) + L = [1,2,3] + assert typeof(L) == "list object", typeof(L) + L1 = L[1] + assert typeof(L1) == "Python object", typeof(L1) + t = (4,5,6) + assert typeof(t) == "tuple object", typeof(t) + t1 = t[1] + assert typeof(t1) == "Python object", typeof(t1) + def multiple_assignments(): """ >>> multiple_assignments() @@ -197,6 +218,15 @@ def loop_over_charptr(): pass return typeof(c) +def loop_over_bytes_literal(): + """ + >>> print( loop_over_bytes_literal() ) + Python object + """ + for c in b'abcdefg': + pass + return typeof(c) + def loop_over_bytes(): """ >>> print( loop_over_bytes() ) @@ -207,6 +237,16 @@ def loop_over_bytes(): pass return typeof(c) +def loop_over_str(): + """ + >>> print( loop_over_str() ) + str object + """ + cdef str string = 'abcdefg' + for c in string: + pass + return typeof(c) + def loop_over_unicode(): """ >>> print( loop_over_unicode() ) -- 2.26.2