1# mode: run
2# ticket: 600
3# tag: genexpr
4# cython: language_level=3
5
6cimport cython
7
8#@cython.test_assert_path_exists('//ComprehensionNode')
9#@cython.test_fail_if_path_exists('//SimpleCallNode')
10def list_genexpr_iterable_lookup():
11    """
12    >>> x = (0,1,2,3,4,5)
13    >>> [ x*2 for x in x if x % 2 == 0 ]  # leaks in Py2 but finds the right 'x'
14    [0, 4, 8]
15
16    >>> list_genexpr_iterable_lookup()
17    [0, 4, 8]
18    """
19    x = (0,1,2,3,4,5)
20    result = list( x*2 for x in x if x % 2 == 0 )
21    assert x == (0,1,2,3,4,5)
22    return result
23
24
25#@cython.test_assert_path_exists('//ComprehensionNode')
26#@cython.test_fail_if_path_exists('//SingleAssignmentNode//SimpleCallNode')
27def genexpr_iterable_in_closure():
28    """
29    >>> genexpr_iterable_in_closure()
30    ['aa', 'cc']
31    """
32    x = 'abc'
33    def f():
34        return x
35    result = list( x*2 for x in x if x != 'b' )
36    assert x == 'abc' # don't leak in Py3 code
37    assert f() == 'abc' # don't leak in Py3 code
38    return result
39
40
41def genexpr_over_complex_arg(func, L):
42    """
43    >>> class wrapper(object):
44    ...     value = 5
45    >>> genexpr_over_complex_arg(list, wrapper())
46    [5]
47    """
48    return func(d for d in set([type(L).value, L.__class__.value, L.value]))
49
50
51def listcomp():
52    """
53    >>> listcomp()
54    """
55    data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)]
56    data.sort(key=lambda r: r[1])
57    keys = [r[1] for r in data]
58    return keys
59
60
61def genexpr_in_listcomp(L):
62    """
63    >>> genexpr_in_listcomp( [[1,2,3]]*2 )
64    [[1, 2, 3], [1, 2, 3]]
65    """
66    return list(d for d in [list(d for d in d) for d in L])
67
68
69@cython.test_assert_path_exists('//ForFromStatNode')
70def genexpr_range_in_listcomp(L):
71    """
72    >>> genexpr_range_in_listcomp( [1,2,3] )
73    [[0], [0, 1], [0, 1, 2]]
74    """
75    cdef int z,d
76    return [list(d for d in range(z)) for z in L]
77
78
79@cython.test_fail_if_path_exists('//ForInStatNode')
80def genexpr_in_dictcomp_dictiter():
81    """
82    >>> sorted(genexpr_in_dictcomp_dictiter())
83    [1, 5]
84    """
85    d = {1:2, 3:4, 5:6}
86    return {k:d for k,d in d.iteritems() if d != 4}
87