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