type inference for some common operations between builtin types
authorStefan Behnel <scoder@users.berlios.de>
Thu, 11 Feb 2010 22:31:20 +0000 (23:31 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Thu, 11 Feb 2010 22:31:20 +0000 (23:31 +0100)
Cython/Compiler/ExprNodes.py
tests/run/type_inference.pyx

index d4d7b350350ab59c25129a8c1a2e4d4c97c870a6..b4f0a695c57ae4c54dbfbbfe412edbab415336e4 100755 (executable)
@@ -4748,6 +4748,28 @@ class BinopNode(ExprNode):
     
     def result_type(self, type1, type2):
         if self.is_py_operation_types(type1, type2):
+            if type2.is_string:
+                type2 = Builtin.bytes_type
+            if type1.is_string:
+                type1 = Builtin.bytes_type
+            elif self.operator == '%' \
+                     and type1 in (Builtin.str_type, Builtin.unicode_type):
+                # note that  b'%s' % b'abc'  doesn't work in Py3
+                return type1
+            if type1.is_builtin_type:
+                if type1 is type2:
+                    if self.operator in '**%+|&^':
+                        # FIXME: at least these operators should be safe - others?
+                        return type1
+                elif self.operator == '*':
+                    if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
+                        return type1
+                    # multiplication of containers/numbers with an
+                    # integer value always (?) returns the same type
+                    if type1.is_int:
+                        return type2
+                    elif type2.is_int:
+                        return type1
             return py_object_type
         else:
             return self.compute_c_result_type(type1, type2)
index 0efe8634e1319511d80f8018576b583c89894c84..b545902e0972ff674fbc3290f6b9894cf0dd2365 100644 (file)
@@ -93,13 +93,38 @@ def arithmetic():
     >>> arithmetic()
     """
     a = 1 + 2
-    assert typeof(a) == "long"
+    assert typeof(a) == "long", typeof(a)
     b = 1 + 1.5
-    assert typeof(b) == "double"
+    assert typeof(b) == "double", typeof(b)
     c = 1 + <object>2
-    assert typeof(c) == "Python object"
-    d = "abc %s" % "x"
-    assert typeof(d) == "Python object"
+    assert typeof(c) == "Python object", typeof(c)
+
+def builtin_type_operations():
+    """
+    >>> builtin_type_operations()
+    """
+    b1 = b'a' * 10
+    assert typeof(b1) == "bytes object", typeof(b1)
+    b2 = b'a' + b'b'
+    assert typeof(b2) == "bytes object", typeof(b2)
+    u1 = u'a' * 10
+    assert typeof(u1) == "unicode object", typeof(u1)
+    u2 = u'a' + u'b'
+    assert typeof(u2) == "unicode object", typeof(u2)
+    s1 = "abc %s" % "x"
+    assert typeof(s1) == "str object", typeof(s1)
+    s2 = "abc %s" + "x"
+    assert typeof(s2) == "str object", typeof(s2)
+    s3 = "abc %s" * 10
+    assert typeof(s3) == "str object", typeof(s3)
+    L1 = [] + []
+    assert typeof(L1) == "list object", typeof(L1)
+    L2 = [] * 2
+    assert typeof(L2) == "list object", typeof(L2)
+    T1 = () + ()
+    assert typeof(T1) == "tuple object", typeof(T1)
+    T2 = () * 2
+    assert typeof(T2) == "tuple object", typeof(T2)
     
 def cascade():
     """