Cython classes with a __dict__

486 views
Skip to first unread message

Nils Bruin

unread,
May 18, 2013, 1:16:01 PM5/18/13
to sage-devel
I don't dare posting this on cython-users because it's a horrible
hack, but it does make a cython class have a dictionary that gets
recognized by python as one to look up attributes in:

The main problem is to convince Cython to compute the offset of a slot
in a type structure.I ended up importing a C macro for that:

#########################
Contents of myheader.h:
#define my_offset(a) (((Py_ssize_t)&(a->__dict__))-((Py_ssize_t)a))
#########################

cdef extern from "myheader.h":
Py_ssize_t my_offset(Test a)

#make sure we can find tp_dictoffset
cdef extern from *:
ctypedef struct PyTypeExtended "PyTypeObject":
Py_ssize_t tp_dictoffset

#definition of class with the appropriate attribute
cdef class Test:
cdef public dict __dict__
def __init__(self):
self.__dict__={}

#initialization function to force the appropriate tp_dictoffset value
#into the relevant PyTypeObject. This should really be happening
#just before cython calls PyType_Ready, but doing it just afterwards
#doesn't seem to cause problems.

def equip_Test_with_dict():
cdef Test t = Test()
(<PyTypeExtended *>(t.__class__)).tp_dictoffset=my_offset(t)

equip_Test_with_dict()


With this loaded, you can do:

sage: t = Test()
sage: t.a = 1000
sage: t.a
1000

which would normally not be possible.

Robert Bradshaw

unread,
May 19, 2013, 3:15:28 AM5/19/13
to sage-devel
Note that adding a __dict__ also massively slows down any cpdef function calls.
> --
> You received this message because you are subscribed to the Google Groups "sage-devel" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+...@googlegroups.com.
> To post to this group, send email to sage-...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sage-devel?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Nils Bruin

unread,
May 19, 2013, 3:42:00 AM5/19/13
to sage-devel
On May 19, 12:15 am, Robert Bradshaw <rober...@math.washington.edu>
wrote:
> Note that adding a __dict__ also massively slows down any cpdef function calls.

Which could be mitigated if cython would grow a pragma that allows
cpdef calls being generated with "__pyx_skip_dispatch=1" (giving them
the semantics of "cdef method that happens to also have a python
wrapper" instead of "fully overridable python method that can be
called directly from C, where it has some speed benefits".

The parameter is already there. The main problem is thinking of a good
way of providing access to it from cython.
Reply all
Reply to author
Forward
0 new messages