|
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()
|