[Python-ideas] Non-boolean return from __contains__
cs at zip.com.au
Tue Jul 27 23:55:20 CEST 2010
On 25Jul2010 11:48, Raymond Hettinger <raymond.hettinger at gmail.com> wrote:
| On Jul 25, 2010, at 11:15 AM, Alex Gaynor wrote:
| > Recently I've been wondering why __contains__ casts all of it's
| > returns to be boolean values. Specifically I'd like to propose that
| > __contains__'s return values be passed directly back as the result of
| > the `in` operation.
| x = y in z # where x is a non boolean.
| One of the beautiful aspects of __contains__ is that its simply signature
| allows it to be used polymorphically throughout the whole language.
Didn't we have the dual of this argument a week or so ago, where rantingrick
was complaining that ints could be used as booleans, and that it was simply
appalling? That Python should immediately make 0 also behave as True because
he didn't feel it was "empty". His argument was widely opposed, and IMHO
Personally, I'm +0.5 on the proposal:
- because Python already allows pretty much anything to be used
in a Boolean context, this means that anything can be "used
polymorphically throughout the whole language", to use your term
above; I do not think it breaks anything
- do any of the other comparison methods enforce Booleanness?
==/__eq__ doesn't and I didn't think the others did.
All that is required for functionality is sane choice of return
value by the implementors.
- have you used SQLAlchemy?
Its SQL constrction by writing:
table.c.COL1 == 3)
is extremely programmer friendly, and works directly off overloading the
column object's .__eq__() method to return something that gets made into a
robust SQL query later.
I'm going to snip two of your paragraphs here and proceed to:
| There is no "natural" interpretation of an in-operator returning
| a non-boolean.
There is in the SQLAlchemy example above; "in" with an SQLA column
object would return a hook to make a "value in (a,b,c,...)" SQL
It is all about context, and in Python the .__* methods let objects
provide the context for evaluation of expressions - that's what
polymorphism does for us.
The proposal changes nothing for pre-existing uses. It in no way causes:
False in [False]
to return False, because it doesn't change bool.__contains__.
The proposal it to not coerce the result of __contains__ to bool(),
allowing _new_ objects to return a more nuanced result for __contains__
for their own purposes.
As long as that make sense in the use context, I believe this is a plus
and not a minus. We can all write nonsensical code by implementing
__eq__ with gibberish. So what?
| If the above snippet assigns "foo" to x, what
| does that mean? If it assigns -10, what does that mean?
In current Python, it means "true".
| Language design is about associating meanings (semantics)
| with syntax. ISTM, this would be poor design.
We already allow programmers to do that all over the place with the
special methods. This proposal removes an apparently arbitrary
restriction on __contains__ that doesn't seem to be applied to the other
+0.5, verging on +1.
Cameron Simpson <cs at zip.com.au> DoD#743
It is in those arenas that he previously extinguished himself.
- Chuck Rogers
More information about the Python-ideas