[Python-ideas] strings as iterables - from str.startswith taking any iterator instead of just tuple

Masklinn masklinn at masklinn.net
Fri Jan 3 13:12:41 CET 2014


On 2014-01-03, at 12:41 , Nick Coghlan <ncoghlan at gmail.com> wrote:
> "def f(iterable_or_atomic)" also has problems, since strings will use
> the "iterable" path, even if the atomic handling would be more
> appropriate.
> 
> Algorithms that recursively descend into containers also need to deal
> with the fact that doing so with strings causes an infinite loop
> (since iterating over a string produces length 1 strings).
> 
> This is a genuine problem, which is why the question of how to cleanly
> deal with these situations keeps coming up every couple of years, and
> the current state of the art answer is "grit your teeth and use
> isinstance(obj, str)" (or a configurable alternative).
> 
> However, I'm wondering if it might be reasonable to add a new entry in
> collections.abc for 3.5:
> 
>>>> from abc import ABC
>>>> from collections.abc import Iterable
>>>> class Atomic(ABC):
> ...     @classmethod
> ...     def __subclasshook__(cls, subclass):
> ...         if not issubclass(subclass, Iterable):
> ...             return True
> ...         return NotImplemented
> ...

I’ve used some sort of ad-hoc version of it enough that I think it’s
a good idea, although I’d suggest “scalar”: “atomic” also
exists (with very different semantics) in concurrency contexts, whereas
I believe scalar always means single-value (non-compound) data type.

>>>> Atomic.register(str)
> <class 'str'>
>>>> Atomic.register(bytes)
> <class 'bytes'>
>>>> Atomic.register(bytearray)
> <class 'bytearray'>
>>>> isinstance(1, Atomic)
> True
>>>> isinstance(1.0, Atomic)
> True
>>>> isinstance(1j, Atomic)
> True
>>>> isinstance("Hello", Atomic)
> True
>>>> isinstance(b"Hello", Atomic)
> True
>>>> isinstance((), Atomic)
> False
>>>> isinstance([], Atomic)
> False
>>>> isinstance({}, Atomic)
> False




More information about the Python-ideas mailing list