[Python-Dev] misbehaving __contains__

Chuck Mason (Visual Concepts) cmason at vcentertainment.com
Tue Jan 22 20:35:12 CET 2008


My guess is that results from the bottom of cmp_outcome (ceval.c),

The default case handles the PyCmp_EQ case via PyObject_RichCompare,
which might not return Py_True or Py_False.

But 'in' is handled inside the switch and is subject to the final
statements:

	v = res ? Py_True : Py_False;
	Py_INCREF(v);
	return v

Though, IANAPydev. 

C

-----Original Message-----
From: python-dev-bounces+cmason=vcentertainment.com at python.org
[mailto:python-dev-bounces+cmason=vcentertainment.com at python.org] On
Behalf Of tomer filiba
Sent: Tuesday, January 22, 2008 11:27 AM
To: python-dev at python.org
Subject: [Python-Dev] misbehaving __contains__

i'm using python to create expression objects, for more intuitive
usage as
predicates, for instance:
    x = (Arg(0) > 17) & (Arg(1).foo == "bar")
instead of
    x = And(Gt(Arg(0), 17), Eq(GetAttr(Arg(1), "foo"), "bar"))

so now i can use x.eval(18, "spam") and get the result of the
expression.

i'm doing it by overriding all the operators to return expression
objects,
instead of evaluating the result immediately. it works fine, but i
encountered
a problem with making __contains__ behave so.

it turns out __contains__ coerces the return value into a bool. this
might
seem logical at first, but is not consistent with the result of the
language.

consider the following code:

>>> class Foo(object):
...     def __contains__(self, key):
...             return 17
...     def __eq__(self, other):
...             return 19
...
>>>
>>> f=Foo()
>>> f == 8
19
>>> 8 in f
True

as you can see, __eq__ does not coerces the result to bool, so why
should
__contains__ do that?

i've looked at PySequence_Contains in objects/abstract.c, but i can't
quite
understand where the coercion is made. is because the function is
typed
as int? if so, i believe it should either be changed to PyObject, or
have
cmp_outcome (in ceval.c) not use this API directly, and rather return
the
result as it is returned from __contains__.

i see no reason it should behave differently than __eq__ and the rest
of comparison operators.


-tomer
_______________________________________________
Python-Dev mailing list
Python-Dev at python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/cmason%40vcentertainme
nt.com


More information about the Python-Dev mailing list