FAQ
I am able to embed the interactive Python interpreter in my C program
except that when the interpreter exits, my entire program exits.

#include <stdio.h>
#include <Python.h>

int main(int argc, char *argv[]){
printf("line %d\n", __LINE__);
Py_Initialize();
printf("line %d\n", __LINE__);
Py_Main(argc, argv);
printf("line %d\n", __LINE__);
Py_Finalize();
printf("line %d\n", __LINE__);
return 0;
}

When I run the resulting binary I get the following....

$ ./embedded_python
line 5
line 7
Python 2.7.1 (r271:86832, Mar 25 2011, 11:56:07)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
print 'hi'
hi
exit()

I never see line 9 or 11 printed.
I need to embed python in an application that needs to do some cleanup
at the end so I need that code to execute.
What am I doing wrong?

Is there something else I should call besides "exit()" from within the
interpreter?
Is there something other than Py_Main that I should be calling?

Thanks,
~Eric

Search Discussions

  • Eric Frederich at Mar 25, 2011 at 5:37 pm
    So.... I found that if I type ctrl-d then the other lines will print.

    It must be a bug then that the exit() function doesn't do the same thing.
    The documentation says "The return value will be the integer passed to
    the sys.exit() function" but clearly nothing is returned since the
    call to Py_Main exits rather than returning (even when calling
    sys.exit instead of just exit).

    In the mean time is there a way to redefine the exit function in
    Python to do the same behavior as "ctrl-d?"
    I realize that in doing that (if its even possible) still won't
    provide a way to pass a value back from the interpreter via sys.exit.

    Thanks,
    ~Eric



    On Fri, Mar 25, 2011 at 12:02 PM, Eric Frederich
    wrote:
    I am able to embed the interactive Python interpreter in my C program
    except that when the interpreter exits, my entire program exits.

    ? ?#include <stdio.h>
    ? ?#include <Python.h>

    ? ?int main(int argc, char *argv[]){
    ? ? ? ?printf("line %d\n", __LINE__);
    ? ? ? ?Py_Initialize();
    ? ? ? ?printf("line %d\n", __LINE__);
    ? ? ? ?Py_Main(argc, argv);
    ? ? ? ?printf("line %d\n", __LINE__);
    ? ? ? ?Py_Finalize();
    ? ? ? ?printf("line %d\n", __LINE__);
    ? ? ? ?return 0;
    ? ?}

    When I run the resulting binary I get the following....

    $ ./embedded_python
    line 5
    line 7
    Python 2.7.1 (r271:86832, Mar 25 2011, 11:56:07)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    print 'hi'
    hi
    exit()

    I never see line 9 or 11 printed.
    I need to embed python in an application that needs to do some cleanup
    at the end so I need that code to execute.
    What am I doing wrong?

    Is there something else I should call besides "exit()" from within the
    interpreter?
    Is there something other than Py_Main that I should be calling?

    Thanks,
    ~Eric
  • MRAB at Mar 25, 2011 at 5:47 pm

    On 25/03/2011 17:37, Eric Frederich wrote:
    So.... I found that if I type ctrl-d then the other lines will print.

    It must be a bug then that the exit() function doesn't do the same thing.
    The documentation says "The return value will be the integer passed to
    the sys.exit() function" but clearly nothing is returned since the
    call to Py_Main exits rather than returning (even when calling
    sys.exit instead of just exit).

    In the mean time is there a way to redefine the exit function in
    Python to do the same behavior as "ctrl-d?"
    I realize that in doing that (if its even possible) still won't
    provide a way to pass a value back from the interpreter via sys.exit.
    You could flush stdout after each print or turn off buffering on stdout
    with:

    setvbuf(stdout, NULL, _IONBF, 0);
    Thanks,
    ~Eric



    On Fri, Mar 25, 2011 at 12:02 PM, Eric Frederich
    wrote:
    I am able to embed the interactive Python interpreter in my C program
    except that when the interpreter exits, my entire program exits.

    #include<stdio.h>
    #include<Python.h>

    int main(int argc, char *argv[]){
    printf("line %d\n", __LINE__);
    Py_Initialize();
    printf("line %d\n", __LINE__);
    Py_Main(argc, argv);
    printf("line %d\n", __LINE__);
    Py_Finalize();
    printf("line %d\n", __LINE__);
    return 0;
    }

    When I run the resulting binary I get the following....

    $ ./embedded_python
    line 5
    line 7
    Python 2.7.1 (r271:86832, Mar 25 2011, 11:56:07)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    print 'hi'
    hi
    exit()

    I never see line 9 or 11 printed.
    I need to embed python in an application that needs to do some cleanup
    at the end so I need that code to execute.
    What am I doing wrong?

    Is there something else I should call besides "exit()" from within the
    interpreter?
    Is there something other than Py_Main that I should be calling?

    Thanks,
    ~Eric
  • Eric Frederich at Mar 25, 2011 at 6:22 pm
    Added a fflush(stdout) after each printf and, as I expected....still
    only the first 2 prints.

    On Fri, Mar 25, 2011 at 1:47 PM, MRAB wrote:
    On 25/03/2011 17:37, Eric Frederich wrote:

    So.... I found that if I type ctrl-d then the other lines will print.

    It must be a bug then that the exit() function doesn't do the same thing.
    The documentation says "The return value will be the integer passed to
    the sys.exit() function" but clearly nothing is returned since the
    call to Py_Main exits rather than returning (even when calling
    sys.exit instead of just exit).

    In the mean time is there a way to redefine the exit function in
    Python to do the same behavior as "ctrl-d?"
    I realize that in doing that (if its even possible) still won't
    provide a way to pass a value back from the interpreter via sys.exit.
    You could flush stdout after each print or turn off buffering on stdout
    with:

    ? ?setvbuf(stdout, NULL, _IONBF, 0);
    Thanks,
    ~Eric



    On Fri, Mar 25, 2011 at 12:02 PM, Eric Frederich
    <eric.frederich at gmail.com> ?wrote:
    I am able to embed the interactive Python interpreter in my C program
    except that when the interpreter exits, my entire program exits.

    ? ?#include<stdio.h>
    ? ?#include<Python.h>

    ? ?int main(int argc, char *argv[]){
    ? ? ? ?printf("line %d\n", __LINE__);
    ? ? ? ?Py_Initialize();
    ? ? ? ?printf("line %d\n", __LINE__);
    ? ? ? ?Py_Main(argc, argv);
    ? ? ? ?printf("line %d\n", __LINE__);
    ? ? ? ?Py_Finalize();
    ? ? ? ?printf("line %d\n", __LINE__);
    ? ? ? ?return 0;
    ? ?}

    When I run the resulting binary I get the following....

    $ ./embedded_python
    line 5
    line 7
    Python 2.7.1 (r271:86832, Mar 25 2011, 11:56:07)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    print 'hi'
    hi
    exit()

    I never see line 9 or 11 printed.
    I need to embed python in an application that needs to do some cleanup
    at the end so I need that code to execute.
    What am I doing wrong?

    Is there something else I should call besides "exit()" from within the
    interpreter?
    Is there something other than Py_Main that I should be calling?

    Thanks,
    ~Eric
    --
    http://mail.python.org/mailman/listinfo/python-list
  • Mark Hammond at Mar 27, 2011 at 7:10 am

    On 26/03/2011 4:37 AM, Eric Frederich wrote:
    So.... I found that if I type ctrl-d then the other lines will print.
    I think ctrl-d just causes sys.stdin to see EOF, so things just "fall
    out" as you desire. exit() will winf up causing the C exit() function
    after finalizing, hence the behaviour you see.
    In the mean time is there a way to redefine the exit function in
    Python to do the same behavior as "ctrl-d?"
    You can just patch exit in builtins with your own function although I'm
    not sure how you would terminate the builtin REPL - another alternative
    may be to look into the code/console modules where you may be able to
    arrange for more control over the REPL.

    Cheers,

    Mark
  • Eric Frederich at Mar 27, 2011 at 1:33 pm
    This is behavior contradicts the documentation which says the value
    passed to sys.exit will be returned from Py_Main.
    Py_Main doesn't return anything, it just exits.
    This is a bug.
    On Sun, Mar 27, 2011 at 3:10 AM, Mark Hammond wrote:
    On 26/03/2011 4:37 AM, Eric Frederich wrote:
    exit() will winf up causing the C exit() function after
    finalizing, hence the behaviour you see.
  • Jerry Hill at Mar 27, 2011 at 5:55 pm

    On Sun, Mar 27, 2011 at 9:33 AM, Eric Frederich wrote:
    This is behavior contradicts the documentation which says the value
    passed to sys.exit will be returned from Py_Main.
    Py_Main doesn't return anything, it just exits.
    This is a bug.
    Are you sure that calling the builtin exit() function is the same as
    calling sys.exit()?

    You keep talking about the documentation for sys.exit(), but that's
    not the function you're calling. I played around in the interactive
    interpreter a bit, and the two functions do seem to behave a bit
    differently from each other. I can't seem to find any detailed
    documentation for the builtin exit() function though, so I'm not sure
    exactly what the differences are.

    A little more digging reveals that the builtin exit() function is
    getting set up by site.py, and it does more than sys.exit() does.
    Particularly, in 3.1 it tries to close stdin then raises SystemExit().
    Does that maybe explain the behavior you're seeing? I didn't go
    digging in 2.7, which appears to be what you're using, but I think you
    need to explore the differences between sys.exit() and the builtin
    exit() functions.

    --
    Jerry
  • Eric Frederich at Mar 27, 2011 at 6:28 pm
    I'm not talking about the documentation for sys.exit()
    I'm talking about the documentation for Py_Main(int argc, char **argv)

    http://docs.python.org/c-api/veryhigh.html?highlight=py_main#Py_Main

    This C function never returns anything whether in the interpreter I
    type "exit(123)" or "sys.exit(123)".
    I cannot call any of my C cleanup code because of this.
    On Sun, Mar 27, 2011 at 1:55 PM, Jerry Hill wrote:
    On Sun, Mar 27, 2011 at 9:33 AM, Eric Frederich
    wrote:
    This is behavior contradicts the documentation which says the value
    passed to sys.exit will be returned from Py_Main.
    Py_Main doesn't return anything, it just exits.
    This is a bug.
    Are you sure that calling the builtin exit() function is the same as
    calling sys.exit()?

    You keep talking about the documentation for sys.exit(), but that's
    not the function you're calling. ?I played around in the interactive
    interpreter a bit, and the two functions do seem to behave a bit
    differently from each other. ?I can't seem to find any detailed
    documentation for the builtin exit() function though, so I'm not sure
    exactly what the differences are.

    A little more digging reveals that the builtin exit() function is
    getting set up by site.py, and it does more than sys.exit() does.
    Particularly, in 3.1 it tries to close stdin then raises SystemExit().
    ?Does that maybe explain the behavior you're seeing? ?I didn't go
    digging in 2.7, which appears to be what you're using, but I think you
    need to explore the differences between sys.exit() and the builtin
    exit() functions.

    --
    Jerry
    --
    http://mail.python.org/mailman/listinfo/python-list
  • Mark Hammond at Mar 27, 2011 at 10:21 pm

    On 28/03/2011 5:28 AM, Eric Frederich wrote:
    I'm not talking about the documentation for sys.exit()
    I'm talking about the documentation for Py_Main(int argc, char **argv)

    http://docs.python.org/c-api/veryhigh.html?highlight=py_main#Py_Main

    This C function never returns anything whether in the interpreter I
    type "exit(123)" or "sys.exit(123)".
    I cannot call any of my C cleanup code because of this.
    I think there is a bug in that documentation - the paragraph:

    Note that if an otherwise unhandled SystemError is raised, this
    function will not return 1, but exit the process, as long as
    Py_InspectFlag is not set.

    Looks like it should refer to SystemExit, not SystemError. If you check
    out pythonrun.c in handle_system_exit, you will note the behaviour
    described above is exactly what is implemented for SystemExit.

    See also http://bugs.python.org/issue6498

    HTH,

    Mark.
  • Eryksun () at Mar 27, 2011 at 9:59 pm

    On Friday, March 25, 2011 12:02:16 PM UTC-4, Eric Frederich wrote:
    Is there something else I should call besides "exit()" from within the
    interpreter?
    Is there something other than Py_Main that I should be calling?
    Does PyRun_InteractiveLoop also have this problem?
  • Eric Frederich at Mar 28, 2011 at 3:06 am
    I'm not sure that I know how to run this function in such a way that
    it gives me an interactive session.
    I passed in stdin as the first parameter and NULL as the second and
    I'd get seg faults when running exit() or even imnport sys.

    I don't want to pass a file. I want to run some C code, start an
    interactive session, then run some more C code once the session is
    over, but I cannot find a way to start an interactive Python session
    within C that won't exit pre-maturely before I have a chance to run my
    cleanup code in C.
    On Sun, Mar 27, 2011 at 5:59 PM, eryksun () wrote:
    On Friday, March 25, 2011 12:02:16 PM UTC-4, Eric Frederich wrote:

    Is there something else I should call besides "exit()" from within the
    interpreter?
    Is there something other than Py_Main that I should be calling?
    Does PyRun_InteractiveLoop also have this problem?
  • Mark Hammond at Mar 29, 2011 at 12:36 am

    On 28/03/2011 2:06 PM, Eric Frederich wrote:
    I'm not sure that I know how to run this function in such a way that
    it gives me an interactive session.
    I passed in stdin as the first parameter and NULL as the second and
    I'd get seg faults when running exit() or even imnport sys.

    I don't want to pass a file. I want to run some C code, start an
    interactive session, then run some more C code once the session is
    over, but I cannot find a way to start an interactive Python session
    within C that won't exit pre-maturely before I have a chance to run my
    cleanup code in C.
    Instead of calling Py_Main, arrange for the following code to be executed:

    import code
    try:
    code.interact()
    except SystemExit:
    pass
    print "Done!"

    If you save that as a script and run it, you will see that when you call
    quit() or use Ctrl+D, the "Done!" is printed (so the exception is
    caught) and things will return normally (albeit without any return code
    that may have been specified in the SystemExit exception). If you
    arrange to call that code in your app (either by importing it as a
    module of even by calling PyRun_SimpleString) things should work as you
    need.

    HTH,

    Mark
  • Eryksun () at Mar 28, 2011 at 3:47 am

    On Sunday, March 27, 2011 11:06:47 PM UTC-4, Eric Frederich wrote:
    I'm not sure that I know how to run this function in such a way that
    it gives me an interactive session.
    I passed in stdin as the first parameter and NULL as the second and
    I'd get seg faults when running exit() or even imnport sys.
    Passing NULL as the 2nd parameter causes the segfault. Do this instead:

    FILE* fp = stdin;
    char *filename = "Embedded";
    PyRun_InteractiveLoop(fp, filename);

    See here regarding the segfault:

    http://bugs.python.org/issue5121

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedMar 25, '11 at 4:02p
activeMar 29, '11 at 12:36a
posts13
users5
websitepython.org

People

Translate

site design / logo © 2022 Grokbase