Moshe seems eager to get comments on this post :-) > Here's a very preliminary, very hackish version of a hook for the "in" > operator. > > Basically, use like: > > class spam: > def __contains__(self, o): > return 1 > 6 in spam() (answers 1) > > I must say I was horrified by the current way the operator was handled: > very non-OO-ish. I'd much rather there'd be a slot in the sequence > interface for this method. This is why there's still no way to use the > hook with regular C extension types. > > Have fun! > > (BTW: I've tested it only minimally, so it might break your Python. Use > with caution). > > PS. > Eric, you can implement sets the *right* way this time. For those who, like me, are too lazy to unpack attachments, here's the text of Moshe's patch: > *** ../../../python/dist/src/Objects/abstract.c Fri Oct 15 14:09:02 1999 > --- Objects/abstract.c Tue Feb 1 10:34:34 2000 > *************** > *** 1110,1115 **** > --- 1110,1140 ---- > } > return 0; > } > + /* special case for instances. Basically emulating Python code, > + but optimizations will come later */ > + if (PyInstance_Check(w)) { > + PyObject *py__contains__, *py_ret, *py_args; > + int ret; > + > + py__contains__ = PyObject_GetAttrString(w, "__contains__"); > + if(py__contains__ == NULL) > + return -1; > + py_args = PyTuple_New(1); > + if(py_args == NULL) { > + Py_DECREF(py__contains__); > + return -1; > + } > + Py_INCREF(v); > + PyTuple_SET_ITEM(py_args, 0, v); > + py_ret = PyObject_CallObject(py__contains__, py_args); > + Py_DECREF(py__contains__); > + Py_DECREF(py_args); > + if(py_ret == NULL) > + return -1; > + ret = PyObject_IsTrue(py_ret); > + Py_DECREF(py_args); > + return ret; > + } > > sq = w->ob_type->tp_as_sequence; > if (sq == NULL || sq->sq_item == NULL) { I like the idea of overloading 'in' (and 'not in') with __contains__. There are several issues with this patch though (apart from the fact that he left out the disclaimer from http://www.python.org/1.5/bugrelease.html :-). First of all, it actually breaks 'in' for descendants of UserList, and other classes that define __getitem__ but not __contains__. That's easily fixed by clearing the error and jumping forward instead of returning an error when the GetAttrString() call fails. Second, it's customary to define a static object variable initialized to NULL, which is set to the interned string object; this speeds up the lookup a bit using PyObject_GetAttr(). Micro-nit: I want a space between 'if' and '('. It just looks better. But the real issue is what Moshe himself already brings up: contains should have a slot in the type struct, so extension types can also define this. Moshe, do you feel like doing this right? --Guido van Rossum (home page: http://www.python.org/~guido/)
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