test_unpack_ex.py revision 0368b726a1859e3c063df5a93f19ccb4254be22a
1# Tests for extended unpacking, starred expressions.
2
3doctests = """
4
5Unpack tuple
6
7    >>> t = (1, 2, 3)
8    >>> a, *b, c = t
9    >>> a == 1 and b == [2] and c == 3
10    True
11
12Unpack list
13
14    >>> l = [4, 5, 6]
15    >>> a, *b = l
16    >>> a == 4 and b == [5, 6]
17    True
18
19Unpack implied tuple
20
21    >>> *a, = 7, 8, 9
22    >>> a == [7, 8, 9]
23    True
24
25Unpack string... fun!
26
27    >>> a, *b = 'one'
28    >>> a == 'o' and b == ['n', 'e']
29    True
30
31Unpack long sequence
32
33    >>> a, b, c, *d, e, f, g = range(10)
34    >>> (a, b, c, d, e, f, g) == (0, 1, 2, [3, 4, 5, 6], 7, 8, 9)
35    True
36
37Unpack short sequence
38
39    >>> a, *b, c = (1, 2)
40    >>> a == 1 and c == 2 and b == []
41    True
42
43Unpack generic sequence
44
45    >>> class Seq:
46    ...     def __getitem__(self, i):
47    ...         if i >= 0 and i < 3: return i
48    ...         raise IndexError
49    ...
50    >>> a, *b = Seq()
51    >>> a == 0 and b == [1, 2]
52    True
53
54Unpack in for statement
55
56    >>> for a, *b, c in [(1,2,3), (4,5,6,7)]:
57    ...     print(a, b, c)
58    ...
59    1 [2] 3
60    4 [5, 6] 7
61
62Unpack in list
63
64    >>> [a, *b, c] = range(5)
65    >>> a == 0 and b == [1, 2, 3] and c == 4
66    True
67
68Multiple targets
69
70    >>> a, *b, c = *d, e = range(5)
71    >>> a == 0 and b == [1, 2, 3] and c == 4 and d == [0, 1, 2, 3] and e == 4
72    True
73
74Now for some failures
75
76Unpacking non-sequence
77
78    >>> a, *b = 7
79    Traceback (most recent call last):
80      ...
81    TypeError: 'int' object is not iterable
82
83Unpacking sequence too short
84
85    >>> a, *b, c, d, e = Seq()
86    Traceback (most recent call last):
87      ...
88    ValueError: need more than 3 values to unpack
89
90Unpacking a sequence where the test for too long raises a different kind of
91error
92
93    >>> class BozoError(Exception):
94    ...     pass
95    ...
96    >>> class BadSeq:
97    ...     def __getitem__(self, i):
98    ...         if i >= 0 and i < 3:
99    ...             return i
100    ...         elif i == 3:
101    ...             raise BozoError
102    ...         else:
103    ...             raise IndexError
104    ...
105
106Trigger code while not expecting an IndexError (unpack sequence too long, wrong
107error)
108
109    >>> a, *b, c, d, e = BadSeq()
110    Traceback (most recent call last):
111      ...
112    test.test_unpack_ex.BozoError
113
114Now some general starred expressions (all fail).
115
116    >>> a, *b, c, *d, e = range(10) # doctest:+ELLIPSIS
117    Traceback (most recent call last):
118      ...
119    SyntaxError: two starred expressions in assignment (...)
120
121    >>> [*b, *c] = range(10) # doctest:+ELLIPSIS
122    Traceback (most recent call last):
123      ...
124    SyntaxError: two starred expressions in assignment (...)
125
126    >>> *a = range(10) # doctest:+ELLIPSIS
127    Traceback (most recent call last):
128      ...
129    SyntaxError: starred assignment target must be in a list or tuple (...)
130
131    >>> *a # doctest:+ELLIPSIS
132    Traceback (most recent call last):
133      ...
134    SyntaxError: can use starred expression only as assignment target (...)
135
136    >>> *1 # doctest:+ELLIPSIS
137    Traceback (most recent call last):
138      ...
139    SyntaxError: can use starred expression only as assignment target (...)
140
141    >>> x = *a # doctest:+ELLIPSIS
142    Traceback (most recent call last):
143      ...
144    SyntaxError: can use starred expression only as assignment target (...)
145
146"""
147
148__test__ = {'doctests' : doctests}
149
150def test_main(verbose=False):
151    import sys
152    from test import test_support
153    from test import test_unpack_ex
154    test_support.run_doctest(test_unpack_ex, verbose)
155
156if __name__ == "__main__":
157    test_main(verbose=True)
158