Hi all, I am trying to implement a subscriptable type in c++ (equivalent to python dict), but I get a 'type is unsubscriptable' error. Here is a minimal code sample I tried:
-------------------------------------------------------------------------- #include <Python.h> #include <iostream> #include "pyerror.hpp" ///////////////////////////////////////////////////////// PyObject* getitem(PyObject* self, PyObject* args) { std::cout << "getitem" << std::endl; return PyString_FromString("this is an item"); } PyMethodDef method[] = { {"__getitem__", &getitem, METH_VARARGS, ""}, {0, 0, 0, 0} }; static PyMethodDef module_methods[] = { { 0, 0, 0, 0 } }; struct MyObject { PyObject_HEAD }; extern const char* code; int main(int argc, char *argv[]) { Py_InitializeEx(0); PyObject* myModule = Py_InitModule3("test", module_methods, "test module"); assert(myModule); PyTypeObject myType; memset(&myType, 0, sizeof(PyTypeObject)); myType.tp_name = "myType"; myType.tp_basicsize = sizeof(MyObject); myType.tp_methods = method; if (PyType_Ready(&myType) < 0) { std::cout << "type error" << std::endl; return 1; } PyModule_AddObject(myModule, myType.tp_name, (PyObject*)&myType); PyObject* m = PyImport_AddModule("__main__"); PyObject* d = PyModule_GetDict(m); MyObject* odef = PyObject_New(MyObject, &myType); PyDict_SetItemString(d, "obj", (PyObject*)odef); PyObject* rv = PyRun_String(code, Py_file_input, d, d); if(rv == 0) { std::cout << "run error" << std::endl; printException(); return 1; } Py_Finalize(); std::cout << "Done.\n"; return 0; } const char* code = "print dir(obj)\n" "x = obj.__getitem__(1)\n" "print 'direct call:', x\n" "x = obj[1]\n" ; -------------------------------------------------------------------------- Compile and run session. -------------------------------------------------------------------------- $ g++ -I/usr/include/python2.6 pymin.cpp -lpython2.6 $ ./a.out ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] getitem direct call: this is an item run error Error in execution: Traceback (most recent call last): line 4, in ?? <type 'exceptions.TypeError'>: 'myType' object is unsubscriptable -------------------------------------------------------------------------- As you can see, when I call __getitem__() directly, it works, but when I call it as a subscriptable object, I get an error. What am I missing? A simple python equivalent class works as expected: -------------------------------------------------------------------------- class Testi: def __getitem__(self, idx): return 10 if __name__ == '__main__': x = Testi() print dir(x) print x['a'] -------------------------------------------------------------------------- Run session. -------------------------------------------------------------------------- $ python tst.py ['__doc__', '__getitem__', '__module__'] 10 -------------------------------------------------------------------------- I had tried using the PyMappingMethods structure as documented, but there is apparently no way to implement the __contains__() method, that is, to check if a key is present in the dict. Any help would be appreciated. _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig