Properly clean up Python when exiting due to --python-exit-code
authorSybren A. Stüvel <sybren@stuvel.eu>
Tue, 8 Jan 2019 11:00:18 +0000 (12:00 +0100)
committerSybren A. Stüvel <sybren@stuvel.eu>
Tue, 8 Jan 2019 11:00:18 +0000 (12:00 +0100)
When BPY_python_end() is not called, there can be buffered data still in
`sys.stdout` or `sys.stderr`. This generally isn't an issue when those are
connected to a terminal, but when they are read by another process (in the case
of rendering with Flamenco, for example) we could miss the actual error message
that's causing the exit in the first place.

The following script demonstrates the issue; before this commit neither the
writes to STDERR and STDOUT nor the traceback of the NameError were shown.

    #!/bin/bash

    cat > file-with-errors.py <<EOT
    import sys
    print('THIS IS STDERR', file=sys.stderr)
    print('THIS IS STDOUT', file=sys.stdout)
    nonexisting.monkey = 3
    EOT

    blender --enable-autoexec -noaudio --background \
any-existing-blendfile.blend \
--python-exit-code 42 \
--python file-with-errors.py 2>&1 | cat

Reviewers: campbellbarton, mont29

Reviewed By: campbellbarton, mont29

Subscribers: fsiddi

Differential Revision: https://developer.blender.org/D4168

source/creator/creator_args.c

index 5b976515dd8fe16231e3460ff94427b9eb658ca5..fe67eff3c40deb84230da08a7b29108904ef5713 100644 (file)
@@ -1615,6 +1615,7 @@ static int arg_handle_python_file_run(int argc, const char **argv, void *data)
                BPY_CTX_SETUP(ok = BPY_execute_filepath(C, filename, NULL));
                if (!ok && app_state.exit_code_on_error.python) {
                        printf("\nError: script failed, file: '%s', exiting.\n", argv[1]);
+                       BPY_python_end();
                        exit(app_state.exit_code_on_error.python);
                }
                return 1;
@@ -1656,6 +1657,7 @@ static int arg_handle_python_text_run(int argc, const char **argv, void *data)
 
                if (!ok && app_state.exit_code_on_error.python) {
                        printf("\nError: script failed, text: '%s', exiting.\n", argv[1]);
+                       BPY_python_end();
                        exit(app_state.exit_code_on_error.python);
                }
 
@@ -1687,6 +1689,7 @@ static int arg_handle_python_expr_run(int argc, const char **argv, void *data)
                BPY_CTX_SETUP(ok = BPY_execute_string_ex(C, NULL, argv[1], false));
                if (!ok && app_state.exit_code_on_error.python) {
                        printf("\nError: script failed, expr: '%s', exiting.\n", argv[1]);
+                       BPY_python_end();
                        exit(app_state.exit_code_on_error.python);
                }
                return 1;