Problems with dict and C API

Matjaz surfmatj at email.si
Mon Sep 6 06:20:37 EDT 2004


Dear all,

I have trouble with creating objects with Python C API,
subclassed from dict type. What I am trying to do is to
subclass a dict class (in Python) and create its instance
in a Python extension (C API).

When I subclass from the (obsolete) UserDict class  it works.
When I subclass from the (recommended) dict class,
the program fails with the following error:

SystemError: classobject.c:518: bad argument to internal function

Below is the complete code, both C and Python, as well as a simple
example.

Please advise what am I missing.

Best regards,

Matjaz.

/* ------------------------------------------------------------------ */
/* example.c */
/* ------------------------------------------------------------------ */

#include "Python.h"

PyObject* find_class(const char *module_name, const char *global_name)
{
         PyObject *global = NULL;
         PyObject *module = NULL;
         PyObject *err    = NULL;
         PyObject *py_module_name = PyString_FromString( module_name ) ;
         PyObject *py_global_name = PyString_FromString( global_name ) ;

         int module_imported = 0;

         module = PySys_GetObject("modules");
         if (module == NULL) return NULL;

         module = PyDict_GetItem(module, py_module_name);
         if (module == NULL) {
            printf("Importing %s\n", module_name);
            module = PyImport_Import(py_module_name);
            if ((err = PyErr_Occurred()))
               if (err == PyExc_ImportError)
                  PyErr_Clear();
               else
                  module_imported = 1;
         }
         if (module) {
            global = PyObject_GetAttr(module, py_global_name);
            if ((err = PyErr_Occurred()))
               if (err == PyExc_AttributeError)
                  PyErr_Clear();
            if (module_imported)
                  Py_DECREF(module);
         }

         return global;
}




static PyObject *
ex_test(PyObject *self, PyObject *args)
{   PyObject *cl, *ob;


     char *module, *name;
     if (!PyArg_ParseTuple(args, "ss", &module, &name))
         return NULL;

     printf("Testing '%s' from '%s'...\n", name, module);

     cl = find_class(module,name);
     ob = PyInstance_New( cl, NULL, NULL);

     return ob;

}

static PyMethodDef example_methods[] = {
         {"test", ex_test, METH_VARARGS , "test() doc string"},
         {NULL, NULL}
};

void
initexample(void)
{
         Py_InitModule("example", example_methods);
}

# ------------------------------------------------------------------
# testcl.py
# ------------------------------------------------------------------

from UserDict import UserDict

class PD(dict):
     def __init__(self):
         dict.__init__(self)


class UD(UserDict):
     def __init__(self):
         UserDict.__init__(self)


# ------------------------------------------------------------------
# test.py
# ------------------------------------------------------------------

import testcl
import example

x = example.test("testcl","UD")  # This works
print x

y = example.test("testcl","PD")  # This fails
print y

# SystemError: classobject.c:518: bad argument to internal function



More information about the Python-list mailing list