MLH-Fellowship/werkzeug

Refactor `Group` to subclass `traceback.StackSummary`

Closed this issue · 0 comments

class Group:
"""A group of frames for an exception in a traceback. If the
exception has a ``__cause__`` or ``__context__``, there are multiple
exception groups.
"""
def __init__(self, exc_type, exc_value, tb):
self.exc_type = exc_type
self.exc_value = exc_value
self.info = None
if exc_value.__cause__ is not None:
self.info = (
"The above exception was the direct cause of the following exception"
)
elif exc_value.__context__ is not None:
self.info = (
"During handling of the above exception, another exception occurred"
)
self.frames = []
while tb is not None:
self.frames.append(Frame(exc_type, exc_value, tb))
tb = tb.tb_next
def filter_hidden_frames(self):
new_frames = []
hidden = False
for frame in self.frames:
hide = frame.hide
if hide in ("before", "before_and_this"):
new_frames = []
hidden = False
if hide == "before_and_this":
continue
elif hide in ("reset", "reset_and_this"):
hidden = False
if hide == "reset_and_this":
continue
elif hide in ("after", "after_and_this"):
hidden = True
if hide == "after_and_this":
continue
elif hide or hidden:
continue
new_frames.append(frame)
# if we only have one frame and that frame is from the codeop
# module, remove it.
if len(new_frames) == 1 and self.frames[0].module == "codeop":
del self.frames[:]
# if the last frame is missing something went terrible wrong :(
elif self.frames[-1] in new_frames:
self.frames[:] = new_frames
@property
def exception(self):
"""String representation of the exception."""
buf = traceback.format_exception_only(self.exc_type, self.exc_value)
rv = "".join(buf).strip()
return _to_str(rv, "utf-8", "replace")
def render(self, mark_lib=True):
out = []
if self.info is not None:
out.append(f'<li><div class="exc-divider">{self.info}:</div>')
for frame in self.frames:
title = f' title="{escape(frame.info)}"' if frame.info else ""
out.append(f"<li{title}>{frame.render(mark_lib=mark_lib)}")
return "\n".join(out)
def render_text(self):
out = []
if self.info is not None:
out.append(f"\n{self.info}:\n")
out.append("Traceback (most recent call last):")
for frame in self.frames:
out.append(frame.render_text())
out.append(self.exception)
return "\n".join(out)