PY-56467: Set python output to UTF-8 to support non-ascii chars

The problem is ``sys.stdout.encoding``.
On Unix Python uses ``LC_`` which is UTF-8 since late 2000s.
But on Windows for non-console based executions (with stdout redirected) it uses one byte encoding (aka non-unicode programs charset) due to backward compatibility with 9x/me.

With one-byte charset you can't have both latin-1 and cyrillic characters.

To fix that, we provide ``PYTHONIOENCODING`` which sets charset explicitly

GitOrigin-RevId: 5c3304e002d80fb5780f11f05fe5f4d1b6aef3ad
This commit is contained in:
Ilya.Kazakevich
2022-09-28 02:03:09 +02:00
committed by intellij-monorepo-bot
parent c5cb239dfa
commit d3bdd60b34
4 changed files with 16 additions and 0 deletions

View File

@@ -25,6 +25,7 @@ import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.run.CommandLinePatcher;
import com.jetbrains.python.run.PyVirtualEnvReader;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
import kotlin.text.Charsets;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,6 +34,7 @@ import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
@@ -58,6 +60,14 @@ public final class PySdkUtil {
// explicitly none
}
public static void configureCharset(@NotNull GeneralCommandLine commandLine) {
var charset = commandLine.getCharset();
if ( charset != Charsets.UTF_8) {
LOG.warn("Charset " + charset + " is not UTF-8, which is likely lead to troubles");
}
PythonEnvUtil.setupEncodingEnvs(commandLine.getEnvironment(), charset);
}
/**
* Executes a process and returns its stdout and stderr outputs as lists of lines.
*
@@ -130,6 +140,7 @@ public final class PySdkUtil {
cmdLinePatcher.patchCommandLine(cmd);
}
PythonEnvUtil.setupEncodingEnvs(commandLine.getEnvironment(), commandLine.getCharset());
final CapturingProcessHandler processHandler = new CapturingProcessHandler(commandLine);
if (stdin != null) {
final OutputStream processInput = processHandler.getProcessInput();