[Python-ideas] Non-boolean return from __contains__

Guido van Rossum guido at python.org
Mon Jul 26 05:07:22 CEST 2010

On Sun, Jul 25, 2010 at 5:01 PM, Raymond Hettinger
<raymond.hettinger at gmail.com> wrote:
> On Jul 25, 2010, at 2:32 PM, Michael Foord wrote:
>> x = y in z          # where x is a non boolean.
>> Yuck.
> How is it any worse than:
>  x = y > z # where x is a non boolean
> And all the other operators that already do this?
> Terrible sales technique:  "how is this any worse than ..." ;-)

Whoa. Reformulate as a consistency argument and I totally buy it.

> Other operations such as rich comparisons have
> complicated our lives but had sufficient offsetting benefits
> than made them more bearable.  Rich comparisons cause
> no end of trouble but at least they allow the numeric folks
> to implement some well studied behaviors than have proven
> benefits in their domain.

True. The argument for rich comparisons is that "A = B <= C" where B
and C are matrices of the same shape could return a matrix of bools of
the same shape, like a generalization for "A = [b <= c for b, c in
zip(B, C)]".

> In contrast, this proposal offers almost zero benefit to offset
> the pain it will cause.  The OP didn't even offer a compelling
> use case or a single piece of code that wouldn't be better
> written with a normal method.

OTOH, there is a similar use case: "A = B in C" could be defined by
the author of a matrix type as (the similar generalization of) "A = [b
in c for b, c in zip(B, C)]".

This is still somewhat less compelling than for rich comparisons
because the elements of C corresponding to those in would have to be
sequences. But it is not totally uncompelling.

BTW Alex *did* mention a use case: expression recoding like SQLAlchemy.

> No existing code expects "in" to return a non-boolean.

Most existing code also doesn't care, and all predefined
implementations of __contains__ will still return bools. It's only
folks like NumPy who would care. We should ask them though -- they had
a chance to ask for this when rich comparisons were introduced, but
apparently didn't.

> A lot of code for containers or that uses containers implicitly
> expects simple invariants to hold:
>    for x in container:
>        assert x in container

Yeah, a lot of code using comparisons also breaks when comparisons
don't return bools. It's a specialized use, but I don't see it as

OTOH the real solution would be something like LINQ in C#

> Raymond
> P.S.  With rich comparisons, we've lost basics assumptions
> like equality operations being reflexive, symmetric, and
> transitive.   We should be cautioned by that experience
> and only go down that path again if there is a darned good reason.

So where's the pain? I don't recall ever seeing a report from someone
who was bitten by this.

--Guido van Rossum (python.org/~guido)

More information about the Python-ideas mailing list