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