Skip to content

Instantly share code, notes, and snippets.

@jnothman
Created February 23, 2014 11:51
Show Gist options
  • Save jnothman/9170380 to your computer and use it in GitHub Desktop.
Save jnothman/9170380 to your computer and use it in GitHub Desktop.
direct __slots__ attribute access in Cython
from cpython cimport PyObject
from libc.string cimport strcmp
cdef extern from "Python.h":
ctypedef struct PyTypeObject:
pass
cdef extern from "structmember.h":
ctypedef struct PyMemberDef:
char *name
int type
Py_ssize_t offset
int flags
char *doc
cdef extern from "object.h":
PyMemberDef *PyHeapType_GET_MEMBERS(PyTypeObject *type)
Py_ssize_t Py_SIZE(obj)
def print_members(obj):
t = type(obj)
cdef Py_ssize_t n = Py_SIZE(t)
cdef PyMemberDef *mp = PyHeapType_GET_MEMBERS(<PyTypeObject *> (<PyObject *> t))
cdef Py_ssize_t i
for i in range(n):
print(mp[i].name)
def get_member_offset(obj, char *name):
t = type(obj)
cdef Py_ssize_t n = Py_SIZE(t)
cdef PyMemberDef *mp = PyHeapType_GET_MEMBERS(<PyTypeObject *> (<PyObject *> t))
cdef Py_ssize_t i
for i in range(n):
if strcmp(name, mp[i].name) == 0:
return mp[i].offset
def get_value_at_offset(obj, Py_ssize_t offset):
cdef PyObject *ret = (<PyObject **> (<char *>(<PyObject *>obj) + offset))[0]
if ret == NULL:
return None
return <object> ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment