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 24Make 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 33Verify 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 46Make 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 53Same 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 59Generators 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 68Make sure that None is a valid return value 69 70 >>> {None for i in range(10)} 71 {None} 72 73########### Tests for various scoping corner cases ############ 74 75Return 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 81Same 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 {4} 86 87Another 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 {4} 93 94And 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 {2} 100 101We 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 {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 {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 {2} 128 129""" 130 131 132__test__ = {'doctests' : doctests} 133 134def test_main(verbose=None): 135 import sys 136 from test import support 137 from test import test_setcomps 138 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 support.run_doctest(test_setcomps, verbose) 146 gc.collect() 147 counts[i] = sys.gettotalrefcount() 148 print(counts) 149 150if __name__ == "__main__": 151 test_main(verbose=True) 152