Blame tests/run/closures_T82.pyx

Packit 562c7a
# mode: run
Packit 562c7a
# tag: closures
Packit 562c7a
# ticket: 82
Packit 562c7a
# preparse: id
Packit 562c7a
# preparse: def_to_cdef
Packit 562c7a
Packit 562c7a
cimport cython
Packit 562c7a
Packit 562c7a
def add_n(int n):
Packit 562c7a
    """
Packit 562c7a
    >>> f = add_n(3)
Packit 562c7a
    >>> f(2)
Packit 562c7a
    5
Packit 562c7a
Packit 562c7a
    >>> f = add_n(1000000)
Packit 562c7a
    >>> f(1000000), f(-1000000)
Packit 562c7a
    (2000000, 0)
Packit 562c7a
    """
Packit 562c7a
    def f(int x):
Packit 562c7a
        return x+n
Packit 562c7a
    return f
Packit 562c7a
Packit 562c7a
def a(int x):
Packit 562c7a
    """
Packit 562c7a
    >>> a(5)()
Packit 562c7a
    8
Packit 562c7a
    """
Packit 562c7a
    def b():
Packit 562c7a
        def c():
Packit 562c7a
            return 3+x
Packit 562c7a
        return c()
Packit 562c7a
    return b
Packit 562c7a
Packit 562c7a
def local_x(int arg_x):
Packit 562c7a
    """
Packit 562c7a
    >>> local_x(1)(2)(4)
Packit 562c7a
    4 2 1
Packit 562c7a
    15
Packit 562c7a
    """
Packit 562c7a
    cdef int local_x = arg_x
Packit 562c7a
    def y(arg_y):
Packit 562c7a
        y = arg_y
Packit 562c7a
        def z(long arg_z):
Packit 562c7a
            cdef long z = arg_z
Packit 562c7a
            print z, y, local_x
Packit 562c7a
            return 8+z+y+local_x
Packit 562c7a
        return z
Packit 562c7a
    return y
Packit 562c7a
Packit 562c7a
def x(int x):
Packit 562c7a
    """
Packit 562c7a
    >>> x(1)(2)(4)
Packit 562c7a
    15
Packit 562c7a
    """
Packit 562c7a
    def y(y):
Packit 562c7a
        def z(long z):
Packit 562c7a
            return 8+z+y+x
Packit 562c7a
        return z
Packit 562c7a
    return y
Packit 562c7a
Packit 562c7a
def x2(int x2):
Packit 562c7a
    """
Packit 562c7a
    >>> x2(1)(2)(4)
Packit 562c7a
    4 2 1
Packit 562c7a
    15
Packit 562c7a
    """
Packit 562c7a
    def y2(y2):
Packit 562c7a
        def z2(long z2):
Packit 562c7a
            print z2, y2, x2
Packit 562c7a
            return 8+z2+y2+x2
Packit 562c7a
        return z2
Packit 562c7a
    return y2
Packit 562c7a
Packit 562c7a
Packit 562c7a
def inner_override(a,b):
Packit 562c7a
    """
Packit 562c7a
    >>> inner_override(2,4)()
Packit 562c7a
    5
Packit 562c7a
    """
Packit 562c7a
    def f():
Packit 562c7a
        a = 1
Packit 562c7a
        return a+b
Packit 562c7a
    return f
Packit 562c7a
Packit 562c7a
Packit 562c7a
def reassign(x):
Packit 562c7a
    """
Packit 562c7a
    >>> reassign(4)(2)
Packit 562c7a
    3
Packit 562c7a
    """
Packit 562c7a
    def f(a):
Packit 562c7a
        return a+x
Packit 562c7a
    x = 1
Packit 562c7a
    return f
Packit 562c7a
Packit 562c7a
def reassign_int(x):
Packit 562c7a
    """
Packit 562c7a
    >>> reassign_int(4)(2)
Packit 562c7a
    3
Packit 562c7a
    """
Packit 562c7a
    def f(int a):
Packit 562c7a
        return a+x
Packit 562c7a
    x = 1
Packit 562c7a
    return f
Packit 562c7a
Packit 562c7a
def reassign_int_int(int x):
Packit 562c7a
    """
Packit 562c7a
    >>> reassign_int_int(4)(2)
Packit 562c7a
    3
Packit 562c7a
    """
Packit 562c7a
    def f(int a):
Packit 562c7a
        return a+x
Packit 562c7a
    x = 1
Packit 562c7a
    return f
Packit 562c7a
Packit 562c7a
Packit 562c7a
def cy_twofuncs(x):
Packit 562c7a
    """
Packit 562c7a
    >>> def py_twofuncs(x):
Packit 562c7a
    ...    def f(a):
Packit 562c7a
    ...        return g(x) + a
Packit 562c7a
    ...    def g(b):
Packit 562c7a
    ...        return x + b
Packit 562c7a
    ...    return f
Packit 562c7a
Packit 562c7a
    >>> py_twofuncs(1)(2) == cy_twofuncs(1)(2)
Packit 562c7a
    True
Packit 562c7a
    >>> py_twofuncs(3)(5) == cy_twofuncs(3)(5)
Packit 562c7a
    True
Packit 562c7a
    """
