1import doctest
2import unittest
3
4
5doctests = """
6########### Tests mostly copied from test_listcomps.py ############
7
8Test simple loop with conditional
9
10    >>> sum({i*i for i in range(100) if i&1 == 1})
11    166650
12
13Test simple case
14
15    >>> {2*y + x + 1 for x in (0,) for y in (1,)}
16    {3}
17
18Test simple nesting
19
20    >>> list(sorted({(i,j) for i in range(3) for j in range(4)}))
21    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
22
23Test nesting with the inner expression dependent on the outer
24
25    >>> list(sorted({(i,j) for i in range(4) for j in range(i)}))
26    [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
27
28Test the idiom for temporary variable assignment in comprehensions.
29
30    >>> sorted({j*j for i in range(4) for j in [i+1]})
31    [1, 4, 9, 16]
32    >>> sorted({j*k for i in range(4) for j in [i+1] for k in [j+1]})
33    [2, 6, 12, 20]
34    >>> sorted({j*k for i in range(4) for j, k in [(i+1, i+2)]})
35    [2, 6, 12, 20]
36
37Not assignment
38
39    >>> sorted({i*i for i in [*range(4)]})
40    [0, 1, 4, 9]
41    >>> sorted({i*i for i in (*range(4),)})
42    [0, 1, 4, 9]
43
44Make sure the induction variable is not exposed
45
46    >>> i = 20
47    >>> sum({i*i for i in range(100)})
48    328350
49
50    >>> i
51    20
52
53Verify that syntax error's are raised for setcomps used as lvalues
54
55    >>> {y for y in (1,2)} = 10          # doctest: +IGNORE_EXCEPTION_DETAIL
56    Traceback (most recent call last):
57       ...
58    SyntaxError: ...
59
60    >>> {y for y in (1,2)} += 10         # doctest: +IGNORE_EXCEPTION_DETAIL
61    Traceback (most recent call last):
62       ...
63    SyntaxError: ...
64
65
66Make a nested set comprehension that acts like set(range())
67
68    >>> def srange(n):
69    ...     return {i for i in range(n)}
70    >>> list(sorted(srange(10)))
71    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
72
73Same again, only as a lambda expression instead of a function definition
74
75    >>> lrange = lambda n:  {i for i in range(n)}
76    >>> list(sorted(lrange(10)))
77    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
78
79Generators can call other generators:
80
81    >>> def grange(n):
82    ...     for x in {i for i in range(n)}:
83    ...         yield x
84    >>> list(sorted(grange(5)))
85    [0, 1, 2, 3, 4]
86
87
88Make sure that None is a valid return value
89
90    >>> {None for i in range(10)}
91    {None}
92
93########### Tests for various scoping corner cases ############
94
95Return lambdas that use the iteration variable as a default argument
96
97    >>> items = {(lambda i=i: i) for i in range(5)}
98    >>> {x() for x in items} == set(range(5))
99    True
100
101Same again, only this time as a closure variable
102
103    >>> items = {(lambda: i) for i in range(5)}
104    >>> {x() for x in items}
105    {4}
106
107Another way to test that the iteration variable is local to the list comp
108
109    >>> items = {(lambda: i) for i in range(5)}
110    >>> i = 20
111    >>> {x() for x in items}
112    {4}
113
114And confirm that a closure can jump over the list comp scope
115
116    >>> items = {(lambda: y) for i in range(5)}
117    >>> y = 2
118    >>> {x() for x in items}
119    {2}
120
121We also repeat each of the above scoping tests inside a function
122
123    >>> def test_func():
124    ...     items = {(lambda i=i: i) for i in range(5)}
125    ...     return {x() for x in items}
126    >>> test_func() == set(range(5))
127    True
128
129    >>> def test_func():
130    ...     items = {(lambda: i) for i in range(5)}
131    ...     return {x() for x in items}
132    >>> test_func()
133    {4}
134
135    >>> def test_func():
136    ...     items = {(lambda: i) for i in range(5)}
137    ...     i = 20
138    ...     return {x() for x in items}
139    >>> test_func()
140    {4}
141
142    >>> def test_func():
143    ...     items = {(lambda: y) for i in range(5)}
144    ...     y = 2
145    ...     return {x() for x in items}
146    >>> test_func()
147    {2}
148
149"""
150
151
152__test__ = {'doctests' : doctests}
153
154def load_tests(loader, tests, pattern):
155    tests.addTest(doctest.DocTestSuite())
156    return tests
157
158
159if __name__ == "__main__":
160    unittest.main()
161