From f2a4b09b94dc0783625dc869af0880742c29f58d Mon Sep 17 00:00:00 2001
From: Stefan Behnel <stefan_ml@behnel.de>
Date: Sun, 24 Feb 2013 12:14:09 +0100
Subject: [PATCH] test and fix tp_new() calling of cimported types

---
 Cython/Compiler/Optimize.py      |  2 +-
 tests/run/tp_new_cimport.srctree | 86 ++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+), 1 deletion(-)
 create mode 100644 tests/run/tp_new_cimport.srctree

diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py
index a2837b3e7..756418b32 100644
--- a/Cython/Compiler/Optimize.py
+++ b/Cython/Compiler/Optimize.py
@@ -2182,7 +2182,7 @@ class OptimizeBuiltinCalls(Visitor.MethodDispatcherTransform):
 
         if type_arg.type_entry:
             ext_type = type_arg.type_entry.type
-            if ext_type.is_extension_type and not ext_type.is_external:
+            if ext_type.is_extension_type and ext_type.typeobj_cname:
                 tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
                 slot_func_cname = TypeSlots.get_slot_function(ext_type.scope, tp_slot)
                 if slot_func_cname:
diff --git a/tests/run/tp_new_cimport.srctree b/tests/run/tp_new_cimport.srctree
new file mode 100644
index 000000000..d60d71207
--- /dev/null
+++ b/tests/run/tp_new_cimport.srctree
@@ -0,0 +1,86 @@
+PYTHON setup.py build_ext --inplace
+PYTHON -c "import tp_new_tests; tp_new_tests.test_all()"
+PYTHON -c "import tp_new_tests; tp_new_tests.test_sub()"
+
+######## setup.py ########
+
+from Cython.Build.Dependencies import cythonize
+from distutils.core import setup
+
+setup(
+    ext_modules = cythonize("**/*.pyx"),
+    )
+
+######## tp_new_tests.py ########
+
+def test_all():
+    test_a()
+    test_b()
+    test_a_in_b()
+    test_sub()
+
+def test_a():
+    import a
+    assert isinstance(a.tpnew_ExtTypeA(), a.ExtTypeA)
+    assert a.tpnew_ExtTypeA().attrA == 123
+
+def test_b():
+    import b
+    assert isinstance(b.tpnew_ExtTypeB(), b.ExtTypeB)
+    assert b.tpnew_ExtTypeB().attrB == 234
+
+def test_a_in_b():
+    import a,b
+    assert isinstance(b.tpnew_ExtTypeA(), a.ExtTypeA)
+    assert b.tpnew_ExtTypeA().attrA == 123
+
+def test_sub():
+    import b
+    assert isinstance(b.tpnew_SubExtTypeA(), b.SubExtTypeA)
+    assert b.tpnew_SubExtTypeA().attrAB == 345
+    assert b.tpnew_SubExtTypeA().attrA == 123
+
+######## a.pxd ########
+
+cdef class ExtTypeA:
+    cdef readonly attrA
+
+######## a.pyx ########
+
+cdef class ExtTypeA:
+    def __cinit__(self):
+        self.attrA = 123
+
+def tpnew_ExtTypeA():
+    return ExtTypeA.__new__(ExtTypeA)
+
+######## b.pxd ########
+
+from a cimport ExtTypeA
+
+cdef class ExtTypeB:
+    cdef readonly attrB
+
+cdef class SubExtTypeA(ExtTypeA):
+    cdef readonly attrAB
+
+######## b.pyx ########
+
+from a cimport ExtTypeA
+
+cdef class ExtTypeB:
+    def __cinit__(self):
+        self.attrB = 234
+
+cdef class SubExtTypeA(ExtTypeA):
+    def __cinit__(self):
+        self.attrAB = 345
+
+def tpnew_ExtTypeA():
+    return ExtTypeA.__new__(ExtTypeA)
+
+def tpnew_ExtTypeB():
+    return ExtTypeB.__new__(ExtTypeB)
+
+def tpnew_SubExtTypeA():
+    return SubExtTypeA.__new__(SubExtTypeA)
-- 
2.30.9