call Py_TYPE(x) instead of type(x)
authorStefan Behnel <scoder@users.berlios.de>
Wed, 9 Dec 2009 15:43:17 +0000 (16:43 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Wed, 9 Dec 2009 15:43:17 +0000 (16:43 +0100)
Cython/Compiler/Builtin.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/Optimize.py
tests/run/builtin_type.pyx [new file with mode: 0644]

index 8d87af992d2013d83be6b4be52f93782864c7015..6f033d1da85131509d1a104bbc50198b05562c31 100644 (file)
@@ -50,7 +50,7 @@ builtin_function_table = [
     #('round',     "",     "",      ""),
     ('setattr',    "OOO",  "r",     "PyObject_SetAttr"),
     #('sum',       "",     "",      ""),
-    ('type',       "O",    "O",     "PyObject_Type"),
+    #('type',       "O",    "O",     "PyObject_Type"),
     #('unichr',    "",     "",      ""),
     #('unicode',   "",     "",      ""),
     #('vars',      "",     "",      ""),
index f89017311b8655efd68ff463004eac24e8fbd1c1..d5b6b2f15d4544c993f5e1d6e57345ba86a97099 100644 (file)
@@ -2615,7 +2615,7 @@ class SimpleCallNode(CallNode):
                             func_type.opt_arg_cname(formal_arg.name),
                             actual_arg.result_as(formal_arg.type)))
             exc_checks = []
-            if self.type.is_pyobject:
+            if self.type.is_pyobject and self.is_temp:
                 exc_checks.append("!%s" % self.result())
             else:
                 exc_val = func_type.exception_value
index 1b1287d85b92fbd85599c329cf81ee8f69bcdcdc..c6500bbe1969c4af8853d992c87bbd79c99dc3c6 100644 (file)
@@ -843,20 +843,6 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
                 return replace_in(arg)
         return node
 
-    Pyx_Type_func_type = PyrexTypes.CFuncType(
-        Builtin.type_type, [
-            PyrexTypes.CFuncTypeArg("object", PyrexTypes.py_object_type, None)
-            ])
-
-    def _handle_simple_function_type(self, node, pos_args):
-        if len(pos_args) != 1:
-            return node
-        self._inject_capi_function(
-            node, "__Pyx_Type",
-            self.Pyx_Type_func_type,
-            pytype_utility_code)
-        return node
-
     def _handle_simple_function_float(self, node, pos_args):
         if len(pos_args) == 0:
             return ExprNodes.FloatNode(node.pos, value='0.0')
@@ -1188,6 +1174,20 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
             )
         return node
 
+    Pyx_Type_func_type = PyrexTypes.CFuncType(
+        Builtin.type_type, [
+            PyrexTypes.CFuncTypeArg("object", PyrexTypes.py_object_type, None)
+            ])
+
+    def _handle_simple_function_type(self, node, pos_args):
+        if len(pos_args) != 1:
+            return node
+        node = ExprNodes.PythonCapiCallNode(
+            node.pos, "Py_TYPE", self.Pyx_Type_func_type,
+            args = pos_args,
+            is_temp = False)
+        return ExprNodes.CastNode(node, PyrexTypes.py_object_type)
+
     ### special methods
 
     Pyx_tp_new_func_type = PyrexTypes.CFuncType(
@@ -1702,17 +1702,6 @@ bad:
 )
 
 
-pytype_utility_code = UtilityCode(
-proto = """
-static INLINE PyObject* __Pyx_Type(PyObject* o) {
-    PyObject* type = (PyObject*) Py_TYPE(o);
-    Py_INCREF(type);
-    return type;
-}
-"""
-)
-
-
 include_string_h_utility_code = UtilityCode(
 proto = """
 #include <string.h>
diff --git a/tests/run/builtin_type.pyx b/tests/run/builtin_type.pyx
new file mode 100644 (file)
index 0000000..2f92906
--- /dev/null
@@ -0,0 +1,40 @@
+cimport cython
+
+@cython.test_assert_path_exists(
+    '//PythonCapiCallNode/PythonCapiFunctionNode[@cname="Py_TYPE"]')
+def get_type_of(a):
+    """
+    >>> get_type_of(object()) is object
+    True
+    """
+    return type(a)
+
+@cython.test_assert_path_exists(
+    '//PythonCapiCallNode/PythonCapiFunctionNode[@cname="Py_TYPE"]')
+def get_type_through_local(a):
+    """
+    >>> get_type_of(object()) is object
+    True
+    """
+    t = type(a)
+    return t
+
+@cython.test_assert_path_exists(
+    '//PythonCapiCallNode/PythonCapiFunctionNode[@cname="Py_TYPE"]')
+@cython.test_fail_if_path_exists(
+    '//PythonCapiCallNode/PythonCapiFunctionNode[@cname="__Pyx_Type"]',
+    '//NameNode[@name="type"]')
+def test_type(a, t):
+    """
+    >>> test_type(object(), object)
+    True
+    """
+    return type(a) and type(a) is t and type(a) == t
+
+@cython.test_assert_path_exists('//NameNode[@name="type"]')
+def type_type():
+    """
+    >>> type_type()(object()) is object
+    True
+    """
+    return type