M
Matjaz
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
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