Skip Menu |

This queue is for tickets about the Inline-Python CPAN distribution.

Report information
The Basics
Id: 47167
Status: resolved
Priority: 0/
Queue: Inline-Python

People
Owner: Nobody in particular
Requestors: jspong [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.28
Fixed in: (no value)



Subject: Py2Pl returns string for function or method reference
When obj is a pointer to a method or function, Py2Pl returns its string representation, rather than the wrapped method/function. On line 48 of py2pl.c, it does a diagnostic check to see if obj is a method, but that is the only occurrence of the words "method" or "function" in the entire file. There should be blocks for "if (PyMethod_Check(obj))" and "if (PyFunction_Check(obj))" that return a PyMethod or PyFunction object respectively.
Seems like that's just not implemented yet. I'll try to give it a look the coming week.
On Fri Jun 19 18:42:28 2009, https://www.google.com/accounts/o8/id?id=AItOawlexYTVVJ0Oz98YNS01DA5avM0engOM7NU wrote: Show quoted text
> When obj is a pointer to a method or function, Py2Pl returns its string > representation, rather than the wrapped method/function. > > On line 48 of py2pl.c, it does a diagnostic check to see if obj is a > method, but that is the only occurrence of the words "method" or > "function" in the entire file. > > There should be blocks for "if (PyMethod_Check(obj))" and "if > (PyFunction_Check(obj))" that return a PyMethod or PyFunction object > respectively.
The freshly uploaded Inline::Python 0.29 does a PyFunction_Check and supports exporting lambda expressions and function references from Python to Perl space as Inline::Python::Function objects which are callable. Does this work for you, so I can close this bug?
From: John Spong
On Tue Jul 07 15:42:47 2009, NINE wrote: Show quoted text
> On Fri Jun 19 18:42:28 2009, >
https://www.google.com/accounts/o8/id?id=AItOawlexYTVVJ0Oz98YNS01DA5avM0engOM7NU Show quoted text
> wrote:
> > When obj is a pointer to a method or function, Py2Pl returns its
> string
> > representation, rather than the wrapped method/function. > > > > On line 48 of py2pl.c, it does a diagnostic check to see if obj is a > > method, but that is the only occurrence of the words "method" or > > "function" in the entire file. > > > > There should be blocks for "if (PyMethod_Check(obj))" and "if > > (PyFunction_Check(obj))" that return a PyMethod or PyFunction object > > respectively.
> > The freshly uploaded Inline::Python 0.29 does a PyFunction_Check and > supports exporting lambda expressions and function references from > Python > to Perl space as Inline::Python::Function objects which are callable. > > Does this work for you, so I can close this bug?
First of all, thanks a lot for the quick turnaround on this. This package is great, and this additional implementation will make it even better! Unfortunately, however, I believe (but have yet to verify) that this will only half-fix the problem. I don't know if perl represents subroutines that are bound to objects differently in the background, but python definitely does. It will probably also require a PyMethod_Check call since python doesn't consider a method to be the same as a function. A python method is an object that contains a class, a function and an instance: Show quoted text
>>> import inspect >>> class MyClass(object):
... def Method(self): ... pass ... Show quoted text
>>> def Function():
... pass ... Show quoted text
>>> inspect.ismethod(MyClass.Method)
True Show quoted text
>>> inspect.isfunction(MyClass.Method)
False Show quoted text
>>> inspect.ismethod(Function)
False Show quoted text
>>> inspect.isfunction(Function)
True Show quoted text
>>> dir(MyClass.Method)
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'im_class', 'im_func', 'im_self'] Show quoted text
>>> MyClass.Method.im_self >>> MyClass.Method.im_class
<class '__main__.MyClass'> Show quoted text
>>> instance = MyClass() >>> instance.Method.im_self
<__main__.MyClass object at 0xb7ef1fac>
From: John Spong
Sorry to take so long to verify this behavior. Perl Script: -------------------------------------------------- use strict; use warnings; use Inline::Python; use Data::Dumper; Inline::Python::py_eval(<<'END'); import inspect def function(arg1, arg2, *args, **kwargs): pass class Test(object): def __init__(self): self.function = function pass def method(self, arg1, arg2, *args, **kwargs): pass END my $test = Inline::Python::py_new_object("JSpong::Python::Test", "__main__", "Test"); my $py_method = Inline::Python::py_call_method($test, '__getattribute__', 'method'); print $py_method, "\n"; eval { my $sig = Inline::Python::py_call_function("inspect", "getargspec", $py_method); my $href = { sig => $sig }; print Dumper($href); print "\n"; }; if ($@) { print "Python error: $@\n"; } my $py_function = Inline::Python::py_call_method($test, '__getattribute__', 'function'); print $py_function, "\n"; eval { my $sig = Inline::Python::py_call_function("inspect", "getargspec", $py_function); my $href = { sig => $sig }; print Dumper($href); print "\n"; }; if ($@) { print "Python error: $@\n"; } -------------------------------------------------- Perl Output: -------------------------------------------------- <bound method Test.method of <__main__.Test object at 0xb7cc54ac>> Error: Python error occurred: Traceback (most recent call last): File "/u/qa/tools/python/lib/python2.4/inspect.py", line 677, in getargspec raise TypeError('arg is not a Python function') TypeError: arg is not a Python function Python error: Error -- PyObject_CallObject(...) failed. Inline::Python::Function=SCALAR(0x9bd8214) $VAR1 = { 'sig' => [ [ 'arg1', 'arg2' ], 'args', 'kwargs', undef ] }; -------------------------------------------------- As you can see, the function is working correctly passed in either direction, but the method is still being returned as its string representation.
Sorry for not writing earlier. I finally fixed this a couply of months ago in version 0.37. Output of your test script is now: Inline::Python::Function=SCALAR(0x993a88) $VAR1 = { 'sig' => bless( do{\(my $o = '140675249052464')}, 'Inline::Python::Object' ) }; Inline::Python::Function=SCALAR(0x8cfb60) $VAR1 = { 'sig' => bless( do{\(my $o = '140675249052464')}, 'Inline::Python::Object' ) }; Btw. the just uploaded 0.38 fixes two bugs and lots of memory leaks. Getting darn stable now :)