Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cython and overloaded c++ constructors

Is there a standardized (or commonly accepted way) to tackle the issue of not being able to overload __cinit__ methods in cython when wrapping C++ classes?

There is the possibility of making __cinit__ take *args and **kwargs to contain parameters and inside the __cinit__ scope select the way to generate the C++ instance according to certain pattern. This approach however has complications:

  • Trying to identify the correct constructor from the arguments might be dangerous in certain circumstances unless the arguments are named and passed as kwargs which might become cumbersome for users.
  • When the arguments are not invoked by their type in the __cinit__ argument list, they are passed as Python objects. In my working case, the arguments are Python wrappers for C++ classes, and trying to retrieve these instances "thisptr" is a task of the devil when they are passed as Python objects from the *args or **kwargs.
  • The implied need of using a sequence of if... elif... else cases to select a C++ constructor from the argument combination ultimately becomes quite messy.

So there has to be a better way. One way may be using the classmethod approach (e.g. see: classmethod to overload __init__ behavior in Python). Nevertheless, as far as I know (and please correct me if I'm wrong), classmethod implies invoking methods with names different of the class name and this does not resemble well the C++ way of constructing instances with just one class name.

Any ideas on this?

like image 366
vladimir montealegre Avatar asked Dec 28 '25 21:12

vladimir montealegre


1 Answers

Personally, I would use classmethods.

WrapperClass.fromSpambar(spambar)

It's not that puzzlin imho. If you wouldn't be able to overload functions in C++, you'd need to fallback to this approach as well.

In case you can accept some heavy weighted operations on initialization, you could implement a method to recognize the way the constructor was called by defining "patterns" or similar. I.e. Regular Expressions for args and kwargs. ;)

I don't see the problem of getting the thisptr from a Python-object.

cdef WrapperClass wrpclsi
if isinstance(instance, WrapperClass):
    wrpclsi = instance
else:
    raise TypeError('expected instance of WrapperClass.')

cdef WrappedClassFromCpp* thisptr = wrpclsi.thisptr 
like image 68
Niklas R Avatar answered Dec 31 '25 11:12

Niklas R