Repository URL to install this package:
|
Version:
0.29.7 ▾
|
# cython: binding=True
# mode: run
# tag: cyfunction, closures
cimport cython
import sys
def get_defaults(func):
if sys.version_info >= (2, 6, 0):
return func.__defaults__
return func.func_defaults
def test_defaults_none():
"""
>>> get_defaults(test_defaults_none)
"""
def test_defaults_literal(a=1, b=(1,2,3)):
"""
>>> get_defaults(test_defaults_literal) is get_defaults(test_defaults_literal)
True
>>> get_defaults(test_defaults_literal)
(1, (1, 2, 3))
>>> a, b = get_defaults(test_defaults_literal)
>>> c, d = test_defaults_literal()
>>> a is c
True
>>> b is d
True
"""
return a, b
def test_defaults_nonliteral():
"""
>>> f0, f1 = test_defaults_nonliteral()
>>> get_defaults(f0) is get_defaults(f0) # cached
True
>>> get_defaults(f0)
(0, {}, (1, 2, 3))
>>> a, b = get_defaults(f0)[1:]
>>> c, d = f0(0)
>>> a is c
True
>>> b is d
True
>>> get_defaults(f1) is get_defaults(f1) # cached
True
>>> get_defaults(f1)
(0, [], (1, 2, 3))
>>> a, b = get_defaults(f1)[1:]
>>> c, d = f1(0)
>>> a is c
True
>>> b is d
True
"""
ret = []
for i in {}, []:
def foo(a, b=0, c=i, d=(1,2,3)):
return c, d
ret.append(foo)
return ret
_counter = 0
def counter():
global _counter
_counter += 1
return _counter
def test_defaults_nonliteral_func_call(f):
"""
>>> f = test_defaults_nonliteral_func_call(counter)
>>> f()
1
>>> get_defaults(f)
(1,)
>>> f = test_defaults_nonliteral_func_call(lambda: list())
>>> f()
[]
>>> get_defaults(f)
([],)
>>> get_defaults(f)[0] is f()
True
"""
def func(a=f()):
return a
return func
def cy_kwonly_default_args(a, x=1, *, b=2):
l = m = 1
def test_kwdefaults(value):
"""
>>> cy_kwonly_default_args.__defaults__
(1,)
>>> cy_kwonly_default_args.func_defaults
(1,)
>>> cy_kwonly_default_args.__kwdefaults__
{'b': 2}
>>> test_kwdefaults.__defaults__
>>> test_kwdefaults.__kwdefaults__
>>> f = test_kwdefaults(5)
>>> f.__defaults__
(1,)
>>> f.__kwdefaults__
{'b': 5}
>>> f.__kwdefaults__ = ()
Traceback (most recent call last):
TypeError: __kwdefaults__ must be set to a dict object
>>> f.__kwdefaults__ = None
>>> f.__kwdefaults__
>>> f.__kwdefaults__ = {}
>>> f.__kwdefaults__
{}
>>> f.__kwdefaults__ = {'a': 2}
>>> f.__kwdefaults__
{'a': 2}
"""
def kwonly_default_args(a, x=1, *, b=value):
return a, x, b
return kwonly_default_args
_counter2 = 1.0
def counter2():
global _counter2
_counter2 += 1.0
return _counter2
def test_defaults_fused(cython.floating arg1, cython.floating arg2 = counter2()):
"""
>>> test_defaults_fused(1.0)
1.0 2.0
>>> test_defaults_fused(1.0, 3.0)
1.0 3.0
>>> _counter2
2.0
>>> get_defaults(test_defaults_fused)
(2.0,)
>>> get_defaults(test_defaults_fused[float])
(2.0,)
"""
print arg1, arg2
funcs = []
for i in range(10):
def defaults_fused(cython.floating a, cython.floating b = i):
return a, b
funcs.append(defaults_fused)
def test_dynamic_defaults_fused():
"""
>>> test_dynamic_defaults_fused()
i 0 func result (1.0, 0.0) defaults (0,)
i 1 func result (1.0, 1.0) defaults (1,)
i 2 func result (1.0, 2.0) defaults (2,)
i 3 func result (1.0, 3.0) defaults (3,)
i 4 func result (1.0, 4.0) defaults (4,)
i 5 func result (1.0, 5.0) defaults (5,)
i 6 func result (1.0, 6.0) defaults (6,)
i 7 func result (1.0, 7.0) defaults (7,)
i 8 func result (1.0, 8.0) defaults (8,)
i 9 func result (1.0, 9.0) defaults (9,)
"""
for i, f in enumerate(funcs):
print "i", i, "func result", f(1.0), "defaults", get_defaults(f)
def test_memoryview_none(const unsigned char[:] b=None):
"""
>>> test_memoryview_none()
>>> test_memoryview_none(None)
>>> test_memoryview_none(b'abc')
97
"""
if b is None:
return None
return b[0]
def test_memoryview_bytes(const unsigned char[:] b=b'xyz'):
"""
>>> test_memoryview_bytes()
120
>>> test_memoryview_bytes(None)
>>> test_memoryview_bytes(b'abc')
97
"""
if b is None:
return None
return b[0]
@cython.test_fail_if_path_exists(
'//NameNode[@entry.in_closure = True]',
'//NameNode[@entry.from_closure = True]')
def test_func_default_inlined():
"""
Make sure we don't accidentally generate a closure.
>>> func = test_func_default_inlined()
>>> func()
1
>>> func(2)
2
"""
def default():
return 1
def func(arg=default()):
return arg
return func
@cython.test_fail_if_path_exists(
'//NameNode[@entry.in_closure = True]',
'//NameNode[@entry.from_closure = True]')
def test_func_default_scope():
"""
Test that the default value expression is evaluated in the outer scope.
>>> func = test_func_default_scope()
3
>>> func()
[0, 1, 2, 3]
>>> func(2)
2
"""
i = -1
def func(arg=[ i for i in range(4) ]):
return arg
print i # list comps leak in Py2 mode => i == 3
return func
def test_func_default_scope_local():
"""
>>> func = test_func_default_scope_local()
-1
>>> func()
[0, 1, 2, 3]
>>> func(2)
2
"""
i = -1
def func(arg=list(i for i in range(4))):
return arg
print i # genexprs don't leak
return func