subclass PyDictObject -- any gotchas?

A

Aaron Brady

Hello all,

I am trying to create a mapping class similar to the base dictionary,
but with some added behaviors that affect pointers on a low level. I
have a bare-bones version I compiled with MinGW, and it is working! I
want to know if there is anything that is going to bite me later, when
I start adding real behavior: for example, times when my overrides
won't get called, shortcuts, better macros, etc.

Later on, I will be altering the 'ma_table' field from one call to
another, overriding most of PyDict_Type's methods with before-and-
after code, adding synchronization, and copying-and-pasting memory
allocation code from 'dictobject.c' directly in, since I need the
object to be at specific addresses. Anything I need to beware of?
Any reason it might be infeasible?

108 lines, please snip on reply.

Thanks in advance and sincerely,
A. Brady

#include <Python.h>
#include <iostream>
using namespace std;

typedef struct {
PyDictObject base;
/* Type-specific fields go here. */

} DictSubObject;

static void
dictsub_dealloc(register PyDictObject *mp) {
cout<< "In 'dictsub_dealloc'"<< endl;
PyDict_Type.tp_dealloc((PyObject*)mp);
}

static int
dictsub_ass_sub(DictSubObject *mp, PyObject *v, PyObject *w)
{
cout<< "In 'dictsub_ass_sub'"<< endl;
return PyDict_Type.tp_as_mapping->mp_ass_subscript( (PyObject *)
mp, v, w );
}

static PyMappingMethods dictsub_as_mapping = {
NULL, /*mp_length*/
NULL, /*mp_subscript*/
(objobjargproc)dictsub_ass_sub, /*mp_ass_subscript*/
};

static PyMethodDef DictSub_methods[] = {
{NULL}
};

PyObject *
dictsub_alloc(PyTypeObject *self, Py_ssize_t nitems) {
cout<< "In 'dictsub_alloc'"<< endl;
return PyDict_Type.tp_alloc(self, nitems);
}

static PyTypeObject DictSubType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"DictSub", /*tp_name*/
sizeof(DictSubObject), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)dictsub_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
&dictsub_as_mapping, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_BASETYPE, /*tp_flags*/
"DictSub objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
DictSub_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
dictsub_alloc, /* tp_alloc */
0, /* tp_new */
};

static PyMethodDef module_methods[] = {
{NULL} /* Sentinel */
};

#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initdictsub(void)
{
PyObject* m;

DictSubType.tp_base= &PyDict_Type;
if (PyType_Ready(&DictSubType) < 0)
return;

m = Py_InitModule3("dictsub", module_methods,
"Custom.");

Py_INCREF(&DictSubType);
PyModule_AddObject(m, "DictSub", (PyObject *)&DictSubType);

if (m == NULL)
return;

}
 
A

Aaron Brady

Hello all,

I am trying to create a mapping class similar to the base dictionary,
but with some added behaviors that affect pointers on a low level.  I
have a bare-bones version I compiled with MinGW, and it is working!  I
want to know if there is anything that is going to bite me later, when
I start adding real behavior: for example, times when my overrides
won't get called, shortcuts, better macros, etc.

Later on, I will be altering the 'ma_table' field from one call to
another, overriding most of PyDict_Type's methods with before-and-
after code, adding synchronization, and copying-and-pasting memory
allocation code from 'dictobject.c' directly in, since I need the
object to be at specific addresses.  Anything I need to beware of?
Any reason it might be infeasible?

108 lines, please snip on reply.

I would also like to know if there is any chance my subclass can use
the native garbage collection. For instance, if I could write my own
PyObject_MALLOC, then I could use _PyObject_GC_New. It doesn't look
promising, since the stuff is all so hard-coded. For instance,
'_PyObject_GC_Malloc' uses some module-level variables that make it
impossible to duplicate the code, since they are out of scope from my
code. What do you think? Is it possible?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,738
Latest member
JinaMacvit

Latest Threads

Top