On Sun, Sep 29, 2019 at 11:27:32AM +0100, Oscar Benjamin wrote:

> That's the point that I would make as well. What can you do with an
> object that is only known to be Subscriptable?

I can subscript it. What did you expect the answer to be?

If you want to know if an object has a length, you can ask if it is 
Sized, without being forced to ask if it also supports a whole bunch of 
methods you don't care about.

If you want to know if something supports the ``in`` operator, you can 
ask if it is a Container, without being forced to check for unneeded 
methods you have no interest in. Nobody asks, "What can you do with an 
object that is only known to be a Container?" because the answer is 
obvious: you can check whether it contains things.

Likewise for awaitable, callable, hashable etc objects.

But subscripting (indexing) is a conspicuous exception. There's no ABC 
for testing whether something supports subscripting.

I don't want to get into an argument about "EAFP is better than LBYL", 
it's not 1999 any more and the Python community has moved past that holy 
war. We should acknowledge that sometimes it is better to test for an 
interface. That's why we have ABCs in the first place.

Whether I use ABC mixins, or write my own dunders, these interfaces are 
composable, orthogonal building blocks. I can give a class a 
__contains__ method without being forced to duplicate the entire list 
API, or even the entire Collection API. If I want to test for that 
__contains__ method, why should I check for the Collection API when I 
don't care about iteration or length?

That's a rhetorical question, because I don't have to check for 
unnecessary and unneeded methods that I don't care about. We have a 
Container ABC and I can just ask isinstance(obj, Container).

Coming back to my purposes...

(1) I have some classes which are infinite, lazily generated "sequences" 
of values. (I put sequences here in inverted commas because I am using 
the word in the regular English sense, not the collections.abc.Sequence 
sense.)

I don't want to falsely advertise that these classes are Sequences by 
giving them an unwanted __len__ method. Is that unreasonable? I just 
want to not give them a __len__ method at all, which Python is perfectly 
happy with me doing.

And I want to test for the minimal set of methods that I need, which is 
getitem, not a superset of methods "getitem plus len plus iter". Is that 
unreasonable?


(2) I have a function which does introspection on arbitrary objects. 
It needs to process objects that are subscriptable differently from 
objects that aren't subscriptable, but it doesn't care about the 
additional Sequence methods. In fact, it specifically needs to 
distinguish unsized "sequences" from sized Sequences.


For my own purposes, I can solve these problems. I can write my own 
Subscriptable test, but I'll probably get it wrong. Or I can copy and 
paste the useful bits from collections.abc, but that's an anti-pattern 
for various reasons that I trust I don't have to explain. For *myself*, 
it doesn't matter whether 3.9 gains this functionality or not.

We can mix-n-match hashing, iteration, indexing, containment etc in our 
classes, without being forced to add extra methods we don't need or care 
about (and sometimes, actively don't want) to meet a higher-order 
protocol like Mapping or Sequence. We can compose new classes from 
individual components, but we can't check for those individual 
components.


-- 
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/GPYOTXDL7MGINEUVUUDTOUKDDEMY6L7R/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to