On Mon, 10 Apr 2000, Barry Warsaw wrote: >... > Below is a very raw set of patches to add an attribute dictionary to > funcs and methods. It's only been minimally tested, but if y'all like > the idea, +1 on concept, -1 on the patch :-) >... > P.S. I promised to add a little note about setattr and getattr > vs. setattro and getattro. There's very little documentation about > the differences, and searching on python.org doesn't seem to turn up > anything. The differences are simple. setattr/getattr take a char* > argument naming the attribute to change, while setattro/getattro take > a PyObject* (hence the trailing `o' -- for Object). This stuff should > get documented in the C API, but at least now, it'll turn up in a SIG > search. :) And note that the getattro/setattro is preferred. It is easy to extract the char* from them; the other direction requires construction of an object. >... > + static int > + instancemethod_setattr(im, name, v) > + register PyMethodObject *im; > + char *name; > + PyObject *v; IMO, this should be instancemethod_setattro() and take a PyObject *name. In the function, you can extract the string for comparison. >... > + { > + int rtn; This variable isn't used. >... > static PyObject * > instancemethod_getattr(im, name) > register PyMethodObject *im; > ! char *name; IMO, this should remain a getattro function. (and fix the name) In your update, note how many GetAttrString calls there are. The plain GetAttr is typically faster. >... > + rtn = PyMember_Get((char *)im, instancemethod_memberlist, name); > + if (rtn == NULL) { > + PyErr_Clear(); > + rtn = PyObject_GetAttrString(im->im_func, name); > + if (rtn == NULL) > + PyErr_SetString(PyExc_AttributeError, name); Why do you mask this second error with the AttributeError? Seems that you should just leave whatever is there (typically an AttributeError, but maybe not!). >... > --- 144,167 ---- > PyFunctionObject *op; > char *name; > { > + PyObject* rtn; > + > if (name[0] != '_' && PyEval_GetRestricted()) { > PyErr_SetString(PyExc_RuntimeError, > "function attributes not accessible in restricted mode"); > return NULL; > + } > + if (strcmp(name, "__dict__") == 0) > + return op->func_dict; This is superfluous. The PyMember_Get will do this. > + rtn = PyMember_Get((char *)op, func_memberlist, name); > + if (rtn == NULL) { > + PyErr_Clear(); > + rtn = PyDict_GetItemString(op->func_dict, name); > + if (rtn == NULL) > + PyErr_SetString(PyExc_AttributeError, name); Again, with the masking... >... > + else if (strcmp(name, "func_dict") == 0) { > + if (value == NULL || !PyDict_Check(value)) { > + PyErr_SetString( > + PyExc_TypeError, > + "func_dict must be set to a dict object"); This raises an interesting thought. Why not just require the mapping protocol? Cheers, -g -- Greg Stein, http://www.lyra.org/
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4