-
Notifications
You must be signed in to change notification settings - Fork 250
[hail] teach tables how to HTML #5666
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
Conversation
hail/build.gradle
Outdated
@@ -279,7 +279,7 @@ task testPython(type: Exec, dependsOn: shadowJar) { | |||
'--color=no', | |||
'-r a', | |||
'--html=build/reports/pytest.html', | |||
'--self-contained-html', | |||
'--self-contained-html', '-vv', '--maxfail=1', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
disable?
hail/python/hail/table.py
Outdated
t = t.flatten() | ||
fields = list(t.row) | ||
|
||
formatted_t = t.select(**{k: hl_format(v) for (k, v) in t.row.items()}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't work - it'll try to call hl_format on expressions. hl_format needs to be called on strings after the take
localizes them to python
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't hl.format
, its hl_format
, which is defined above to escape after calling Table._hl_repr
. This is basically the same code as what show previously did except I removed truncation and added cgi.escape
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait, but isn't this calling cgi.escape
inside of a TableMapRows (select) above? How does that work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lmao nice: https://github.com/python/cpython/blob/3.5/Lib/html/__init__.py#L12
replace just works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import html
print(html.escape(hl.str("tlocus<GRCh37>"))._ir)
(Apply replace (Apply replace (Apply replace (Apply replace (Apply replace (Str "tlocus<GRCh37>") (Str "&") (Str "&")) (Str "<") (Str "<")) (Str ">") (Str ">")) (Str "\"") (Str """)) (Str "'") (Str "'"))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like this -- I think there's nothing that prevents the cgi
or html
implementation from changing and breaking this, and Hail string manipulation is also extremely slow right now.
Can we just call hl_format
on each string coming out in line 1367?
hail/python/hail/table.py
Outdated
|
||
if has_more: | ||
n_rows = len(rows) | ||
s += f"<p>showing top { n_rows } { 'row' if n_rows == 1 else 'rows' }</p>\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have a plural
utility function in hail.utils.misc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
handler(self._show(n, width, truncate, types)) | ||
if n is None or width is None: | ||
import shutil | ||
(columns, lines) = shutil.get_terminal_size((80, 10)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very nice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move hl_format
doctest failure from show() changing the width, it seems |
hail/python/hail/table.py
Outdated
s = "{" + hl.delimit(hl.map(lambda x: Table._hl_repr(x[0]) + ":" + Table._hl_repr(x[1]), hl.array(v)), ",") + "}" | ||
elif v.dtype == hl.tstr: | ||
s = hl.str('"') + hl.expr.functions._escape_string(v) + '"' | ||
elif isinstance(v.dtype, (hl.tstruct, hl.tarray)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you didn't change this code, but this should be ttuple not tarray
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So awesome.
hail/python/hail/table.py
Outdated
elif v.dtype == hl.tstr: | ||
s = hl.str('"') + hl.expr.functions._escape_string(v) + '"' | ||
elif isinstance(v.dtype, (hl.tstruct, hl.ttuple)): | ||
s = "(" + hl.delimit([Table._hl_repr(v[i]) for i in range(len(v))], ",") + ")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs to check for empty array - that can't be type-imputed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(this is your test failure)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
le sigh. fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
boom!
Take a look at the docs for
IPython.display.display
.I preserve the user's ability to specify a custom handler. The handler is no longer given a string but an object that has a sensible
__str__
and__repr__
. Moreover, this object has a_repr_html_
which Jupyter uses to display an HTML table. Detecting what frontend is being run is done byIPython.display.display
.I use the
_Show
shim class to avoid having tables themselves print as HTML.I also check for terminal size and use that to pick
n
andwidth
.Should
_hl_repr
live here?Resolves #5663, #2847