subclass PyDictObject -- any gotchas?

Discussion in 'Python' started by Aaron Brady, Jan 22, 2009.

  1. Aaron Brady

    Aaron Brady Guest

    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;

    }
    Aaron Brady, Jan 22, 2009
    #1
    1. Advertising

  2. Aaron Brady

    Aaron Brady Guest

    On Jan 22, 7:49 am, Aaron Brady <> wrote:
    > 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?
    Aaron Brady, Jan 22, 2009
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jstorta
    Replies:
    3
    Views:
    427
    jstorta
    Feb 20, 2006
  2. Replies:
    1
    Views:
    305
    Duncan Booth
    Aug 1, 2006
  3. S.Volkov
    Replies:
    2
    Views:
    205
    S.Volkov
    Mar 12, 2006
  4. Trans
    Replies:
    8
    Views:
    306
    Robert Klemme
    Oct 23, 2008
  5. Fab

    Subclass of subclass

    Fab, Aug 9, 2012, in forum: C++
    Replies:
    0
    Views:
    383
Loading...

Share This Page