Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Mapping between runtime types and C/compile-time types

  • Status: Idea

This is just Dag Sverre's draft for now; I'll start a discussion on the mailing list when it is a better time for it.

This is a feature which helps bridge the gap between C types and Python types in instances where the entire state of the object can be accurately represented by a variable of a native C type. The primary use case is with the ctypes module as well as the datatypes declared in numpy.

Description

cdef classes (or, cdef classes in pxd-files which overlay the names of Python counterpart classes?) can implement two new operator overloads, __tocvar__ and __fromcvar__.

ctypes.pxd:

   #!python
   cdef class c_uint:
       cdef final inline unsigned int __tocvar__(object x):
           return <unsigned int>(c_uint(x).value)
       cdef final inline object __fromcvar__(unsigned int x):
           return c_uint(x)

* The functions should only be used if the *entire state of the object can be accurately represented by a variable of a native C type*. (This includes C++ classes used in "stack mode", i.e. not allocated on the heap).
* These functions are considered static methods, and do not take the "self" parameter. Also they must be declared ``cdef`` (and, if implemented in a pxd file, ``final``).
* ``__tocvar__`` should have a native C type (or a typedef of such) as the return type, and take an ``object`` as first parameter.
* ``__fromcvar__`` is symmetric to this, it takes the same native C type as the first parameter and must have ``object`` as return type.
* Both or none of the functions must be provided.

The most important point is that when these functions are provided, cdef c_uint x no longer has the traditional meaning (declare the x variable as a reference/pointer to a c_uint object). Instead, the variable x is declared to be of the return type of ``__tocvar__``. Effectively a type alias is created so that in type context, c_uint means unsigned int.

In addition the functions are called when doing conversion between the variable and Python objects. Such conversion is fully automatic and considered to be lossless.

Operator overloading is not considered. I.e. it is expected that normal C operations on the variable will provide the right results.

Finally, the run-time type is of course the class itself.

Examples build on the pxd file declared above.

Example 1

#!python
cdef c_uint x = 8
c_func(x + 4)

This only uses c_uint as a convenient typedef, and is completely equivalent to

#!python
cdef unsigned int x = 8
c_func(x + 4)

Note that the + operator is going to be handled C-side.

Example 2

#!python
o = 8
cdef c_uint x = o
print x
print c_uint

This is equivalent to the following:

#!python
o = 8
cdef unsigned int x = <unsigned int>(c_uint(o).value)
print c_uint(x)
print c_uint

Line 4 demonstrates how c_uint refers to the Python c_uint class object.

Something went wrong with that request. Please try again.