isinstance()

Chris Angelico rosuav at gmail.com
Fri Aug 4 19:18:34 EDT 2023


On Sat, 5 Aug 2023 at 09:08, dn via Python-list <python-list at python.org> wrote:
>
> On 03/08/2023 11.38, Jon Ribbens via Python-list wrote:
> > On 2023-08-02, dn <PythonList at DancesWithMice.info> wrote:
> >> Can you please explain why a multi-part second-argument must be a tuple
> >> and not any other form of collection-type?
> >
> > The following comment may hold a clue:
> >
> >      if (PyTuple_Check(cls)) {
> >          /* Not a general sequence -- that opens up the road to
> >             recursion and stack overflow. */
> >
> > https://github.com/python/cpython/blob/main/Objects/abstract.c#L2684
> >
> > Plus an almost total lack of demand for change I should think.
>
> Thanks for the reference!
>
>
> Am not proposing a change (have learned 'the rule' and accepted
> life-as-it-is), but was curious about the restriction: why not any
> (reasonable sequence)?

There are quite a few places where the only option is a tuple.

>>> "spam".startswith(["sp", "h"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: startswith first arg must be str or a tuple of str, not list
>>> try: 1/0
... except [ValueError, IndexError]: pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: catching classes that do not inherit from BaseException is
not allowed

It simplifies a lot of checks. Either it's a tuple or it's a single
thing. A *lot* of values are iterable, but only tuples are tuples.

As the C comment notes, this also means you don't have to worry about
recursion; otherwise, even core language features like exception
handling would have to iterate over a thing while ensuring that they
don't get stuck in self-referential objects. (Incidentally, it seems
that exception handling doesn't bother with recursion *at all*, and
won't catch "(a, (b, c))" - but even if recursion is handled, it can't
go infinite, short of some serious messing around in ctypes or the C
API.)

ChrisA


More information about the Python-list mailing list