mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
Implement condition and log expression for Exception breakpoints (PY-24593)
This commit is contained in:
@@ -19,6 +19,8 @@ class ExceptionBreakpoint:
|
||||
def __init__(
|
||||
self,
|
||||
qname,
|
||||
condition,
|
||||
expression,
|
||||
notify_always,
|
||||
notify_on_terminate,
|
||||
notify_on_first_raise_only,
|
||||
@@ -31,6 +33,8 @@ class ExceptionBreakpoint:
|
||||
else:
|
||||
self.name = None
|
||||
|
||||
self.condition = condition
|
||||
self.expression = expression
|
||||
self.notify_on_terminate = notify_on_terminate
|
||||
self.notify_always = notify_always
|
||||
self.notify_on_first_raise_only = notify_on_first_raise_only
|
||||
|
||||
@@ -13,7 +13,7 @@ from _pydevd_bundle.pydevd_comm import CMD_STEP_CAUGHT_EXCEPTION, CMD_STEP_RETUR
|
||||
from _pydevd_bundle.pydevd_constants import STATE_SUSPEND, dict_contains, get_thread_id, STATE_RUN, dict_iter_values, IS_PY3K, \
|
||||
dict_keys, RETURN_VALUES_DICT
|
||||
from _pydevd_bundle.pydevd_dont_trace_files import DONT_TRACE, PYDEV_FILE
|
||||
from _pydevd_bundle.pydevd_frame_utils import add_exception_to_frame, just_raised
|
||||
from _pydevd_bundle.pydevd_frame_utils import add_exception_to_frame, just_raised, remove_exception_from_frame
|
||||
from _pydevd_bundle.pydevd_utils import get_clsname_for_code
|
||||
from pydevd_file_utils import get_abs_path_real_path_and_base_from_frame
|
||||
|
||||
@@ -167,6 +167,12 @@ class PyDBFrame:
|
||||
exception, main_debugger.break_on_caught_exceptions)
|
||||
|
||||
if exception_breakpoint is not None:
|
||||
add_exception_to_frame(frame, (exception, value, trace))
|
||||
if exception_breakpoint.condition is not None:
|
||||
eval_result = handle_breakpoint_condition(main_debugger, info, exception_breakpoint, frame)
|
||||
if not eval_result:
|
||||
return False, frame
|
||||
|
||||
if exception_breakpoint.ignore_libraries:
|
||||
if exception_breakpoint.notify_on_first_raise_only:
|
||||
if main_debugger.first_appearance_in_scope(trace):
|
||||
@@ -198,6 +204,12 @@ class PyDBFrame:
|
||||
except:
|
||||
flag = False
|
||||
|
||||
if flag:
|
||||
if exception_breakpoint.expression is not None:
|
||||
handle_breakpoint_expression(exception_breakpoint, info, frame)
|
||||
else:
|
||||
remove_exception_from_frame(frame)
|
||||
|
||||
return flag, frame
|
||||
|
||||
def handle_exception(self, frame, event, arg):
|
||||
|
||||
@@ -29,6 +29,11 @@ class FCode(object):
|
||||
def add_exception_to_frame(frame, exception_info):
|
||||
frame.f_locals['__exception__'] = exception_info
|
||||
|
||||
|
||||
def remove_exception_from_frame(frame):
|
||||
frame.f_locals.pop('__exception__')
|
||||
|
||||
|
||||
FILES_WITH_IMPORT_HOOKS = ['pydev_monkey_qt.py', 'pydev_import_hook.py']
|
||||
|
||||
def just_raised(trace):
|
||||
|
||||
@@ -493,11 +493,26 @@ def process_net_command(py_db, cmd_id, seq, text):
|
||||
pass
|
||||
|
||||
elif cmd_id == CMD_ADD_EXCEPTION_BREAK:
|
||||
condition = None
|
||||
expression = None
|
||||
if text.find('\t') != -1:
|
||||
exception, notify_always, notify_on_terminate, ignore_libraries = text.split('\t', 3)
|
||||
try:
|
||||
exception, condition, expression, notify_always, notify_on_terminate, ignore_libraries = text.split('\t', 5)
|
||||
except:
|
||||
exception, notify_always, notify_on_terminate, ignore_libraries = text.split('\t', 3)
|
||||
else:
|
||||
exception, notify_always, notify_on_terminate, ignore_libraries = text, 0, 0, 0
|
||||
|
||||
condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n').replace("@_@TAB_CHAR@_@", '\t').strip()
|
||||
|
||||
if len(condition) == 0 or condition == "None":
|
||||
condition = None
|
||||
|
||||
expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n').replace("@_@TAB_CHAR@_@", '\t').strip()
|
||||
|
||||
if len(expression) == 0 or expression == "None":
|
||||
expression = None
|
||||
|
||||
if exception.find('-') != -1:
|
||||
breakpoint_type, exception = exception.split('-')
|
||||
else:
|
||||
@@ -508,8 +523,10 @@ def process_net_command(py_db, cmd_id, seq, text):
|
||||
pydev_log.warn("Deprecated parameter: 'notify always' policy removed in PyCharm\n")
|
||||
exception_breakpoint = py_db.add_break_on_exception(
|
||||
exception,
|
||||
condition=condition,
|
||||
expression=expression,
|
||||
notify_always=int(notify_always) > 0,
|
||||
notify_on_terminate = int(notify_on_terminate) == 1,
|
||||
notify_on_terminate=int(notify_on_terminate) == 1,
|
||||
notify_on_first_raise_only=int(notify_always) == 2,
|
||||
ignore_libraries=int(ignore_libraries) > 0
|
||||
)
|
||||
|
||||
@@ -609,6 +609,8 @@ class PyDB:
|
||||
def add_break_on_exception(
|
||||
self,
|
||||
exception,
|
||||
condition,
|
||||
expression,
|
||||
notify_always,
|
||||
notify_on_terminate,
|
||||
notify_on_first_raise_only,
|
||||
@@ -617,6 +619,8 @@ class PyDB:
|
||||
try:
|
||||
eb = ExceptionBreakpoint(
|
||||
exception,
|
||||
condition,
|
||||
expression,
|
||||
notify_always,
|
||||
notify_on_terminate,
|
||||
notify_on_first_raise_only,
|
||||
|
||||
@@ -94,6 +94,21 @@ public abstract class AbstractCommand<T> {
|
||||
|
||||
protected abstract void buildPayload(Payload payload);
|
||||
|
||||
|
||||
@NotNull
|
||||
public static String buildCondition(String expression) {
|
||||
String condition;
|
||||
|
||||
if (expression != null) {
|
||||
condition = expression.replaceAll("\n", NEW_LINE_CHAR);
|
||||
condition = condition.replaceAll("\t", TAB_CHAR);
|
||||
}
|
||||
else {
|
||||
condition = "None";
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
public boolean isResponseExpected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
package com.jetbrains.python.debugger.pydev;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public class AddExceptionBreakpointCommand extends ExceptionBreakpointCommand {
|
||||
final ExceptionBreakpointNotifyPolicy myNotifyPolicy;
|
||||
final String myCondition;
|
||||
final String myLogExpression;
|
||||
|
||||
public AddExceptionBreakpointCommand(@NotNull final RemoteDebugger debugger,
|
||||
@NotNull String exception, @NotNull ExceptionBreakpointNotifyPolicy notifyPolicy) {
|
||||
@NotNull String exception,
|
||||
@Nullable String condition,
|
||||
@Nullable String logExpression,
|
||||
@NotNull ExceptionBreakpointNotifyPolicy notifyPolicy) {
|
||||
super(debugger, ADD_EXCEPTION_BREAKPOINT, exception);
|
||||
myNotifyPolicy = notifyPolicy;
|
||||
myCondition = condition;
|
||||
myLogExpression = logExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void buildPayload(Payload payload) {
|
||||
super.buildPayload(payload);
|
||||
payload.add(myNotifyPolicy.isNotifyOnlyOnFirst() ? 2 : 0)
|
||||
payload.add(buildCondition(myCondition))
|
||||
.add(buildCondition(myLogExpression))
|
||||
.add(myNotifyPolicy.isNotifyOnlyOnFirst() ? 2 : 0)
|
||||
.add(myNotifyPolicy.isNotifyOnTerminate())
|
||||
.add(myNotifyPolicy.isIgnoreLibraries());
|
||||
}
|
||||
|
||||
@@ -23,8 +23,13 @@ public class ExceptionBreakpointCommand extends AbstractCommand {
|
||||
payload.add(myException);
|
||||
}
|
||||
|
||||
public static ExceptionBreakpointCommand addExceptionBreakpointCommand(@NotNull final RemoteDebugger debugger, String exception, AddExceptionBreakpointCommand.ExceptionBreakpointNotifyPolicy notifyPolicy) {
|
||||
return new AddExceptionBreakpointCommand(debugger, exception, notifyPolicy);
|
||||
public static ExceptionBreakpointCommand
|
||||
addExceptionBreakpointCommand(@NotNull final RemoteDebugger debugger,
|
||||
String exception,
|
||||
String condition,
|
||||
String logExpression,
|
||||
AddExceptionBreakpointCommand.ExceptionBreakpointNotifyPolicy notifyPolicy) {
|
||||
return new AddExceptionBreakpointCommand(debugger, exception, condition, logExpression, notifyPolicy);
|
||||
}
|
||||
|
||||
public static ExceptionBreakpointCommand removeExceptionBreakpointCommand(@NotNull final RemoteDebugger debugger, String exception) {
|
||||
|
||||
@@ -40,18 +40,4 @@ public class SetBreakpointCommand extends LineBreakpointCommand {
|
||||
payload.add(buildCondition(myFuncName)).add(mySuspendPolicy.name()).add(buildCondition(myCondition))
|
||||
.add(buildCondition(myLogExpression));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String buildCondition(String expression) {
|
||||
String condition;
|
||||
|
||||
if (expression != null) {
|
||||
condition = expression.replaceAll("\n", NEW_LINE_CHAR);
|
||||
condition = condition.replaceAll("\t", TAB_CHAR);
|
||||
}
|
||||
else {
|
||||
condition = "None";
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jetbrains.python.debugger;
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
|
||||
import com.jetbrains.python.debugger.pydev.ExceptionBreakpointCommandFactory;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
@@ -31,4 +32,10 @@ public abstract class ExceptionBreakpointProperties<T> extends XBreakpointProper
|
||||
}
|
||||
|
||||
public abstract String getExceptionBreakpointId();
|
||||
|
||||
public void setCondition(@Nullable String condition) {
|
||||
}
|
||||
|
||||
public void setLogExpression(@Nullable String condition) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,6 +888,14 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
public void addExceptionBreakpoint(XBreakpoint<? extends ExceptionBreakpointProperties> breakpoint) {
|
||||
myRegisteredExceptionBreakpoints.put(breakpoint.getProperties().getException(), breakpoint);
|
||||
if (isConnected()) {
|
||||
String conditionExpression = breakpoint.getConditionExpression() == null
|
||||
? null
|
||||
: breakpoint.getConditionExpression().getExpression();
|
||||
breakpoint.getProperties().setCondition(conditionExpression);
|
||||
String logExpression = breakpoint.getLogExpressionObject() == null
|
||||
? null
|
||||
: breakpoint.getLogExpressionObject().getExpression();
|
||||
breakpoint.getProperties().setLogExpression(logExpression);
|
||||
myDebugger.addExceptionBreakpoint(breakpoint.getProperties());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.jetbrains.python.debugger.pydev.AddExceptionBreakpointCommand;
|
||||
import com.jetbrains.python.debugger.pydev.ExceptionBreakpointCommand;
|
||||
import com.jetbrains.python.debugger.pydev.RemoteDebugger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
@@ -31,6 +32,8 @@ public class PyExceptionBreakpointProperties extends ExceptionBreakpointProperti
|
||||
public boolean myNotifyOnTerminate;
|
||||
@Attribute("ignoreLibraries")
|
||||
public boolean myIgnoreLibraries;
|
||||
public @Nullable String myCondition;
|
||||
public @Nullable String myLogExpression;
|
||||
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
@@ -41,6 +44,8 @@ public class PyExceptionBreakpointProperties extends ExceptionBreakpointProperti
|
||||
myException = exception;
|
||||
myNotifyOnTerminate = true;
|
||||
myIgnoreLibraries = false;
|
||||
myCondition = null;
|
||||
myLogExpression = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,13 +85,34 @@ public class PyExceptionBreakpointProperties extends ExceptionBreakpointProperti
|
||||
return myIgnoreLibraries;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getCondition() {
|
||||
return myCondition;
|
||||
}
|
||||
|
||||
public void setCondition(@Nullable String condition) {
|
||||
myCondition = condition;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLogExpression() {
|
||||
return myLogExpression;
|
||||
}
|
||||
|
||||
public void setLogExpression(@Nullable String logExpression) {
|
||||
myLogExpression = logExpression;
|
||||
}
|
||||
|
||||
public String getExceptionBreakpointId() {
|
||||
return "python-" + myException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExceptionBreakpointCommand createAddCommand(RemoteDebugger debugger) {
|
||||
return ExceptionBreakpointCommand.addExceptionBreakpointCommand(debugger, getExceptionBreakpointId(),
|
||||
return ExceptionBreakpointCommand.addExceptionBreakpointCommand(debugger,
|
||||
getExceptionBreakpointId(),
|
||||
getCondition(),
|
||||
getLogExpression(),
|
||||
new AddExceptionBreakpointCommand.ExceptionBreakpointNotifyPolicy(
|
||||
isNotifyOnTerminate(), isNotifyOnlyOnFirst(), isIgnoreLibraries()));
|
||||
}
|
||||
|
||||
@@ -33,9 +33,11 @@ import com.intellij.xdebugger.XDebuggerManager;
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpoint;
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpointType;
|
||||
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
|
||||
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -138,6 +140,13 @@ public class PyExceptionBreakpointType
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public XDebuggerEditorsProvider getEditorsProvider(@NotNull XBreakpoint<PyExceptionBreakpointProperties> breakpoint,
|
||||
@NotNull Project project) {
|
||||
return new PyDebuggerEditorsProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public XBreakpoint<PyExceptionBreakpointProperties> createDefaultBreakpoint(@NotNull XBreakpointCreator<PyExceptionBreakpointProperties> creator) {
|
||||
final XBreakpoint<PyExceptionBreakpointProperties> breakpoint = creator.createBreakpoint(createDefaultBreakpointProperties());
|
||||
|
||||
Reference in New Issue
Block a user