Skip to content

Commit 14deb53

Browse files
committed
Restore Windows stdio flags after Python initialisation.
Python forcibly sets the file mode for stdin, stdout, and stderr to O_BINARY for several reasons. This causes wprintf() to output UTF-16 instead of going through the proper text conversion. As a result, standard output was all messed up after the module was initialised. The Python developers do not really consider this a bug because they are not familiar with wprintf() (https://bugs.python.org/issue16587). Unfortunately this is what UE4 uses for logging.
1 parent b279548 commit 14deb53

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

Source/UnrealEnginePython/Private/UnrealEnginePython.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@ const char *ue4_module_options = "linux_global_symbols";
3434
#include "Runtime/Core/Public/Misc/CommandLine.h"
3535
#include "Runtime/Core/Public/Misc/ConfigCacheIni.h"
3636
#include "Runtime/Core/Public/GenericPlatform/GenericPlatformFile.h"
37+
#include "Runtime/Core/Public/GenericPlatform/GenericPlatformMisc.h"
3738

3839
#include "Runtime/Core/Public/HAL/FileManagerGeneric.h"
3940

41+
#if PLATFORM_WINDOWS
42+
#include <fcntl.h>
43+
#endif
44+
4045
#if PLATFORM_ANDROID
4146
#include "Android/AndroidJNI.h"
4247
#include "Android/AndroidApplication.h"
@@ -447,6 +452,22 @@ void FUnrealEnginePythonModule::StartupModule()
447452

448453
Py_Initialize();
449454

455+
#if PLATFORM_WINDOWS
456+
// Restore stdio state after Py_Initialize set it to O_BINARY, otherwise
457+
// everything that the engine will output is going to be encoded in UTF-16.
458+
// The behaviour is described here: https://bugs.python.org/issue16587
459+
_setmode(fileno(stdin), O_TEXT);
460+
_setmode(fileno(stdout), O_TEXT);
461+
_setmode(fileno(stderr), O_TEXT);
462+
463+
// Also restore the user-requested UTF-8 flag if relevant (behaviour copied
464+
// from LaunchEngineLoop.cpp).
465+
if (FParse::Param(FCommandLine::Get(), TEXT("UTF8Output")))
466+
{
467+
FPlatformMisc::SetUTF8Output();
468+
}
469+
#endif
470+
450471
PyEval_InitThreads();
451472

452473
#if WITH_EDITOR

0 commit comments

Comments
 (0)