22

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 ?

w00d
  • 5,416
  • 12
  • 53
  • 85

2 Answers2

21

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:

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).

0 _
  • 10,524
  • 11
  • 77
  • 109
lbolla
  • 5,387
  • 1
  • 22
  • 35
  • nice, so `object` can be used to assign any python object ? – w00d Jan 12 '14 at 03:11
  • 1
    @w00d: that's right (http://docs.cython.org/src/userguide/language_basics.html#python-objects-as-parameters-and-return-values). – lbolla Jan 12 '14 at 14:38
1

I would use something like this:

cdef class SomeCls:
    cdef object _x

    def __cinit__(self, x_):
        self._x = x_

    property x:
        def __get__(self):
            return self._x
        def __set__(self, x_):
            self._x = x_

The above is especially useful when exposing attributes of an extern struct or class. Refer to example here: wrapping C++

Al Conrad
  • 1,528
  • 18
  • 12