473,396 Members | 2,020 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Problems with dict and C API

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
Jul 18 '05 #1
3 3168
Matjaz <su******@email.si> wrote:
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).


PyIntance_New wants specifically an old-style class as its first
argument, and you're not giving that in the latter case (a subclass of
dict is intrinsically new-style) so it's diagnosing that and raising the
exception you see. Just use PyObject_Call and you should be fine. More
generally, use abstract-object-layer API calls unless you've got very
specific reasons to use something lower-level (concrete layer) -- 90%+
of the time you'll be far happied with the AOL calls.

BTW, to get sys.modules, I suggest you use PyImport_GetModuleDict()
rather than PySys_GetObject("modules") -- it's slightly more direct.
Alex
Jul 18 '05 #2
Alex,

thank you for this valuable piece of information. I will
indeed try to use mapping protocol as much as possible.
However, I am curious of the following: were the
functions for setting/getting items (should be PyMapping_SetItem
and PyMapping_GetItem, like that for object and dictionaries)
left out on purpose, because there exist
only "string" versions PyMapping_SetItemString and
PyMapping_GetItemString?

Matjaz.

Alex Martelli wrote:

PyIntance_New wants specifically an old-style class as its first
argument, and you're not giving that in the latter case (a subclass of
dict is intrinsically new-style) so it's diagnosing that and raising the
exception you see. Just use PyObject_Call and you should be fine. More
generally, use abstract-object-layer API calls unless you've got very
specific reasons to use something lower-level (concrete layer) -- 90%+
of the time you'll be far happied with the AOL calls.

BTW, to get sys.modules, I suggest you use PyImport_GetModuleDict()
rather than PySys_GetObject("modules") -- it's slightly more direct.
Alex

Jul 18 '05 #3
Matjaz <su******@email.si> wrote:
Alex,

thank you for this valuable piece of information. I will
indeed try to use mapping protocol as much as possible.
However, I am curious of the following: were the
functions for setting/getting items (should be PyMapping_SetItem
and PyMapping_GetItem, like that for object and dictionaries)
left out on purpose, because there exist
only "string" versions PyMapping_SetItemString and
PyMapping_GetItemString?


No, you're just still looking at a too-specific level -- think abstract!

PyObject_SetItem and PyObject_GetItem are the API functions you're
looking for; there is no PyMapping_SetItem because it would just be a
total duplicate of PyObject_SetItem, just about. The ...String
convenience functions are there because using a string key is such a
frequent task on mappings specifically, not on objects in general. But
indexing _IS_ frequent on objects in general, so it's supported at that
level.
Alex
Jul 18 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Robin Cull | last post by:
Imagine I have a dict looking something like this: myDict = {"key 1": , "key 2": , "key 3": , "key 4": } That is, a set of keys which have a variable length list of associated values after...
18
by: jblazi | last post by:
I should like to search certain characters in a string and when they are found, I want to replace other characters in other strings that are at the same position (for a very simply mastermind game)...
0
by: Simon Dahlbacka | last post by:
I'm trying to cache some information using cPickle and I thought that using cPickle.HIGHEST_PROTOCOL would give me an efficient representation. However, when trying to load the information...
3
by: Bengt Richter | last post by:
Has anyone found a way besides not deriving from dict? Shouldn't there be a way? TIA (need this for what I hope is an improvement on the Larosa/Foord OrderedDict ;-) I guess I can just document...
7
by: Timo Haberkern | last post by:
Hi there, i have some troubles with my TSearch2 Installation. I have done this installation as described in http://www.sai.msu.su/~megera/oddmuse/index.cgi/Tsearch_V2_compound_words...
3
by: vida00 | last post by:
this has to be a very silly thing. I have a function foo taking a dictionary as parameters. i.e.: def foo(**kwargs): pass when I call foo(param1='blah',param2='bleh',param3='blih') everything...
15
by: George Sakkis | last post by:
Although I consider dict(**kwds) as one of the few unfortunate design choices in python since it prevents the future addition of useful keyword arguments (e.g a default value or an orderby...
15
by: manstey | last post by:
Hi, I have a text file called a.txt: # comments I read it using this:
6
by: Spartacus | last post by:
Hello, I have an HTML form I'd like to process. <select name="items" multiple> <option value="doughnuts">Hot Doughnuts</option> <option value="coffee">Hot Brewed Coffee</option> <option...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.