PY-24875: Filter messages in console, do not use InputFilter EP

With InputFilter API we can't check if are in test console and even
if it is Python console or not.
Affecting any console in Intellij-based product is not good idea
and may lead to performance problems.

See https://buildserver.labs.intellij.net/viewLog.html?buildId=22270794&tab=buildResultsDiv&buildTypeId=ijplatform_master_Idea_PerformanceTests
This commit is contained in:
Ilya.Kazakevich
2017-09-28 23:30:57 +03:00
parent a4b595baca
commit 354078660d
7 changed files with 32 additions and 23 deletions
@@ -169,7 +169,6 @@
<runConfigurationProducer implementation="com.jetbrains.python.testing.tox.PyToxConfigurationProducer"/>
<runConfigurationProducer implementation="com.jetbrains.python.testing.nosetestLegacy.PythonNoseTestConfigurationProducer"/>
<runConfigurationProducer implementation="com.jetbrains.python.testing.PyTestsConfigurationProducer"/>
<consoleInputFilterProvider implementation="com.jetbrains.python.testing.PyTestConsoleInputFilterProvider"/>
<codeInsight.lineMarkerProvider language="Python" implementationClass="com.jetbrains.python.codeInsight.PyLineMarkerProvider"/>
<codeInsight.typeInfo language="Python" implementationClass="com.jetbrains.python.actions.PythonExpressionTypeProvider"/>
@@ -387,7 +387,7 @@ public class PydevConsoleRunnerImpl implements PydevConsoleRunner {
}
private PythonConsoleView createConsoleView() {
PythonConsoleView consoleView = new PythonConsoleView(myProject, myTitle, mySdk);
PythonConsoleView consoleView = new PythonConsoleView(myProject, myTitle, mySdk, false);
myPydevConsoleCommunication.setConsoleFile(consoleView.getVirtualFile());
consoleView.addMessageFilter(new PythonTracebackFilter(myProject));
return consoleView;
@@ -72,6 +72,7 @@ import com.jetbrains.python.debugger.PyStackFrameInfo;
import com.jetbrains.python.highlighting.PyHighlighter;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.sdk.PythonSdkType;
import com.jetbrains.python.testing.PyTestsSharedKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -85,6 +86,7 @@ public class PythonConsoleView extends LanguageConsoleImpl implements Observable
private static final Logger LOG = Logger.getInstance(PythonConsoleView.class);
private final ConsolePromptDecorator myPromptView;
private final boolean myTestMode;
private PythonConsoleExecuteActionHandler myExecuteActionHandler;
private PyConsoleSourceHighlighter mySourceHighlighter;
@@ -97,8 +99,12 @@ public class PythonConsoleView extends LanguageConsoleImpl implements Observable
private ActionCallback myInitialized = new ActionCallback();
private boolean isShowVars = true;
public PythonConsoleView(final Project project, final String title, final Sdk sdk) {
/**
* @param testMode this console will be used to display test output and should support TC messages
*/
public PythonConsoleView(final Project project, final String title, final Sdk sdk, final boolean testMode) {
super(project, title, PythonLanguage.getInstance());
myTestMode = testMode;
getVirtualFile().putUserData(LanguageLevel.KEY, PythonSdkType.getLanguageLevelForSdk(sdk));
// Mark editor as console one, to prevent autopopup completion
@@ -263,6 +269,9 @@ public class PythonConsoleView extends LanguageConsoleImpl implements Observable
@Override
public void print(@NotNull String text, @NotNull final ConsoleViewContentType outputType) {
if (myTestMode) {
text = PyTestsSharedKt.processTCMessage(text);
}
detectIPython(text, outputType);
if (PyConsoleUtil.detectIPythonEnd(text)) {
myIsIPythonOutput = false;
@@ -42,8 +42,11 @@ public class PythonDebugLanguageConsoleView extends DuplexConsoleView<ConsoleVie
public static final String DEBUG_CONSOLE_START_COMMAND = "import sys; print('Python %s on %s' % (sys.version, sys.platform))";
private boolean myDebugConsoleInitialized = false;
public PythonDebugLanguageConsoleView(final Project project, Sdk sdk, ConsoleView consoleView) {
super(consoleView, new PythonConsoleView(project, "Python Console", sdk));
/**
* @param testMode this console will be used to display test output and should support TC messages
*/
public PythonDebugLanguageConsoleView(final Project project, Sdk sdk, ConsoleView consoleView, final boolean testMode) {
super(consoleView, new PythonConsoleView(project, "Python Console", sdk, testMode));
enableConsole(!PyConsoleOptions.getInstance(project).isShowDebugConsoleByDefault());
@@ -56,7 +59,7 @@ public class PythonDebugLanguageConsoleView extends DuplexConsoleView<ConsoleVie
}
public PythonDebugLanguageConsoleView(final Project project, Sdk sdk) {
this(project, sdk, TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole());
this(project, sdk, TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole(), false);
}
@Override
@@ -85,6 +85,19 @@ val factories: Array<PythonConfigurationFactoryBase> = arrayOf(
PyNoseTestFactory,
PyTrialTestFactory)
/**
* Accepts text that may be wrapped in TC message. Unwarps it and removes TC escape code.
* Regular text is unchanged
*/
fun processTCMessage(text: String): String {
val parsedMessage = ServiceMessage.parse(text.trim()) ?: return text // Not a TC message
return when (parsedMessage) {
is TestStdOut -> parsedMessage.stdOut // TC with stdout
is TestStdErr -> parsedMessage.stdErr // TC with stderr
else -> "" // TC with out of any output
}
}
internal fun getAdditionalArgumentsPropertyName() = com.jetbrains.python.testing.PyAbstractTestConfiguration::additionalArguments.name
/**
@@ -789,21 +802,6 @@ object PyTestsConfigurationProducer : AbstractPythonTestConfigurationProducer<Py
}
}
private object PyTestInputFilter : InputFilter {
override fun applyFilter(text: String, contentType: ConsoleViewContentType?): List<Pair<String, ConsoleViewContentType>>? {
val parsedMessage = ServiceMessage.parse(text.trim()) ?: return null // Not a TC message
return when (parsedMessage) {
is TestStdOut -> listOf(Pair(parsedMessage.stdOut, contentType!!)) // TC with stdout
is TestStdErr -> listOf(Pair(parsedMessage.stdErr, contentType!!)) // TC with stderr
else -> emptyList() // TC with out of any output
}
}
}
object PyTestConsoleInputFilterProvider : ConsoleInputFilterProvider {
override fun getDefaultFilters(project: Project): Array<InputFilter> = arrayOf(PyTestInputFilter)
}
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY)
/**
@@ -72,7 +72,7 @@ public abstract class PythonTestCommandLineStateBase<T extends AbstractPythonRun
consoleProperties);
final ConsoleView consoleView =
new PythonDebugLanguageConsoleView(project, PythonSdkType.findSdkByPath(myConfiguration.getInterpreterPath()),
testsOutputConsoleView);
testsOutputConsoleView, true);
consoleView.attachToProcess(processHandler);
addTracebackFilter(project, consoleView, processHandler);
return consoleView;
@@ -40,7 +40,7 @@ class PyConsoleEnterHandlerTest : PyTestCase() {
}
private fun resetEditor() {
myEditor = disposeOnTearDown(PythonConsoleView(myFixture.project, "Console", projectDescriptor?.sdk)).consoleEditor
myEditor = disposeOnTearDown(PythonConsoleView(myFixture.project, "Console", projectDescriptor?.sdk, false)).consoleEditor
}
fun push(text: String): Boolean {