def test_nested_templates(): (i1, i2,), map_ = DeclResolver.resolve_decls_from_string(""" from libcpp.string cimport string as libcpp_string from libcpp.vector cimport vector as libcpp_vector cdef extern from "templated.hpp": cdef cppclass T: T(int) T(T) # wrap-ignore int get() cdef cppclass Templated[X]: # wrap-instances: # Templated := Templated[T] Templated(X) libcpp_vector[Templated[X]] reverse(libcpp_vector[Templated[X]] v) int getTwice(Templated[X]) """) rev, = i2.methods.get("reverse") (n, t), = rev.arguments assert str(t) == "libcpp_vector[Templated]" rev, = i2.methods.get("getTwice") (n, t), = rev.arguments assert str(t) == "Templated", str(t)
def test_method_resolution_in_template_class(): decls, instance_mapping = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": ctypedef int X cdef cppclass T[Y]: # wrap-instances: # T := T[float] Y fun(X i) C[Y] gun(C[X] i) T[Y] hun(T[Y] j) """) T, X = sorted(decls, key=lambda d: d.name) assert T.name == "T" fun, = T.methods.get("fun") assert str(fun.result_type) == "float" (n, t), = fun.arguments assert str(t) == "int" assert n == "i" gun, = T.methods.get("gun") assert str(gun.result_type) == "C[float]" (n, t), = gun.arguments assert str(t) == "C[int]" assert n == "i" gun, = T.methods.get("hun") assert str(gun.result_type) == "T" (n, t), = gun.arguments assert str(t) == "T" assert n == "j"
def test_typedef_with_class3(): decls, map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "X.h": ctypedef int X cdef cppclass A[B,C]: # wrap-instances: # A := A[X *,int] X foo(C*) C* bar(B) """) A, X = sorted(decls, key=lambda d: d.name) assert A.name == "A" assert str(map_.get("A")) == "A[int *,int]" foo, = A.methods.get("foo") assert str(foo.result_type) == "int", foo.result_type (__, arg_t), = foo.arguments assert str(arg_t) == "int *", str(arg_t) bar, = A.methods.get("bar") assert str(bar.result_type) == "int *" (__, arg_t), = bar.arguments assert str(arg_t) == "int *", str(arg_t)
def test_nested_templates(): ( i1, i2, ), map_ = DeclResolver.resolve_decls_from_string(""" from libcpp.string cimport string as libcpp_string from libcpp.vector cimport vector as libcpp_vector cdef extern from "templated.hpp": cdef cppclass T: T(int) T(T) # wrap-ignore int get() cdef cppclass Templated[X]: # wrap-instances: # Templated := Templated[T] Templated(X) libcpp_vector[Templated[X]] reverse(libcpp_vector[Templated[X]] v) int getTwice(Templated[X]) """) rev, = i2.methods.get("reverse") (n, t), = rev.arguments assert str(t) == "libcpp_vector[Templated]" rev, = i2.methods.get("getTwice") (n, t), = rev.arguments assert str(t) == "Templated", str(t)
def test_typedef_with_class(): decls, map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "X.h": ctypedef int X ctypedef int * Y cdef cppclass A[B]: # wrap-instances: # A := A[X] X foo(B) B bar(X *) Y fun(X *) """) A, X_, Y, fun = sorted(decls, key=lambda d: d.name) assert A.name == "A" assert str(map_.get("A")) == "A[int]" foo, = A.methods.get("foo") assert str(foo.result_type) == "int", foo.result_type (__, arg_t), = foo.arguments assert str(arg_t) == "int", str(arg_t) bar, = A.methods.get("bar") assert str(bar.result_type) == "int" (__, arg_t), = bar.arguments assert str(arg_t) == "int *" assert fun.name == "fun" assert str(fun.result_type) == "int *" (__, arg_t), = fun.arguments assert str(arg_t) == "int *", str(arg_t)
def test_method_return_values(): (resolved,), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "minimal.hpp": cdef cppclass Minimal: Minimal create() """) meth, = resolved.methods.get("create") assert str(meth.result_type) == "Minimal"
def test_without_header(): # broken return resolved, = DeclResolver.resolve_decls_from_string(""" cdef extern: ctypedef int X X fun(X x) """)
def test_method_return_values(): (resolved, ), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "minimal.hpp": cdef cppclass Minimal: Minimal create() """) meth, = resolved.methods.get("create") assert str(meth.result_type) == "Minimal"
def test_non_template_class_with_annotation(): (instance,), map_I = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": cdef cppclass A: # wrap-instances: # B := A pass """) assert instance.name == "B"
def test_non_template_class_with_annotation(): (instance, ), map_I = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": cdef cppclass A: # wrap-instances: # B := A pass """) assert instance.name == "B"
def double_ptr_typedef(): (function, ), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "X.h": ctypedef int X ctypedef X * iptr ctypedef X * Y ctypedef Y * iptr2 iptr2 fun(iptr, Y) """)
def ctypedef_with_cycle(): (function, ), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "X.h": ctypedef int X ctypedef X Y ctypedef Y Z ctypedef Z X iptr2 fun(iptr, Y) """)
def ctypedef_with_cycle(): (function,), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "X.h": ctypedef int X ctypedef X Y ctypedef Y Z ctypedef Z X iptr2 fun(iptr, Y) """)
def double_ptr_typedef(): (function,), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "X.h": ctypedef int X ctypedef X * iptr ctypedef X * Y ctypedef Y * iptr2 iptr2 fun(iptr, Y) """)
def test_template_class_with_ptrtype(): (instance, ), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": cdef cppclass A[X]: # wrap-instances: # Ax := A[int*] pass """) assert instance.name == "Ax" real_type, = map_.values() assert str(real_type) == "A[int *]", str(real_type)
def test_template_class_with_ptrtype(): (instance,), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": cdef cppclass A[X]: # wrap-instances: # Ax := A[int*] pass """) assert instance.name == "Ax" real_type, = map_.values() assert str(real_type) == "A[int *]", str(real_type)
def test_multi_inherit(): resolved, map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": cdef cppclass A[U]: # wrap-ignore void Afun(U, int) cdef extern from "B.h": cdef cppclass B[X]: # wrap-ignore # wrap-inherits: # A[X] X BIdentity(X) cdef extern from "C.h": cdef cppclass C[Y]: # wrap-ignore # wrap-inherits: # A[Y] void Cint(int, Y) cdef extern from "D.h": cdef cppclass D[F, G]: # wrap-inherits: # B[G] # C[F] # # wrap-instances: # D1 := D[float,int] # D2 := D[int,float] pass """) data = dict() for class_instance in resolved: mdata = [] for m in class_instance.get_flattened_methods(): li = [str(m.result_type), m.name] li += [str(t) for n, t in m.arguments] mdata.append(li) data[class_instance.name] = sorted(mdata) assert data == { 'D1': sorted([['void', 'Afun', 'int', 'int'], ['void', 'Afun', 'float', 'int'], ['int', 'BIdentity', 'int'], ['void', 'Cint', 'int', 'float']]), 'D2': sorted([['void', 'Afun', 'float', 'int'], ['void', 'Afun', 'int', 'int'], ['float', 'BIdentity', 'float'], ['void', 'Cint', 'int', 'int']]) }
def test_copy_cons_decl_for_templated_class(): (A, ), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "": cdef cppclass A[T]: # wrap-instances: # A := A[int] A(A[T] &) """) assert A.name == "A" m, = A.methods["A"] print(m)
def test_typedef_with_fun(): decls, map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "X.h": ctypedef int X X fun(X x) """) X, fun = sorted(decls, key=lambda d: d.name) assert fun.name == "fun" assert str(fun.result_type) == "int" (n, t), = fun.arguments assert n == "x" assert str(t) == "int"
def test_copy_cons_decl_for_templated_class(): (A,), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "": cdef cppclass A[T]: # wrap-instances: # A := A[int] A(A[T] &) """) assert A.name == "A" m, = A.methods["A"] print (m)
def test_with_no_gil_annotation(): (instance, ), map_I = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": cdef cppclass A: A() void Expensive() nogil # wrap-with-no-gil void Cheap() """) assert instance.name == "A" method, = instance.methods.get("Expensive") assert method.with_nogil method, = instance.methods.get("Cheap") assert not method.with_nogil
def test_with_no_gil_annotation(): (instance,), map_I = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": cdef cppclass A: A() void Expensive() nogil # wrap-with-no-gil void Cheap() """) assert instance.name == "A" method, = instance.methods.get("Expensive") assert method.with_nogil method, = instance.methods.get("Cheap") assert not method.with_nogil
def test_multi_inherit(): resolved, map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": cdef cppclass A[U]: # wrap-ignore void Afun(U, int) cdef extern from "B.h": cdef cppclass B[X]: # wrap-ignore # wrap-inherits: # A[X] X BIdentity(X) cdef extern from "C.h": cdef cppclass C[Y]: # wrap-ignore # wrap-inherits: # A[Y] void Cint(int, Y) cdef extern from "D.h": cdef cppclass D[F, G]: # wrap-inherits: # B[G] # C[F] # # wrap-instances: # D1 := D[float,int] # D2 := D[int,float] pass """) data = dict() for class_instance in resolved: mdata = [] for m in class_instance.get_flattened_methods(): li = [str(m.result_type), m.name] li += [str(t) for n, t in m.arguments] mdata.append(li) data[class_instance.name] = sorted(mdata) assert data == {'D1': sorted([['void', 'Afun', 'int', 'int'], ['void', 'Afun', 'float', 'int'], ['int', 'BIdentity', 'int'], ['void', 'Cint', 'int', 'float']]), 'D2': sorted([['void', 'Afun', 'float', 'int'], ['void', 'Afun', 'int', 'int'], ['float', 'BIdentity', 'float'], ['void', 'Cint', 'int', 'int']])}
def test_typedef_chaining(): decls, map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "X.h": ctypedef int X ctypedef X* iptr ctypedef X Y ctypedef Y* iptr2 iptr2 fun(iptr, Y *) """) X, Y, fun, iptr, iptr2 = sorted(decls, key=lambda d: d.name) assert str(fun.result_type) == "int *" t1, t2 = map(str, (t for (n, t) in fun.arguments)) assert t1 == "int *", t1 assert t2 == "int *", t2
def test_function_resolution(): decls, instance_mapping = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": ctypedef int X ctypedef float Y Y fun(X i) C[Y] gun(C[X] i) """) X, Y, fun, gun = sorted(decls, key=lambda d: d.name) assert str(fun.result_type) == "float" (n, t), = fun.arguments assert str(t) == "int" assert n == "i" assert str(gun.result_type) == "C[float]" (n, t), = gun.arguments assert str(t) == "C[int]" assert n == "i"
def test_class_and_enum(): (A, E), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "": cdef cppclass A: A() cdef enum E: A, B, C """) assert A.name == "A" method, = A.methods.values()[0] assert method.name == "A" assert len(method.arguments) == 0 assert E.name == "E" A, B, C = E.items assert A == ("A", 0) assert B == ("B", 1) assert C == ("C", 2)
def test_method_resolution(): decls, instance_mapping = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": ctypedef int X ctypedef float Y cdef cppclass T: Y fun(X i) C[Y] gun(C[X] i) """) T, X, Y = sorted(decls, key=lambda d: d.name) assert T.name == "T" fun, = T.methods.get("fun") assert str(fun.result_type) == "float" (n, t), = fun.arguments assert str(t) == "int" assert n == "i" gun, = T.methods.get("gun") assert str(gun.result_type) == "C[float]" (n, t), = gun.arguments assert str(t) == "C[int]" assert n == "i"
def test_multi_decls_in_one_file(): (inst1, inst2, enum), map_ = DeclResolver.resolve_decls_from_string(""" cdef extern from "A.h": cdef cppclass A[B,C] : # wrap-instances: # A := A[int,int] pass cdef cppclass C[E] : # wrap-instances: # C := C[float] pass cdef enum F: G, H=4, I """) assert inst1.name == "A" T1, T2 = inst1.cpp_decl.template_parameters assert T1 == "B", T1 assert T2 == "C", T2 assert len(inst1.methods) == 0 assert inst2.name == "C" T1, = inst2.cpp_decl.template_parameters assert T1 == "E", T1 assert len(inst2.methods) == 0 assert enum.name == "F" G, H, I = enum.items assert G == ("G", 0) assert H == ("H", 4) assert I == ("I", 5) assert str(map_["A"]) == "A[int,int]" assert str(map_["C"]) == "C[float]" assert str(map_["F"]) == "F"