Templated instances defined by wrap-instances are not resolved by PXDParser
Defining a templated class with instances specified by wrap-instances in a PXD file does not make the instanced type available for template resolution in another PXD file.
Example: in file a.pxd:
cdef cppclass IteratorWrapper[Iterator]:
# wrap-instances:
# ScoreTypeRef := IteratorWrapper[libcpp_set[ ScoreType ].iterator]
...
in file b.pxd:
libcpp_vector[ ScoreTypeRef ] assigned_scores
results in:
b.pxd:XX:YY: unknown type in template argument
Looking at the pyx code generated by a ScoreTypeRef is properly generated, in b however the templated type is just error.
Hi,
can you add test files, add the test to e.g. test_code_generator and open a PR?
Does it work with more basic instantiation? E.g. # ScoreTypeRef := IteratorWrapper[A]
It looks like it doesn't work with the more basic instantiation either. Looking at our existing codebase it looks like wrap-instances are only used locally, so it may be this issue has never come up.
ahh hmm that might also be the cause, yes. Can you check if it works locally in the same pxd file?
Is a cimport for ScoreTypeRef generated in the b.pxd file?
It appears to not work even in the same pxd file (though it's necessarily in a different cdef extern from block on account of coming from different cpp files)
Yup.
There is a similar test for this in autowrap already. There we just explicitly specify the instantiation again. https://github.com/OpenMS/autowrap/blob/04192b9ab6ed74d9d72c032587e222dbbfdb6a38/tests/test_files/templated.pxd#L45
Probably only "cppclass"es can be put as template parameter. And the instantiation is already a cython "class".
So at least in the triply nested case libcpp_vector[ IteratorWrapper [ libcpp_set [ ScoreType ] ] ] assigned_scores this fails.
Probably only "cppclass"es can be put as template parameter. And the instantiation is already a cython "class".
libcpp_vector[ IteratorWrapper [ libcpp_set [ String ] ] ] assigned_scores also fails, so I think its probably how deeply nested these are allowed.
yes I can confirm.
self = <autowrap.Types.CppType object at 0x113478700>
typemap = {'T': <autowrap.Types.CppType object at 0x113703520>, 'T2': <autowrap.Types.CppType object at 0x113703910>, 'Templated': <autowrap.Types.CppType object at 0x113703040>, 'Templated_other': <autowrap.Types.CppType object at 0x113703700>, ...}
indent = 0
def _transform(self, typemap, indent):
aliased_t = typemap.get(self.base_type)
if aliased_t is not None:
if self.template_args is not None:
if aliased_t.template_args is not None:
map_ = printable(typemap, "\n ")
m = "invalid transform of %s with:\n %s" % (self, map_)
> raise Exception(m)
E Exception: invalid transform of Templated[libcpp_vector[T]] with:
E T -> _T
E T2 -> _T2
E Templated -> _Templated[_T]
E Templated_other -> _Templated[_T2]
E Y -> _Y
E Z -> _Z
autowrap/Types.py:92: Exception
What if you introduce (c)typedefs for now? Let me try
What if you introduce (c)typedefs for now? Let me try
That at least gives us a more detailed error message:
Exception: Recursion in std::vector<T> is not implemented for other STL methods and wrapped template arguments