[libinline-python-perl] 02/07: New upstream version 0.55
Tony Mancill
tmancill at moszumanska.debian.org
Mon Jul 10 00:53:41 UTC 2017
This is an automated email from the git hooks/post-receive script.
tmancill pushed a commit to branch master
in repository libinline-python-perl.
commit 0c3168325bc232e9b48472156da32e6135e2368d
Author: tony mancill <tmancill at debian.org>
Date: Sun Jul 9 17:36:57 2017 -0700
New upstream version 0.55
---
Changes | 11 ++++++
META.json | 6 +--
META.yml | 4 +-
Python.pm | 7 +++-
perlmodule.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++--
py2pl.c | 7 ++++
t/25py_sub.t | 9 ++++-
t/30floats.t | 11 +++++-
t/31stringification.t | 11 +++++-
t/32boolean.t | 9 ++++-
10 files changed, 166 insertions(+), 14 deletions(-)
diff --git a/Changes b/Changes
index 9f8fca5..bd99202 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,16 @@
Revision history for Perl extension Inline::Python.
+0.55 Tue Jul 03 09:30:00 CEST 2017 (Stefan Seifert)
+ - Pass Python floats as floats to Perl, not as string.
+
+0.54 Tue Jun 13 08:40:00 CEST 2017 (Stefan Seifert)
+ - Fix object stringification crashing on Perl < 5.16 (RT #122082)
+
+0.53 Fri Jun 02 12:10:00 CEST 2017 (Stefan Seifert)
+ - Better support for serializing booleans with JSON
+ - Support calling Perl objects with overloaded code dereferencing
+ - Support overloaded stringification of Perl objects
+
0.52 Thu Dec 01 20:31:00 CET 2016 (Stefan Seifert)
- Fix test failing on lots of machines
by Linas Valiukas
diff --git a/META.json b/META.json
index 7869341..0c0c405 100644
--- a/META.json
+++ b/META.json
@@ -4,7 +4,7 @@
"Neil Watkiss <NEILW at cpan.org>"
],
"dynamic_config" : 1,
- "generated_by" : "ExtUtils::MakeMaker version 7.18, CPAN::Meta::Converter version 2.150005",
+ "generated_by" : "ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 2.150005",
"license" : [
"perl_5"
],
@@ -54,6 +54,6 @@
"web" : "http://github.com/niner/inline-python-pm"
}
},
- "version" : "0.52",
- "x_serialization_backend" : "JSON::PP version 2.27300"
+ "version" : "0.55",
+ "x_serialization_backend" : "JSON::PP version 2.27300_01"
}
diff --git a/META.yml b/META.yml
index e53ff95..d5b40ad 100644
--- a/META.yml
+++ b/META.yml
@@ -11,7 +11,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 7.18, CPAN::Meta::Converter version 2.150005'
+generated_by: 'ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 2.150005'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -27,5 +27,5 @@ requires:
Inline: '0.46'
resources:
repository: http://github.com/niner/inline-python-pm.git
-version: '0.52'
+version: '0.55'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff --git a/Python.pm b/Python.pm
index 3a2c9d7..2013f67 100644
--- a/Python.pm
+++ b/Python.pm
@@ -6,7 +6,7 @@ require DynaLoader;
require Exporter;
our ($VERSION, @ISA, @EXPORT_OK);
@ISA = qw(Inline DynaLoader Exporter);
-$VERSION = '0.52';
+$VERSION = '0.55';
@EXPORT_OK = qw(py_eval
py_new_object
py_call_method
@@ -395,4 +395,9 @@ sub negate {
return $self ? $false : $true;
}
+sub TO_JSON {
+ my ($self) = @_;
+ return $self ? JSON::true() : JSON::false();
+}
+
1;
diff --git a/perlmodule.c b/perlmodule.c
index 909d39b..5400f82 100644
--- a/perlmodule.c
+++ b/perlmodule.c
@@ -33,7 +33,9 @@ staticforward PyObject * PerlPkg_getattr(PerlPkg_object *self, char *name);
PyObject * newPerlObj_object(SV *obj, PyObject *pkg);
staticforward void PerlObj_dealloc(PerlObj_object *self);
-staticforward PyObject * PerlObj_repr(PerlObj_object *self, PyObject *args);
+staticforward PyObject * PerlObj_repr(PerlObj_object *self);
+staticforward PyObject * PerlObj_str(PerlObj_object *self);
+staticforward PyObject * PerlObj_call(PerlObj_object *self, PyObject *args, PyObject *kw);
staticforward PyObject * PerlObj_getattr(PerlObj_object *self, char *name);
staticforward PyObject * PerlObj_mp_subscript(PerlObj_object *self, PyObject *key);
@@ -247,7 +249,7 @@ PerlObj_dealloc(PerlObj_object *self) {
}
static PyObject *
-PerlObj_repr(PerlObj_object *self, PyObject *args) {
+PerlObj_repr(PerlObj_object *self) {
PyObject *s;
char * const str = (char*)malloc((strlen("<perl object: ''>")
+ PyObject_Length(self->pkg)
@@ -264,6 +266,17 @@ PerlObj_repr(PerlObj_object *self, PyObject *args) {
}
static PyObject *
+PerlObj_str(PerlObj_object *self) {
+ STRLEN len;
+ SV* const sv = ((SvTHINKFIRST(self->obj) && !SvIsCOW(self->obj)) || isGV_with_GP(self->obj))
+ ? sv_mortalcopy(self->obj)
+ : self->obj;
+
+ char * const str = SvPVutf8(sv, len);
+ return PyUnicode_DecodeUTF8(str, len, "replace");
+}
+
+static PyObject *
PerlObj_getattr(PerlObj_object *self, char *name) {
PyObject *retval = NULL;
if (strcmp(name,"__methods__") == 0) {
@@ -395,6 +408,90 @@ PerlObj_mp_subscript(PerlObj_object *self, PyObject *key) {
return item;
}
+static PyObject *
+PerlObj_call(PerlObj_object *self, PyObject *args, PyObject *kw) {
+ dSP;
+ int i;
+ int const len = PyObject_Length(args);
+ int count;
+ PyObject *retval;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(SP);
+
+ if (self->obj) XPUSHs(self->obj);
+
+ if (kw) { /* if keyword arguments are present, positional arguments get pushed as into an arrayref */
+ AV * const positional = newAV();
+ for (i=0; i<len; i++) {
+ SV * const arg = Py2Pl(PyTuple_GetItem(args, i));
+ av_push(positional, sv_isobject(arg) ? SvREFCNT_inc(arg) : arg);
+ }
+ XPUSHs((SV *) sv_2mortal((SV *) newRV_inc((SV *) positional)));
+
+ SV * const kw_hash = Py2Pl(kw);
+ XPUSHs(kw_hash);
+ sv_2mortal(kw_hash);
+ sv_2mortal((SV *)positional);
+ }
+ else {
+ for (i=0; i<len; i++) {
+ SV * const arg = Py2Pl(PyTuple_GetItem(args, i));
+ XPUSHs(arg);
+ if (! sv_isobject(arg))
+ sv_2mortal(arg);
+ }
+ }
+
+ PUTBACK;
+
+ /* call the function */
+ /* because the Perl sub *could* be arbitrary Python code,
+ * I probably should temporarily hold a reference here */
+ Py_INCREF(self);
+
+ count = perl_call_sv(self->obj, G_EVAL);
+ SPAGAIN;
+
+ Py_DECREF(self); /* release*/
+
+
+ if (SvTRUE(ERRSV)) {
+ PyObject *exc = Pl2Py(ERRSV);
+ PyErr_SetObject(PyExc_Perl, exc);
+ ERRSV = NULL;
+ return NULL;
+ }
+
+ /* what to return? */
+ if (count == 0) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (count == 1) {
+ retval = Pl2Py(POPs);
+ }
+ else {
+ AV * const lst = newAV();
+ av_extend(lst, count);
+ for (i = count - 1; i >= 0; i--) {
+ av_store(lst, i, SvREFCNT_inc(POPs));
+ }
+ SV * const rv_lst = newRV_inc((SV*)lst);
+ retval = Pl2Py(rv_lst);
+ SvREFCNT_dec(rv_lst);
+ sv_2mortal((SV*)lst); /* this will get killed shortly */
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return retval;
+}
+
#if PY_MAJOR_VERSION >= 3 // Python 3 rich compare
static PyObject*
PerlObj_richcompare(PerlObj_object *o1, PerlObj_object *o2, int op) {
@@ -549,8 +646,8 @@ PyTypeObject PerlObj_type = {
0, /*tp_as_sequence*/
&mp_methods, /*tp_as_mapping*/
(hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)PerlObj_repr, /*tp_str*/
+ (ternaryfunc)PerlObj_call, /*tp_call*/
+ (reprfunc)PerlObj_str, /*tp_str*/
/* Space for future expansion */
0L,0L,0L,0L,
diff --git a/py2pl.c b/py2pl.c
index 7e35327..7930b71 100644
--- a/py2pl.c
+++ b/py2pl.c
@@ -281,6 +281,13 @@ SV *Py2Pl(PyObject * const obj) {
return sv;
}
+ /* a float */
+ else if (PyFloat_Check(obj)) {
+ SV * const sv = newSVnv(PyFloat_AsDouble(obj));
+ Printf(("Py2Pl: float\n"));
+ return sv;
+ }
+
/* a function or method */
else if (PyFunction_Check(obj) || PyMethod_Check(obj)) {
SV * const inst_ptr = newSViv(0);
diff --git a/t/25py_sub.t b/t/25py_sub.t
index 37b5ce8..3b95f0f 100644
--- a/t/25py_sub.t
+++ b/t/25py_sub.t
@@ -1,4 +1,4 @@
-use Test::More tests => 16;
+use Test::More tests => 17;
use Data::Dumper;
use Inline Config => DIRECTORY => './blib_test';
@@ -17,6 +17,9 @@ def call_perl_sub(foo):
sub = getattr(foo, 'testsub')
return sub()
+def call_perl_object(foo):
+ return foo()
+
def get_sub_from_perl(foo):
return foo.testsub
@@ -49,6 +52,8 @@ ok($sub->(), 'Perl sub got passed through successfully');
ok($sub = getattr_sub_from_perl(bless {}, 'Foo'), 'Got a reference to a Perl method via getattr');
ok($sub->(), 'Perl sub got passed through getattr successfully');
+is(call_perl_object(bless {}, 'Foo'), 1, 'Calling Perl object works');
+
ok(pass_through(sub { return 1; }), 'Pass through of perl sub ref works');
ok(call_perl_sub(bless {}, 'Bar'), 'Call inherited Perl method via getattr');
@@ -61,6 +66,8 @@ is($method->(), 'foo', 'Reference to Python method works');
package Foo;
+use overload '&{}' => sub { return \&testsub };
+
sub testsub {
return 1;
}
diff --git a/t/30floats.t b/t/30floats.t
index a6f7bee..b621065 100644
--- a/t/30floats.t
+++ b/t/30floats.t
@@ -2,13 +2,19 @@ use strict;
use warnings;
use Inline Config => DIRECTORY => './blib_test';
-use Test::More tests => 5;
+use Test::More tests => 7;
use POSIX qw(setlocale LC_NUMERIC);
use Inline Python => <<END;
def pyprint(*args):
return str(args)
+def give_float():
+ return 1.2
+
+def is_float(x):
+ return isinstance(x, float)
+
END
like(pyprint(0.1 + 0.1), qr/\(0\.2(0000000000000001)?,\)/);
@@ -24,3 +30,6 @@ like(pyprint(\@a), qr/\(\[0\.1(0000000000000001)?, 0\.2(0000000000000001)?, 0\.(
# test if float conversion works despite localized number format
setlocale LC_NUMERIC, "de_DE.UTF-8";
is(pyprint(0.25), '(0.25,)');
+
+ok(is_float(0.1), "Perl float arrives as float in Python");
+ok(is_float(give_float()), "Python float arrives as float in Perl (and can be passed through)");
diff --git a/t/31stringification.t b/t/31stringification.t
index c53863c..bb62cb2 100644
--- a/t/31stringification.t
+++ b/t/31stringification.t
@@ -2,7 +2,7 @@ use strict;
use warnings;
use Inline Config => DIRECTORY => './blib_test';
-use Test::More tests => 2;
+use Test::More tests => 3;
use Inline Python => <<END;
@@ -16,6 +16,9 @@ class NoString:
def __init__(self, foo):
self.foo = foo
+def stringify(foo):
+ return str(foo)
+
END
my $stringify = Stringify->new('foo');
@@ -23,3 +26,9 @@ my $nostring = NoString->new('foo');
is("$stringify", 'foo');
like("$nostring", qr/NoString/);
+
+is(stringify(bless {}, 'Foo'), 'stringified', 'overloaded stringification of Perl objects works');
+
+package Foo;
+
+use overload '""' => sub { return "stringified" };
diff --git a/t/32boolean.t b/t/32boolean.t
index 03bb679..c967d11 100644
--- a/t/32boolean.t
+++ b/t/32boolean.t
@@ -2,7 +2,7 @@ use strict;
use warnings;
use Inline Config => DIRECTORY => './blib_test';
-use Test::More tests => 14;
+use Test::More tests => 16;
use Inline Python => <<END;
@@ -44,3 +44,10 @@ ok(is_boolean(get_true()), 'True got passed as Boolean through perl space');
ok(is_boolean(get_false()), 'False got passed as Boolean through perl space');
ok(values_are_boolean(get_hash_with_bools()), 'True and False work as dict values');
+
+SKIP: {
+ skip 'JSON module required for JSON interop tests', 2
+ unless eval { require JSON; };
+ is JSON::to_json([get_true()], {convert_blessed => 1}), '[true]';
+ is JSON::to_json([get_false()], {convert_blessed => 1}), '[false]';
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libinline-python-perl.git
More information about the Pkg-perl-cvs-commits
mailing list