[Python-3000] interfaces

Mike Orr sluggoster at gmail.com
Sun Nov 19 19:56:01 CET 2006


On 11/19/06, George Sakkis <gsakkis at rutgers.edu> wrote:
> That's perhaps one of the top gotchas in Python today; thankfully it
> will change in 3.0. Until then, I can't see how one can avoid an
> explicit check, either by testing with isinstance() or trying to call
> an arbitrary method of the expected protocol. Having said that both
> are necessary evils, I'd go with the isinstance check as the lesser
> evil. Checking for an arbitrary method is not only an ugly kludge; it
> is both unnecessary (if the tested method is not used in the actual
> code) and error-prone (e.g. for instances of a type that just happens
> to define __add__ so that x + 0 doesn't raise an exception, although x
> is an unappropriate argument in the specific context).

One of Python's biggest surprises is it has distinct concepts of
"sequence" and "mapping", but the API is intertwined so much you can't
even test whether an object is one or the other.  Say you want to
verify an object is a sequence:

    (1) isinstance(obj, list): fails for UserList et al, but many
users have gone this route of requiring a list subclass because it's
the most straighforward.

    (2) hasattr(obj, "__getitem__"): it may have that method, but that
doesn't mean it's list-like.

    (3) Does .__getitem__() accept int arguments?  All lists/dicts do.

    (4) Does .__getitem__() return a value for all ints within range
(0, len(obj))?  No way to test for this without calling with all
possible args and seeing if it raises LookupError.

I can't think of any way around this except a 'sequence' interface
that 'list' would implement.  That in itself wouldn't verify test 4,
but the fact that 'implements(obj, sequence) == True' would mean the
class author has promised it will.

However, requiring objects to be list subclasses hasn't been that much
of a burden in practical terms.

-- 
Mike Orr <sluggoster at gmail.com>


More information about the Python-3000 mailing list