STINNER Victor <[email protected]> added the comment:
Joachim:
> It's possible to use a tuple subclass, though, and while it doesn't break the
> function because it reads , the tuple is not explored through the __iter__
> interface: (...)
I don't think that the example from the first message is an issue in
isinstance(). Defining __iter__() does not override __getitem__() nor __len__():
---
class T(tuple):
def __iter__(self):
print("__iter__")
yield self
inst = T(("a", "b"))
print(len(inst))
print(inst[0])
print(inst[1])
---
Output:
---
2
a
b
---
But isinstance() doesn't call overriden __getitem__() and __len__() methods,
only tuple.__getitem__() and tuple.__len__() original methods.
Joachim:
> Solutions could be handling any iterable but explicitely checking for
> recursion or, as suggested by Victor Stinner, forbidding subclasses of tuple.
isinstance() should use PyTuple_CheckExact(): only accept the exact tuple type,
and reject any other type.
We can start by deprecating tuple subclasses in Python 3.9.
Paul:
> Should we switch to using __iter__ when it's defined because there are other
> cases where the custom behavior of the subclass is defined by its __iter__?
I just restored an old comment from Guido van Rossum which was lost in a
previous refactoring, commit 850a4bd839ca11b59439e21dda2a3ebe917a9a16:
if (PyTuple_Check(cls)) {
/* Not a general sequence -- that opens up the road to
recursion and stack overflow. */
...
}
--
By the way, nested tuples are accepted:
>>> isinstance(1, ((((int,),),),))
True
I am -0 on nested tuples. The implementation is not so crazy (simple recursive
code), so it is maybe ok to keep it.
----------
Added file: https://bugs.python.org/file48884/isinstance_iter.py
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue39550>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com