Issue #23757: Only call the concrete list API for exact lists.

This commit is contained in:
Raymond Hettinger 2015-05-17 14:45:58 -07:00
parent 6558190e52
commit 610a51f364
3 changed files with 16 additions and 1 deletions

View File

@ -85,6 +85,14 @@ def itermulti(seqn):
'Test multiple tiers of iterators' 'Test multiple tiers of iterators'
return chain(map(lambda x:x, iterfunc(IterGen(Sequence(seqn))))) return chain(map(lambda x:x, iterfunc(IterGen(Sequence(seqn)))))
class LyingTuple(tuple):
def __iter__(self):
yield 1
class LyingList(list):
def __iter__(self):
yield 1
class CommonTest(unittest.TestCase): class CommonTest(unittest.TestCase):
# The type to be tested # The type to be tested
type2test = None type2test = None
@ -131,6 +139,10 @@ class CommonTest(unittest.TestCase):
self.assertRaises(TypeError, self.type2test, IterNoNext(s)) self.assertRaises(TypeError, self.type2test, IterNoNext(s))
self.assertRaises(ZeroDivisionError, self.type2test, IterGenExc(s)) self.assertRaises(ZeroDivisionError, self.type2test, IterGenExc(s))
# Issue #23757
self.assertEqual(self.type2test(LyingTuple((2,))), self.type2test((1,)))
self.assertEqual(self.type2test(LyingList([2])), self.type2test([1]))
def test_truth(self): def test_truth(self):
self.assertFalse(self.type2test()) self.assertFalse(self.type2test())
self.assertTrue(self.type2test([42])) self.assertTrue(self.type2test([42]))

View File

@ -13,6 +13,9 @@ Core and Builtins
- Issue #20274: Remove ignored and erroneous "kwargs" parameters from three - Issue #20274: Remove ignored and erroneous "kwargs" parameters from three
METH_VARARGS methods on _sqlite.Connection. METH_VARARGS methods on _sqlite.Connection.
- Issue #23757: PySequence_Tuple() incorrectly called the concrete list API
when the data was a list subclass.
- Issue #24096: Make warnings.warn_explicit more robust against mutation of the - Issue #24096: Make warnings.warn_explicit more robust against mutation of the
warnings.filters list. warnings.filters list.

View File

@ -1636,7 +1636,7 @@ PySequence_Tuple(PyObject *v)
Py_INCREF(v); Py_INCREF(v);
return v; return v;
} }
if (PyList_Check(v)) if (PyList_CheckExact(v))
return PyList_AsTuple(v); return PyList_AsTuple(v);
/* Get iterator. */ /* Get iterator. */