Skip to content

Commit

Permalink
Implement calling Python functions with named arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
niner committed Jan 3, 2017
1 parent 0660c00 commit e45adf8
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
22 changes: 20 additions & 2 deletions lib/Inline/Python.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ sub py_dict_set_item(OpaquePointer, OpaquePointer, OpaquePointer)
sub py_call_function(Str, Str, OpaquePointer)
returns OpaquePointer { ... }
native(&py_call_function);
sub py_call_function_kw(Str, Str, Pointer, Pointer)
returns OpaquePointer { ... }
native(&py_call_function_kw);
sub py_call_static_method(Str, Str, Str, OpaquePointer)
returns OpaquePointer { ... }
native(&py_call_static_method);
Expand Down Expand Up @@ -312,6 +315,19 @@ method !setup_arguments(@args) {
return $tuple;
}

method !setup_arguments_kw(@args, %args) {
my $len = @args.elems;
my $tuple = py_tuple_new($len);
loop (my int32 $i = 0; $i < $len; $i = $i + 1) {
py_tuple_set_item($tuple, $i, self.p6_to_py(@args[$i]));
}
my $dict = py_dict_new();
for %args -> $item {
py_dict_set_item($dict, self.p6_to_py($item.key), self.p6_to_py($item.value));
}
return $tuple, $dict;
}

method handle_python_exception() is hidden-from-backtrace {
my @exception := CArray[OpaquePointer].new();
@exception[$_] = OpaquePointer for ^4;
Expand All @@ -337,8 +353,10 @@ multi method run($python, :$file) {
self.py_to_p6($res);
}

method call(Str $package, Str $function, *@args) {
my $py_retval = py_call_function($package, $function, self!setup_arguments(@args));
method call(Str $package, Str $function, *@args, *%args) {
my $py_retval = %args
?? py_call_function_kw($package, $function, |self!setup_arguments_kw(@args, %args))
!! py_call_function($package, $function, self!setup_arguments(@args));
self.handle_python_exception();
my \retval = self.py_to_p6($py_retval);
return retval;
Expand Down
21 changes: 21 additions & 0 deletions pyhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,27 @@ PyObject *py_call_function(char *pkg, char *name, PyObject *args) {
return py_retval;
}

PyObject *py_call_function_kw(char *pkg, char *name, PyObject *args, PyObject *kw) {
PyObject * const mod = PyImport_AddModule(pkg);
PyObject * const dict = PyModule_GetDict(mod);
PyObject * const func = PyMapping_GetItemString(dict, name);
PyObject *py_retval = NULL;

if (func == NULL) {
PyErr_Format(PyExc_NameError, "name '%s' is not defined", name);
goto cleanup;
}

py_retval = PyObject_Call(func, args, kw);

Py_DECREF(func);
cleanup:
Py_DECREF(args);
Py_DECREF(kw);

return py_retval;
}

void py_fetch_error(PyObject **exception) {
/* ex_type, ex_value, ex_trace, ex_message */
PyErr_Fetch(&exception[0], &exception[1], &exception[2]);
Expand Down
12 changes: 7 additions & 5 deletions t/call.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use v6;
use Inline::Python;

say "1..12";
say "1..13";

my $py = Inline::Python.new();
$py.run('
Expand All @@ -19,11 +19,11 @@ def test_int_params(a, b):
print "not ok 2 - int params";
return;
def test_str_params(a, b):
def test_str_params(a, b, i):
if a == "Hello" and b == "Python":
print "ok 3 - str params";
print "ok %i - str params" % i;
else:
print "not ok 3 - str params";
print "not ok %i - str params" % i;
return;
def test_int_retval():
Expand Down Expand Up @@ -72,7 +72,7 @@ class Foo:

$py.call('__main__', 'test');
$py.call('__main__', 'test_int_params', 2, 1);
$py.call('__main__', 'test_str_params', 'Hello', 'Python');
$py.call('__main__', 'test_str_params', 'Hello', 'Python', 3);

$py.run('
import sys
Expand Down Expand Up @@ -145,4 +145,6 @@ else {
say "not ok 12 - Passing Python objects back from Perl 6";
}

$py.call('__main__', 'test_str_params', :i(13), :a<Hello>, :b<Python>);

# vim: ft=perl6

0 comments on commit e45adf8

Please sign in to comment.