diff --git a/IPython/nbconvert/preprocessors/tests/files/Interrupt.ipynb b/IPython/nbconvert/preprocessors/tests/files/Interrupt.ipynb new file mode 100644 index 0000000..ffcde4a --- /dev/null +++ b/IPython/nbconvert/preprocessors/tests/files/Interrupt.ipynb @@ -0,0 +1,49 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;32mcontinue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "while True: continue" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "done\n" + ] + } + ], + "source": [ + "print(\"done\")" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/IPython/nbconvert/preprocessors/tests/test_execute.py b/IPython/nbconvert/preprocessors/tests/test_execute.py index 101b66c..f6ea6d9 100644 --- a/IPython/nbconvert/preprocessors/tests/test_execute.py +++ b/IPython/nbconvert/preprocessors/tests/test_execute.py @@ -62,63 +62,76 @@ class TestExecute(PreprocessorTestsBase): self.assertEqual(expected_execution_count, actual_execution_count) - def build_preprocessor(self): + def build_preprocessor(self, opts): """Make an instance of a preprocessor""" preprocessor = ExecutePreprocessor() preprocessor.enabled = True + for opt in opts: + setattr(preprocessor, opt, opts[opt]) return preprocessor def test_constructor(self): """Can a ExecutePreprocessor be constructed?""" - self.build_preprocessor() + self.build_preprocessor({}) + def run_notebook(self, filename, opts, resources): + """Loads and runs a notebook, returning both the version prior to + running it and the version after running it. + + """ + with io.open(filename) as f: + input_nb = nbformat.read(f, 4) + preprocessor = self.build_preprocessor(opts) + cleaned_input_nb = copy.deepcopy(input_nb) + for cell in cleaned_input_nb.cells: + if 'execution_count' in cell: + del cell['execution_count'] + cell['outputs'] = [] + output_nb, _ = preprocessor(cleaned_input_nb, resources) + return input_nb, output_nb + def test_run_notebooks(self): """Runs a series of test notebooks and compares them to their actual output""" current_dir = os.path.dirname(__file__) input_files = glob.glob(os.path.join(current_dir, 'files', '*.ipynb')) for filename in input_files: - with io.open(filename) as f: - input_nb = nbformat.read(f, 4) - res = self.build_resources() - res['metadata']['path'] = os.path.dirname(filename) - preprocessor = self.build_preprocessor() - cleaned_input_nb = copy.deepcopy(input_nb) - for cell in cleaned_input_nb.cells: - if 'execution_count' in cell: - del cell['execution_count'] - cell['outputs'] = [] - output_nb, _ = preprocessor(cleaned_input_nb, res) - if os.path.basename(filename) == "Disable Stdin.ipynb": - # We need to special-case this particular notebook, because the - # traceback contains machine-specific stuff like where IPython - # is installed. It is sufficient here to just check that an error - # was thrown, and that it was a StdinNotImplementedError - self.assertEqual(len(output_nb['cells']), 1) - self.assertEqual(len(output_nb['cells'][0]['outputs']), 1) - output = output_nb['cells'][0]['outputs'][0] - self.assertEqual(output['output_type'], 'error') - self.assertEqual(output['ename'], 'StdinNotImplementedError') - self.assertEqual(output['evalue'], 'raw_input was called, but this frontend does not support input requests.') - + continue + elif os.path.basename(filename) == "Interrupt.ipynb": + opts = dict(timeout=1, interrupt_on_timeout=True) else: - self.assert_notebooks_equal(output_nb, input_nb) + opts = {} + res = self.build_resources() + res['metadata']['path'] = os.path.dirname(filename) + input_nb, output_nb = self.run_notebook(filename, opts, res) + self.assert_notebooks_equal(input_nb, output_nb) def test_empty_path(self): """Can the kernel be started when the path is empty?""" current_dir = os.path.dirname(__file__) filename = os.path.join(current_dir, 'files', 'HelloWorld.ipynb') - with io.open(filename) as f: - input_nb = nbformat.read(f, 4) res = self.build_resources() res['metadata']['path'] = '' - preprocessor = self.build_preprocessor() - cleaned_input_nb = copy.deepcopy(input_nb) - for cell in cleaned_input_nb.cells: - if 'execution_count' in cell: - del cell['execution_count'] - cell['outputs'] = [] - output_nb, _ = preprocessor(cleaned_input_nb, res) - self.assert_notebooks_equal(output_nb, input_nb) + input_nb, output_nb = self.run_notebook(filename, {}, res) + self.assert_notebooks_equal(input_nb, output_nb) + + def test_disable_stdin(self): + """Test disabling standard input""" + current_dir = os.path.dirname(__file__) + filename = os.path.join(current_dir, 'files', 'Disable Stdin.ipynb') + res = self.build_resources() + res['metadata']['path'] = os.path.dirname(filename) + input_nb, output_nb = self.run_notebook(filename, {}, res) + + # We need to special-case this particular notebook, because the + # traceback contains machine-specific stuff like where IPython + # is installed. It is sufficient here to just check that an error + # was thrown, and that it was a StdinNotImplementedError + self.assertEqual(len(output_nb['cells']), 1) + self.assertEqual(len(output_nb['cells'][0]['outputs']), 1) + output = output_nb['cells'][0]['outputs'][0] + self.assertEqual(output['output_type'], 'error') + self.assertEqual(output['ename'], 'StdinNotImplementedError') + self.assertEqual(output['evalue'], 'raw_input was called, but this frontend does not support input requests.')