def _get_buffer(self, **kw): if kw.get("color", True): normalize_color = lambda x: x else: normalize_color = uncolored def _format_context(context): if not isinstance(context, dict): return repr(context) # when it comes from rpyc context = context.copy() context.pop("indentation", None) breadcrumbs = ";".join(context.pop('context', [])) return ", ".join( filter( None, chain((breadcrumbs, ), ("%s=%s" % p for p in sorted(context.items()))))) buff = IndentableTextBuffer("{0.__class__.__qualname__}", self) if self.message: buff.write(normalize_color("WHITE<<%s>>" % self.message)) traceback_fmt = normalize_color("DARK_GRAY<<{}>>") # workaround incompatibilty with rpyc, which serializes .actual into an str # instead of a list of exceptions. This makes the string flatten into a long # and incomprehensible text buffer. if hasattr(self, "_remote_tb"): with buff.indent("Remote Traceback:"): buff.write(self._remote_tb) return buff def add_details(exc): if kw.get("timestamp", True) and getattr(exc, "timestamp", None): ts = datetime.fromtimestamp(exc.timestamp).isoformat() buff.write(normalize_color("MAGENTA<<Timestamp: %s>>" % ts)) if kw.get("context", True) and getattr(exc, "context", None): buff.write("Context: %s" % _format_context(exc.context)) add_details(self) for exc in self.actual: with buff.indent("{.__class__.__qualname__}", exc): if isinstance(exc, MultiException): buff.extend(exc._get_buffer(**kw)) elif callable(getattr(exc, "render", None)): buff.write(exc.render(**kw)) else: buff.write("{}", exc) add_details(exc) if hasattr(exc, "__traceback__"): show_traceback = getattr(exc, 'traceback', None) if show_traceback is not False: buff.write("Traceback:") for line in format_tb(exc.__traceback__): buff.write(traceback_fmt, line.rstrip()) return buff
def _get_buffer(self, **kw): color = kw.get("color", True) buff = IndentableTextBuffer("{0.__class__.__qualname__}", self) if self.message: buff.write(("WHITE<<%s>>" % self.message) if color else self.message) traceback_fmt = "DARK_GRAY@{{{}}}@" if color else "{}" # workaround incompatibilty with rpyc, which serializes .actual into an str # instead of a list of exceptions. This makes the string flatten into a long # and incomprehensible text buffer. if hasattr(self, "_remote_tb"): with buff.indent("Remote Traceback:"): buff.write(self._remote_tb) return buff for exc in self.actual: with buff.indent("{.__class__.__qualname__}", exc): if isinstance(exc, self.__class__): buff.extend(exc._get_buffer(**kw)) elif hasattr(exc, "render"): buff.write(exc.render(**kw)) else: if not hasattr(exc, "context"): context = "" elif not isinstance(exc.context, dict): context = repr(exc) else: context = exc.context.copy() context.pop("indentation", None) if 'context' in context: # 'context' should be renamed 'breadcrumbs' context['context'] = ";".join(context['context']) context = "(%s)" % ", ".join("%s=%s" % p for p in sorted(context.items())) buff.write("{}: {}", exc, context) if hasattr(exc, "__traceback__"): show_traceback = getattr(exc, 'traceback', None) if show_traceback != False: for line in format_tb(exc.__traceback__): buff.write(traceback_fmt, line.rstrip()) return buff