From 124fd89aaae0671f1ec6b68684a02c76d76ba776 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Sat, 3 Oct 2009 22:37:02 -0700 Subject: [PATCH] Type inference tests. --- Cython/Compiler/ExprNodes.py | 7 ++- Cython/Compiler/Options.py | 2 +- Cython/Compiler/TypeInference.py | 3 +- tests/run/isinstance.pyx | 2 +- tests/run/type_inference.pyx | 80 ++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 tests/run/type_inference.pyx diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index a1a36cf8..6c918eb6 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -13,7 +13,7 @@ import Nodes from Nodes import Node import PyrexTypes from PyrexTypes import py_object_type, c_long_type, typecast, error_type, unspecified_type -from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type, bytes_type +from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type, bytes_type, type_type import Builtin import Symtab import Options @@ -990,6 +990,11 @@ class NameNode(AtomicExprNode): self.entry = env.lookup(self.name) if self.entry is None: return py_object_type + elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \ + self.name == self.entry.type.name: + # Unfortunately the type attribute of type objects + # is used for the pointer to the type the represent. + return type_type else: return self.entry.type diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py index 13787e24..8f551999 100644 --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py @@ -68,7 +68,7 @@ option_defaults = { 'c99_complex' : False, # Don't use macro wrappers for complex arith, not sure what to name this... 'callspec' : "", 'profile': False, - 'infer_types': True, + 'infer_types': False, 'autotestdict': True, # test support diff --git a/Cython/Compiler/TypeInference.py b/Cython/Compiler/TypeInference.py index 0d9b2753..d5b4ef58 100644 --- a/Cython/Compiler/TypeInference.py +++ b/Cython/Compiler/TypeInference.py @@ -152,7 +152,8 @@ class SimpleAssignmentTypeInferer: if types: entry.type = reduce(spanning_type, types) else: - print "No assignments", entry.pos, entry + # List comprehension? + # print "No assignments", entry.pos, entry entry.type = py_object_type resolve_dependancy(entry) # Deal with simple circular dependancies... diff --git a/tests/run/isinstance.pyx b/tests/run/isinstance.pyx index 12dbd08c..19336b97 100644 --- a/tests/run/isinstance.pyx +++ b/tests/run/isinstance.pyx @@ -35,7 +35,7 @@ def test_all(): assert not isinstance(u"foo", int) # Non-optimized - foo = A + cdef object foo = A assert isinstance(A(), foo) assert isinstance(0, (int, long)) assert not isinstance(u"xyz", (int, long)) diff --git a/tests/run/type_inference.pyx b/tests/run/type_inference.pyx new file mode 100644 index 00000000..1f542b5d --- /dev/null +++ b/tests/run/type_inference.pyx @@ -0,0 +1,80 @@ +# cython: infer_types = True + +__doc__ = u""" + >>> simple() + >>> multiple_assignments() + >>> arithmatic() + >>> cascade() + >>> increment() + >>> loop() +""" + +from cython cimport typeof + +def simple(): + i = 3 + assert typeof(i) == "long" + x = 1.41 + assert typeof(x) == "double" + xptr = &x + assert typeof(xptr) == "double *" + xptrptr = &xptr + assert typeof(xptrptr) == "double **" + s = "abc" + assert typeof(s) == "char *" + u = u"xyz" + assert typeof(u) == "unicode object" + L = [1,2,3] + assert typeof(L) == "list object" + t = (4,5,6) + assert typeof(t) == "tuple object" + +def multiple_assignments(): + a = 3 + a = 4 + a = 5 + assert typeof(a) == "long" + b = a + b = 3.1 + b = 3.14159 + assert typeof(b) == "double" + c = a + c = b + c = [1,2,3] + assert typeof(c) == "Python object" + +def arithmatic(): + a = 1 + 2 + assert typeof(a) == "long" + b = 1 + 1.5 + assert typeof(b) == "double" + c = 1 + 2 + assert typeof(c) == "Python object" + d = "abc %s" % "x" + assert typeof(d) == "Python object" + +def cascade(): + a = 1.0 + b = a + 2 + c = b + 3 + d = c + 4 + assert typeof(d) == "double" + e = a + b + c + d + assert typeof(e) == "double" + +def increment(): + a = 5 + a += 1 + assert typeof(a) == "long" + +def loop(): + for a in range(10): + pass + assert typeof(a) == "long" + b = 1.0 + for b in range(5): + pass + assert typeof(b) == "double" + for c from 0 <= c < 10 by .5: + pass + assert typeof(c) == "double" -- 2.26.2