prevent Py_UNICODE from becoming a plain integer during arithmetic operations
authorStefan Behnel <scoder@users.berlios.de>
Wed, 12 May 2010 14:24:29 +0000 (16:24 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Wed, 12 May 2010 14:24:29 +0000 (16:24 +0200)
Cython/Compiler/ExprNodes.py
Cython/Compiler/PyrexTypes.py
tests/run/unicode_indexing.pyx

index 8d728365d75b7edd90e24df0bb4bdd9518e6bfbe..3c49e88b4d8253ecf3b722087ff8e9c7d4375edb 100755 (executable)
@@ -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]
 
index d4cecbd53d0b852af759adf43f376ec17656a236..f76922bb1cf89044921c80021f1ace45c804197e 100755 (executable)
@@ -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
index 1f124fd6f972bd4ad5fe5f2bdbb3d5d4a96aec8d..1032d52dbc397c550a0794609090af3c163d6b3f 100644 (file)
@@ -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]