# mode: run # tag: cyfunction,call,python # cython: binding=True ####### # Test that Cython and Python functions can call each other in various signature combinations. ####### py_call_noargs = eval("lambda: 'noargs'") py_call_onearg = eval("lambda arg: arg") py_call_twoargs = eval("lambda arg, arg2: (arg, arg2)") py_call_starargs = eval("lambda *args: args") py_call_pos_and_starargs = eval("lambda arg, *args: (arg, args)") py_call_starstarargs = eval("lambda **kw: sorted(kw.items())") py_call_args_and_starstarargs = eval("lambda *args, **kw: (args, sorted(kw.items()))") def cy_call_noargs(): """ >>> cy_call_noargs() 'noargs' """ return py_call_noargs() def cy_call_onearg(f): """ >>> cy_call_onearg(py_call_onearg) 'onearg' >>> try: cy_call_onearg(py_call_noargs) ... except TypeError: pass ... else: print("FAILED!") >>> try: cy_call_onearg(py_call_twoargs) ... except TypeError: pass ... else: print("FAILED!") >>> class Class(object): ... def method(self, arg): return arg >>> cy_call_onearg(Class().method) 'onearg' """ return f('onearg') def cy_call_twoargs(f, arg): """ >>> cy_call_twoargs(py_call_twoargs, 132) (132, 'twoargs') >>> class Class2(object): ... def method(self, arg, arg2): return arg, arg2 >>> cy_call_twoargs(Class2().method, 123) (123, 'twoargs') >>> class Class1(object): ... def method(self, arg): return arg >>> cy_call_twoargs(Class1.method, Class1()) 'twoargs' """ return f(arg, 'twoargs') def cy_call_two_kwargs(f, arg): """ >>> cy_call_two_kwargs(py_call_twoargs, arg=132) (132, 'two-kwargs') >>> cy_call_two_kwargs(f=py_call_twoargs, arg=132) (132, 'two-kwargs') >>> cy_call_two_kwargs(arg=132, f=py_call_twoargs) (132, 'two-kwargs') >>> class Class(object): ... def method(self, arg, arg2): return arg, arg2 >>> cy_call_two_kwargs(Class().method, 123) (123, 'two-kwargs') """ return f(arg2='two-kwargs', arg=arg) def cy_call_starargs(*args): """ >>> cy_call_starargs() () >>> cy_call_starargs(1) (1,) >>> cy_call_starargs(1, 2) (1, 2) >>> cy_call_starargs(1, 2, 3) (1, 2, 3) """ return py_call_starargs(*args) def cy_call_pos_and_starargs(f, *args): """ >>> cy_call_pos_and_starargs(py_call_onearg) 'no-arg' >>> cy_call_pos_and_starargs(py_call_onearg, 123) 123 >>> cy_call_pos_and_starargs(py_call_twoargs, 123, 321) (123, 321) >>> cy_call_pos_and_starargs(py_call_starargs) ('no-arg',) >>> cy_call_pos_and_starargs(py_call_starargs, 123) (123,) >>> cy_call_pos_and_starargs(py_call_starargs, 123, 321) (123, 321) >>> cy_call_pos_and_starargs(py_call_pos_and_starargs) ('no-arg', ()) >>> cy_call_pos_and_starargs(py_call_pos_and_starargs, 123) (123, ()) >>> cy_call_pos_and_starargs(py_call_pos_and_starargs, 123, 321) (123, (321,)) >>> cy_call_pos_and_starargs(py_call_pos_and_starargs, 123, 321, 234) (123, (321, 234)) >>> class Class(object): ... def method(self, arg, arg2): return arg, arg2 >>> cy_call_pos_and_starargs(Class().method, 123, 321) (123, 321) >>> cy_call_pos_and_starargs(Class.method, Class(), 123, 321) (123, 321) """ return f(args[0] if args else 'no-arg', *args[1:]) def cy_call_starstarargs(**kw): """ >>> kw = {} >>> cy_call_starstarargs(**kw) [] >>> kw = {'a': 123} >>> cy_call_starstarargs(**kw) [('a', 123)] >>> kw = {'a': 123, 'b': 321} >>> cy_call_starstarargs(**kw) [('a', 123), ('b', 321)] """ return py_call_starstarargs(**kw) def cy_call_kw_and_starstarargs(f=None, arg1=None, **kw): """ >>> kw = {} >>> cy_call_kw_and_starstarargs(**kw) [('arg', None)] >>> try: cy_call_kw_and_starstarargs(py_call_noargs, **kw) ... except TypeError: pass >>> try: cy_call_kw_and_starstarargs(py_call_twoargs, **kw) ... except TypeError: pass ... else: print("FAILED!") >>> cy_call_kw_and_starstarargs(py_call_onearg, **kw) >>> cy_call_kw_and_starstarargs(f=py_call_onearg, **kw) >>> cy_call_kw_and_starstarargs(py_call_pos_and_starargs, **kw) (None, ()) >>> kw = {'arg1': 123} >>> cy_call_kw_and_starstarargs(**kw) [('arg', 123)] >>> cy_call_kw_and_starstarargs(py_call_onearg, **kw) 123 >>> cy_call_kw_and_starstarargs(f=py_call_onearg, **kw) 123 >>> cy_call_kw_and_starstarargs(py_call_twoargs, arg2=321, **kw) (123, 321) >>> cy_call_kw_and_starstarargs(f=py_call_twoargs, arg2=321, **kw) (123, 321) >>> try: cy_call_kw_and_starstarargs(py_call_twoargs, **kw) ... except TypeError: pass ... else: print("FAILED!") >>> try: cy_call_kw_and_starstarargs(py_call_twoargs, arg2=321, other=234, **kw) ... except TypeError: pass ... else: print("FAILED!") >>> cy_call_kw_and_starstarargs(py_call_pos_and_starargs, **kw) (123, ()) >>> try: cy_call_kw_and_starstarargs(arg=321, **kw) # duplicate kw in Python call ... except TypeError: pass ... else: print("FAILED!") >>> kw = {'a': 123} >>> cy_call_kw_and_starstarargs(**kw) [('a', 123), ('arg', None)] >>> cy_call_kw_and_starstarargs(arg1=321, **kw) [('a', 123), ('arg', 321)] >>> kw = {'a': 123, 'b': 321} >>> cy_call_kw_and_starstarargs(**kw) [('a', 123), ('arg', None), ('b', 321)] >>> cy_call_kw_and_starstarargs(arg1=234, **kw) [('a', 123), ('arg', 234), ('b', 321)] >>> class Class2(object): ... def method(self, arg, arg2): return arg, arg2 >>> cy_call_kw_and_starstarargs(Class2().method, arg1=123, arg2=321) (123, 321) """ return (f or py_call_starstarargs)(arg=arg1, **kw) def cy_call_pos_and_starstarargs(f=None, arg1=None, **kw): """ >>> cy_call_pos_and_starstarargs(arg=123) ((None,), [('arg', 123)]) >>> cy_call_pos_and_starstarargs(arg1=123) ((123,), []) >>> cy_call_pos_and_starstarargs(arg=123, arg2=321) ((None,), [('arg', 123), ('arg2', 321)]) >>> cy_call_pos_and_starstarargs(arg1=123, arg2=321) ((123,), [('arg2', 321)]) >>> class Class2(object): ... def method(self, arg, arg2=None): return arg, arg2 >>> cy_call_pos_and_starstarargs(Class2().method, 123) (123, None) >>> cy_call_pos_and_starstarargs(Class2().method, 123, arg2=321) (123, 321) >>> cy_call_pos_and_starstarargs(Class2().method, arg1=123, arg2=321) (123, 321) >>> cy_call_pos_and_starstarargs(Class2.method, Class2(), arg=123) (123, None) >>> cy_call_pos_and_starstarargs(Class2.method, Class2(), arg=123, arg2=321) (123, 321) >>> cy_call_pos_and_starstarargs(Class2.method, arg1=Class2(), arg=123, arg2=321) (123, 321) """ return (f or py_call_args_and_starstarargs)(arg1, **kw)