From dfcca8d86b7dd4bb2a8076ea9a2febf1b278f05f Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Fri, 12 Feb 2010 02:31:57 -0800 Subject: [PATCH] Infer common basetype for extension types. --- Cython/Compiler/PyrexTypes.py | 11 +++++++++++ tests/run/type_inference.pyx | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index d2e16663..e9c4ff38 100755 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -2366,6 +2366,17 @@ def spanning_type(type1, type2): return widest_numeric_type(type1, c_double_type) elif type1.is_pyobject ^ type2.is_pyobject: return py_object_type + elif type1.is_extension_type and type2.is_extension_type: + if type1.typeobj_is_imported() or type2.typeobj_is_imported(): + return py_object_type + while True: + if type1.subtype_of(type2): + return type2 + elif type2.subtype_of(type1): + return type1 + type1, type2 = type1.base_type, type2.base_type + if type1 is None or type2 is None: + return py_object_type elif type1.assignable_from(type2): if type1.is_extension_type and type1.typeobj_is_imported(): # external types are unsafe, so we use PyObject instead diff --git a/tests/run/type_inference.pyx b/tests/run/type_inference.pyx index 8ef4e2b4..b61cf191 100644 --- a/tests/run/type_inference.pyx +++ b/tests/run/type_inference.pyx @@ -304,3 +304,36 @@ def args_tuple_keywords_reassign_pyobjects(*args, **kwargs): args = [] kwargs = "test" + +# / A -> AA -> AAA +# Base0 -> Base - +# \ B -> BB +# C -> CC + +cdef class Base0: pass +cdef class Base(Base0): pass +cdef class A(Base): pass +cdef class AA(A): pass +cdef class AAA(AA): pass +cdef class B(Base): pass +cdef class BB(B): pass +cdef class C: pass +cdef class CC(C): pass + +@infer_types(None) +def common_extension_type_base(): + """ + >>> common_extension_type_base() + """ + x = A() + x = AA() + assert typeof(x) == "A", typeof(x) + y = A() + y = B() + assert typeof(y) == "Base", typeof(y) + z = AAA() + z = BB() + assert typeof(z) == "Base", typeof(z) + w = A() + w = CC() + assert typeof(w) == "Python object", typeof(w) -- 2.26.2