mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Generalize tuple() to work nicely with iterators.
NEEDS DOC CHANGES. This one surprised me! While I expected tuple() to be a no-brainer, turns out it's actually dripping with consequences: 1. It will *allow* the popular PySequence_Fast() to work with any iterable object (code for that not yet checked in, but should be trivial). 2. It caused two std tests to fail. This because some places used PyTuple_Sequence() (the C spelling of tuple()) as an indirect way to test whether something *is* a sequence. But tuple() code only looked for the existence of sq->item to determine that, and e.g. an instance passed that test whether or not it supported the other operations tuple() needed (e.g., __len__). So some things the tests *expected* to fail with an AttributeError now fail with a TypeError instead. This looks like an improvement to me; e.g., test_coercion used to produce 559 TypeErrors and 2 AttributeErrors, and now they're all TypeErrors. The error details are more informative too, because the places calling this were *looking* for TypeErrors in order to replace the generic tuple() "not a sequence" msg with their own more specific text, and AttributeErrors snuck by that.
This commit is contained in:
parent
f4848dac41
commit
6912d4ddf0
6 changed files with 89 additions and 49 deletions
|
@ -275,6 +275,39 @@ class TestCase(unittest.TestCase):
|
|||
except OSError:
|
||||
pass
|
||||
|
||||
# Test tuples()'s use of iterators.
|
||||
def test_builtin_tuple(self):
|
||||
self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4))
|
||||
self.assertEqual(tuple(SequenceClass(0)), ())
|
||||
self.assertEqual(tuple([]), ())
|
||||
self.assertEqual(tuple(()), ())
|
||||
self.assertEqual(tuple("abc"), ("a", "b", "c"))
|
||||
|
||||
d = {"one": 1, "two": 2, "three": 3}
|
||||
self.assertEqual(tuple(d), tuple(d.keys()))
|
||||
|
||||
self.assertRaises(TypeError, tuple, list)
|
||||
self.assertRaises(TypeError, tuple, 42)
|
||||
|
||||
f = open(TESTFN, "w")
|
||||
try:
|
||||
for i in range(5):
|
||||
f.write("%d\n" % i)
|
||||
finally:
|
||||
f.close()
|
||||
f = open(TESTFN, "r")
|
||||
try:
|
||||
self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n"))
|
||||
f.seek(0, 0)
|
||||
self.assertEqual(tuple(f.xreadlines()),
|
||||
("0\n", "1\n", "2\n", "3\n", "4\n"))
|
||||
finally:
|
||||
f.close()
|
||||
try:
|
||||
unlink(TESTFN)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# Test filter()'s use of iterators.
|
||||
def test_builtin_filter(self):
|
||||
self.assertEqual(filter(None, SequenceClass(5)), range(1, 5))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue