Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stack_data #5

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 32 additions & 98 deletions heartrate/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
import webbrowser
from collections import defaultdict, deque, Counter
from functools import lru_cache
from itertools import islice, takewhile
from itertools import islice

import pygments
import stack_data
from executing import Source
from flask import Flask, render_template, jsonify, url_for, request
# noinspection PyUnresolvedReferences
from pygments.formatters import HtmlFormatter
# noinspection PyUnresolvedReferences
from pygments.lexers import PythonLexer, Python3Lexer
from stack_data.utils import _pygmented_with_ranges, iter_stack

from heartrate import files as files_filters

Expand All @@ -27,38 +26,8 @@
]


lexer = Python3Lexer()
formatter = HtmlFormatter(nowrap=True)


def highlight_python(code):
return pygments.highlight(
code,
lexer,
formatter,
)


def highlight_python_and_ranges(code):
return (highlight_python(code)
.replace(highlight_python(open_sentinel).rstrip('\n'), "<b>")
.replace(highlight_python(close_sentinel).rstrip('\n'), "</b>")
)


def highlight_stack_frame(frame):
executing = Source.executing(frame)
node = executing.node
source = executing.source
if node:
source.asttokens()
start = node.first_token.start[0]
end = node.last_token.end[0]
else:
start = end = frame.f_lineno

highlighted = '\n'.join(highlight_ranges(source, [frame]).splitlines()[start - 1:end])
return highlight_python_and_ranges(highlighted)
style = stack_data.style_with_executing_node("monokai", "bg:#acf9ff")
formatter = HtmlFormatter(nowrap=True, style=style)


