From a59eab5286e6c0e5acb7f1aa928ae024117c4c35 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Thu, 11 Feb 2010 23:31:20 +0100 Subject: [PATCH] type inference for some common operations between builtin types --- Cython/Compiler/ExprNodes.py | 22 ++++++++++++++++++++++ tests/run/type_inference.pyx | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index d4d7b350..b4f0a695 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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) diff --git a/tests/run/type_inference.pyx b/tests/run/type_inference.pyx index 0efe8634..b545902e 100644 --- a/tests/run/type_inference.pyx +++ b/tests/run/type_inference.pyx @@ -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 + 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(): """ -- 2.26.2