I keep finding myself needing to test for objects that support 
subscripting. This is one case where EAFP is *not* actually easier:

    try:
        obj[0]
    except TypeError:
        subscriptable = False
    except (IndexError, KeyError):
        subscriptable = True
    else:
        subscriptable = True
    if subscriptable:
        ...


But I don't like manually testing for it like this:

    if getattr(obj, '__getitem__', None) is not None: ...

because it is wrong. (Its wrong because an object with __getitem__ 
defined as an instance attribute isn't subscriptable; it has to be in 
the class, or a superclass.)

But doing it correctly is too painful:

    if any(getattr(T, '__getitem__', None) is not None for T in type(obj).mro())

and besides I've probably still got it wrong in some subtle way. What 
I'd really like to do is use the collections.abc module to do the check:

    if isinstance(obj, collections.abc.Subscriptable): ...

in the same way we can check for Sized, Hashable etc.

Alternatively, if we had a getclassattr that skipped the instance 
attributes, I could say:

    if getclassattr(obj, '__getitem__', None) is not None: ...


(1) Am I doing it wrong? Perhaps I've missed some already existing 
solution to this.

(2) If not, is there any reason why we shouldn't add Subscriptable to 
the collection.abc module? I think I have the implementation:

    class Subscriptable(metaclass=ABCMeta):
        __slots__ = ()
        @abstractmethod
        def __getitem__(self, idx):
            return None
        @classmethod
        def __subclasshook__(cls, C):
            if cls is Subscriptable:
                return _check_methods(C, "__getitem__")
            return NotImplemented

Comments, questions, flames?



-- 
Steven
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/JCQJP5K32SELHRZFQB75CNLTECT3YD3K/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to