Skip to content

Commit cb3450c

Browse files
committed
Flush stderr even if site import fails
1 parent 461a434 commit cb3450c

File tree

2 files changed

+55
-29
lines changed

2 files changed

+55
-29
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
import static com.oracle.graal.python.builtins.PythonOS.PLATFORM_WIN32;
5555
import static com.oracle.graal.python.builtins.PythonOS.getPythonOS;
5656
import static com.oracle.graal.python.builtins.modules.io.IONodes.T_BUFFER;
57-
import static com.oracle.graal.python.builtins.modules.io.IONodes.T_CLOSE;
5857
import static com.oracle.graal.python.builtins.modules.io.IONodes.T_ENCODING;
5958
import static com.oracle.graal.python.builtins.modules.io.IONodes.T_MODE;
6059
import static com.oracle.graal.python.builtins.modules.io.IONodes.T_R;
@@ -790,18 +789,12 @@ public void initStd(Python3Core core) {
790789
PBuffered writer = factory.createBufferedWriter(PythonBuiltinClassType.PBufferedWriter);
791790
BufferedWriterBuiltins.BufferedWriterInit.internalInit(writer, (PFileIO) getBuiltinConstant(T_STDOUT), BufferedReaderBuiltins.DEFAULT_BUFFER_SIZE, factory, posixSupport,
792791
posixLib);
793-
PTextIO stdout = setWrapper(T_STDOUT, T___STDOUT__, T_W, stdioEncoding, stdioError, writer, sysModule, factory);
792+
setWrapper(T_STDOUT, T___STDOUT__, T_W, stdioEncoding, stdioError, writer, sysModule, factory);
794793

795794
writer = factory.createBufferedWriter(PythonBuiltinClassType.PBufferedWriter);
796795
BufferedWriterBuiltins.BufferedWriterInit.internalInit(writer, (PFileIO) getBuiltinConstant(T_STDERR), BufferedReaderBuiltins.DEFAULT_BUFFER_SIZE, factory, posixSupport,
797796
posixLib);
798-
PTextIO stderr = setWrapper(T_STDERR, T___STDERR__, T_W, stdioEncoding, T_BACKSLASHREPLACE, writer, sysModule, factory);
799-
800-
// register atexit close std out/err
801-
core.getContext().registerAtexitHook((ctx) -> {
802-
callClose(stdout);
803-
callClose(stderr);
804-
});
797+
setWrapper(T_STDERR, T___STDERR__, T_W, stdioEncoding, T_BACKSLASHREPLACE, writer, sysModule, factory);
805798
}
806799

