Cython: how to make an python object as a property of cython class

binding, c, class, cython, python

Solution

I don't think you can (http://docs.cython.org/src/userguide/sharing_declarations.html#sharing-extension-types) but you can work-around it using `__cinit__` to assert that the attribute has the correct type. The declaration `cdef public object x` of the extension type attribute has the following meaning:

- `cdef` is used to declare attributes of Cython extension types

- `public` makes the attribute accessible from Python code

- `object` is the type of the attribute, and means that it is a Python object

- `x` is the identifier of the attribute

In your Cython file (named "p.pyx" for example):

import my_python_module as q

cdef class Y:
    cdef int i
    cdef public object x  # public so it can be accessed from Python

    def __cinit__(self, x_):
        assert isinstance(x_, q.X)
        self.x = x_

and `my_python_module.py` is where you have defined your class X:

class X(object):
    def __init__(self):
        self.i = 1

Then, you use it like this:

import my_python_module as q
import p

y = p.Y(q.X())
print y.x
print y.x.i

Also, note that `cpdef` means the same as `cdef` as of `cython == 0.29.22`, and will not be supported in `cython == 3` (Cython issue 3959, and the warning that `cython == 0.29.22` prints if an attribute is declared with `cpdef`; see also the changelog entry for that Cython version).

Problem

I have a existing python class `X` and I want to do the followings: ``` from my_python_module import X cdef class Y: cdef X test ``` But this does not work out of the box, the cdef only accepts C type, not a Python class. Any work-around ?

Original source