diff --git a/python/helpers/pydev/pydevd.py b/python/helpers/pydev/pydevd.py index b2d22bd317e0..1fc7b81bc34a 100644 --- a/python/helpers/pydev/pydevd.py +++ b/python/helpers/pydev/pydevd.py @@ -394,6 +394,18 @@ class PyDB: return False return True + def first_appearance_in_scope(self, trace): + if trace is None or self.not_in_scope(trace.tb_frame.f_code.co_filename): + return False + else: + trace = trace.tb_next + while trace is not None: + frame = trace.tb_frame + if not self.not_in_scope(frame.f_code.co_filename): + return False + trace = trace.tb_next + return True + def haveAliveThreads(self): for t in threadingEnumerate(): if getattr(t, 'is_pydev_daemon_thread', False): @@ -1146,6 +1158,8 @@ class PyDB: type = 'python' if type == 'python': + if int(notify_always) == 1: + pydev_log.warn("Deprecated parameter: 'notify always' policy removed in PyCharm\n") exception_breakpoint = self.add_break_on_exception( exception, notify_always=int(notify_always) > 0, diff --git a/python/helpers/pydev/pydevd_frame.py b/python/helpers/pydev/pydevd_frame.py index e5a942c75775..6014e146599f 100644 --- a/python/helpers/pydev/pydevd_frame.py +++ b/python/helpers/pydev/pydevd_frame.py @@ -74,18 +74,22 @@ class PyDBFrame: exception, mainDebugger.break_on_caught_exceptions) if exception_breakpoint is not None: - if not exception_breakpoint.notify_on_first_raise_only or just_raised(trace): - # print frame.f_code.co_name - if exception_breakpoint.ignore_libraries: - if mainDebugger.not_in_scope(frame.f_code.co_filename): + if exception_breakpoint.ignore_libraries: + if exception_breakpoint.notify_on_first_raise_only: + if mainDebugger.first_appearance_in_scope(trace): + add_exception_to_frame(frame, (exception, value, trace)) + thread.additionalInfo.message = exception_breakpoint.qname + flag = True + else: pydev_log.debug("Ignore exception %s in library %s" % (exception, frame.f_code.co_filename)) - return False, frame - - add_exception_to_frame(frame, (exception, value, trace)) - thread.additionalInfo.message = exception_breakpoint.qname - flag = True + flag = False else: - flag = False + if not exception_breakpoint.notify_on_first_raise_only or just_raised(trace): + add_exception_to_frame(frame, (exception, value, trace)) + thread.additionalInfo.message = exception_breakpoint.qname + flag = True + else: + flag = False else: try: if mainDebugger.plugin is not None: diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AddExceptionBreakpointCommand.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AddExceptionBreakpointCommand.java index b79a220b26d5..8be639cea4ef 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AddExceptionBreakpointCommand.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AddExceptionBreakpointCommand.java @@ -17,29 +17,23 @@ public class AddExceptionBreakpointCommand extends ExceptionBreakpointCommand { @Override protected void buildPayload(Payload payload) { super.buildPayload(payload); - payload.add(myNotifyPolicy.isNotifyAlways() ? 1 : myNotifyPolicy.isNotifyOnlyOnFirst() ? 2 : 0) + payload.add(myNotifyPolicy.isNotifyOnlyOnFirst() ? 2 : 0) .add(myNotifyPolicy.isNotifyOnTerminate()) .add(myNotifyPolicy.isIgnoreLibraries()); } public static class ExceptionBreakpointNotifyPolicy { - private final boolean myNotifyAlways; private final boolean myNotifyOnTerminate; private final boolean myNotifyOnlyOnFirst; private final boolean myIgnoreLibraries; - public ExceptionBreakpointNotifyPolicy(boolean notifyAlways, boolean notifyOnTerminate, boolean notifyOnlyOnFirst, + public ExceptionBreakpointNotifyPolicy(boolean notifyOnTerminate, boolean notifyOnlyOnFirst, boolean ignoreLibraries) { - myNotifyAlways = notifyAlways; myNotifyOnTerminate = notifyOnTerminate; myNotifyOnlyOnFirst = notifyOnlyOnFirst; myIgnoreLibraries = ignoreLibraries; } - public boolean isNotifyAlways() { - return myNotifyAlways; - } - public boolean isNotifyOnTerminate() { return myNotifyOnTerminate; } diff --git a/python/src/com/jetbrains/python/debugger/PyExceptionBreakpointProperties.java b/python/src/com/jetbrains/python/debugger/PyExceptionBreakpointProperties.java index 099d6d0811a2..e4a56d652f5e 100644 --- a/python/src/com/jetbrains/python/debugger/PyExceptionBreakpointProperties.java +++ b/python/src/com/jetbrains/python/debugger/PyExceptionBreakpointProperties.java @@ -25,8 +25,6 @@ import org.jetbrains.annotations.NotNull; * @author traff */ public class PyExceptionBreakpointProperties extends ExceptionBreakpointProperties { - @Attribute("notifyAlways") - public boolean myNotifyAlways; @Attribute("notifyOnlyOnFirst") public boolean myNotifyOnlyOnFirst; @Attribute("notifyOnTerminate") @@ -53,7 +51,6 @@ public class PyExceptionBreakpointProperties extends ExceptionBreakpointProperti @Override public void loadState(final PyExceptionBreakpointProperties state) { myException = state.myException; - myNotifyAlways = state.myNotifyAlways; myNotifyOnlyOnFirst = state.myNotifyOnlyOnFirst; myNotifyOnTerminate = state.myNotifyOnTerminate; myIgnoreLibraries = state.myIgnoreLibraries; @@ -67,14 +64,6 @@ public class PyExceptionBreakpointProperties extends ExceptionBreakpointProperti myNotifyOnTerminate = notifyOnTerminate; } - public boolean isNotifyAlways() { - return myNotifyAlways; - } - - public void setNotifyAlways(boolean notifyAlways) { - myNotifyAlways = notifyAlways; - } - public boolean isNotifyOnlyOnFirst() { return myNotifyOnlyOnFirst; } @@ -99,7 +88,6 @@ public class PyExceptionBreakpointProperties extends ExceptionBreakpointProperti public ExceptionBreakpointCommand createAddCommand(RemoteDebugger debugger) { return ExceptionBreakpointCommand.addExceptionBreakpointCommand(debugger, getExceptionBreakpointId(), new AddExceptionBreakpointCommand.ExceptionBreakpointNotifyPolicy( - isNotifyAlways(), isNotifyOnTerminate(), isNotifyOnlyOnFirst(), isIgnoreLibraries())); } diff --git a/python/src/com/jetbrains/python/debugger/PyExceptionBreakpointType.java b/python/src/com/jetbrains/python/debugger/PyExceptionBreakpointType.java index 4b06475ad718..6427c2afe0f9 100644 --- a/python/src/com/jetbrains/python/debugger/PyExceptionBreakpointType.java +++ b/python/src/com/jetbrains/python/debugger/PyExceptionBreakpointType.java @@ -155,8 +155,7 @@ public class PyExceptionBreakpointType private static PyExceptionBreakpointProperties createDefaultBreakpointProperties() { PyExceptionBreakpointProperties p = new PyExceptionBreakpointProperties(BASE_EXCEPTION); p.setNotifyOnTerminate(true); - p.setNotifyAlways(false); - p.setNotifyAlways(false); + p.setNotifyOnlyOnFirst(false); return p; } @@ -168,45 +167,28 @@ public class PyExceptionBreakpointType private static class PyExceptionBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPanel> { - private JCheckBox myIgnoreLibrariesCheckBox; private JCheckBox myNotifyOnTerminateCheckBox; private JCheckBox myNotifyOnRaiseCheckBox; - private JRadioButton myAlwaysRadio; - private JRadioButton myOnlyOnFirstRadio; + private JCheckBox myIgnoreLibrariesCheckBox; @NotNull @Override public JComponent getComponent() { - myIgnoreLibrariesCheckBox = new JCheckBox("Ignore library files"); myNotifyOnTerminateCheckBox = new JCheckBox("On termination"); myNotifyOnRaiseCheckBox = new JCheckBox("On raise"); - myAlwaysRadio = new JRadioButton("At each level of call chain"); - myOnlyOnFirstRadio = new JRadioButton("At top of call chain"); - - ButtonGroup group = new ButtonGroup(); - group.add(myAlwaysRadio); - group.add(myOnlyOnFirstRadio); + myIgnoreLibrariesCheckBox = new JCheckBox("Ignore library files"); Box notificationsBox = Box.createVerticalBox(); JPanel panel = new JPanel(new BorderLayout()); - panel.add(myIgnoreLibrariesCheckBox, BorderLayout.NORTH); - notificationsBox.add(panel); - panel = new JPanel(new BorderLayout()); panel.add(myNotifyOnTerminateCheckBox, BorderLayout.NORTH); notificationsBox.add(panel); panel = new JPanel(new BorderLayout()); panel.add(myNotifyOnRaiseCheckBox, BorderLayout.NORTH); notificationsBox.add(panel); panel = new JPanel(new BorderLayout()); - EmptyBorder border = new EmptyBorder(0, 20, 0, 0); - panel.setBorder(border); - panel.add(myAlwaysRadio, BorderLayout.NORTH); - panel.add(myOnlyOnFirstRadio, BorderLayout.CENTER); - - + panel.add(myIgnoreLibrariesCheckBox, BorderLayout.NORTH); notificationsBox.add(panel); - panel = new JPanel(new BorderLayout()); JPanel innerPanel = new JPanel(new BorderLayout()); innerPanel.add(notificationsBox, BorderLayout.CENTER); @@ -215,58 +197,21 @@ public class PyExceptionBreakpointType panel.add(innerPanel, BorderLayout.NORTH); panel.setBorder(IdeBorderFactory.createTitledBorder("Activation policy", true)); - ActionListener listener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - setRadioButtonsEnabled(); - } - }; - - myNotifyOnRaiseCheckBox.addActionListener(listener); - - setRadioButtonsEnabled(); - return panel; } - private void setRadioButtonsEnabled() { - setRadioButtonsEnabled(myNotifyOnRaiseCheckBox.isSelected()); - } - - private void setNotifyOnRaiseSelected(boolean selected) { - myNotifyOnRaiseCheckBox.setSelected(selected); - setRadioButtonsEnabled(selected); - } - - private void setRadioButtonsEnabled(boolean selected) { - myAlwaysRadio.setEnabled(selected); - myOnlyOnFirstRadio.setEnabled(selected); - if (selected && !(myAlwaysRadio.isSelected() || myOnlyOnFirstRadio.isSelected())) { - myAlwaysRadio.setSelected(true); - } - } - @Override public void saveTo(@NotNull XBreakpoint breakpoint) { - breakpoint.getProperties().setIgnoreLibraries(myIgnoreLibrariesCheckBox.isSelected()); breakpoint.getProperties().setNotifyOnTerminate(myNotifyOnTerminateCheckBox.isSelected()); - - breakpoint.getProperties().setNotifyAlways(myNotifyOnRaiseCheckBox.isSelected() && myAlwaysRadio.isSelected()); - breakpoint.getProperties().setNotifyOnlyOnFirst(myNotifyOnRaiseCheckBox.isSelected() && myOnlyOnFirstRadio.isSelected()); + breakpoint.getProperties().setNotifyOnlyOnFirst(myNotifyOnRaiseCheckBox.isSelected()); + breakpoint.getProperties().setIgnoreLibraries(myIgnoreLibrariesCheckBox.isSelected()); } @Override public void loadFrom(@NotNull XBreakpoint breakpoint) { myIgnoreLibrariesCheckBox.setSelected(breakpoint.getProperties().isIgnoreLibraries()); myNotifyOnTerminateCheckBox.setSelected(breakpoint.getProperties().isNotifyOnTerminate()); - - boolean always = breakpoint.getProperties().isNotifyAlways(); - boolean onFirst = breakpoint.getProperties().isNotifyOnlyOnFirst(); - - setNotifyOnRaiseSelected(always || onFirst); - - myAlwaysRadio.setSelected(always); - myOnlyOnFirstRadio.setSelected(onFirst); + myNotifyOnRaiseCheckBox.setSelected(breakpoint.getProperties().isNotifyOnlyOnFirst()); } } } diff --git a/python/testSrc/com/jetbrains/env/python/PythonDebuggerTest.java b/python/testSrc/com/jetbrains/env/python/PythonDebuggerTest.java index d1d93db199e9..0cc86d63eea9 100644 --- a/python/testSrc/com/jetbrains/env/python/PythonDebuggerTest.java +++ b/python/testSrc/com/jetbrains/env/python/PythonDebuggerTest.java @@ -324,7 +324,7 @@ public class PythonDebuggerTest extends PyEnvTestCase { runPythonTest(new PyDebuggerTask("/debug", "test_exceptbreak.py") { @Override public void before() throws Exception { - createExceptionBreakZeroDivisionError(myFixture, true, false, false, false); + createExceptionBreakZeroDivisionError(myFixture, true, false, false); } @Override @@ -344,7 +344,6 @@ public class PythonDebuggerTest extends PyEnvTestCase { private static void createExceptionBreakZeroDivisionError(IdeaProjectTestFixture fixture, boolean notifyOnTerminate, - boolean notifyAlways, boolean notifyOnFirst, boolean ignoreLibraries) { XDebuggerTestUtil.removeAllBreakpoints(fixture.getProject()); @@ -352,49 +351,21 @@ public class PythonDebuggerTest extends PyEnvTestCase { PyExceptionBreakpointProperties properties = new PyExceptionBreakpointProperties("exceptions.ZeroDivisionError"); properties.setNotifyOnTerminate(notifyOnTerminate); - properties.setNotifyAlways(notifyAlways); properties.setNotifyOnlyOnFirst(notifyOnFirst); properties.setIgnoreLibraries(ignoreLibraries); addExceptionBreakpoint(fixture, properties); properties = new PyExceptionBreakpointProperties("builtins.ZeroDivisionError"); //for python 3 properties.setNotifyOnTerminate(notifyOnTerminate); - properties.setNotifyAlways(notifyAlways); properties.setNotifyOnlyOnFirst(notifyOnFirst); properties.setIgnoreLibraries(ignoreLibraries); addExceptionBreakpoint(fixture, properties); } - public void testExceptionBreakpointAlways() throws Exception { - runPythonTest(new PyDebuggerTask("/debug", "test_exceptbreak.py") { - @Override - public void before() throws Exception { - createExceptionBreakZeroDivisionError(myFixture, false, true, false, false); - } - - @Override - public void testing() throws Exception { - waitForPause(); - eval("__exception__[0].__name__").hasValue("'ZeroDivisionError'"); - resume(); - waitForPause(); - resume(); - waitForPause(); - resume(); - waitForTerminate(); - } - - @Override - public Set getTags() { - return ImmutableSet.of("-pypy"); //TODO: fix it for Pypy - } - }); - } - public void testExceptionBreakpointOnFirstRaise() throws Exception { runPythonTest(new PyDebuggerTask("/debug", "test_exceptbreak.py") { @Override public void before() throws Exception { - createExceptionBreakZeroDivisionError(myFixture, false, false, true, false); + createExceptionBreakZeroDivisionError(myFixture, false, true, false); } @Override @@ -414,7 +385,6 @@ public class PythonDebuggerTest extends PyEnvTestCase { private static void createExceptionBreak(IdeaProjectTestFixture fixture, boolean notifyOnTerminate, - boolean notifyAlways, boolean notifyOnFirst, boolean ignoreLibraries) { XDebuggerTestUtil.removeAllBreakpoints(fixture.getProject()); @@ -422,7 +392,6 @@ public class PythonDebuggerTest extends PyEnvTestCase { PyExceptionBreakpointProperties properties = new PyExceptionBreakpointProperties("BaseException"); properties.setNotifyOnTerminate(notifyOnTerminate); - properties.setNotifyAlways(notifyAlways); properties.setNotifyOnlyOnFirst(notifyOnFirst); properties.setIgnoreLibraries(ignoreLibraries); addExceptionBreakpoint(fixture, properties); @@ -432,7 +401,7 @@ public class PythonDebuggerTest extends PyEnvTestCase { runPythonTest(new PyDebuggerTask("/debug", "test_ignore_lib.py") { @Override public void before() throws Exception { - createExceptionBreak(myFixture, false, true, false, true); + createExceptionBreak(myFixture, false, true, true); } @Override @@ -454,7 +423,7 @@ public class PythonDebuggerTest extends PyEnvTestCase { runPythonTest(new PyDebuggerTask("/debug", "test_ignore_lib.py") { @Override public void before() throws Exception { - createExceptionBreak(myFixture, true, false, false, true); + createExceptionBreak(myFixture, true, false, true); } @Override