def trace(
Expand Down Expand Up @@ -98,9 +67,11 @@ def file_table_context():
source = Source.for_filename(filename)
queue = queues[filename]

highlighted = highlight_ranges(source, frames_matching(filename))
highlighted = highlight_python_and_ranges(highlighted)
highlighted_lines = list(enumerate(highlighted.splitlines()))
highlighted_lines = list(enumerate(_pygmented_with_ranges(
formatter,
source.text,
executing_ranges(filename),
)))

counters = [
queue_counter(queue, 2 ** i)
Expand Down Expand Up @@ -137,7 +108,6 @@ def file_table_context():
zip=zip,
lightnesses=lightnesses,
filename=filename,
highlighted=highlighted,
)

@app.route('/table/')
Expand All @@ -147,36 +117,39 @@ def file_table_view():
def current_frame():
return sys._current_frames()[thread_ident]

def frames_matching(filename):
frame = current_frame()
while frame:
def executing_ranges(filename):
for frame in iter_stack(current_frame()):
if frame.f_code.co_filename == filename:
yield frame
frame = frame.f_back
executing = Source.executing(frame)
if executing.node:
yield executing.text_range()

@app.route('/stacktrace/')
def stacktrace():
def gen():
frame = current_frame()
while frame:
code = frame.f_code
filename = code.co_filename
name = Source.for_frame(frame).code_qualname(code)
options = stack_data.Options(before=0, after=0, pygments_formatter=formatter)
frame_infos = stack_data.FrameInfo.stack_data(
current_frame(),
options,
collapse_repeated_frames=False,
)
for frame_info in frame_infos:
filename = frame_info.filename
name = frame_info.executing.code_qualname()
if "heartrate" in filename and name.endswith(trace_func.__name__):
continue
yield (
filename,
frame.f_lineno,
frame_info.lineno,
name,
highlight_stack_frame(frame),
"\n".join(
line.render(pygmented=True)
for line in frame_info.lines
),
include_file(filename)
)
frame = frame.f_back

return jsonify(list(takewhile(
lambda entry: not (
'heartrate' in entry[0]
and entry[2].endswith(trace_func.__name__)),
list(gen())[::-1]
)))
return jsonify(list(gen()))

threading.Thread(
target=lambda: app.run(
Expand Down Expand Up @@ -212,45 +185,6 @@ def trace_func(frame, event, _arg):
webbrowser.open_new_tab(url)


open_sentinel = " $$heartrate_open$$ "
close_sentinel = " $$heartrate_close$$ "


def highlight_ranges(source, frames):
text = source.text
ranges = set()
for frame in frames:
executing = Source.executing(frame)
if executing.node:
text_range = executing.text_range()
ranges.add(text_range)

positions = []

for start, end in ranges:
positions.append((start, open_sentinel))
positions.append((end, close_sentinel))
while True:
start = text.find('\n', start + 1, end)
if start == -1:
break
positions.append((start, close_sentinel))
positions.append((start + 1, open_sentinel))

# This just makes the loop below simpler
positions.append((len(text), ''))

positions.sort()

parts = []
start = 0
for position, part in positions:
parts.append(text[start:position])
parts.append(part)
start = position
return ''.join(parts)


def queue_counter(queue, n):
while True:
try:
Expand Down
71 changes: 71 additions & 0 deletions heartrate/static/css/monokai.css
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,74 @@
.highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */
.highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */
.highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */
.highlight .hll-ExecutingNode { background-color: #49483e; background: rgba(172, 249, 255, 0.5) }
.highlight -ExecutingNode { background: #272822; color: #f8f8f2; background: rgba(172, 249, 255, 0.5) }
.highlight .c-ExecutingNode { color: #75715e; background: rgba(172, 249, 255, 0.5) } /* Comment */
.highlight .err-ExecutingNode { color: #960050; background-color: #1e0010; background: rgba(172, 249, 255, 0.5) } /* Error */
.highlight .k-ExecutingNode { color: #66d9ef; background: rgba(172, 249, 255, 0.5) } /* Keyword */
.highlight .l-ExecutingNode { color: #ae81ff; background: rgba(172, 249, 255, 0.5) } /* Literal */
.highlight .n-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name */
.highlight .o-ExecutingNode { color: #f92672; background: rgba(172, 249, 255, 0.5) } /* Operator */
.highlight .p-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Punctuation */
.highlight .ch-ExecutingNode { color: #75715e; background: rgba(172, 249, 255, 0.5) } /* Comment.Hashbang */
.highlight .cm-ExecutingNode { color: #75715e; background: rgba(172, 249, 255, 0.5) } /* Comment.Multiline */
.highlight .cp-ExecutingNode { color: #75715e; background: rgba(172, 249, 255, 0.5) } /* Comment.Preproc */
.highlight .cpf-ExecutingNode { color: #75715e; background: rgba(172, 249, 255, 0.5) } /* Comment.PreprocFile */
.highlight .c1-ExecutingNode { color: #75715e; background: rgba(172, 249, 255, 0.5) } /* Comment.Single */
.highlight .cs-ExecutingNode { color: #75715e; background: rgba(172, 249, 255, 0.5) } /* Comment.Special */
.highlight .gd-ExecutingNode { color: #f92672; background: rgba(172, 249, 255, 0.5) } /* Generic.Deleted */
.highlight .ge-ExecutingNode { font-style: italic; background: rgba(172, 249, 255, 0.5) } /* Generic.Emph */
.highlight .gi-ExecutingNode { color: #a6e22e; background: rgba(172, 249, 255, 0.5) } /* Generic.Inserted */
.highlight .gs-ExecutingNode { font-weight: bold; background: rgba(172, 249, 255, 0.5) } /* Generic.Strong */
.highlight .gu-ExecutingNode { color: #75715e; background: rgba(172, 249, 255, 0.5) } /* Generic.Subheading */
.highlight .kc-ExecutingNode { color: #66d9ef; background: rgba(172, 249, 255, 0.5) } /* Keyword.Constant */
.highlight .kd-ExecutingNode { color: #66d9ef; background: rgba(172, 249, 255, 0.5) } /* Keyword.Declaration */
.highlight .kn-ExecutingNode { color: #f92672; background: rgba(172, 249, 255, 0.5) } /* Keyword.Namespace */
.highlight .kp-ExecutingNode { color: #66d9ef; background: rgba(172, 249, 255, 0.5) } /* Keyword.Pseudo */
.highlight .kr-ExecutingNode { color: #66d9ef; background: rgba(172, 249, 255, 0.5) } /* Keyword.Reserved */
.highlight .kt-ExecutingNode { color: #66d9ef; background: rgba(172, 249, 255, 0.5) } /* Keyword.Type */
.highlight .ld-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.Date */
.highlight .m-ExecutingNode { color: #ae81ff; background: rgba(172, 249, 255, 0.5) } /* Literal.Number */
.highlight .s-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String */
.highlight .na-ExecutingNode { color: #a6e22e; background: rgba(172, 249, 255, 0.5) } /* Name.Attribute */
.highlight .nb-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Builtin */
.highlight .nc-ExecutingNode { color: #a6e22e; background: rgba(172, 249, 255, 0.5) } /* Name.Class */
.highlight .no-ExecutingNode { color: #66d9ef; background: rgba(172, 249, 255, 0.5) } /* Name.Constant */
.highlight .nd-ExecutingNode { color: #a6e22e; background: rgba(172, 249, 255, 0.5) } /* Name.Decorator */
.highlight .ni-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Entity */
.highlight .ne-ExecutingNode { color: #a6e22e; background: rgba(172, 249, 255, 0.5) } /* Name.Exception */
.highlight .nf-ExecutingNode { color: #a6e22e; background: rgba(172, 249, 255, 0.5) } /* Name.Function */
.highlight .nl-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Label */
.highlight .nn-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Namespace */
.highlight .nx-ExecutingNode { color: #a6e22e; background: rgba(172, 249, 255, 0.5) } /* Name.Other */
.highlight .py-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Property */
.highlight .nt-ExecutingNode { color: #f92672; background: rgba(172, 249, 255, 0.5) } /* Name.Tag */
.highlight .nv-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Variable */
.highlight .ow-ExecutingNode { color: #f92672; background: rgba(172, 249, 255, 0.5) } /* Operator.Word */
.highlight .w-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Text.Whitespace */
.highlight .mb-ExecutingNode { color: #ae81ff; background: rgba(172, 249, 255, 0.5) } /* Literal.Number.Bin */
.highlight .mf-ExecutingNode { color: #ae81ff; background: rgba(172, 249, 255, 0.5) } /* Literal.Number.Float */
.highlight .mh-ExecutingNode { color: #ae81ff; background: rgba(172, 249, 255, 0.5) } /* Literal.Number.Hex */
.highlight .mi-ExecutingNode { color: #ae81ff; background: rgba(172, 249, 255, 0.5) } /* Literal.Number.Integer */
.highlight .mo-ExecutingNode { color: #ae81ff; background: rgba(172, 249, 255, 0.5) } /* Literal.Number.Oct */
.highlight .sa-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Affix */
.highlight .sb-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Backtick */
.highlight .sc-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Char */
.highlight .dl-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Delimiter */
.highlight .sd-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Doc */
.highlight .s2-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Double */
.highlight .se-ExecutingNode { color: #ae81ff; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Escape */
.highlight .sh-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Heredoc */
.highlight .si-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Interpol */
.highlight .sx-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Other */
.highlight .sr-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Regex */
.highlight .s1-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Single */
.highlight .ss-ExecutingNode { color: #e6db74; background: rgba(172, 249, 255, 0.5) } /* Literal.String.Symbol */
.highlight .bp-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Builtin.Pseudo */
.highlight .fm-ExecutingNode { color: #a6e22e; background: rgba(172, 249, 255, 0.5) } /* Name.Function.Magic */
.highlight .vc-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Variable.Class */
.highlight .vg-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Variable.Global */
.highlight .vi-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Variable.Instance */
.highlight .vm-ExecutingNode { color: #f8f8f2; background: rgba(172, 249, 255, 0.5) } /* Name.Variable.Magic */
.highlight .il-ExecutingNode { color: #ae81ff; background: rgba(172, 249, 255, 0.5) } /* Literal.Number.Integer.Long */
.highlight .-ExecutingNode { background: rgba(172, 249, 255, 0.5) } /* Literal.Number.Integer.Long */