summaryrefslogtreecommitdiff
path: root/python/helpers/pydev/pydevd_breakpoints.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/helpers/pydev/pydevd_breakpoints.py')
-rw-r--r--python/helpers/pydev/pydevd_breakpoints.py141
1 files changed, 51 insertions, 90 deletions
diff --git a/python/helpers/pydev/pydevd_breakpoints.py b/python/helpers/pydev/pydevd_breakpoints.py
index beebebf4abed..82a230db2f47 100644
--- a/python/helpers/pydev/pydevd_breakpoints.py
+++ b/python/helpers/pydev/pydevd_breakpoints.py
@@ -2,14 +2,12 @@ from pydevd_constants import *
import pydevd_tracing
import sys
import pydev_log
+import pydevd_import_class
_original_excepthook = None
_handle_exceptions = None
-NOTIFY_ALWAYS="NOTIFY_ALWAYS"
-NOTIFY_ON_TERMINATE="NOTIFY_ON_TERMINATE"
-
if USE_LIB_COPY:
import _pydev_threading as threading
else:
@@ -20,52 +18,39 @@ threadingCurrentThread = threading.currentThread
from pydevd_comm import GetGlobalDebugger
class ExceptionBreakpoint:
- def __init__(self, qname, notify_always, notify_on_terminate):
- exctype = get_class(qname)
+
+ def __init__(
+ self,
+ qname,
+ notify_always,
+ notify_on_terminate,
+ notify_on_first_raise_only,
+ ):
+ exctype = _get_class(qname)
self.qname = qname
if exctype is not None:
self.name = exctype.__name__
else:
self.name = None
- self.notify_on_terminate = int(notify_on_terminate) == 1
- self.notify_always = int(notify_always) > 0
- self.notify_on_first_raise_only = int(notify_always) == 2
+ self.notify_on_terminate = notify_on_terminate
+ self.notify_always = notify_always
+ self.notify_on_first_raise_only = notify_on_first_raise_only
self.type = exctype
- self.notify = {NOTIFY_ALWAYS: self.notify_always, NOTIFY_ON_TERMINATE: self.notify_on_terminate}
def __str__(self):
return self.qname
class LineBreakpoint:
- def __init__(self, type, flag, condition, func_name, expression):
- self.type = type
+
+ def __init__(self, line, condition, func_name, expression):
+ self.line = line
self.condition = condition
self.func_name = func_name
self.expression = expression
- def get_break_dict(self, breakpoints, file):
- if DictContains(breakpoints, file):
- breakDict = breakpoints[file]
- else:
- breakDict = {}
- breakpoints[file] = breakDict
- return breakDict
-
- def trace(self, file, line, func_name):
- if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
- pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n' % (file, line, func_name))
- sys.stderr.flush()
-
- def add(self, breakpoints, file, line, func_name):
- self.trace(file, line, func_name)
-
- breakDict = self.get_break_dict(breakpoints, file)
-
- breakDict[line] = self
-
def get_exception_full_qname(exctype):
if not exctype:
return None
@@ -77,41 +62,41 @@ def get_exception_name(exctype):
return exctype.__name__
-def get_exception_breakpoint(exctype, exceptions, notify_class):
- name = get_exception_full_qname(exctype)
+def get_exception_breakpoint(exctype, exceptions):
+ exception_full_qname = get_exception_full_qname(exctype)
+
exc = None
if exceptions is not None:
- for k, e in exceptions.items():
- if e.notify[notify_class]:
- if name == k:
- return e
- if (e.type is not None and issubclass(exctype, e.type)):
- if exc is None or issubclass(e.type, exc.type):
- exc = e
+ try:
+ return exceptions[exception_full_qname]
+ except KeyError:
+ for exception_breakpoint in DictIterValues(exceptions):
+ if exception_breakpoint.type is not None and issubclass(exctype, exception_breakpoint.type):
+ if exc is None or issubclass(exception_breakpoint.type, exc.type):
+ exc = exception_breakpoint
return exc
#=======================================================================================================================
-# excepthook
+# _excepthook
#=======================================================================================================================
-def excepthook(exctype, value, tb):
+def _excepthook(exctype, value, tb):
global _handle_exceptions
- if _handle_exceptions is not None:
- exception_breakpoint = get_exception_breakpoint(exctype, _handle_exceptions, NOTIFY_ON_TERMINATE)
+ if _handle_exceptions:
+ exception_breakpoint = get_exception_breakpoint(exctype, _handle_exceptions)
else:
exception_breakpoint = None
- if exception_breakpoint is None:
- return _original_excepthook(exctype, value, tb)
-
#Always call the original excepthook before going on to call the debugger post mortem to show it.
_original_excepthook(exctype, value, tb)
+ if not exception_breakpoint:
+ return
+
if tb is None: #sometimes it can be None, e.g. with GTK
- return
+ return
frames = []
- traceback = tb
while tb:
frames.append(tb.tb_frame)
tb = tb.tb_next
@@ -122,9 +107,7 @@ def excepthook(exctype, value, tb):
thread.additionalInfo.exception = (exctype, value, tb)
thread.additionalInfo.pydev_force_stop_at_exception = (frame, frames_byid)
thread.additionalInfo.message = exception_breakpoint.qname
- #sys.exc_info = lambda : (exctype, value, traceback)
debugger = GetGlobalDebugger()
- debugger.force_post_mortem_stop += 1
pydevd_tracing.SetTrace(None) #no tracing from here
@@ -133,38 +116,27 @@ def excepthook(exctype, value, tb):
debugger.handle_post_mortem_stop(thread.additionalInfo, thread)
#=======================================================================================================================
-# set_pm_excepthook
+# _set_pm_excepthook
#=======================================================================================================================
-def set_pm_excepthook(handle_exceptions_arg=None):
+def _set_pm_excepthook(handle_exceptions_dict=None):
'''
Should be called to register the excepthook to be used.
- It's only useful for uncaucht exceptions. I.e.: exceptions that go up to the excepthook.
-
- Can receive a parameter to stop only on some exceptions.
-
- E.g.:
- register_excepthook((IndexError, ValueError))
-
- or
+ It's only useful for uncaught exceptions. I.e.: exceptions that go up to the excepthook.
- register_excepthook(IndexError)
-
- if passed without a parameter, will break on any exception
-
- @param handle_exceptions: exception or tuple(exceptions)
+ @param handle_exceptions: dict(exception -> ExceptionBreakpoint)
The exceptions that should be handled.
'''
global _handle_exceptions
global _original_excepthook
- if sys.excepthook != excepthook:
- #Only keep the original if it's not our own excepthook (if called many times).
+ if sys.excepthook != _excepthook:
+ #Only keep the original if it's not our own _excepthook (if called many times).
_original_excepthook = sys.excepthook
- _handle_exceptions = handle_exceptions_arg
- sys.excepthook = excepthook
+ _handle_exceptions = handle_exceptions_dict
+ sys.excepthook = _excepthook
-def restore_pm_excepthook():
+def _restore_pm_excepthook():
global _original_excepthook
if _original_excepthook:
sys.excepthook = _original_excepthook
@@ -172,27 +144,16 @@ def restore_pm_excepthook():
def update_exception_hook(dbg):
- if dbg.exception_set:
- set_pm_excepthook(dict(dbg.exception_set))
+ if dbg.break_on_uncaught_exceptions:
+ _set_pm_excepthook(dbg.break_on_uncaught_exceptions)
else:
- restore_pm_excepthook()
+ _restore_pm_excepthook()
-def get_class( kls ):
+def _get_class( kls ):
if IS_PY24 and "BaseException" == kls:
kls = "Exception"
- parts = kls.split('.')
- module = ".".join(parts[:-1])
- if module == "":
- if IS_PY3K:
- module = "builtins"
- else:
- module = "__builtin__"
+
try:
- m = __import__( module )
- for comp in parts[-1:]:
- if m is None:
- return None
- m = getattr(m, comp, None)
- return m
- except ImportError:
- return None \ No newline at end of file
+ return eval(kls)
+ except:
+ return pydevd_import_class.ImportName(kls)