mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[pycharm] PY-38965 Add debugger response timeout setting
GitOrigin-RevId: 9356bdfb3e7f72e9a6d93391989e68cfc0272e0f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
290ba9eba8
commit
d61687f0f6
@@ -542,9 +542,9 @@ sdk.create.not.executable.does.not.exist.error=Executable does not exist
|
||||
sdk.create.executable.directory.error=Path can't be a directory
|
||||
sdk.create.tooltip.browse=Browse\u2026
|
||||
sdk.create.custom.venv.install.fix.title=Install {0} {1}
|
||||
sdk.create.custom.venv.run.error.message= Error Running {0}
|
||||
sdk.create.custom.venv.run.error.message=Error Running {0}
|
||||
sdk.create.custom.venv.progress.title.detect.executable=Detect executable
|
||||
sdk.create.custom.existing.env.title ={0} env use
|
||||
sdk.create.custom.existing.env.title={0} env use
|
||||
|
||||
sdk.create.targets.local=Local Machine
|
||||
sdk.create.custom.virtualenv=Virtualenv
|
||||
@@ -1051,6 +1051,7 @@ form.debugger.pyqt.compatible=PyQt compatible
|
||||
form.debugger.run.debugger.in.server.mode=Run debugger in server mode
|
||||
form.debugger.debugger.port=Debugger port:
|
||||
form.debugger.remote.interpreter.docker.default.interpreter.path=python
|
||||
form.debugger.response.timeout=Debugger evaluation response timeout (ms):
|
||||
form.data.viewer.current.slice=Current slice
|
||||
form.data.viewer.dialog.show.svn.map.table.header.column.format.title=Format
|
||||
form.data.viewer.format=Format:
|
||||
|
||||
+16
-6
@@ -177,14 +177,20 @@ public class ClientModeMultiProcessDebugger implements ProcessDebugger {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyDebugValue evaluate(String threadId, String frameId, String expression, boolean execute) throws PyDebuggerException {
|
||||
return debugger(threadId).evaluate(threadId, frameId, expression, execute);
|
||||
public PyDebugValue evaluate(String threadId, String frameId, String expression, boolean execute, int evaluationTimeout)
|
||||
throws PyDebuggerException {
|
||||
return debugger(threadId).evaluate(threadId, frameId, expression, execute, evaluationTimeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyDebugValue evaluate(String threadId, String frameId, String expression, boolean execute, boolean trimResult)
|
||||
public PyDebugValue evaluate(String threadId,
|
||||
String frameId,
|
||||
String expression,
|
||||
boolean execute,
|
||||
int evaluationTimeout,
|
||||
boolean trimResult)
|
||||
throws PyDebuggerException {
|
||||
return debugger(threadId).evaluate(threadId, frameId, expression, execute, trimResult);
|
||||
return debugger(threadId).evaluate(threadId, frameId, expression, execute, evaluationTimeout, trimResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -201,7 +207,8 @@ public class ClientModeMultiProcessDebugger implements ProcessDebugger {
|
||||
public @Nullable String execTableCommand(String threadId,
|
||||
String frameId,
|
||||
String command,
|
||||
TableCommandType commandType, TableCommandParameters tableCommandParameters) throws PyDebuggerException {
|
||||
TableCommandType commandType, TableCommandParameters tableCommandParameters)
|
||||
throws PyDebuggerException {
|
||||
return debugger(threadId).execTableCommand(threadId, frameId, command, commandType, tableCommandParameters);
|
||||
}
|
||||
|
||||
@@ -235,7 +242,10 @@ public class ClientModeMultiProcessDebugger implements ProcessDebugger {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadReferrers(String threadId, String frameId, PyReferringObjectsValue var, PyDebugCallback<? super XValueChildrenList> callback) {
|
||||
public void loadReferrers(String threadId,
|
||||
String frameId,
|
||||
PyReferringObjectsValue var,
|
||||
PyDebugCallback<? super XValueChildrenList> callback) {
|
||||
debugger(threadId).loadReferrers(threadId, frameId, var, callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,16 +17,18 @@ public class EvaluateCommand extends AbstractFrameCommand {
|
||||
private final boolean myTrimResult;
|
||||
private PyDebugValue myValue = null;
|
||||
private final String myTempName;
|
||||
private final int myEvaluationTimeout;
|
||||
|
||||
|
||||
public EvaluateCommand(final RemoteDebugger debugger, final String threadId, final String frameId, final String expression,
|
||||
final boolean execute, final boolean trimResult) {
|
||||
final boolean execute, final boolean trimResult, final int evaluationTimeout) {
|
||||
super(debugger, (execute ? EXECUTE : EVALUATE), threadId, frameId);
|
||||
myExpression = expression;
|
||||
myExecute = execute;
|
||||
myDebugProcess = debugger.getDebugProcess();
|
||||
myTrimResult = trimResult;
|
||||
myTempName = myDebugProcess.canSaveToTemp(expression)? debugger.generateSaveTempName(threadId, frameId): "";
|
||||
myTempName = myDebugProcess.canSaveToTemp(expression) ? debugger.generateSaveTempName(threadId, frameId) : "";
|
||||
myEvaluationTimeout = evaluationTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,6 +52,11 @@ public class EvaluateCommand extends AbstractFrameCommand {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getResponseTimeout() {
|
||||
return myEvaluationTimeout;
|
||||
}
|
||||
|
||||
public PyDebugValue getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
@@ -190,14 +190,20 @@ public class MultiProcessDebugger implements ProcessDebugger {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyDebugValue evaluate(String threadId, String frameId, String expression, boolean execute) throws PyDebuggerException {
|
||||
return debugger(threadId).evaluate(threadId, frameId, expression, execute);
|
||||
public PyDebugValue evaluate(String threadId, String frameId, String expression, boolean execute, int evaluationTimeout)
|
||||
throws PyDebuggerException {
|
||||
return debugger(threadId).evaluate(threadId, frameId, expression, execute, evaluationTimeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyDebugValue evaluate(String threadId, String frameId, String expression, boolean execute, boolean trimResult)
|
||||
public PyDebugValue evaluate(String threadId,
|
||||
String frameId,
|
||||
String expression,
|
||||
boolean execute,
|
||||
int evaluationTimeout,
|
||||
boolean trimResult)
|
||||
throws PyDebuggerException {
|
||||
return debugger(threadId).evaluate(threadId, frameId, expression, execute, trimResult);
|
||||
return debugger(threadId).evaluate(threadId, frameId, expression, execute, evaluationTimeout, trimResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -214,7 +220,8 @@ public class MultiProcessDebugger implements ProcessDebugger {
|
||||
public @Nullable String execTableCommand(String threadId,
|
||||
String frameId,
|
||||
String command,
|
||||
TableCommandType commandType, TableCommandParameters tableCommandParameters) throws PyDebuggerException {
|
||||
TableCommandType commandType, TableCommandParameters tableCommandParameters)
|
||||
throws PyDebuggerException {
|
||||
return debugger(threadId).execTableCommand(threadId, frameId, command, commandType, tableCommandParameters);
|
||||
}
|
||||
|
||||
@@ -248,7 +255,10 @@ public class MultiProcessDebugger implements ProcessDebugger {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadReferrers(String threadId, String frameId, PyReferringObjectsValue var, PyDebugCallback<? super XValueChildrenList> callback) {
|
||||
public void loadReferrers(String threadId,
|
||||
String frameId,
|
||||
PyReferringObjectsValue var,
|
||||
PyDebugCallback<? super XValueChildrenList> callback) {
|
||||
debugger(threadId).loadReferrers(threadId, frameId, var, callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,12 +23,16 @@ public interface ProcessDebugger {
|
||||
|
||||
PyDebugValue evaluate(String threadId,
|
||||
String frameId,
|
||||
String expression, boolean execute) throws PyDebuggerException;
|
||||
String expression,
|
||||
boolean execute,
|
||||
final int evaluationTimeout)
|
||||
throws PyDebuggerException;
|
||||
|
||||
PyDebugValue evaluate(String threadId,
|
||||
String frameId,
|
||||
String expression,
|
||||
boolean execute,
|
||||
final int evaluationTimeout,
|
||||
boolean trimResult)
|
||||
throws PyDebuggerException;
|
||||
|
||||
@@ -151,5 +155,5 @@ public interface ProcessDebugger {
|
||||
|
||||
void suspendOtherThreads(PyThreadInfo thread);
|
||||
|
||||
default void interruptDebugConsole() {}
|
||||
default void interruptDebugConsole() { }
|
||||
}
|
||||
|
||||
@@ -147,21 +147,29 @@ public class RemoteDebugger implements ProcessDebugger {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyDebugValue evaluate(final String threadId,
|
||||
final String frameId,
|
||||
final String expression, final boolean execute) throws PyDebuggerException {
|
||||
return evaluate(threadId, frameId, expression, execute, true);
|
||||
public PyDebugValue evaluate(
|
||||
final String threadId,
|
||||
final String frameId,
|
||||
final String expression,
|
||||
final boolean execute,
|
||||
final int evaluationTimeout
|
||||
) throws PyDebuggerException {
|
||||
return evaluate(threadId, frameId, expression, execute, evaluationTimeout, true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PyDebugValue evaluate(final String threadId,
|
||||
final String frameId,
|
||||
final String expression,
|
||||
final boolean execute,
|
||||
boolean trimResult)
|
||||
throws PyDebuggerException {
|
||||
return executeCommand(new EvaluateCommand(this, threadId, frameId, expression, execute, trimResult)).getValue();
|
||||
public PyDebugValue evaluate(
|
||||
final String threadId,
|
||||
final String frameId,
|
||||
final String expression,
|
||||
final boolean execute,
|
||||
final int evaluationTimeout,
|
||||
boolean trimResult
|
||||
) throws PyDebuggerException {
|
||||
return executeCommand(
|
||||
new EvaluateCommand(this, threadId, frameId, expression, execute, trimResult, evaluationTimeout)
|
||||
).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -325,7 +333,7 @@ public class RemoteDebugger implements ProcessDebugger {
|
||||
final String expression = "del " + StringUtil.join(frameVars, ",");
|
||||
final String wrappedExpression = String.format("try:\n %s\nexcept:\n pass", expression);
|
||||
try {
|
||||
evaluate(threadId, entry.getKey(), wrappedExpression, true);
|
||||
evaluate(threadId, entry.getKey(), wrappedExpression, true, RESPONSE_TIMEOUT);
|
||||
}
|
||||
catch (PyDebuggerException e) {
|
||||
LOG.error(e);
|
||||
@@ -787,7 +795,6 @@ public class RemoteDebugger implements ProcessDebugger {
|
||||
* If the command execution throws an exception and the debugger is in
|
||||
* "connected" state then the exception is rethrown. If the debugger is not
|
||||
* connected at this moment then the exception is ignored.
|
||||
*
|
||||
*/
|
||||
private <T extends AbstractCommand<?>> T executeCommand(@NotNull T command) throws PyDebuggerException {
|
||||
try {
|
||||
@@ -808,7 +815,6 @@ public class RemoteDebugger implements ProcessDebugger {
|
||||
* If the command execution throws an exception and the debugger is in
|
||||
* "connected" state then the error is logged. If the debugger is not
|
||||
* connected at this moment then the exception is ignored.
|
||||
*
|
||||
*/
|
||||
private <T extends AbstractCommand<?>> void executeCommandSafely(@NotNull T command) {
|
||||
try {
|
||||
|
||||
@@ -810,7 +810,9 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
}
|
||||
|
||||
private PyDebugValue evaluate(String expression, boolean execute, PyStackFrame frame, boolean trimResult) throws PyDebuggerException {
|
||||
return myDebugger.evaluate(frame.getThreadId(), frame.getFrameId(), expression, execute, trimResult);
|
||||
PyDebuggerOptionsProvider settings = PyDebuggerOptionsProvider.getInstance(getProject());
|
||||
return myDebugger.evaluate(frame.getThreadId(), frame.getFrameId(), expression, execute,
|
||||
settings.getEvaluationResponseTimeout(), trimResult);
|
||||
}
|
||||
|
||||
public void consoleExec(String command, PyDebugCallback<String> callback) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.python.debugger.PyDebuggerConfigurable">
|
||||
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="4" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="735" height="319"/>
|
||||
<xy x="20" y="20" width="735" height="333"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -135,7 +135,7 @@
|
||||
</grid>
|
||||
<vspacer id="5915a">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="3" column="1" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="ffb0f" class="com.intellij.ui.components.JBLabel" binding="myAttachFilterLabel">
|
||||
@@ -150,6 +150,18 @@
|
||||
<html.disable class="java.lang.Boolean" value="false"/>
|
||||
</clientProperties>
|
||||
</component>
|
||||
<component id="4a05c" class="com.intellij.ui.components.JBLabel" binding="myDebuggerEvaluationResponseTimeoutLabel" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="79ca8"/>
|
||||
<text resource-bundle="messages/PyBundle" key="form.debugger.response.timeout"/>
|
||||
</properties>
|
||||
<clientProperties>
|
||||
<html.disable class="java.lang.Boolean" value="false"/>
|
||||
</clientProperties>
|
||||
</component>
|
||||
<component id="79ca8" class="com.intellij.ui.components.JBTextField" binding="myAttachProcessFilter" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="3" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
|
||||
@@ -166,6 +178,15 @@
|
||||
<grid row="1" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="2" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<component id="fa84d" class="com.intellij.ui.JBIntSpinner" binding="myDebuggerEvaluationResponseTimeout" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<max value="65535"/>
|
||||
<min value="0"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
@@ -43,6 +43,8 @@ public final class PyDebuggerConfigurable implements SearchableConfigurable, Con
|
||||
private JBIntSpinner myDebuggerPort;
|
||||
private JBCheckBox myRunDebuggerInServerMode;
|
||||
private JPanel myDebuggerPortPanel;
|
||||
private JBLabel myDebuggerEvaluationResponseTimeoutLabel;
|
||||
private JBIntSpinner myDebuggerEvaluationResponseTimeout;
|
||||
|
||||
private enum PyQtBackend {
|
||||
AUTO(PyBundle.messagePointer("python.debugger.qt.backend.auto")),
|
||||
@@ -130,7 +132,8 @@ public final class PyDebuggerConfigurable implements SearchableConfigurable, Con
|
||||
!StringUtil.toLowerCase((((PyQtBackend)myPyQtBackend.getSelectedItem()).name())).equals(settings.getPyQtBackend())) ||
|
||||
myRunDebuggerInServerMode.isSelected() != settings.isRunDebuggerInServerMode() ||
|
||||
myDebuggerPort.getNumber() != settings.getDebuggerPort() ||
|
||||
!myAttachProcessFilter.getText().equals(settings.getAttachProcessFilter());
|
||||
!myAttachProcessFilter.getText().equals(settings.getAttachProcessFilter()) ||
|
||||
myDebuggerEvaluationResponseTimeout.getNumber() != settings.getEvaluationResponseTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -151,6 +154,7 @@ public final class PyDebuggerConfigurable implements SearchableConfigurable, Con
|
||||
settings.setDebuggerPort(myDebuggerPort.getNumber());
|
||||
|
||||
settings.setAttachProcessFilter(myAttachProcessFilter.getText());
|
||||
settings.setEvaluationResponseTimeout(myDebuggerEvaluationResponseTimeout.getNumber());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,6 +169,7 @@ public final class PyDebuggerConfigurable implements SearchableConfigurable, Con
|
||||
myDebuggerPort.setNumber(settings.getDebuggerPort());
|
||||
myRunDebuggerInServerMode.setSelected(settings.isRunDebuggerInServerMode());
|
||||
myAttachProcessFilter.setText(settings.getAttachProcessFilter());
|
||||
myDebuggerEvaluationResponseTimeout.setNumber(settings.getEvaluationResponseTimeout());
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
@@ -175,15 +180,15 @@ public final class PyDebuggerConfigurable implements SearchableConfigurable, Con
|
||||
PyBundle.message("debugger.warning.message")));
|
||||
|
||||
myActionLink = new ActionLink(PyBundle.message("form.debugger.clear.caches.action"), e -> {
|
||||
boolean cleared = PySignatureCacheManager.getInstance(myProject).clearCache();
|
||||
String message;
|
||||
if (cleared) {
|
||||
message = PyBundle.message("python.debugger.collection.signatures.deleted");
|
||||
}
|
||||
else {
|
||||
message = PyBundle.message("python.debugger.nothing.to.delete");
|
||||
}
|
||||
Messages.showInfoMessage(myProject, message, PyBundle.message("debugger.delete.signature.cache"));
|
||||
boolean cleared = PySignatureCacheManager.getInstance(myProject).clearCache();
|
||||
String message;
|
||||
if (cleared) {
|
||||
message = PyBundle.message("python.debugger.collection.signatures.deleted");
|
||||
}
|
||||
else {
|
||||
message = PyBundle.message("python.debugger.nothing.to.delete");
|
||||
}
|
||||
Messages.showInfoMessage(myProject, message, PyBundle.message("debugger.delete.signature.cache"));
|
||||
});
|
||||
|
||||
myRunDebuggerInServerMode = new JBCheckBox();
|
||||
@@ -197,5 +202,8 @@ public final class PyDebuggerConfigurable implements SearchableConfigurable, Con
|
||||
myDebuggerPortLabel.setVisible(false);
|
||||
myDebuggerPort.setVisible(false);
|
||||
}
|
||||
|
||||
myDebuggerEvaluationResponseTimeoutLabel = new JBLabel(PyBundle.message("form.debugger.response.timeout"));
|
||||
myDebuggerEvaluationResponseTimeout = new JBIntSpinner(0, 0, Integer.MAX_VALUE, 500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ public final class PyDebuggerOptionsProvider implements PersistentStateComponent
|
||||
public boolean myRunDebuggerInServerMode = true;
|
||||
public int myDebuggerPort = 29781;
|
||||
public @NonNls String myAttachProcessFilter = "python";
|
||||
public int myEvaluationResponseTimeout = 60_000;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,8 +87,9 @@ public final class PyDebuggerOptionsProvider implements PersistentStateComponent
|
||||
}
|
||||
|
||||
public String getPyQtBackend() {
|
||||
if (StringUtil.toLowerCase(PyBundle.messagePointer("python.debugger.qt.backend.auto").get()).equals(myState.myPyQtBackend))
|
||||
if (StringUtil.toLowerCase(PyBundle.messagePointer("python.debugger.qt.backend.auto").get()).equals(myState.myPyQtBackend)) {
|
||||
return "auto";
|
||||
}
|
||||
return myState.myPyQtBackend;
|
||||
}
|
||||
|
||||
@@ -118,5 +120,13 @@ public final class PyDebuggerOptionsProvider implements PersistentStateComponent
|
||||
public void setAttachProcessFilter(String filter) {
|
||||
myState.myAttachProcessFilter = filter;
|
||||
}
|
||||
|
||||
public int getEvaluationResponseTimeout() {
|
||||
return myState.myEvaluationResponseTimeout;
|
||||
}
|
||||
|
||||
public void setEvaluationResponseTimeout(int timeout) {
|
||||
myState.myEvaluationResponseTimeout = timeout;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user