Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Delgan committed Sep 7, 2023
1 parent 5c7bc8b commit 085122a
Show file tree
Hide file tree
Showing 12 changed files with 1,052 additions and 10 deletions.
80 changes: 70 additions & 10 deletions loguru/_better_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@
import tokenize
import traceback

if sys.version_info >= (3, 11):

def is_exception_group(exc):
return isinstance(exc, ExceptionGroup)

else:

def is_exception_group(exc):
return False


class SyntaxHighlighter:
_default_style = {
Expand Down Expand Up @@ -344,7 +354,9 @@ def _format_locations(self, frames_lines, *, has_introduction):

yield frame

def _format_exception(self, value, tb, *, seen=None, is_first=False, from_decorator=False):
def _format_exception(
self, value, tb, *, seen=None, is_first=False, from_decorator=False, group_nesting=0
):
# Implemented from built-in traceback module:
# https://github.com/python/cpython/blob/a5b76167/Lib/traceback.py#L468
exc_type, exc_value, exc_traceback = type(value), value, tb
Expand All @@ -354,36 +366,50 @@ def _format_exception(self, value, tb, *, seen=None, is_first=False, from_decora

seen.add(id(exc_value))

def indent(text):
if group_nesting == 0:
yield text
return
for line in text.splitlines(True):
indented = " " * group_nesting + "| " + line
yield indented.rstrip() + "\n"

if exc_value:
if exc_value.__cause__ is not None and id(exc_value.__cause__) not in seen:
for text in self._format_exception(
exc_value.__cause__, exc_value.__cause__.__traceback__, seen=seen
exc_value.__cause__,
exc_value.__cause__.__traceback__,
seen=seen,
group_nesting=group_nesting,
):
yield text
cause = "The above exception was the direct cause of the following exception:"
if self._colorize:
cause = self._theme["cause"].format(cause)
if self._diagnose:
yield "\n\n" + cause + "\n\n\n"
yield from indent("\n\n" + cause + "\n\n\n")
else:
yield "\n" + cause + "\n\n"
yield from indent("\n" + cause + "\n\n")

elif (
exc_value.__context__ is not None
and id(exc_value.__context__) not in seen
and not exc_value.__suppress_context__
):
for text in self._format_exception(
exc_value.__context__, exc_value.__context__.__traceback__, seen=seen
exc_value.__context__,
exc_value.__context__.__traceback__,
seen=seen,
group_nesting=group_nesting,
):
yield text
context = "During handling of the above exception, another exception occurred:"
if self._colorize:
context = self._theme["context"].format(context)
if self._diagnose:
yield "\n\n" + context + "\n\n\n"
yield from indent("\n\n" + context + "\n\n\n")
else:
yield "\n" + context + "\n\n"
yield from indent("\n" + context + "\n\n")

try:
tracebacklimit = sys.tracebacklimit
Expand Down Expand Up @@ -426,12 +452,46 @@ def _format_exception(self, value, tb, *, seen=None, is_first=False, from_decora
yield self._prefix

if has_introduction:
introduction = "Traceback (most recent call last):"
if is_exception_group(value):
introduction = "Exception Group Traceback (most recent call last):"
else:
introduction = "Traceback (most recent call last):"
if self._colorize:
introduction = self._theme["introduction"].format(introduction)
yield introduction + "\n"
if is_exception_group(value) and group_nesting == 0:
yield " + " + introduction + "\n"
else:
yield from indent(introduction + "\n")

if is_exception_group(value) and group_nesting == 0:
group_nesting = 1

yield "".join(frames_lines)
if group_nesting <= 10 or not is_exception_group(value):
yield from indent("".join(frames_lines))

if is_exception_group(value):
if group_nesting > 10:
yield " " * (group_nesting) + "| ... (max_group_depth is 10)\n"
else:
for n, exc in enumerate(value.exceptions, start=1):
pref = "+-+" if n == 1 else " +"
if n > 15:
yield " " * (group_nesting) + pref + " ... ".center(35, "-") + "\n"
yield " " * (group_nesting) + " | and %d more exceptions\n" % (
len(value.exceptions) - 15
)
break
yield " " * (group_nesting) + pref + (" %d " % n).center(35, "-") + "\n"
lines = self._format_exception(
exc,
exc.__traceback__,
seen=seen,
group_nesting=group_nesting + 1,
)
yield "".join(lines)

if not is_exception_group(exc) or group_nesting == 10:
yield " " * (group_nesting + 1) + "+------------------------------------\n"

def format_exception(self, type_, value, tb, *, from_decorator=False):
yield from self._format_exception(value, tb, is_first=True, from_decorator=from_decorator)
Loading

0 comments on commit 085122a

Please sign in to comment.