[Python-Dev] RE: PySequence_Contains

Tim Peters tim.one@home.com
Sat, 5 May 2001 17:24:58 -0400


[Guido]
> 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.

I'd say "safer", but not "safe":  at that point we only know that *some*
attribute didn't exist, somewhere, while attempting to look up
"__contains__".  Ignoring it could, e.g., be masking a bug in a __getattr__
hook, like

    def __getattr__(self, attr):
        return global_resolver.resolve(self, attr)

where global_resolver has lost its "resolve" attr.  "except" clauses aren't
more bulletproof in C than in Python <0.9 wink>.

> 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.

I don't believe I ever knew that!  Thanks.  I erronesouly assumed that the
looping behavior was *introduced* when __contains__ was added.

> ...
> 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.)

I factored out the new iterator-based __contains__ logic into a new private
API function, called when appropriate by both PySequence_Contains() and
instance_contains().  So any future changes to what iterator-based
__contains__ means will only need to be made in one place.

too-easy<wink>-ly y'rs  - tim