Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do Inline::Python functions that print fail to be redirected?

Here is the simplest reproducible for my problem:

#!/usr/bin/env perl
use 5.16.3;
say "Got back ", test_print();
use Inline Python => <<'END_OF_PYTHON_CODE';
def test_print() -> int:
    print("In the python test print")
    return 32
END_OF_PYTHON_CODE

When run simply:

$ perl small.pl
In the python test print
Got back 32

But when redirected:

$ perl small.pl | tee foo
Got back 32
$ cat foo
Got back 32

What could I be doing wrong such that Inline::Pythoncode fails to print to a redirected output?

like image 783
mpersico Avatar asked Aug 04 '21 18:08

mpersico


2 Answers

Py_Finalize() isn't called to properly destruct the Python interpreter.

Thankfully, the module exposes this function as py_finalize, allowing us to call it ourselves. Add the following to your program:

END { Inline::Python::py_finalize(); }

Demo:

use feature qw( say );

use Inline Python => <<'END_OF_PYTHON_CODE';

def test_print() -> int:
    print("In the python test print")
    return 32

END_OF_PYTHON_CODE

END { Inline::Python::py_finalize() if $ARGV[0]; }

say "Got back ", test_print();
$ perl a.pl 0
In the python test print
Got back 32

$ perl a.pl 0 | cat
Got back 32

$ perl a.pl 1
In the python test print
Got back 32

$ perl a.pl 1 | cat
In the python test print
Got back 32
like image 167
ikegami Avatar answered Nov 15 '22 11:11

ikegami


The complete thing to do is:

BEGIN {
    # Unbuffer Python's output
    $ENV{PYTHONUNBUFFERED}=1;

    # Unbuffer Perl's output
    select((select(STDOUT), $|=1)[0]);
    select((select(STDERR), $|=1)[0]);
}
...
END { 
    # Shut down the Python interpreter.
    Inline::Python::py_finalize();
}

You must also unbuffer Perl's output. Thanks to ikegami who commented to that effect in a now-deleted post, and reminded me about py_finalize().

like image 39
mpersico Avatar answered Nov 15 '22 13:11

mpersico