def show(self, frame, note=''): if frame is None: return filepath = inspect.getsourcefile(frame) or inspect.getfile(frame) if match(filepath, __file__): return elif match(filepath, self.suppressed_paths): line_info = (filepath, frame.f_lineno, frame.f_code.co_name) frame_str = 'File %s, line %s, in %s\n' % line_info if len(note) > 123: note == note[:120] + '...' else: frame_str = self.fmt(frame) depth = count_stack(frame) - self.starting_depth our_callsite = frame.f_back callsite_of_previous_frame = getattr(self.previous_frame, 'f_back', -1) if self.previous_frame is our_callsite and our_callsite is not None: # we're a child frame self.emit(add_indent(' └──┐\n', depth - 1)) if frame is callsite_of_previous_frame: # we're a parent frame self.emit(add_indent('┌──────┘\n', depth)) frame_str += note self.emit(add_indent(frame_str, depth)) self.previous_frame = frame
def format_stack(frames, style='plaintext', source_lines=5, show_signature=True, show_vals='like_source', truncate_vals=500, line_wrap=60, reverse=False, suppressed_paths=None): """ Render a list of frames (or FrameInfo tuples) keyword args like stackprinter.format() """ min_src_lines = 0 if source_lines == 0 else 1 minimal_formatter = get_formatter(style=style, source_lines=min_src_lines, show_signature=False, show_vals=False) reduced_formatter = get_formatter(style=style, source_lines=min_src_lines, show_signature=show_signature, show_vals=show_vals, truncate_vals=truncate_vals, line_wrap=line_wrap, suppressed_paths=suppressed_paths) verbose_formatter = get_formatter(style=style, source_lines=source_lines, show_signature=show_signature, show_vals=show_vals, truncate_vals=truncate_vals, line_wrap=line_wrap, suppressed_paths=suppressed_paths) frame_msgs = [] parent_is_boring = True for frame in frames: fi = ex.get_info(frame) is_boring = match(fi.filename, suppressed_paths) if is_boring: if parent_is_boring: formatter = minimal_formatter else: formatter = reduced_formatter else: formatter = verbose_formatter parent_is_boring = is_boring frame_msgs.append(formatter(fi)) if reverse: frame_msgs = reversed(frame_msgs) return ''.join(frame_msgs)
def hide(name): value = fi.assignments[name] if callable(value): qualified_name, path, *_ = inspect_callable(value) is_builtin = value.__class__.__name__ == 'builtin_function_or_method' is_boring = is_builtin or (qualified_name == name) is_suppressed = match(path, suppressed_paths) return is_boring or is_suppressed return False
def get_vars(names, loc, glob, suppressed_vars): assignments = [] for name in names: if match(name, suppressed_vars): assignments.append((name, CensoredVariable())) else: try: val = lookup(name, loc, glob) except LookupError: pass else: assignments.append((name, val)) return OrderedDict(assignments)
def test_match(): assert match('my/ignored/path', None) is False assert match('my/ignored/path', ['not']) is False assert match('my/ignored/path', [re.compile('not ignored')]) is False assert match('my/ignored/path', 'ignored') assert match('my/ignored/path', ['not', 'ignored']) assert match('my/ignored/path', [re.compile('not ignored'), re.compile('ignored')])