[Python-Dev] RE: PySequence_Contains (original) (raw)

Guido van Rossum guido@digicool.com
Sat, 05 May 2001 16:48:33 -0500


[Guido] > This kind of thing happens everywhere -- instances always define all > slots but using the slots sometimes fails when the corresponding > foo doesn't exist. Decisions based on the presence or absence of > a slot are therefore in general not reliable; the only exception is > the decision to call the slot or not. The correct solution is not > to catch AttributeError and pretend that the slot didn't exist (which > would mask an AttributeError occurring inside the contains method > if there was one),

[Tim]

Ya, it sucks. I was inspired by that instancecontains() itself makes dubious assumptions about what an AttributeError means when the functions it calls raise it .

Actually, instance_contains checks for AttributeError only after calling instance_getattr(), whose only purpose is to return the requested attribute or raise AttributeError, so here it is safe: the contains function hasn't been called yet.

> but to reimplement the default behavior in the instance slot > implementation.

The "backward compatibility" comment in instancecontains() was scary: compatibility with what?

With previous behavior of 'x in instance'. Before we had contains, 'x in y' always iterated over the items of y as a sequence, comparing them to x one at a time. The loop does that.

instancecontains() is pretty darn new. I assumed it meant there was some good (but unidentified) reason we had to use PyObjectCmp() instead of PyObjectRichCompareBool(..., PyEQ) if instanceitem() "worked".

No, that was probably just an oversight -- clearly it should have used rich comparisons. (I guess this is a disadvantage of the approach I'm recommending here: if the default behavior changes, the reimplementation of the default behavior in the class must be changed too.)

But I haven't thought of one, except to ensure that

somecomplex in someinstancewith_getitem_ continues to blow up -- but that's not a good reason.

Indeed not.

So:

> In this case, that means that PySequenceContains() can be simplified > (no need to test for AttributeError), and instancecontains() should > fall back to a loop over iter(self) rather than trying to use > instanceitem(). Will do!

Thanks!

--Guido van Rossum (home page: http://www.python.org/~guido/)