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