Last active
October 2, 2022 19:56
-
-
Save zmughal/56525c7ad0ca5ba47293c020fc6aec2c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# PODNAME: inline-python-named-args | |
# ABSTRACT: Example of passing named args to Python via Inline::Python | |
use strict; | |
use warnings; | |
use 5.16.3; | |
use Test2::V0; | |
use Inline Python => <<'END_OF_PYTHON_CODE'; | |
def py_call_wrapper(callable, args, kwargs): | |
return callable(*args, **kwargs) | |
# Interface | |
def get_sbom_of_package ( | |
package_name = None, | |
target_path = None, | |
): | |
assert package_name is not None | |
assert target_path is not None | |
print ( package_name, target_path ) | |
return package_name | |
def pos_and_named ( | |
first_arg, | |
n1 = None, | |
n2 = None, | |
): | |
assert first_arg is not None | |
assert n1 is not None | |
assert n2 is not None | |
return first_arg + n1 + n2 | |
def pos_then_named ( | |
first_arg, | |
second_arg, | |
*, | |
n1 = None, | |
n2 = None, | |
): | |
assert first_arg is not None | |
assert second_arg is not None | |
assert n1 is not None | |
assert n2 is not None | |
return first_arg + second_arg + n1 + n2 | |
def no_pos_just_named ( | |
*, | |
n1 = None, | |
n2 = None, | |
): | |
assert n1 is not None | |
assert n2 is not None | |
return "n1 = {} and n2 = {}".format(n1, n2) | |
END_OF_PYTHON_CODE | |
my $package = 'thePackage'; | |
my $target_path = $ENV{HOME}; | |
use List::Util qw(pairmap unpairs); | |
use List::SomeUtils qw(part); | |
sub kw_pairs { | |
@_ % 2 == 0 or die "Named arguments need pairs of name and value"; | |
my @kw_pairs = pairmap { bless [$a, $b], 'PyKwArgs' } @_; | |
} | |
# idea taken from PerlX::ArraySkip | |
sub kw :prototype(@) { ( kw_pairs(@_[0,1]), @_[2..$#_] ) } | |
sub python_call_with_named_args { | |
my ($callable, @args) = @_; | |
my ($pos, $named) = part { $_->isa('PyKwArgs') } @args; | |
my %named_unpacked = unpairs @$named; | |
py_call_wrapper( | |
Inline::Python::py_eval($callable, 0), | |
($pos // []), | |
\%named_unpacked, | |
); | |
} | |
is python_call_with_named_args( | |
get_sbom_of_package => | |
kw package_name => $package, | |
kw target_path => $target_path | |
), $package, 'just kwargs'; | |
is python_call_with_named_args( | |
pos_and_named => | |
'Does ', | |
kw n2 => 'work?', | |
kw n1 => 'it ', | |
), 'Does it work?', 'positional args and kwargs'; | |
is python_call_with_named_args( | |
pos_and_named => | |
'Does ', | |
'it really ', | |
'work?' | |
), 'Does it really work?', 'just positional args'; | |
is python_call_with_named_args( | |
pos_then_named => | |
'Yes, ', | |
'it ', | |
kw n1 => 'does ', | |
kw n2 => 'work', | |
), 'Yes, it does work', 'kwargs must be passed as kwargs, not positional'; | |
is python_call_with_named_args( | |
no_pos_just_named => | |
kw n1 => 'hello', | |
kw n2 => 'world', | |
), 'n1 = hello and n2 = world', 'no positionals allowed, just named'; | |
done_testing; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment