// 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; }
// 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; }