blob: ecc4fffec0d8492272342dde19fd0de764eeecfb [file] [log] [blame]
Nick Coghlan650f0d02007-04-15 12:05:43 +00001doctests = """
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
Serhiy Storchaka8c579b12020-02-12 12:18:59 +020024Test 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
Nick Coghlan650f0d02007-04-15 12:05:43 +000040Make 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
Guido van Rossum805365e2007-05-07 22:24:25 +000062Make a nested set comprehension that acts like set(range())
Nick Coghlan650f0d02007-04-15 12:05:43 +000063
64 >>> def srange(n):
Guido van Rossum805365e2007-05-07 22:24:25 +000065 ... return {i for i in range(n)}
Nick Coghlan650f0d02007-04-15 12:05:43 +000066 >>> 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
Guido van Rossum805365e2007-05-07 22:24:25 +000071 >>> lrange = lambda n: {i for i in range(n)}
Nick Coghlan650f0d02007-04-15 12:05:43 +000072 >>> 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):
Guido van Rossum805365e2007-05-07 22:24:25 +000078 ... for x in {i for i in range(n)}:
Nick Coghlan650f0d02007-04-15 12:05:43 +000079 ... 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
Guido van Rossum805365e2007-05-07 22:24:25 +000086 >>> {None for i in range(10)}
Nick Coghlan650f0d02007-04-15 12:05:43 +000087 {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
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000152 from test import support
Guido van Rossum0368b722007-05-11 16:50:42 +0000153 from test import test_setcomps
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000154 support.run_doctest(test_setcomps, verbose)
Nick Coghlan650f0d02007-04-15 12:05:43 +0000155
156 # verify reference counting
157 if verbose and hasattr(sys, "gettotalrefcount"):
158 import gc
159 counts = [None] * 5
Guido van Rossum805365e2007-05-07 22:24:25 +0000160 for i in range(len(counts)):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000161 support.run_doctest(test_setcomps, verbose)
Nick Coghlan650f0d02007-04-15 12:05:43 +0000162 gc.collect()
163 counts[i] = sys.gettotalrefcount()
164 print(counts)
165
166if __name__ == "__main__":
167 test_main(verbose=True)