pythonc++templatesbindingcppyy

Cppyy pythonization with templates?


Is there a way to write pythonizations in cppyy that work for all templates?

I have a class in C++ that requires a template

template <typename TValueType>
Bound<TValueType> Bound<TValueType>::buildInclusiveBound(TValueType value) {
  return Bound<TValueType>{BoundCategory::Inclusive, value};
}

I noticed that when I was writing a pythonization of this function, this did not work

import cppyy.gbl as Cpp

Cpp.Bound.__str__ = lambda self: "test" 

but

import cppyy.gbl as Cpp

Cpp.Bound['double'].__str__ = lambda self: "test" 

did.


Solution

  • Bound isn't a class just as much as e.g. std::vector isn't, so there's no Python proxy to Pythonize. Easiest solution is probably a name check using a pre-registered pythonizor. Example:

    import cppyy
    
    cppyy.cppdef(r"""\
    namespace MyNamespace {
    template<typename T>
    class MyClass {
    public:
        MyClass(T t) : m_data(t) {}
        T m_data;
    };
    }""")
    
    def pythonize_myclass(klass, name):
        if 'MyClass' in name:
            klass.__str__ = lambda x: str(x.m_data)
    
    cppyy.py.add_pythonization(pythonize_myclass, 'MyNamespace')
    
    mi = cppyy.gbl.MyNamespace.MyClass[int](42)
    print(mi)
    
    md = cppyy.gbl.MyNamespace.MyClass['double'](42.)
    print(md)