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