807800
private static PTextIO setWrapper(TruffleString name, TruffleString specialName, TruffleString mode, TruffleString encoding, TruffleString error, PBuffered buffered, PythonModule sysModule,
@@ -820,13 +813,6 @@ private static void setAttribute(PythonObject obj, TruffleString key, Object val
820813
obj.setAttribute(key, value);
821814
}
822815

823-
private static void callClose(Object obj) {
824-
try {
825-
PyObjectCallMethodObjArgs.executeUncached(obj, T_CLOSE);
826-
} catch (PException e) {
827-
}
828-
}
829-
830816
public PDict getModules() {
831817
return (PDict) getBuiltinConstant(T_MODULES);
832818
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@
3030
import static com.oracle.graal.python.builtins.PythonOS.getPythonOS;
3131
import static com.oracle.graal.python.builtins.modules.SysModuleBuiltins.T_CACHE_TAG;
3232
import static com.oracle.graal.python.builtins.modules.SysModuleBuiltins.T__MULTIARCH;
33+
import static com.oracle.graal.python.builtins.modules.io.IONodes.T_CLOSED;
34+
import static com.oracle.graal.python.builtins.modules.io.IONodes.T_FLUSH;
3335
import static com.oracle.graal.python.builtins.objects.str.StringUtils.cat;
3436
import static com.oracle.graal.python.builtins.objects.thread.PThread.GRAALPYTHON_THREADS;
3537
import static com.oracle.graal.python.nodes.BuiltinNames.T_SHA3;
38+
import static com.oracle.graal.python.nodes.BuiltinNames.T_STDERR;
39+
import static com.oracle.graal.python.nodes.BuiltinNames.T_STDOUT;
3640
import static com.oracle.graal.python.nodes.BuiltinNames.T_SYS;
3741
import static com.oracle.graal.python.nodes.BuiltinNames.T_THREADING;
3842
import static com.oracle.graal.python.nodes.BuiltinNames.T___BUILTINS__;
@@ -145,10 +149,12 @@
145149
import com.oracle.graal.python.compiler.CodeUnit;
146150
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
147151
import com.oracle.graal.python.lib.PyObjectGetAttr;
152+
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
148153
import com.oracle.graal.python.nodes.ErrorMessages;
149154
import com.oracle.graal.python.nodes.PRaiseNode;
150155
import com.oracle.graal.python.nodes.SpecialAttributeNames;
151156
import com.oracle.graal.python.nodes.SpecialMethodNames;
157+
import com.oracle.graal.python.nodes.WriteUnraisableNode;
152158
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
153159
import com.oracle.graal.python.nodes.call.CallNode;
154160
import com.oracle.graal.python.nodes.object.SetDictNode;
@@ -1526,19 +1532,24 @@ public void patch(Env newEnv) {
15261532
}
15271533

15281534
private void importSiteIfForced() {
1529-
if (getOption(PythonOptions.ForceImportSite)) {
1530-
AbstractImportNode.importModule(T_SITE);
1531-
}
1532-
if (!getOption(PythonOptions.WarnOptions).isEmpty()) {
1533-
// we must force an import of the warnings module here if warnings were passed
1534-
AbstractImportNode.importModule(T_WARNINGS);
1535-
}
1536-
if (getOption(PythonOptions.InputFilePath).isEmpty()) {
1537-
// When InputFilePath is set, this is handled by __graalpython__.run_path
1538-
addSysPath0();
1539-
}
1540-
if (getOption(PythonOptions.SetupLLVMLibraryPaths)) {
1541-
ImpModuleBuiltins.importFrozenModuleObject(this, toTruffleStringUncached("graalpy.sulong_support"), false);
1535+
try {
1536+
if (getOption(PythonOptions.ForceImportSite)) {
1537+
AbstractImportNode.importModule(T_SITE);
1538+
}
1539+
if (!getOption(PythonOptions.WarnOptions).isEmpty()) {
1540+
// we must force an import of the warnings module here if warnings were passed
1541+
AbstractImportNode.importModule(T_WARNINGS);
1542+
}
1543+
if (getOption(PythonOptions.InputFilePath).isEmpty()) {
1544+
// When InputFilePath is set, this is handled by __graalpython__.run_path
1545+
addSysPath0();
1546+
}
1547+
if (getOption(PythonOptions.SetupLLVMLibraryPaths)) {
1548+
ImpModuleBuiltins.importFrozenModuleObject(this, toTruffleStringUncached("graalpy.sulong_support"), false);
1549+
}
1550+
} catch (PException e) {
1551+
flushStdFiles();
1552+
throw e;
15421553
}
15431554
}
15441555

@@ -2013,6 +2024,7 @@ public void finalizeContext() {
20132024
finalizing = true;
20142025
// interrupt and join or kill python threads
20152026
joinThreads();
2027+
flushStdFiles();
20162028
if (cApiContext != null) {
20172029
cApiContext.finalizeCApi();
20182030
}
@@ -2029,6 +2041,34 @@ public void finalizeContext() {
20292041
mainThread = null;
20302042
}
20312043

2044+
// Equivalent of CPython's flush_std_files
2045+
@TruffleBoundary
2046+
public void flushStdFiles() {
2047+
PythonModule sysModule = getSysModule();
2048+
flushFile(sysModule.getAttribute(T_STDOUT), true);
2049+
flushFile(sysModule.getAttribute(T_STDERR), false);
2050+
}
2051+
2052+
private static void flushFile(Object file, boolean useWriteUnraisable) {
2053+
if (!(file instanceof PNone)) {
2054+
boolean closed = false;
2055+
try {
2056+
closed = PyObjectIsTrueNode.executeUncached(PyObjectGetAttr.executeUncached(file, T_CLOSED));
2057+
} catch (PException e) {
2058+
// Ignore
2059+
}
2060+
if (!closed) {
2061+
try {
2062+
PyObjectCallMethodObjArgs.executeUncached(file, T_FLUSH);
2063+
} catch (PException e) {
2064+
if (useWriteUnraisable) {
2065+
WriteUnraisableNode.getUncached().execute(e.getEscapedException(), null, null);
2066+
}
2067+
}
2068+
}
2069+
}
2070+
}
2071+
20322072
@TruffleBoundary
20332073
public int getAtexitHookCount() {
20342074
return atExitHooks.size();

0 commit comments

Comments
 (0)