Packit 562c7a
    def f(a):
Packit 562c7a
        return g(x) + a
Packit 562c7a
    def g(b):
Packit 562c7a
        return x + b
Packit 562c7a
    return f
Packit 562c7a
Packit 562c7a
def switch_funcs(a, b, int ix):
Packit 562c7a
    """
Packit 562c7a
    >>> switch_funcs([1,2,3], [4,5,6], 0)([10])
Packit 562c7a
    [1, 2, 3, 10]
Packit 562c7a
    >>> switch_funcs([1,2,3], [4,5,6], 1)([10])
Packit 562c7a
    [4, 5, 6, 10]
Packit 562c7a
    >>> switch_funcs([1,2,3], [4,5,6], 2) is None
Packit 562c7a
    True
Packit 562c7a
    """
Packit 562c7a
    def f(x):
Packit 562c7a
        return a + x
Packit 562c7a
    def g(x):
Packit 562c7a
        return b + x
Packit 562c7a
    if ix == 0:
Packit 562c7a
        return f
Packit 562c7a
    elif ix == 1:
Packit 562c7a
        return g
Packit 562c7a
    else:
Packit 562c7a
        return None
Packit 562c7a
Packit 562c7a
def ignore_func(x):
Packit 562c7a
    def f():
Packit 562c7a
        return x
Packit 562c7a
    return None
Packit 562c7a
Packit 562c7a
def call_ignore_func():
Packit 562c7a
    """
Packit 562c7a
    >>> call_ignore_func()
Packit 562c7a
    """
Packit 562c7a
    ignore_func((1,2,3))
Packit 562c7a
Packit 562c7a
def more_inner_funcs(x):
Packit 562c7a
    """
Packit 562c7a
    >>> inner_funcs = more_inner_funcs(1)(2,4,8)
Packit 562c7a
    >>> inner_funcs[0](16), inner_funcs[1](32), inner_funcs[2](64)
Packit 562c7a
    (19, 37, 73)
Packit 562c7a
    """
Packit 562c7a
    # called with x==1
Packit 562c7a
    def f(a):
Packit 562c7a
        def g(b):
Packit 562c7a
            # called with 16
Packit 562c7a
            return a+b+x
Packit 562c7a
        return g
Packit 562c7a
    def g(b):
Packit 562c7a
        def f(a):
Packit 562c7a
            # called with 32
Packit 562c7a
            return a+b+x
Packit 562c7a
        return f
Packit 562c7a
    def h(b):
Packit 562c7a
        def f(a):
Packit 562c7a
            # called with 64
Packit 562c7a
            return a+b+x
Packit 562c7a
        return f
Packit 562c7a
    def resolve(a_f, b_g, b_h):
Packit 562c7a
        # called with (2,4,8)
Packit 562c7a
        return f(a_f), g(b_g), h(b_h)
Packit 562c7a
    return resolve
Packit 562c7a
Packit 562c7a
Packit 562c7a
@cython.test_assert_path_exists("//DefNode//DefNode//DefNode//DefNode",
Packit 562c7a
                                "//DefNode[@needs_outer_scope = False]", # deep_inner()
Packit 562c7a
                                "//DefNode//DefNode//DefNode//DefNode[@needs_closure = False]", # h()
Packit 562c7a
                                )
Packit 562c7a
@cython.test_fail_if_path_exists("//DefNode//DefNode[@needs_outer_scope = False]")
Packit 562c7a
def deep_inner():
Packit 562c7a
    """
Packit 562c7a
    >>> deep_inner()()
Packit 562c7a
    2
Packit 562c7a
    """
Packit 562c7a
    cdef int x = 1
Packit 562c7a
    def f():
Packit 562c7a
        def g():
Packit 562c7a
            def h():
Packit 562c7a
                return x+1
Packit 562c7a
            return h
Packit 562c7a
        return g()
Packit 562c7a
    return f()
Packit 562c7a
Packit 562c7a
Packit 562c7a
@cython.test_assert_path_exists("//DefNode//DefNode//DefNode",
Packit 562c7a
                                "//DefNode//DefNode//DefNode[@needs_outer_scope = False]",  # a()
Packit 562c7a
                                "//DefNode//DefNode//DefNode[@needs_closure = False]", # a(), g(), h()
Packit 562c7a
                                )
Packit 562c7a
@cython.test_fail_if_path_exists("//DefNode//DefNode//DefNode[@needs_closure = True]") # a(), g(), h()
Packit 562c7a
def deep_inner_sibling():
Packit 562c7a
    """
Packit 562c7a
    >>> deep_inner_sibling()()
Packit 562c7a
    2
Packit 562c7a
    """
Packit 562c7a
    cdef int x = 1
Packit 562c7a
    def f():
Packit 562c7a
        def a():
Packit 562c7a
            return 1
Packit 562c7a
        def g():
Packit 562c7a
            return x+a()
Packit 562c7a
        def h():
Packit 562c7a
            return g()
Packit 562c7a
        return h
Packit 562c7a
    return f()