PY-59463: Remove requirement for Python 2.* to format Epytext docs

(cherry picked from commit 8fd59526a1f849dcf426da65867b9c37039f273e)

IJ-CR-147140

GitOrigin-RevId: 041794293699d490b6220f22e4156c934a32912b
This commit is contained in:
Irina Fediaeva
2024-10-18 00:11:28 +02:00
committed by intellij-monorepo-bot
parent e634ac917f
commit 106c9fdaa5
3 changed files with 57 additions and 72 deletions

View File

@@ -82,7 +82,7 @@ public final class PythonRuntimeServiceImpl extends PythonRuntimeService {
@NotNull DocStringFormat format,
@NotNull String input,
@NotNull List<String> formatterFlags) {
return PyRuntimeDocstringFormatter.runExternalTool(module, format, input, formatterFlags);
return PyRuntimeDocstringFormatter.INSTANCE.runExternalTool(module, format, input, formatterFlags);
}
@Override

View File

@@ -1,71 +0,0 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.documentation;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.text.HtmlChunk;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.JBColor;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.PythonHelper;
import com.jetbrains.python.documentation.docstrings.DocStringFormat;
import com.jetbrains.python.sdk.PySdkUtil;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
public final class PyRuntimeDocstringFormatter {
private static final Logger LOG = Logger.getInstance(PyStructuredDocstringFormatter.class);
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
public static @Nullable String runExternalTool(final @NotNull Module module,
final @NotNull DocStringFormat format,
final @NotNull String input,
final @NotNull List<String> formatterFlags) {
final Sdk sdk;
final String missingInterpreterMessage;
if (format == DocStringFormat.EPYTEXT) {
sdk = PythonSdkType.findPython2Sdk(module);
missingInterpreterMessage = PyPsiBundle.message("QDOC.epydoc.python2.sdk.not.found");
}
else {
sdk = PythonSdkType.findLocalCPython(module);
missingInterpreterMessage = PyPsiBundle.message("QDOC.local.sdk.not.found");
}
if (sdk == null) {
LOG.warn("Python SDK for input formatter " + format + " is not found");
return HtmlChunk.p().attr("color", ColorUtil.toHtmlColor(JBColor.RED)).addRaw(missingInterpreterMessage).toString();
}
final String sdkHome = sdk.getHomePath();
if (sdkHome == null) return null;
final ByteBuffer encoded = DEFAULT_CHARSET.encode(input);
final byte[] data = new byte[encoded.limit()];
encoded.get(data);
final List<String> arguments = ContainerUtil.prepend(formatterFlags, "--format", format.getFormatterCommand());
final GeneralCommandLine commandLine = PythonHelper.DOCSTRING_FORMATTER.newCommandLine(sdk, arguments);
commandLine.setCharset(DEFAULT_CHARSET);
LOG.debug("Command for launching docstring formatter: " + commandLine.getCommandLineString());
final ProcessOutput output = PySdkUtil.getProcessOutput(commandLine, new File(sdkHome).getParent(), null, 5000, data, false);
if (!output.checkSuccess(LOG)) {
LOG.info("Malformed input:\n" + input);
return null;
}
return output.getStdout();
}
}

View File

@@ -0,0 +1,56 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.documentation
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.module.Module
import com.intellij.openapi.util.text.HtmlChunk
import com.intellij.ui.ColorUtil
import com.intellij.ui.JBColor
import com.jetbrains.python.PyPsiBundle
import com.jetbrains.python.PythonHelper
import com.jetbrains.python.documentation.docstrings.DocStringFormat
import com.jetbrains.python.sdk.PySdkUtil
import com.jetbrains.python.sdk.PythonSdkType
import java.io.File
object PyRuntimeDocstringFormatter {
fun runExternalTool(module: Module, format: DocStringFormat, input: String, formatterFlags: List<String>): String? {
val sdk = PythonSdkType.findLocalCPython(module) ?: return logErrorAndReturnMessage(format)
val sdkHome = sdk.homePath ?: return null
val encodedInput = DEFAULT_CHARSET.encode(input)
val data = ByteArray(encodedInput.limit()).also { encodedInput.get(it) }
val arguments = formatterFlags.toMutableList().apply {
add("--format")
add(format.formatterCommand)
}
val commandLine = PythonHelper.DOCSTRING_FORMATTER
.newCommandLine(sdk, arguments)
.withCharset(DEFAULT_CHARSET)
LOG.debug("Command for launching docstring formatter: ${commandLine.commandLineString}")
val output = PySdkUtil.getProcessOutput(commandLine, File(sdkHome).parent, null, 5000, data, false)
return if (output.checkSuccess(LOG)) {
output.stdout
}
else logScriptError(input)
}
private fun logErrorAndReturnMessage(format: DocStringFormat): String {
LOG.warn("Python SDK for input formatter $format is not found")
val missingInterpreterMessage = PyPsiBundle.message("QDOC.local.sdk.not.found")
return HtmlChunk.p().attr("color", ColorUtil.toHtmlColor(JBColor.RED))
.addRaw(missingInterpreterMessage).toString()
}
private fun logScriptError(input: String): String? {
LOG.warn("Malformed input or internal script error:\n$input")
return null
}
private val LOG: Logger by lazy { Logger.getInstance(PyRuntimeDocstringFormatter::class.java) }
private val DEFAULT_CHARSET = Charsets.UTF_8
}