3030import static com .oracle .graal .python .builtins .PythonOS .getPythonOS ;
3131import static com .oracle .graal .python .builtins .modules .SysModuleBuiltins .T_CACHE_TAG ;
3232import 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 ;
3335import static com .oracle .graal .python .builtins .objects .str .StringUtils .cat ;
3436import static com .oracle .graal .python .builtins .objects .thread .PThread .GRAALPYTHON_THREADS ;
3537import 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 ;
3640import static com .oracle .graal .python .nodes .BuiltinNames .T_SYS ;
3741import static com .oracle .graal .python .nodes .BuiltinNames .T_THREADING ;
3842import static com .oracle .graal .python .nodes .BuiltinNames .T___BUILTINS__ ;
145149import com .oracle .graal .python .compiler .CodeUnit ;
146150import com .oracle .graal .python .lib .PyObjectCallMethodObjArgs ;
147151import com .oracle .graal .python .lib .PyObjectGetAttr ;
152+ import com .oracle .graal .python .lib .PyObjectIsTrueNode ;
148153import com .oracle .graal .python .nodes .ErrorMessages ;
149154import com .oracle .graal .python .nodes .PRaiseNode ;
150155import com .oracle .graal .python .nodes .SpecialAttributeNames ;
151156import com .oracle .graal .python .nodes .SpecialMethodNames ;
157+ import com .oracle .graal .python .nodes .WriteUnraisableNode ;
152158import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
153159import com .oracle .graal .python .nodes .call .CallNode ;
154160import 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