[Cython] Why does "__cinit__" insists on converting its arguments to Python objects?

Dieter Maurer dieter at handshake.de
Thu Jun 7 13:32:43 CEST 2012

The following cython source leads to a "Cannot convert 'pointer' to Python object".

ctypedef void * pointer

cdef extern from "nonexistant.h":
  cdef pointer to_pointer(object)

cdef class C:
  cdef pointer p

  def __cinit__(self, pointer p): self.p = p

c = C(to_pointer(None))

Why does the constructor call tries an implicit conversion to a
Python object even though it gets precisely the type indicated by
its signature?

I am working on a binding for "libxmlsec". The behaviour above leads
to an unnatural mapping. Two examples:

1. "libxmlsec" has the concept of a key (used for digital signatures or
   encryption), naturally mapped onto a "cdef class Key" encapsulating
   the xmlsec key pointer.

   "libxmlsec" provides many functions to create keys - naturally mapped
   onto class methods used as alternative constructors.
   Would "Cython" allow C level parameters for "__cinit__",
   they could look like:

     cdef xmlSecKeyPtr xkey = ... some "libxmlsec" key generating function ...
     return Key(xkey)

   With the restriction, this must look like:

     cdef Key key
     key.xkey = ... some "libxmlsec" key generating function ...
     return key

   Not yet too bad, unless the constructor requires C level arguments.

2. "libxmlsec" provides a whole bunch of transforms, handled in C code
   via a set of so called "TransformId"s. Each "TransformId" is
   generated by a function.

   The natural way would like:

      cdef class TransformId:
        cdef xmlSecTransformId tid
	def __cinit__(self, xmlSecTransformId tid): self.tid = tid

      TransformInclC14N = TransformId(xmlSecTransformInclC14NGetKlass())
      ... for all standard transforms ...

   The restriction forces the introduction of a helper function:

      cdef class TransformId:
        cdef xmlSecTransformId tid

      cdef _mkti(xmlSecTransformId tid):
        cdef TransformId t = TransformId()
        t.tid = tid
        return t

      TransformInclC14N = _mkti(xmlSecTransformInclC14NGetKlass())
      ... for all standard transforms ...


More information about the cython-devel mailing list