add a None check, except for plain extension type names
authorStefan Behnel <scoder@users.berlios.de>
Sat, 31 Oct 2009 13:17:41 +0000 (14:17 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Sat, 31 Oct 2009 13:17:41 +0000 (14:17 +0100)
Cython/Compiler/Optimize.py
tests/run/tp_new.pyx

index c26a32a588c451742c978c62f1799e38dcc45474..44a9cda0353bb9e932c8530d1138f1592f383c12 100644 (file)
@@ -1076,9 +1076,15 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
                 PyrexTypes.CFuncTypeArg("type", PyrexTypes.py_object_type, None)
                 ])
 
+        if not type_arg.type_entry:
+            # arbitrary variable, needs a None check for safety
+            type_arg = ExprNodes.NoneCheckNode(
+                type_arg, "PyExc_TypeError",
+                "object.__new__(X): X is not a type object (NoneType)")
+
         return ExprNodes.PythonCapiCallNode(
             node.pos, "__Pyx_tp_new", func_type,
-            args = args,
+            args = [type_arg],
             utility_code = tpnew_utility_code,
             is_temp = node.is_temp
             )
index 87ad202e152c618ac8b24b61afb6a1bb16c78c83..d176fc3b3781c304cf7aa58a7a2e69cfae09f5ab 100644 (file)
@@ -41,6 +41,17 @@ def make_new_builtin():
     m = tuple.__new__(tuple)
     return m
 
+@cython.test_assert_path_exists('//PythonCapiCallNode')
+@cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode')
+def make_new_none(type t=None):
+    """
+    >>> isinstance(make_new_none(), MyType)
+    Traceback (most recent call last):
+    TypeError: object.__new__(X): X is not a type object (NoneType)
+    """
+    m = t.__new__(t)
+    return m
+
 # these cannot:
 
 @cython.test_assert_path_exists('//SimpleCallNode/AttributeNode')
@@ -81,24 +92,13 @@ def make_new_args(type t1=None, type t2=None):
 
 @cython.test_assert_path_exists('//SimpleCallNode/AttributeNode')
 @cython.test_fail_if_path_exists('//PythonCapiCallNode')
-def make_new_none(type t1=None, type t2=None):
-    """
-    >>> isinstance(make_new_none(), MyType)
-    Traceback (most recent call last):
-    TypeError: object.__new__(X): X is not a type object (NoneType)
-    """
-    m = t1.__new__(t2)
-    return m
-
-@cython.test_assert_path_exists('//SimpleCallNode/AttributeNode')
-@cython.test_fail_if_path_exists('//PythonCapiCallNode')
-def make_new_none_typed(tuple t1=None, tuple t2=None):
+def make_new_none_typed(tuple t=None):
     """
     >>> isinstance(make_new_none(), MyType)
     Traceback (most recent call last):
     TypeError: object.__new__(X): X is not a type object (NoneType)
     """
-    m = t1.__new__(t2)
+    m = t.__new__(t)
     return m
 
 @cython.test_assert_path_exists('//SimpleCallNode/AttributeNode')