@@ -1521,6 +1521,14 @@ def test_vars(self):
15211521 self .assertRaises (TypeError , vars , 42 )
15221522 self .assertEqual (vars (self .C_get_vars ()), {'a' :2 })
15231523
1524+ def iter_error (self , iterable , error ):
1525+ """Collect `iterable` into a list, catching an expected `error`."""
1526+ items = []
1527+ with self .assertRaises (error ):
1528+ for item in iterable :
1529+ items .append (item )
1530+ return items
1531+
15241532 def test_zip (self ):
15251533 a = (1 , 2 , 3 )
15261534 b = (4 , 5 , 6 )
@@ -1573,6 +1581,66 @@ def test_zip_pickle(self):
15731581 z1 = zip (a , b )
15741582 self .check_iter_pickle (z1 , t , proto )
15751583
1584+ def test_zip_pickle_strict (self ):
1585+ a = (1 , 2 , 3 )
1586+ b = (4 , 5 , 6 )
1587+ t = [(1 , 4 ), (2 , 5 ), (3 , 6 )]
1588+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
1589+ z1 = zip (a , b , strict = True )
1590+ self .check_iter_pickle (z1 , t , proto )
1591+
1592+ def test_zip_pickle_strict_fail (self ):
1593+ a = (1 , 2 , 3 )
1594+ b = (4 , 5 , 6 , 7 )
1595+ t = [(1 , 4 ), (2 , 5 ), (3 , 6 )]
1596+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
1597+ z1 = zip (a , b , strict = True )
1598+ z2 = pickle .loads (pickle .dumps (z1 , proto ))
1599+ self .assertEqual (self .iter_error (z1 , ValueError ), t )
1600+ self .assertEqual (self .iter_error (z2 , ValueError ), t )
1601+
1602+ def test_zip_pickle_stability (self ):
1603+ # Pickles of zip((1, 2, 3), (4, 5, 6)) dumped from 3.9:
1604+ pickles = [
1605+ b'citertools\n izip\n p0\n (c__builtin__\n iter\n p1\n ((I1\n I2\n I3\n tp2\n tp3\n Rp4\n I0\n bg1\n ((I4\n I5\n I6\n tp5\n tp6\n Rp7\n I0\n btp8\n Rp9\n .' ,
1606+ b'citertools\n izip\n q\x00 (c__builtin__\n iter\n q\x01 ((K\x01 K\x02 K\x03 tq\x02 tq\x03 Rq\x04 K\x00 bh\x01 ((K\x04 K\x05 K\x06 tq\x05 tq\x06 Rq\x07 K\x00 btq\x08 Rq\t .' ,
1607+ b'\x80 \x02 citertools\n izip\n q\x00 c__builtin__\n iter\n q\x01 K\x01 K\x02 K\x03 \x87 q\x02 \x85 q\x03 Rq\x04 K\x00 bh\x01 K\x04 K\x05 K\x06 \x87 q\x05 \x85 q\x06 Rq\x07 K\x00 b\x86 q\x08 Rq\t .' ,
1608+ b'\x80 \x03 cbuiltins\n zip\n q\x00 cbuiltins\n iter\n q\x01 K\x01 K\x02 K\x03 \x87 q\x02 \x85 q\x03 Rq\x04 K\x00 bh\x01 K\x04 K\x05 K\x06 \x87 q\x05 \x85 q\x06 Rq\x07 K\x00 b\x86 q\x08 Rq\t .' ,
1609+ b'\x80 \x04 \x95 L\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x8c \x08 builtins\x94 \x8c \x03 zip\x94 \x93 \x94 \x8c \x08 builtins\x94 \x8c \x04 iter\x94 \x93 \x94 K\x01 K\x02 K\x03 \x87 \x94 \x85 \x94 R\x94 K\x00 bh\x05 K\x04 K\x05 K\x06 \x87 \x94 \x85 \x94 R\x94 K\x00 b\x86 \x94 R\x94 .' ,
1610+ b'\x80 \x05 \x95 L\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x8c \x08 builtins\x94 \x8c \x03 zip\x94 \x93 \x94 \x8c \x08 builtins\x94 \x8c \x04 iter\x94 \x93 \x94 K\x01 K\x02 K\x03 \x87 \x94 \x85 \x94 R\x94 K\x00 bh\x05 K\x04 K\x05 K\x06 \x87 \x94 \x85 \x94 R\x94 K\x00 b\x86 \x94 R\x94 .' ,
1611+ ]
1612+ for protocol , dump in enumerate (pickles ):
1613+ z1 = zip ((1 , 2 , 3 ), (4 , 5 , 6 ))
1614+ z2 = zip ((1 , 2 , 3 ), (4 , 5 , 6 ), strict = False )
1615+ z3 = pickle .loads (dump )
1616+ l3 = list (z3 )
1617+ self .assertEqual (type (z3 ), zip )
1618+ self .assertEqual (pickle .dumps (z1 , protocol ), dump )
1619+ self .assertEqual (pickle .dumps (z2 , protocol ), dump )
1620+ self .assertEqual (list (z1 ), l3 )
1621+ self .assertEqual (list (z2 ), l3 )
1622+
1623+ def test_zip_pickle_strict_stability (self ):
1624+ # Pickles of zip((1, 2, 3), (4, 5), strict=True) dumped from 3.10:
1625+ pickles = [
1626+ b'citertools\n izip\n p0\n (c__builtin__\n iter\n p1\n ((I1\n I2\n I3\n tp2\n tp3\n Rp4\n I0\n bg1\n ((I4\n I5\n tp5\n tp6\n Rp7\n I0\n btp8\n Rp9\n I01\n b.' ,
1627+ b'citertools\n izip\n q\x00 (c__builtin__\n iter\n q\x01 ((K\x01 K\x02 K\x03 tq\x02 tq\x03 Rq\x04 K\x00 bh\x01 ((K\x04 K\x05 tq\x05 tq\x06 Rq\x07 K\x00 btq\x08 Rq\t I01\n b.' ,
1628+ b'\x80 \x02 citertools\n izip\n q\x00 c__builtin__\n iter\n q\x01 K\x01 K\x02 K\x03 \x87 q\x02 \x85 q\x03 Rq\x04 K\x00 bh\x01 K\x04 K\x05 \x86 q\x05 \x85 q\x06 Rq\x07 K\x00 b\x86 q\x08 Rq\t \x88 b.' ,
1629+ b'\x80 \x03 cbuiltins\n zip\n q\x00 cbuiltins\n iter\n q\x01 K\x01 K\x02 K\x03 \x87 q\x02 \x85 q\x03 Rq\x04 K\x00 bh\x01 K\x04 K\x05 \x86 q\x05 \x85 q\x06 Rq\x07 K\x00 b\x86 q\x08 Rq\t \x88 b.' ,
1630+ b'\x80 \x04 \x95 L\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x8c \x08 builtins\x94 \x8c \x03 zip\x94 \x93 \x94 \x8c \x08 builtins\x94 \x8c \x04 iter\x94 \x93 \x94 K\x01 K\x02 K\x03 \x87 \x94 \x85 \x94 R\x94 K\x00 bh\x05 K\x04 K\x05 \x86 \x94 \x85 \x94 R\x94 K\x00 b\x86 \x94 R\x94 \x88 b.' ,
1631+ b'\x80 \x05 \x95 L\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x8c \x08 builtins\x94 \x8c \x03 zip\x94 \x93 \x94 \x8c \x08 builtins\x94 \x8c \x04 iter\x94 \x93 \x94 K\x01 K\x02 K\x03 \x87 \x94 \x85 \x94 R\x94 K\x00 bh\x05 K\x04 K\x05 \x86 \x94 \x85 \x94 R\x94 K\x00 b\x86 \x94 R\x94 \x88 b.' ,
1632+ ]
1633+ a = (1 , 2 , 3 )
1634+ b = (4 , 5 )
1635+ t = [(1 , 4 ), (2 , 5 )]
1636+ for protocol , dump in enumerate (pickles ):
1637+ z1 = zip (a , b , strict = True )
1638+ z2 = pickle .loads (dump )
1639+ self .assertEqual (pickle .dumps (z1 , protocol ), dump )
1640+ self .assertEqual (type (z2 ), zip )
1641+ self .assertEqual (self .iter_error (z1 , ValueError ), t )
1642+ self .assertEqual (self .iter_error (z2 , ValueError ), t )
1643+
15761644 def test_zip_bad_iterable (self ):
15771645 exception = TypeError ()
15781646
@@ -1585,6 +1653,88 @@ def __iter__(self):
15851653
15861654 self .assertIs (cm .exception , exception )
15871655
1656+ def test_zip_strict (self ):
1657+ self .assertEqual (tuple (zip ((1 , 2 , 3 ), 'abc' , strict = True )),
1658+ ((1 , 'a' ), (2 , 'b' ), (3 , 'c' )))
1659+ self .assertRaises (ValueError , tuple ,
1660+ zip ((1 , 2 , 3 , 4 ), 'abc' , strict = True ))
1661+ self .assertRaises (ValueError , tuple ,
1662+ zip ((1 , 2 ), 'abc' , strict = True ))
1663+ self .assertRaises (ValueError , tuple ,
1664+ zip ((1 , 2 ), (1 , 2 ), 'abc' , strict = True ))
1665+
1666+ def test_zip_strict_iterators (self ):
1667+ x = iter (range (5 ))
1668+ y = [0 ]
1669+ z = iter (range (5 ))
1670+ self .assertRaises (ValueError , list ,
1671+ (zip (x , y , z , strict = True )))
1672+ self .assertEqual (next (x ), 2 )
1673+ self .assertEqual (next (z ), 1 )
1674+
1675+ def test_zip_strict_error_handling (self ):
1676+
1677+ class Error (Exception ):
1678+ pass
1679+
1680+ class Iter :
1681+ def __init__ (self , size ):
1682+ self .size = size
1683+ def __iter__ (self ):
1684+ return self
1685+ def __next__ (self ):
1686+ self .size -= 1
1687+ if self .size < 0 :
1688+ raise Error
1689+ return self .size
1690+
1691+ l1 = self .iter_error (zip ("AB" , Iter (1 ), strict = True ), Error )
1692+ self .assertEqual (l1 , [("A" , 0 )])
1693+ l2 = self .iter_error (zip ("AB" , Iter (2 ), "A" , strict = True ), ValueError )
1694+ self .assertEqual (l2 , [("A" , 1 , "A" )])
1695+ l3 = self .iter_error (zip ("AB" , Iter (2 ), "ABC" , strict = True ), Error )
1696+ self .assertEqual (l3 , [("A" , 1 , "A" ), ("B" , 0 , "B" )])
1697+ l4 = self .iter_error (zip ("AB" , Iter (3 ), strict = True ), ValueError )
1698+ self .assertEqual (l4 , [("A" , 2 ), ("B" , 1 )])
1699+ l5 = self .iter_error (zip (Iter (1 ), "AB" , strict = True ), Error )
1700+ self .assertEqual (l5 , [(0 , "A" )])
1701+ l6 = self .iter_error (zip (Iter (2 ), "A" , strict = True ), ValueError )
1702+ self .assertEqual (l6 , [(1 , "A" )])
1703+ l7 = self .iter_error (zip (Iter (2 ), "ABC" , strict = True ), Error )
1704+ self .assertEqual (l7 , [(1 , "A" ), (0 , "B" )])
1705+ l8 = self .iter_error (zip (Iter (3 ), "AB" , strict = True ), ValueError )
1706+ self .assertEqual (l8 , [(2 , "A" ), (1 , "B" )])
1707+
1708+ def test_zip_strict_error_handling_stopiteration (self ):
1709+
1710+ class Iter :
1711+ def __init__ (self , size ):
1712+ self .size = size
1713+ def __iter__ (self ):
1714+ return self
1715+ def __next__ (self ):
1716+ self .size -= 1
1717+ if self .size < 0 :
1718+ raise StopIteration
1719+ return self .size
1720+
1721+ l1 = self .iter_error (zip ("AB" , Iter (1 ), strict = True ), ValueError )
1722+ self .assertEqual (l1 , [("A" , 0 )])
1723+ l2 = self .iter_error (zip ("AB" , Iter (2 ), "A" , strict = True ), ValueError )
1724+ self .assertEqual (l2 , [("A" , 1 , "A" )])
1725+ l3 = self .iter_error (zip ("AB" , Iter (2 ), "ABC" , strict = True ), ValueError )
1726+ self .assertEqual (l3 , [("A" , 1 , "A" ), ("B" , 0 , "B" )])
1727+ l4 = self .iter_error (zip ("AB" , Iter (3 ), strict = True ), ValueError )
1728+ self .assertEqual (l4 , [("A" , 2 ), ("B" , 1 )])
1729+ l5 = self .iter_error (zip (Iter (1 ), "AB" , strict = True ), ValueError )
1730+ self .assertEqual (l5 , [(0 , "A" )])
1731+ l6 = self .iter_error (zip (Iter (2 ), "A" , strict = True ), ValueError )
1732+ self .assertEqual (l6 , [(1 , "A" )])
1733+ l7 = self .iter_error (zip (Iter (2 ), "ABC" , strict = True ), ValueError )
1734+ self .assertEqual (l7 , [(1 , "A" ), (0 , "B" )])
1735+ l8 = self .iter_error (zip (Iter (3 ), "AB" , strict = True ), ValueError )
1736+ self .assertEqual (l8 , [(2 , "A" ), (1 , "B" )])
1737+
15881738 def test_format (self ):
15891739 # Test the basic machinery of the format() builtin. Don't test
15901740 # the specifics of the various formatters
0 commit comments