Skip to content
Merged
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
2 changes: 1 addition & 1 deletion graphblas/dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def lookup_dtype(key, value=None):
return lookup_dtype(key.literal_type) # For numba dtype inference
except Exception:
pass
raise ValueError(f"Unknown dtype: {key}", type(key))
raise ValueError(f"Unknown dtype: {key} of type {type(key)}")


def unify(type1, type2, *, is_left_scalar=False, is_right_scalar=False):
Expand Down
61 changes: 40 additions & 21 deletions graphblas/recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,7 @@ def __iter__(self):
def is_recording(self):
return self._token is not None and _recorder.get(base._prev_recorder) is self

def _repr_markdown_(self):
# Syntax highlighting from github-flavored markdown looks better than
# using IPython.display.Code or pygments
def _repr_base_(self):
status = (
'<div style="'
"height: 12px; "
Expand All @@ -118,11 +116,11 @@ def _repr_markdown_(self):
)
if self.is_recording:
# red circle for recording
status = status % ("background-color: red; " "border-radius: 50%;")
status = status % ("background-color: red; border-radius: 50%;")
else:
# two vertical bars for paused
status = status % ("border-right: 5px solid gray; " "border-left: 5px solid gray;")
lines = [
status = status % ("border-right: 5px solid gray; border-left: 5px solid gray;")
head = [
"<div>",
f"{CSS_STYLE}",
'<details open class="gb-arg-details">',
Expand All @@ -135,27 +133,48 @@ def _repr_markdown_(self):
"</table>",
"</summary>",
'<blockquote class="gb-expr-blockquote" style="margin-left: -8px;">',
"",
"```C",
" " + "\n ".join(self.data),
"```",
"</blockquote>",
"</details>",
"</div>",
]
return "\n".join(lines)
tail = "\n</blockquote>\n</details>\n</div>"
return "\n".join(head), tail

def _repr_html_(self): # pragma: no cover
try:
from IPython.display import Code
except ImportError:
raise NotImplementedError()
lines = self._get_repr_lines()
code = Code("\n".join(lines), language="C")
head, tail = self._repr_base_()
return head + code._repr_html_() + tail

def __repr__(self):
lines = [f'gb.Recorder ({"" if self.is_recording else "not "}recording)']
lines.append("-" * len(lines[0]))
def _repr_markdown_(self):
# Syntax highlighting from github-flavored markdown looks better than
# using IPython.display.Code or pygments
lines = self._get_repr_lines()
code = "\n\n```C\n" + "\n".join(lines) + "\n```"
head, tail = self._repr_base_()
return head + code + tail

def _get_repr_lines(self, indent=""):
lines = []
if self.max_rows is not None and len(self.data) > self.max_rows:
lines.extend(f" {line}" for line in self.data[: self.max_rows // 2])
lines.extend(f"{indent}{line}" for line in self.data[: self.max_rows // 2])
lines.append("")
lines.append(f" ... ({len(self.data) - self.max_rows} rows not shown)")
lines.append(
f"{indent}// {len(self.data) - self.max_rows} rows not shown; "
# f"{indent}// {len(self.data) - self.max_rows} rows not shown; "
"set `recorder.max_rows` attribute to show more (or less)"
)
lines.append("")
lines.extend(f" {line}" for line in self.data[-((self.max_rows + 1) // 2) :])
lines.extend(f"{indent}{line}" for line in self.data[-((self.max_rows + 1) // 2) :])
else:
lines.extend(f" {line}" for line in self.data)
lines.extend(f"{indent}{line}" for line in self.data)
return lines

def __repr__(self):
lines = [f'gb.Recorder ({"" if self.is_recording else "not "}recording)']
lines.append("-" * len(lines[0]))
lines.extend(self._get_repr_lines(indent=" "))
return "\n".join(lines)


Expand Down
31 changes: 21 additions & 10 deletions graphblas/tests/test_recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def test_record_repr(switch):
rec.max_rows = 10
for i in range(1, 20):
A[0, 0].new(name=f"c{i}")
n = len(rec.data) - rec.max_rows
if switch:
assert repr(rec) == (
"gb.Recorder (recording)\n"
Expand All @@ -121,7 +122,7 @@ def test_record_repr(switch):
" GrB_Matrix_extractElement_INT64(&c3, A, 0, 0);\n"
" GrB_Matrix_extractElement_INT64(&c4, A, 0, 0);\n"
"\n"
" ... (10 rows not shown)\n"
f" // {n} rows not shown; set `recorder.max_rows` attribute to show more (or less)\n"
"\n"
" GrB_Matrix_extractElement_INT64(&c15, A, 0, 0);\n"
" GrB_Matrix_extractElement_INT64(&c16, A, 0, 0);\n"
Expand All @@ -139,7 +140,7 @@ def test_record_repr(switch):
" GrB_Matrix_extractElement_Scalar(c1, A, 0, 0);\n"
" GrB_Scalar_new(&c2, GrB_INT64);\n"
"\n"
" ... (30 rows not shown)\n"
f" // {n} rows not shown; set `recorder.max_rows` attribute to show more (or less)\n"
"\n"
" GrB_Matrix_extractElement_Scalar(c17, A, 0, 0);\n"
" GrB_Scalar_new(&c18, GrB_INT64);\n"
Expand All @@ -156,11 +157,9 @@ def test_record_repr_markdown(switch):
rec.start()
A[0, 0].new(name="c")
if switch:
text = " GrB_Matrix_extractElement_INT64(&c, A, 0, 0);\n"
text = "GrB_Matrix_extractElement_INT64(&c, A, 0, 0);\n"
else:
text = (
" GrB_Scalar_new(&c, GrB_INT64);\n" " GrB_Matrix_extractElement_Scalar(c, A, 0, 0);\n"
)
text = "GrB_Scalar_new(&c, GrB_INT64);\nGrB_Matrix_extractElement_Scalar(c, A, 0, 0);\n"
assert rec._repr_markdown_() == (
"<div>\n"
f"{CSS_STYLE}\n"
Expand All @@ -185,11 +184,9 @@ def test_record_repr_markdown(switch):
)
rec.stop()
if switch:
text = " GrB_Matrix_extractElement_INT64(&c, A, 0, 0);\n"
text = "GrB_Matrix_extractElement_INT64(&c, A, 0, 0);\n"
else:
text = (
" GrB_Scalar_new(&c, GrB_INT64);\n" " GrB_Matrix_extractElement_Scalar(c, A, 0, 0);\n"
)
text = "GrB_Scalar_new(&c, GrB_INT64);\nGrB_Matrix_extractElement_Scalar(c, A, 0, 0);\n"
assert rec._repr_markdown_() == (
"<div>\n"
f"{CSS_STYLE}\n"
Expand All @@ -214,6 +211,20 @@ def test_record_repr_markdown(switch):
)


def test_record_repr_html(switch):
A = gb.Matrix(int, 3, 3, name="A")
rec = gb.Recorder()
rec.start()
A[0, 0].new(name="c")
try:
import IPython # noqa
except ImportError:
with pytest.raises(NotImplementedError):
rec._repr_html_()
else: # pragma: no cover
assert isinstance(rec._repr_html_(), str)


def test_record_failed_call():
BIG = gb.Vector(int, size=2**55)
small = gb.Vector(int, size=2**55)
Expand Down