@@ -1521,6 +1521,14 @@ def test_vars(self):
1521
1521
self .assertRaises (TypeError , vars , 42 )
1522
1522
self .assertEqual (vars (self .C_get_vars ()), {'a' :2 })
1523
1523
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
+
1524
1532
def test_zip (self ):
1525
1533
a = (1 , 2 , 3 )
1526
1534
b = (4 , 5 , 6 )
@@ -1573,6 +1581,66 @@ def test_zip_pickle(self):
1573
1581
z1 = zip (a , b )
1574
1582
self .check_iter_pickle (z1 , t , proto )
1575
1583
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
+
1576
1644
def test_zip_bad_iterable (self ):
1577
1645
exception = TypeError ()
1578
1646
@@ -1585,6 +1653,88 @@ def __iter__(self):
1585
1653
1586
1654
self .assertIs (cm .exception , exception )
1587
1655
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
+
1588
1738
def test_format (self ):
1589
1739
# Test the basic machinery of the format() builtin. Don't test
1590
1740
# the specifics of the various formatters
0 commit comments