If Tim, Guido, you and I are so completely out of sync with normal people that they will immediately intuit what we had to think hard about, we're in deep doo-doo!
Na, we're not, they are: they're *never* gonna figure it out <wink>.
I suggest a compile-time warning and then eventually we would make "in" non-chainable.
An incompatible language change would, I think, need to go thru the __future__ (however spelled) business.
Perhaps it should even have a different precedence than the other comparison operators. Tim's example looks reasonable to me:
assert k in d1 == k in d2
It *used* to look reasonable to me too <wink>.
And it would never, ever make sense to say:
assert k in (d1==k) in d2
Thin ice, there. __eq__ and __contains__ are both user-definable now, and there is no limit to how perverse ex-APL'ers can get with this stuff.
So why not interpret it the way that any normal human would:
assert (k in d1) == (k in d2)
That sounds best to me, but may be too much a bother. For example, it's not a stretch at all anymore to believe that someone *is* using
a in b in c
now deliberately for its
(a in b) and (b in c)
meaning. Perfectly natural if, e.g., you use __contains__ to implement an "is subset of" relation. If we have to keep chaining for "in", then having two distinct levels of chaining operators is bound to harbor its own odd corners.
x == y in d
I have no idea what that *should* mean, but having gone thru recent related pain I'm very clear now on what it *does* mean.
I think that this is a subtle flaw in Python that just took a long time to manifest itself...
You can thank Digital Creations for that, too. They're keeping Guido so busy that he doesn't have enough time to cloud our minds anymore. Makes you wonder how many other surprises he's been hiding from us <wink>!