-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Enhance %notebook
to save outputs, including MIME types and exceptions
#14780
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
Changes from 3 commits
49d14a0
479eba0
787d4bd
786812a
db746f2
fe26455
de1a604
e90fd4c
436dad9
f1b962a
55c5ad1
c97055f
9978579
da863e1
73c2343
b0a2459
a29eefb
0587325
eb6a602
71862af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -3200,6 +3200,11 @@ async def run_cell_async( | |||||||||||||||
|
||||||||||||||||
def error_before_exec(value): | ||||||||||||||||
if store_history: | ||||||||||||||||
if self.history_manager: | ||||||||||||||||
# Store formatted traceback and error details | ||||||||||||||||
self.history_manager.exceptions[self.execution_count] = ( | ||||||||||||||||
self.format_exception_for_storage(value) | ||||||||||||||||
) | ||||||||||||||||
self.execution_count += 1 | ||||||||||||||||
result.error_before_exec = value | ||||||||||||||||
self.last_execution_succeeded = False | ||||||||||||||||
|
@@ -3309,12 +3314,54 @@ def error_before_exec(value): | |||||||||||||||
assert self.history_manager is not None | ||||||||||||||||
# Write output to the database. Does nothing unless | ||||||||||||||||
# history output logging is enabled. | ||||||||||||||||
self.history_manager.store_output(self.execution_count) | ||||||||||||||||
hm = self.history_manager | ||||||||||||||||
hm.store_output(self.execution_count) | ||||||||||||||||
exec_count = self.execution_count | ||||||||||||||||
|
||||||||||||||||
if result.result: | ||||||||||||||||
Darshan808 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
# Format the result into a MIME bundle | ||||||||||||||||
try: | ||||||||||||||||
mime_obj = ( | ||||||||||||||||
result.result[0] | ||||||||||||||||
if isinstance(result.result, list) | ||||||||||||||||
else result.result | ||||||||||||||||
) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To capture the result passed to ipython/IPython/core/displaypub.py Lines 132 to 138 in 5a183ac
I am not yet 100% sure if this is the best place, but seems fine for first iteration. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm facing a slight issue while capturing When only How can we determine whether the MIME bundle should be associated with the current or previous In the screenshot below, in both cases |
||||||||||||||||
mime_fig = mime_obj.get_figure() | ||||||||||||||||
mime_bundle, _ = self.display_formatter.format(mime_fig) | ||||||||||||||||
Darshan808 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
except: | ||||||||||||||||
Darshan808 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
# In case formatting fails, fallback to text/plain | ||||||||||||||||
mime_bundle = {"text/plain": repr(result.result)} | ||||||||||||||||
Darshan808 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
hm.output_mime_bundles[exec_count] = mime_bundle | ||||||||||||||||
Darshan808 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
if result.error_in_exec: | ||||||||||||||||
# Store formatted traceback and error details | ||||||||||||||||
hm.exceptions[exec_count] = self.format_exception_for_storage( | ||||||||||||||||
result.error_in_exec | ||||||||||||||||
) | ||||||||||||||||
|
||||||||||||||||
# Each cell is a *single* input, regardless of how many lines it has | ||||||||||||||||
self.execution_count += 1 | ||||||||||||||||
|
||||||||||||||||
return result | ||||||||||||||||
|
||||||||||||||||
def format_exception_for_storage(self, exception): | ||||||||||||||||
Darshan808 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
""" | ||||||||||||||||
Format an exception's traceback and details for storage in exceptions. | ||||||||||||||||
""" | ||||||||||||||||
etype = type(exception) | ||||||||||||||||
evalue = exception | ||||||||||||||||
tb = exception.__traceback__ | ||||||||||||||||
|
||||||||||||||||
if isinstance(exception, SyntaxError): | ||||||||||||||||
# Use SyntaxTB for syntax errors | ||||||||||||||||
stb = self.SyntaxTB.structured_traceback(etype, evalue, tb) | ||||||||||||||||
else: | ||||||||||||||||
# Use InteractiveTB for other exceptions, skipping IPython's internal frame | ||||||||||||||||
stb = self.InteractiveTB.structured_traceback( | ||||||||||||||||
etype, evalue, tb, tb_offset=1 | ||||||||||||||||
) | ||||||||||||||||
|
||||||||||||||||
return {"ename": etype.__name__, "evalue": str(evalue), "traceback": stb} | ||||||||||||||||
|
||||||||||||||||
def transform_cell(self, raw_cell): | ||||||||||||||||
"""Transform an input cell before parsing it. | ||||||||||||||||
|
||||||||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.