From 7505eae52c463ab83b0b9ce6744af1fb837e3c05 2016-02-22 17:30:43 From: Thomas Kluyver Date: 2016-02-22 17:30:43 Subject: [PATCH] Fix 'interactive' tests using pipes to a subprocess --- diff --git a/IPython/core/tests/test_shellapp.py b/IPython/core/tests/test_shellapp.py index 197e828..6e2e31b 100644 --- a/IPython/core/tests/test_shellapp.py +++ b/IPython/core/tests/test_shellapp.py @@ -52,8 +52,9 @@ class TestFileToRun(unittest.TestCase, tt.TempFileMixin): src = "True\n" self.mktmp(src) + out = 'In [1]: False\n\nIn [2]:' err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None - tt.ipexec_validate(self.fname, 'False', err, options=['-i'], + tt.ipexec_validate(self.fname, out, err, options=['-i'], commands=['"__file__" in globals()', 'exit()']) @dec.skip_win32 @@ -63,6 +64,7 @@ class TestFileToRun(unittest.TestCase, tt.TempFileMixin): src = "from __future__ import division\n" self.mktmp(src) + out = 'In [1]: float\n\nIn [2]:' err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None - tt.ipexec_validate(self.fname, 'float', err, options=['-i'], + tt.ipexec_validate(self.fname, out, err, options=['-i'], commands=['type(1/2)', 'exit()']) diff --git a/IPython/terminal/ptshell.py b/IPython/terminal/ptshell.py index 4c7418f..97f8bb5 100644 --- a/IPython/terminal/ptshell.py +++ b/IPython/terminal/ptshell.py @@ -4,7 +4,7 @@ from __future__ import print_function import sys from IPython.core.interactiveshell import InteractiveShell -from IPython.utils.py3compat import PY3, cast_unicode_py2 +from IPython.utils.py3compat import PY3, cast_unicode_py2, input from traitlets import Bool, Unicode, Dict from prompt_toolkit.completion import Completer, Completion @@ -83,6 +83,14 @@ class PTInteractiveShell(InteractiveShell): ] def init_prompt_toolkit_cli(self): + if not sys.stdin.isatty(): + # Piped input - e.g. for tests. Fall back to plain non-interactive + # output. This is very limited, and only accepts a single line. + def prompt(): + return cast_unicode_py2(input('In [%d]: ' % self.execution_count)) + self.prompt_for_code = prompt + return + kbmanager = KeyBindingManager.for_prompt(enable_vi_mode=self.vi_mode) insert_mode = ViStateFilter(kbmanager.get_vi_state, InputMode.INSERT) # Ctrl+J == Enter, seemingly @@ -160,6 +168,10 @@ class PTInteractiveShell(InteractiveShell): self.pt_cli = CommandLineInterface(app, eventloop=create_eventloop(self.inputhook)) + def prompt_for_code(self): + document = self.pt_cli.run(pre_run=self.pre_prompt) + return document.text + def init_io(self): if sys.platform not in {'win32', 'cli'}: return @@ -194,14 +206,14 @@ class PTInteractiveShell(InteractiveShell): print(self.separate_in, end='') try: - document = self.pt_cli.run(pre_run=self.pre_prompt) + code = self.prompt_for_code() except EOFError: if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'): self.ask_exit() else: - if document: - self.run_cell(document.text, store_history=True) + if code: + self.run_cell(code, store_history=True) def mainloop(self): # An extra layer of protection in case someone mashing Ctrl-C breaks