From f30c3a6bd99cb19fb59460e7c44df4edc6a46edf Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Wed, 12 May 2010 16:24:29 +0200 Subject: [PATCH] prevent Py_UNICODE from becoming a plain integer during arithmetic operations --- Cython/Compiler/ExprNodes.py | 5 +++++ Cython/Compiler/PyrexTypes.py | 3 +++ tests/run/unicode_indexing.pyx | 28 ++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) 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] -- 2.26.2