On Mon, Mar 2, 2009 at 11:20 AM, Raymond Hettinger <pyt...@rcn.com> wrote: >> But you'll have to convince me, > > Okay, here's one stab at it. If it doesn't take, I give in. > ISTM, either way is right depending on your point of view and what > you're trying do at the time. My judgment tips in favor of not > specializing the __eq__ method.
Comparing dicts is relatively uncommon. So we'd have to find and look at use cases to decide. > But it is not lost on me why > one might think that something that iterates in a specified order > would also make an order sensitive comparison. My hunch is that not taking the ordering into account is going to confuse people who consciously use odicts and bother to compare them. I expect this is going to be a FAQ, no matter how much you try to document it -- especially since the concept of an odict is so simple and the API so clean that most people will not bother reading *any* docs. I expect this to be the most common use case. Use cases where people compare mappings knowing they may have different concrete types are probably exceedingly rare, and if I was doing that I wouldn't rely on __eq__ not being overridden -- IOW I'd either explicitly invoke Mapping.__eq__(a, b) or write the equivalent code myself. The third class of use case is people comparing dicts not thinking much about the possibility of there being a subclass that overrides __eq__, and being surprised by the substitution of an odict. This seems to be the use case you favor; to me it seems pretty rare too. To convince me otherwise you'd have to find a common use case that does this *and* is likely to encounter an odict in real life. >> Liskov cares about the signature, not about the computed value. > > That wasn't my understanding. I thought it was entirely about computed > values, "Let q(x) be a property provable about objects x of type T. Then > q(y) should be true for objects y of type S where S is a subtype of T." Or > phrased differently, "In class hierarchies, it should be possible to treat a > specialized object as if it were a base class object." This strict interpretation is violated all the time in OO programming; consider e.g. the common overriding of object.__repr__. (In fact, even the definition of dict.__eq__ overriding object.__eq__ would validate it.) AFAIK a more common use of the term in OO languages is about signatures only: if a method of class C accepts an argument of type T, then you shouldn't override that method in a class D derived from C to require an argument type S which is a subtype of T. (This is also known as Contravariance. Read the section on Design by contract in http://en.wikipedia.org/wiki/Liskov_substitution_principle.) > In this case, Armin wants to be able to pass in an ordered dictionary to > functions that weren't designed with ordered dicts in mind (config parser, > json/yaml parsers, nose, unittest, etc.). Those functions should be able to > assume that all the usual dictionary properties are still true. In > particular, those functions may make internal comparisons to a regular dict > (perhaps as a cached value) and would expect those comparisons to succeed. That's a hypothetical use case. Have you found any real code that uses __eq__ on dicts in this matter? >> I would propose the following formal specification for odict.__eq__: >> >> def __eq__(self, other): >> if not isinstance(other, odict): >> return NotImplemented # Give other a chance; defaults to False >> return list(self.items()) == list(other.items()) > > > If I haven't convinced you, then I would be happy to put this in. Great. >>> Outside of your differing judgment on the __eq__ method, are you >>> basically happy with the ordered dict PEP? > >> I am. > > Once you've decided on __eq__, can I mark the PEP as approved? Yes. (With the caveat that I haven't read it very closely, but the basic spec seems sound apart from the __eq__ issue.) Hm, I wonder if you should spec odict.__repr__ (and hence odict.__str__). It would be confusing if an odict's repr() were the same as a plain dict's. -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com