Discussion:
Inline::Python Python child process stdout redirection
Chris Nighswonger
2013-03-19 01:10:24 UTC
Permalink
Hi all,

I'm using Inline::Python to call a Python function which writes to stdout.
I'm guessing that Inline::Python forks at some point to run Python. Is
there a way to redirect the stdout of the resulting child process? I'm
(again) guessing that there is no way of knowing the process id in time to
do anything with it.

Kind Regards,
Chris
Stefan Seifert
2013-03-19 07:15:33 UTC
Permalink
Post by Chris Nighswonger
I'm using Inline::Python to call a Python function which writes to stdout.
I'm guessing that Inline::Python forks at some point to run Python.
No, Inline::Python uses an embedded Python interpreter to run Python code.
Post by Chris Nighswonger
Is
there a way to redirect the stdout of the resulting child process?
It's the same stdout, you use in Perl. You can redirect it just in the same
way:

use Inline Python => <<PYTHON;
def test():
print "hello"
PYTHON
open STDOUT, ">/tmp/stdout";
test();

Regards,
Stefan
Chris Nighswonger
2013-03-19 14:51:08 UTC
Permalink
On Monday 18 March 2013 21:10:24 Chris Nighswonger wrote:> Is
Post by Chris Nighswonger
there a way to redirect the stdout of the resulting child process?
It's the same stdout, you use in Perl.
I'm sorry: I should have worded my question directly. Here is what I need
to do:

open STDOUT, ">", \$var

So long as I have STDOUT write to a file, things work fine. when attempting
to write to a variable, Perl borks.

Kind Regards,
Chris
David Mertens
2013-03-19 18:28:37 UTC
Permalink
I can say that it is *not* possible to generically capture stdout from
Inline::C (a la printf), as far as I know. I would not expect to be able to
do it with Python, since that's a C library as far as Perl is concerned. If
you can redirect the output to a file handle, that's not too big a
surprise, but already better than I would have expected.

David
Post by Chris Nighswonger
On Monday 18 March 2013 21:10:24 Chris Nighswonger wrote:> Is
Post by Chris Nighswonger
there a way to redirect the stdout of the resulting child process?
It's the same stdout, you use in Perl.
I'm sorry: I should have worded my question directly. Here is what I need
open STDOUT, ">", \$var
So long as I have STDOUT write to a file, things work fine. when attempting
to write to a variable, Perl borks.
Kind Regards,
Chris
Stefan Seifert
2013-03-19 18:58:47 UTC
Permalink
Post by Chris Nighswonger
I'm sorry: I should have worded my question directly. Here is what I need
open STDOUT, ">", \$var
So long as I have STDOUT write to a file, things work fine. when attempting
to write to a variable, Perl borks.
Ok, that would not work, since this is just some Perl trickery and nothing
really gets written to any file handle.
But you can use just the same trick in Python:

use Inline Python => <<'PYTHON';

import sys
from cStringIO import StringIO

sys.stdout = capturer = StringIO()

def print_stuff():
print "hello world"

def get_printed():
return capturer.getvalue()

PYTHON

print_stuff();
print 'Perl got: ', get_printed();

Regards,
Stefan
Chris Nighswonger
2013-03-20 16:29:09 UTC
Permalink
Post by Stefan Seifert
Ok, that would not work, since this is just some Perl trickery and nothing
really gets written to any file handle.
This is probably a question for another list, so feel free to say so.

The example supplied worked exactly. However, when implement the same
technique using the Python library I need I get such as this:

exceptions.AttributeError: 'cStringIO.StringO' object has no attribute
'encoding' at line blah.

Some reading around seems to indicate that this may happen if stdout is
being messed with elsewhere. So I took a look through the code of the
library I'm using and could not find any other stdout redirection occurring.

Any thoughts on what else to look at?

Kind Regards,
Chris
Chris Nighswonger
2013-03-20 19:12:04 UTC
Permalink
On Wed, Mar 20, 2013 at 12:29 PM, Chris Nighswonger <
Post by Chris Nighswonger
Post by Stefan Seifert
Ok, that would not work, since this is just some Perl trickery and nothing
really gets written to any file handle.
This is probably a question for another list, so feel free to say so.
The example supplied worked exactly. However, when implement the same
exceptions.AttributeError: 'cStringIO.StringO' object has no attribute
'encoding' at line blah.
I finally located the problem which I'll post just for completeness.

Some code in the Python lib was checking the 'encoding' attribute of the
stdout object. Per the Python manual, cStringIO objects have no settable
attributes:

"Since this is a factory function which returns objects of built-in types,
there’s no way to build your own version using subclassing. It’s not
possible to set attributes on it. Use the original StringIO module in those
cases."[1]

Using the StringIO module allowed me to set the 'encoding' attribute which
fixed things.

Thanks again for the kind assistance.

Chris


[1] http://docs.python.org/2/library/stringio.html#module-cStringIO
Loading...