Cython: overloaded constructor initialization using raw pointer
Question: I'm trying to wrap two C++ classes: Cluster and ClusterTree. ClusterTree has a
method get_current_cluster() that instantiates a Cluster object, and returns a
reference to it. ClusterTree owns the Cluster object, and manages its creation
and deletion in C++.

I've wrapped Cluster with cython, resulting in PyCluster.

PyCluster should have two ways of creation:

1) By passing in two arrays, which then implies that Python should then
automatically handle deletion (via __dealloc__)  
2) By directly passing in a raw C++ pointer (created by ClusterTree's
get_current_cluster()). In this case, ClusterTree then assumes responsibility
of deleting the underlying pointer.

    
    
    from libcpp cimport bool
    from libcpp.vector cimport vector
    
    cdef extern from "../include/Cluster.h" namespace "Terran":
        cdef cppclass Cluster:
            Cluster(vector[vector[double]],vector[int]) except +
    
    cdef class PyCluster:
        cdef Cluster* __thisptr
        __autoDelete = True
    
        def __cinit__(self, vector[vector[double]] data, vector[int] period):
            self.__thisptr = new Cluster(data, period)  
    
        @classmethod
        def __constructFromRawPointer(self, raw_ptr):
            self.__thisptr = raw_ptr
            self.__autoDelete = False
    
        def __dealloc__(self):
            if self.__autoDelete:
                del self.__thisptr
    
    cdef extern from "../include/ClusterTree.h" namespace "Terran":
        cdef cppclass ClusterTree:
            ClusterTree(vector[vector[double]],vector[int]) except +
            Cluster& getCurrentCluster()
    
    cdef class PyClusterTree:
    
        cdef ClusterTree *__thisptr
    
        def __cinit__(self, vector[vector[double]] data, vector[int] period):
            self.__thisptr = new ClusterTree(data,period)
    
        def __dealloc__(self):
            del self.__thisptr
    
        def get_current_cluster(self):
    
            cdef Cluster* ptr = &(self.__thisptr.getCurrentCluster())
            return PyCluster.__constructFromRawPointer(ptr)
    

This results in:

    
    
    Error compiling Cython file:
    ------------------------------------------------------------
    ...
        def get_current_cluster(self):
            cdef Cluster* ptr = &(self.__thisptr.getCurrentCluster())
            return PyCluster.__constructFromRawPointer(ptr)
                                                         ^
    ------------------------------------------------------------
    
    terran.pyx:111:54: Cannot convert 'Cluster *' to Python object
    

Note I cannot cdef __init__ or @classmethods.


Answer: I know this is an old question, but after my own recent struggles with Cython
I thought I'd post an answer for the sake of posterity.

It seems to me you could use a copy constructor to create a new PyCluster
object from an existing Cluster object.

Define the copy constructor in your C code, then call the copy constructor in
the Python class definition (in this case, when a pointer is passed) using
`new`. This will work, although it may not be the best or most performant
solution.

