diff options
Diffstat (limited to 'python/helpers/pydev/pydevd_breakpoints.py')
-rw-r--r-- | python/helpers/pydev/pydevd_breakpoints.py | 141 |
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) |