17db96d56Sopenharmony_ciimport doctest
27db96d56Sopenharmony_ciimport unittest
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci
57db96d56Sopenharmony_cidoctests = """
67db96d56Sopenharmony_ci########### Tests borrowed from or inspired by test_genexps.py ############
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_ciTest simple loop with conditional
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ci    >>> sum([i*i for i in range(100) if i&1 == 1])
117db96d56Sopenharmony_ci    166650
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ciTest simple nesting
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci    >>> [(i,j) for i in range(3) for j in range(4)]
167db96d56Sopenharmony_ci    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ciTest nesting with the inner expression dependent on the outer
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci    >>> [(i,j) for i in range(4) for j in range(i)]
217db96d56Sopenharmony_ci    [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ciTest the idiom for temporary variable assignment in comprehensions.
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ci    >>> [j*j for i in range(4) for j in [i+1]]
267db96d56Sopenharmony_ci    [1, 4, 9, 16]
277db96d56Sopenharmony_ci    >>> [j*k for i in range(4) for j in [i+1] for k in [j+1]]
287db96d56Sopenharmony_ci    [2, 6, 12, 20]
297db96d56Sopenharmony_ci    >>> [j*k for i in range(4) for j, k in [(i+1, i+2)]]
307db96d56Sopenharmony_ci    [2, 6, 12, 20]
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ciNot assignment
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_ci    >>> [i*i for i in [*range(4)]]
357db96d56Sopenharmony_ci    [0, 1, 4, 9]
367db96d56Sopenharmony_ci    >>> [i*i for i in (*range(4),)]
377db96d56Sopenharmony_ci    [0, 1, 4, 9]
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ciMake sure the induction variable is not exposed
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci    >>> i = 20
427db96d56Sopenharmony_ci    >>> sum([i*i for i in range(100)])
437db96d56Sopenharmony_ci    328350
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ci    >>> i
467db96d56Sopenharmony_ci    20
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_ciVerify that syntax error's are raised for listcomps used as lvalues
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ci    >>> [y for y in (1,2)] = 10          # doctest: +IGNORE_EXCEPTION_DETAIL
517db96d56Sopenharmony_ci    Traceback (most recent call last):
527db96d56Sopenharmony_ci       ...
537db96d56Sopenharmony_ci    SyntaxError: ...
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci    >>> [y for y in (1,2)] += 10         # doctest: +IGNORE_EXCEPTION_DETAIL
567db96d56Sopenharmony_ci    Traceback (most recent call last):
577db96d56Sopenharmony_ci       ...
587db96d56Sopenharmony_ci    SyntaxError: ...
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci########### Tests borrowed from or inspired by test_generators.py ############
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ciMake a nested list comprehension that acts like range()
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ci    >>> def frange(n):
667db96d56Sopenharmony_ci    ...     return [i for i in range(n)]
677db96d56Sopenharmony_ci    >>> frange(10)
687db96d56Sopenharmony_ci    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ciSame again, only as a lambda expression instead of a function definition
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ci    >>> lrange = lambda n:  [i for i in range(n)]
737db96d56Sopenharmony_ci    >>> lrange(10)
747db96d56Sopenharmony_ci    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ciGenerators can call other generators:
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci    >>> def grange(n):
797db96d56Sopenharmony_ci    ...     for x in [i for i in range(n)]:
807db96d56Sopenharmony_ci    ...         yield x
817db96d56Sopenharmony_ci    >>> list(grange(5))
827db96d56Sopenharmony_ci    [0, 1, 2, 3, 4]
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ciMake sure that None is a valid return value
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci    >>> [None for i in range(10)]
887db96d56Sopenharmony_ci    [None, None, None, None, None, None, None, None, None, None]
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_ci########### Tests for various scoping corner cases ############
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ciReturn lambdas that use the iteration variable as a default argument
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ci    >>> items = [(lambda i=i: i) for i in range(5)]
957db96d56Sopenharmony_ci    >>> [x() for x in items]
967db96d56Sopenharmony_ci    [0, 1, 2, 3, 4]
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ciSame again, only this time as a closure variable
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ci    >>> items = [(lambda: i) for i in range(5)]
1017db96d56Sopenharmony_ci    >>> [x() for x in items]
1027db96d56Sopenharmony_ci    [4, 4, 4, 4, 4]
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ciAnother way to test that the iteration variable is local to the list comp
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_ci    >>> items = [(lambda: i) for i in range(5)]
1077db96d56Sopenharmony_ci    >>> i = 20
1087db96d56Sopenharmony_ci    >>> [x() for x in items]
1097db96d56Sopenharmony_ci    [4, 4, 4, 4, 4]
1107db96d56Sopenharmony_ci
1117db96d56Sopenharmony_ciAnd confirm that a closure can jump over the list comp scope
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ci    >>> items = [(lambda: y) for i in range(5)]
1147db96d56Sopenharmony_ci    >>> y = 2
1157db96d56Sopenharmony_ci    >>> [x() for x in items]
1167db96d56Sopenharmony_ci    [2, 2, 2, 2, 2]
1177db96d56Sopenharmony_ci
1187db96d56Sopenharmony_ciWe also repeat each of the above scoping tests inside a function
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_ci    >>> def test_func():
1217db96d56Sopenharmony_ci    ...     items = [(lambda i=i: i) for i in range(5)]
1227db96d56Sopenharmony_ci    ...     return [x() for x in items]
1237db96d56Sopenharmony_ci    >>> test_func()
1247db96d56Sopenharmony_ci    [0, 1, 2, 3, 4]
1257db96d56Sopenharmony_ci
1267db96d56Sopenharmony_ci    >>> def test_func():
1277db96d56Sopenharmony_ci    ...     items = [(lambda: i) for i in range(5)]
1287db96d56Sopenharmony_ci    ...     return [x() for x in items]
1297db96d56Sopenharmony_ci    >>> test_func()
1307db96d56Sopenharmony_ci    [4, 4, 4, 4, 4]
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_ci    >>> def test_func():
1337db96d56Sopenharmony_ci    ...     items = [(lambda: i) for i in range(5)]
1347db96d56Sopenharmony_ci    ...     i = 20
1357db96d56Sopenharmony_ci    ...     return [x() for x in items]
1367db96d56Sopenharmony_ci    >>> test_func()
1377db96d56Sopenharmony_ci    [4, 4, 4, 4, 4]
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ci    >>> def test_func():
1407db96d56Sopenharmony_ci    ...     items = [(lambda: y) for i in range(5)]
1417db96d56Sopenharmony_ci    ...     y = 2
1427db96d56Sopenharmony_ci    ...     return [x() for x in items]
1437db96d56Sopenharmony_ci    >>> test_func()
1447db96d56Sopenharmony_ci    [2, 2, 2, 2, 2]
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ci"""
1477db96d56Sopenharmony_ci
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ci__test__ = {'doctests' : doctests}
1507db96d56Sopenharmony_ci
1517db96d56Sopenharmony_cidef load_tests(loader, tests, pattern):
1527db96d56Sopenharmony_ci    tests.addTest(doctest.DocTestSuite())
1537db96d56Sopenharmony_ci    return tests
1547db96d56Sopenharmony_ci
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_ciif __name__ == "__main__":
1577db96d56Sopenharmony_ci    unittest.main()
158