// get attribute 'name' for object. // uses obj->attr list of tuples for storage. // returns new reference. PyObject* pyjobject_getattr(PyJObject *obj, char *name) { PyObject *ret, *pyname, *methods, *members; ret = pyname = methods = members = NULL; if (!name) { Py_RETURN_NONE; } pyname = PyString_FromString(name); methods = PyString_FromString("__methods__"); members = PyString_FromString("__members__"); if (PyObject_RichCompareBool(pyname, methods, Py_EQ)) { Py_DECREF(pyname); Py_DECREF(methods); Py_DECREF(members); Py_INCREF(obj->methods); return obj->methods; } Py_DECREF(methods); if (PyObject_RichCompareBool(pyname, members, Py_EQ)) { Py_DECREF(pyname); Py_DECREF(members); Py_INCREF(obj->fields); return obj->fields; } Py_DECREF(members); if (!PyList_Check(obj->attr)) { Py_DECREF(pyname); PyErr_Format(PyExc_RuntimeError, "Invalid attr list."); return NULL; } // util function fetches from attr list for us. ret = tuplelist_getitem(obj->attr, pyname); /* new reference */ Py_DECREF(pyname); // method optimizations if (pyjmethod_check(ret) || PyJmultiMethod_Check(ret)) { /* * TODO Should not bind non-static methods to pyjclass objects, but not * sure yet how to handle multimethods and static methods. */ #if PY_MAJOR_VERSION >= 3 PyObject* wrapper = PyMethod_New(ret, (PyObject*) obj); #else PyObject* wrapper = PyMethod_New(ret, (PyObject*) obj, (PyObject*) Py_TYPE(obj)); #endif Py_DECREF(ret); ret = wrapper; } if (PyErr_Occurred() || ret == Py_None) { if (ret == Py_None) { Py_DECREF(Py_None); } PyErr_Format(PyExc_AttributeError, "attr not found: %s", name); return NULL; } if (pyjfield_check(ret)) { PyObject *t = pyjfield_get((PyJFieldObject *) ret); Py_DECREF(ret); return t; } return ret; }
// set attribute v for object. // uses obj->attr dictionary for storage. int pyjobject_setattr(PyJObject *obj, char *name, PyObject *v) { PyObject *pyname, *tuple; if (!name) { PyErr_Format(PyExc_RuntimeError, "Invalid name: NULL."); return -1; } if (!PyList_Check(obj->attr)) { PyErr_Format(PyExc_RuntimeError, "Invalid attr list."); return -1; } Py_INCREF(v); if (obj->finishAttr) { PyObject *cur, *pyname; int ret; // finished setting internal objects. // don't allow python to add new, but do // allow python script to change values on pyjfields pyname = PyString_FromString(name); cur = tuplelist_getitem(obj->attr, pyname); /* new reference */ Py_DECREF(pyname); if (PyErr_Occurred()) { return -1; } if (cur == Py_None) { PyErr_SetString(PyExc_RuntimeError, "No such field."); return -1; } if (!pyjfield_check(cur)) { PyErr_SetString(PyExc_TypeError, "Not a pyjfield object."); return -1; } if (!PyList_Check(obj->attr)) { Py_DECREF(pyname); PyErr_SetString(PyExc_RuntimeError, "Invalid attr list."); return -1; } // now, just ask pyjfield to handle. ret = pyjfield_set((PyJFieldObject *) cur, v); /* borrows ref */ Py_DECREF(cur); Py_DECREF(v); return ret; } pyname = PyString_FromString((const char *) name); tuple = PyTuple_New(2); Py_INCREF(pyname); PyTuple_SetItem(tuple, 0, pyname); /* steals ref */ PyTuple_SetItem(tuple, 1, v); /* steals ref */ // the docs don't mention this, but the source INCREFs tuple // ... // after much printf'ing. uhm. must decref it somewhere. // ... // doh. the docs suck. // Py_INCREF(tuple); PyList_Append(obj->attr, tuple); Py_DECREF(tuple); Py_DECREF(pyname); return 0; // success }
// get attribute 'name' for object. // uses obj->attr list of tuples for storage. // returns new reference. static PyObject* pyjobject_getattr(PyJobject_Object *obj, char *name) { PyObject *ret, *pyname, *methods, *members; int listSize, i, found; ret = pyname = methods = members = NULL; listSize = i = found = 0; if(!name) { Py_INCREF(Py_None); return Py_None; } pyname = PyString_FromString(name); methods = PyString_FromString("__methods__"); members = PyString_FromString("__members__"); if(PyObject_Compare(pyname, methods) == 0) { Py_DECREF(pyname); Py_DECREF(methods); Py_DECREF(members); Py_INCREF(obj->methods); return obj->methods; } Py_DECREF(methods); if(PyObject_Compare(pyname, members) == 0) { Py_DECREF(pyname); Py_DECREF(members); Py_INCREF(obj->fields); return obj->fields; } Py_DECREF(members); if(!PyList_Check(obj->attr)) { Py_DECREF(pyname); PyErr_Format(PyExc_RuntimeError, "Invalid attr list."); return NULL; } // util function fetches from attr list for us. ret = tuplelist_getitem(obj->attr, pyname); /* new reference */ Py_DECREF(pyname); if(PyErr_Occurred() || ret == Py_None) { if(ret == Py_None) Py_DECREF(Py_None); PyErr_Format(PyExc_AttributeError, "attr not found: %s", name); return NULL; } if(pyjfield_check(ret)) { PyObject *t = pyjfield_get((PyJfield_Object *) ret); Py_DECREF(ret); return t; } if(pyjmethod_check(ret)) Py_INCREF(obj); return ret; }