6. Creating New Types¶
The creation of new extension types (AKA ‘classes’) is pretty well described in the Python documentation tutorial and reference. This section just describes a rag bag of tricks and examples.
6.1. Properties¶
6.1.1. Referencing Existing Properties¶
If the property is part of the extension type then it is fairly easy to make it directly accessible as described here
For example the Noddy
struct has a Python object (a string) and a C object (an int):
typedef struct {
PyObject_HEAD
PyObject *first; /* first name */
/* ... */
int number;
} Noddy;
These can be exposed by identifying them as members with an array of PyMemberDef
like this:
static PyMemberDef Noddy_members[] = {
{"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
"first name"},
/* ... */
{"number", T_INT, offsetof(Noddy, number), 0,
"noddy number"},
{NULL} /* Sentinel */
};
And the type struct must reference this array of PyMemberDef
thus:
static PyTypeObject NoddyType = {
/* ... */
Noddy_members, /* tp_members */
/* ... */
};
6.1.2. Created Properties¶
If the properties are not directly accessible, for example they might need to be created, then an array of PyGetSetDef
structures is used in the PyTypeObject.tp_getset slot.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | static PyObject*
Foo_property_getter(Foo* self, void * /* closure */) {
return /* ... */;
}
int
Foo_property_setter(Foo* self, PyObject *value) {
return /* 0 on success, -1 on failure with error set. */;
}
static PyGetSetDef Foo_properties[] = {
{"id", (getter) Foo_property_getter, (setter) Foo_property_setter,
"The property documentation.", NULL },
{NULL} /* Sentinel */
};
|
And the type struct must reference this array of PyMemberDef
thus:
static PyTypeObject FooType = {
/* ... */
Foo_properties, /* tp_getset */
/* ... */
};