Skip to content

Commit fd34cf5

Browse files
committed
Swallow potential exceptions from showtraceback()
The nbgrader project is aware of a form of cheating where students disrupt `InteractiveShell.showtraceback` in hopes of hiding exceptions to avoid losing points. They have implemented a solution to prevent this cheating from working on the client side, and have some tests to demonstrate this technique: https://github.com/jupyter/nbgrader/blob/main/nbgrader/tests/apps/files/submitted-cheat-attempt.ipynb https://github.com/jupyter/nbgrader/blob/main/nbgrader/tests/apps/files/submitted-cheat-attempt-alternative.ipynb In essence, these attacks import the interactive shell and erase the traceback handler so that their failing tests won't report failures. import IPython.core.interactiveshell IPython.core.interactiveshell.InteractiveShell.showtraceback = None The problem is that this causes an exception inside the kernel, leading to a stalled execution. The kernel has stopped working, but the client continues to wait for messages. So far, nbgrader's solution to this is to require a timeout value so the client can eventually decide it is done. This prevents allowing a value of `None` for `Execute.timeout` because this would cause a test case to infinitely hang. This commit addresses the problem by making `InteractiveShell._run_cell` a little more protective around it's call to `showtraceback()`. There is already a try/except block around running the cell. This commit adds a finally clause so that the method will _always_ return an `ExecutionResult`, even if a new exception is thrown within the except clause. For the record, the exception thrown is: TypeError: 'NoneType' object is not callable Accepting this change will allow nbgrader to update `nbgrader.preprocessors.Execute` to support a type of `Integer(allow_none=True)` as the parent `NotebookClient` intended. Discussion about this is ongoing in jupyter/nbgrader#1690.
1 parent 7dab272 commit fd34cf5

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

IPython/core/interactiveshell.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3013,14 +3013,15 @@ def _run_cell(
30133013
runner = _pseudo_sync_runner
30143014

30153015
try:
3016-
return runner(coro)
3016+
result = runner(coro)
30173017
except BaseException as e:
30183018
info = ExecutionInfo(
30193019
raw_cell, store_history, silent, shell_futures, cell_id
30203020
)
30213021
result = ExecutionResult(info)
30223022
result.error_in_exec = e
30233023
self.showtraceback(running_compiled_code=True)
3024+
finally:
30243025
return result
30253026

30263027
def should_run_async(

0 commit comments

Comments
 (0)