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