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 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
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
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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)...
|
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...
|
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...
|
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...
|
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...
|
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...
|
by: manstey |
last post by:
Hi,
I have a text file called a.txt:
# comments
I read it using this:
|
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...
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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,...
|
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...
|
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...
|
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...
|
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...
|
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,...
| |