On Mon, 16 Jan 2006 21:18:35 +0000, Bengt Richter wrote: > On Mon, 16 Jan 2006 21:58:26 +1100, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > >>On Mon, 16 Jan 2006 10:34:40 +0000, Bengt Richter wrote: >> >>> >>> class A: >>> ... def __getattr__(self, attr): print 'A().%s'%attr; raise >>> AttributeError >>> ... >>> >>> class B: >>> ... def __getattr__(self, attr): print 'B().%s'%attr; raise >>> AttributeError >>> ... >>> >>> A()==B() >>> A().__eq__ >>> B().__eq__ >>> B().__eq__ >>> A().__eq__ >>> A().__coerce__ >>> B().__coerce__ >>> A().__cmp__ >>> B().__cmp__ >>> False >> >>Why are A().__eq__ and B().__eq__ both being called twice? >> > I imagine it's trying the calls with args swapped or something like that. > Want to write a test and see? (Don't hold your breath if you're waiting for > me to do it ;-)
You already wrote a test. I can't think of any test I can write which would give more information than yours. I'd like a test where I can see the arguments which Python would apply to each method call, but I can't think of any way to get those arguments inside the __getattr__ method. Perhaps I'm not thinking hard enough. (Actually writing __eq__ methods would defeat the purpose.) There aren't that many possibilities. We can predict the other argument from each call: if you call a method of A, the argument must be B and vice versa. So it looks like Python is making the following calls: A().__eq__(B) B().__eq__(A) B().__eq__(A) A().__eq__(B) followed by the unproblematic calls to __coerce__ and __cmp__. What puzzles me is that after trying B.__eq__(A), it tries it again immediately. It only calls coerce and cmp once with each set of args. What am I missing? -- Steven. -- http://mail.python.org/mailman/listinfo/python-list