WIP: Dynamic attribute support

This commit is contained in:
empyrical 2016-07-08 22:56:05 -06:00
parent 4be37c17d7
commit 7a3ced7a84
2 changed files with 26 additions and 0 deletions

View File

@ -239,6 +239,7 @@ inline std::string error_string();
template <typename type> struct instance_essentials {
PyObject_HEAD
type *value;
PyObject *dict;
PyObject *parent;
PyObject *weakrefs;
bool owned : 1;

View File

@ -498,6 +498,24 @@ public:
};
NAMESPACE_BEGIN(detail)
static PyObject* generic_get_dict(PyObject* op, void*)
{
instance<void> *self = (instance<void> *) op;
if (self->dict == 0){
self->dict = PyDict_New();
}
Py_INCREF(self->dict);
return self->dict;
}
static PyGetSetDef generic_getsets[] = {
{(char*)"__dict__", (getter)generic_get_dict, NULL, NULL, NULL},
{NULL, NULL, NULL, NULL, NULL}
};
/// Generic support for creating new Python heap types
class generic_type : public object {
template <typename type, typename holder_type, typename type_alias> friend class class_;
@ -583,6 +601,12 @@ protected:
/* Support weak references (needed for the keep_alive feature) */
type->ht_type.tp_weaklistoffset = offsetof(instance_essentials<void>, weakrefs);
/* Support dynamic attributes */
type->ht_type.tp_dictoffset = offsetof(struct instance_essentials<void>, dict);
type->ht_type.tp_getset = generic_getsets;
type->ht_type.tp_getattro = PyObject_GenericGetAttr;
type->ht_type.tp_setattro = PyObject_GenericSetAttr;
/* Flags */
type->ht_type.tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
#if PY_MAJOR_VERSION < 3
@ -673,6 +697,7 @@ protected:
registered_instances.erase(it);
}
Py_XDECREF(self->parent);
Py_XDECREF(self->dict);
if (self->weakrefs)
PyObject_ClearWeakRefs((PyObject *) self);
}