On 2007-12-15, Carl Banks <[EMAIL PROTECTED]> wrote: > On Dec 15, 9:05 am, [EMAIL PROTECTED] wrote: >> My reasoning is (I hope) that the container ought to support >> every comparison operation supported by the contained objects. >> This can be ensured by being careful in the implementation. > > I see what you're asking now. Yep, probably a bad idea to use > that shortcut.
I put together a test suite, and discovered that the built-in list assumes that all contained object support __eq__, i.e., it may call __eq__ while performing some other comparison, e.g., __gt__. This is contrary to the rule I was contemplating for sequence comparisons in this thread. >>> class Evil: ... def __init__(self, i): ... self.i = i ... def __eq__(self, o): ... raise RuntimeError ... def __gt__(self, o): ... if isinstance(o, Evil): ... return self.i > o.i ... return NotImplemented ... >>> [Evil(1)] > [Evil(0)] Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 5, in __eq__ RuntimeError This prompted inspection of listobject.c. After trying some short-cuts for __ne__ and __eq__, list_richcompare iterates through both lists until the first non-equal elements are found, and then performs the correct comparison, or simply returns, depending on if the lists were the same length. Otherwise, the built-in list rich comparison follows the advice posted in this thread, i.e., it uses only the comparison operation being implemented to compare contained objects. When implementing a mutable sequence in Python, the rule of thumb seems to be "do as lists do," so as of the Python's current implementation, there's a small limit on the perversity level of the rich comparison operations of types contained in lists. -- Neil Cerutti -- http://mail.python.org/mailman/listinfo/python-list