From: Stefan Behnel Date: Wed, 12 May 2010 14:24:29 +0000 (+0200) Subject: prevent Py_UNICODE from becoming a plain integer during arithmetic operations X-Git-Tag: 0.13.beta0~91 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=f30c3a6bd99cb19fb59460e7c44df4edc6a46edf;p=cython.git prevent Py_UNICODE from becoming a plain integer during arithmetic operations --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 8d728365..3c49e88b 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -5015,6 +5015,11 @@ class NumBinopNode(BinopNode): self.operand1.result(), self.operand2.result()) + def is_py_operation_types(self, type1, type2): + return (type1 is PyrexTypes.c_py_unicode_type or + type2 is PyrexTypes.c_py_unicode_type or + BinopNode.is_py_operation_types(self, type1, type2)) + def py_operation_function(self): return self.py_functions[self.operator] diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index d4cecbd5..f76922bb 100755 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -2443,6 +2443,9 @@ def spanning_type(type1, type2): return type1 elif type1 is py_object_type or type2 is py_object_type: return py_object_type + elif type1 is c_py_unicode_type or type2 is c_py_unicode_type: + # Py_UNICODE behaves more like a string than an int + return py_object_type span_type = _spanning_type(type1, type2) if span_type is None: return py_object_type diff --git a/tests/run/unicode_indexing.pyx b/tests/run/unicode_indexing.pyx index 1f124fd6..1032d52d 100644 --- a/tests/run/unicode_indexing.pyx +++ b/tests/run/unicode_indexing.pyx @@ -126,3 +126,31 @@ def index_compare_string(unicode ustring, Py_ssize_t i, unicode other): IndexError: string index out of range """ return ustring[i] == other + +@cython.test_assert_path_exists("//CoerceToPyTypeNode", + "//IndexNode", + "//MulNode", + "//MulNode/CoerceToPyTypeNode") +@cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") +def index_multiply(unicode ustring, Py_ssize_t i, int mul): + """ + >>> ustring[0] * 5 + u'aaaaa' + >>> index_multiply(ustring, 0, 5) + u'aaaaa' + """ + return ustring[i] * mul + +@cython.test_assert_path_exists("//CoerceToPyTypeNode", + "//IndexNode", + "//AddNode", + "//AddNode/CoerceToPyTypeNode") +@cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") +def index_add(unicode ustring, Py_ssize_t i, Py_ssize_t j): + """ + >>> ustring[0] + ustring[-1] + u'a6' + >>> index_add(ustring, 0, -1) + u'a6' + """ + return ustring[i] + ustring[j]