def __init__(self, exc_value=None, exc_type=None, exc_tb=None): """ Initialize me with an explanation of the error. By default, this will use the current C{exception} (L{sys.exc_info}()). However, if you want to specify a particular kind of failure, you can pass an exception as an argument. If no C{exc_value} is passed, then an "original" C{Failure} will be searched for. If the current exception handler that this C{Failure} is being constructed in is handling an exception raised by L{raiseException}, then this C{Failure} will act like the original C{Failure}. For C{exc_tb} only L{traceback} instances or C{None} are allowed. If C{None} is supplied for C{exc_value}, the value of C{exc_tb} is ignored, otherwise if C{exc_tb} is C{None}, it will be found from execution context (ie, L{sys.exc_info}). """ global count count = count + 1 self.count = count self.type = self.value = tb = None #strings Exceptions/Failures are bad, mmkay? if isinstance(exc_value, (str, unicode)) and exc_type is None: import warnings warnings.warn( "Don't pass strings (like %r) to failure.Failure (replacing with a DefaultException)." % exc_value, DeprecationWarning, stacklevel=2) exc_value = DefaultException(exc_value) stackOffset = 0 if exc_value is None: exc_value = self._findFailure() if exc_value is None: self.type, self.value, tb = sys.exc_info() if self.type is None: raise NoCurrentExceptionError() stackOffset = 1 elif exc_type is None: if isinstance(exc_value, Exception): self.type = exc_value.__class__ else: #allow arbitrary objects. self.type = type(exc_value) self.value = exc_value else: self.type = exc_type self.value = exc_value if isinstance(self.value, Failure): self.__dict__ = self.value.__dict__ return if tb is None: if exc_tb: tb = exc_tb # else: # log.msg("Erf, %r created with no traceback, %s %s." % ( # repr(self), repr(exc_value), repr(exc_type))) # for s in traceback.format_stack(): # log.msg(s) frames = self.frames = [] stack = self.stack = [] # added 2003-06-23 by Chris Armstrong. Yes, I actually have a # use case where I need this traceback object, and I've made # sure that it'll be cleaned up. self.tb = tb if tb: f = tb.tb_frame elif not isinstance(self.value, Failure): # we don't do frame introspection since it's expensive, # and if we were passed a plain exception with no # traceback, it's not useful anyway f = stackOffset = None while stackOffset and f: # This excludes this Failure.__init__ frame from the # stack, leaving it to start with our caller instead. f = f.f_back stackOffset -= 1 # Keeps the *full* stack. Formerly in spread.pb.print_excFullStack: # # The need for this function arises from the fact that several # PB classes have the peculiar habit of discarding exceptions # with bareword "except:"s. This premature exception # catching means tracebacks generated here don't tend to show # what called upon the PB object. while f: localz = f.f_locals.copy() if f.f_locals is f.f_globals: globalz = {} else: globalz = f.f_globals.copy() for d in globalz, localz: if d.has_key("__builtins__"): del d["__builtins__"] stack.insert(0, [ f.f_code.co_name, f.f_code.co_filename, f.f_lineno, localz.items(), globalz.items(), ]) f = f.f_back while tb is not None: f = tb.tb_frame localz = f.f_locals.copy() if f.f_locals is f.f_globals: globalz = {} else: globalz = f.f_globals.copy() for d in globalz, localz: if d.has_key("__builtins__"): del d["__builtins__"] frames.append([ f.f_code.co_name, f.f_code.co_filename, tb.tb_lineno, localz.items(), globalz.items(), ]) tb = tb.tb_next if inspect.isclass(self.type) and issubclass(self.type, Exception): parentCs = reflect.allYourBase(self.type) self.parents = map(reflect.qual, parentCs) self.parents.append(reflect.qual(self.type)) else: self.parents = [self.type]
def _aybabtu(c): l = [] for b in reflect.allYourBase(c, Versioned): if b not in l and b is not Versioned: l.append(b) return l