[Python-ideas] Deprecating the old-style sequence protocol
M.-A. Lemburg
mal at egenix.com
Sun Dec 27 07:25:57 EST 2015
On 27.12.2015 04:07, Andrew Barnert via Python-ideas wrote:
> This idea seems to come up regularly, so maybe it would be good to actually discuss it out (and, if necessary, explicitly reject it). Most recently, at https://github.com/ambv/typehinting/issues/170, Guido said:
>
>> FWIW, maybe we should try to deprecate supporting iteration using the old-style protocol? It's really a very old backwards compatibility measure (from when iterators were first introduced). Then eventually we could do the same for reversing using the old-style protocol.
>
> The best discussion I found was from a 2013 thread (http://article.gmane.org/gmane.comp.python.ideas/23369/), which I'll quote below.
>
> Anyway, the main argument for eliminating the old-style sequence protocol is that, unlike most other protocols in Python, it can't actually be checked for (without iterating the values). Despite a bunch of explicit workaround code (which registers builtin sequence types with `Iterable`, checks for C-API mappings in `reversed`, etc.), you still get false negatives when type-checking types like Steven's at runtime or type-checking time, and you still get false positives from `iter` and `reversed` themselves (`reversed(MyCustomMapping({1:2, 3:4}))` or `iter(typing.Iterable)` won't give you a `TypeError`, they'll give you a useless iterator--which may throw some other exception later when trying to iterate it, but even that isn't reliable).
I'm not sure I follow. The main purpose of ABCs was to be able
to explicitly define a type as complying to the sequence, mapping, etc.
protocols by registering the class with the appropriate ABCs.
https://www.python.org/dev/peps/pep-3119/
The "sequence protocol" is defined by the Sequence ABC, so by
running an isinstance(obj, collections.abc.Sequence) check you can
verify the protocol compliance.
Now, most of your email talks about iteration, so perhaps you're
referring to a different protocol, that of iterating over arbitrary
objects which implement .__getitem__(), but don't implement .__iter__()
or .__len__().
However, the support for the iteration protocol is part of the
Sequence ABC, so there's no way to separate the two. A Sequence must
implement .__len__() as well as .__getitem__() and thus can always
implement .__reversed__() and .__iter__().
An object which implements .__getitem__() without .__len__()
is not a Python sequence (*).
Overall, the discussion feels somewhat arbitrary to me and is
perhaps caused more by a misinterpretation or vague documentation
which would need to be clarified, than by an actually missing
feature in Python, paired with an important existing practical
need :-)
Putting all this together, I believe you're talking about the
iter() support for non-sequence, indexable objects. We don't have
an ABC for this:
https://docs.python.org/3.5/library/collections.abc.html#collections-abstract-base-classes
and can thus not check for it.
(*) The CPython interpreter actually has a different view on
this. It only checks for a .__getitem__() method, not a .__len__()
method, in PySequence_Check(). The length information is only
queried where necessary and a missing implementation then results in
an exception.
--
Marc-Andre Lemburg
eGenix.com
Professional Python Services directly from the Experts (#1, Dec 27 2015)
>>> Python Projects, Coaching and Consulting ... http://www.egenix.com/
>>> Python Database Interfaces ... http://products.egenix.com/
>>> Plone/Zope Database Interfaces ... http://zope.egenix.com/
________________________________________________________________________
::: We implement business ideas - efficiently in both time and costs :::
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
Registered at Amtsgericht Duesseldorf: HRB 46611
http://www.egenix.com/company/contact/
http://www.malemburg.com/
More information about the Python-ideas
mailing list