##// END OF EJS Templates
Backport PR #4120: support `input` in Python 2 kernels...
MinRK -
Show More
@@ -24,7 +24,7 b' import nose.tools as nt'
24 from IPython.kernel import KernelManager
24 from IPython.kernel import KernelManager
25 from IPython.kernel.tests.test_message_spec import execute, flush_channels
25 from IPython.kernel.tests.test_message_spec import execute, flush_channels
26 from IPython.testing import decorators as dec
26 from IPython.testing import decorators as dec
27 from IPython.utils import path
27 from IPython.utils import path, py3compat
28
28
29 #-------------------------------------------------------------------------------
29 #-------------------------------------------------------------------------------
30 # Tests
30 # Tests
@@ -33,6 +33,9 b' IPYTHONDIR = None'
33 save_env = None
33 save_env = None
34 save_get_ipython_dir = None
34 save_get_ipython_dir = None
35
35
36 STARTUP_TIMEOUT = 60
37 TIMEOUT = 15
38
36 def setup():
39 def setup():
37 """setup temporary IPYTHONDIR for tests"""
40 """setup temporary IPYTHONDIR for tests"""
38 global IPYTHONDIR
41 global IPYTHONDIR
@@ -75,7 +78,7 b' def new_kernel():'
75
78
76 # wait for kernel to be ready
79 # wait for kernel to be ready
77 KC.shell_channel.execute("import sys")
80 KC.shell_channel.execute("import sys")
78 KC.shell_channel.get_msg(block=True, timeout=5)
81 KC.shell_channel.get_msg(block=True, timeout=STARTUP_TIMEOUT)
79 flush_channels(KC)
82 flush_channels(KC)
80 try:
83 try:
81 yield KC
84 yield KC
@@ -116,6 +119,8 b' def _check_mp_mode(kc, expected=False, stream="stdout"):'
116 nt.assert_equal(eval(stdout.strip()), expected)
119 nt.assert_equal(eval(stdout.strip()), expected)
117
120
118
121
122 # printing tests
123
119 def test_simple_print():
124 def test_simple_print():
120 """simple print statement in kernel"""
125 """simple print statement in kernel"""
121 with new_kernel() as kc:
126 with new_kernel() as kc:
@@ -125,7 +130,6 b' def test_simple_print():'
125 nt.assert_equal(stdout, 'hi\n')
130 nt.assert_equal(stdout, 'hi\n')
126 nt.assert_equal(stderr, '')
131 nt.assert_equal(stderr, '')
127 _check_mp_mode(kc, expected=False)
132 _check_mp_mode(kc, expected=False)
128 print ('hello')
129
133
130
134
131 @dec.knownfailureif(sys.platform == 'win32', "subprocess prints fail on Windows")
135 @dec.knownfailureif(sys.platform == 'win32', "subprocess prints fail on Windows")
@@ -201,3 +205,47 b' def test_subprocess_error():'
201
205
202 _check_mp_mode(kc, expected=False)
206 _check_mp_mode(kc, expected=False)
203 _check_mp_mode(kc, expected=False, stream="stderr")
207 _check_mp_mode(kc, expected=False, stream="stderr")
208
209
210 # raw_input tests
211
212 def test_raw_input():
213 """test [raw_]input"""
214 with new_kernel() as kc:
215 iopub = kc.iopub_channel
216
217 input_f = "input" if py3compat.PY3 else "raw_input"
218 theprompt = "prompt> "
219 code = 'print({input_f}("{theprompt}"))'.format(**locals())
220 msg_id = kc.execute(code, allow_stdin=True)
221 msg = kc.get_stdin_msg(block=True, timeout=TIMEOUT)
222 nt.assert_equal(msg['header']['msg_type'], u'input_request')
223 content = msg['content']
224 nt.assert_equal(content['prompt'], theprompt)
225 text = "some text"
226 kc.input(text)
227 reply = kc.get_shell_msg(block=True, timeout=TIMEOUT)
228 nt.assert_equal(reply['content']['status'], 'ok')
229 stdout, stderr = assemble_output(iopub)
230 nt.assert_equal(stdout, text + "\n")
231
232
233 @dec.skipif(py3compat.PY3)
234 def test_eval_input():
235 """test input() on Python 2"""
236 with new_kernel() as kc:
237 iopub = kc.iopub_channel
238
239 input_f = "input" if py3compat.PY3 else "raw_input"
240 theprompt = "prompt> "
241 code = 'print(input("{theprompt}"))'.format(**locals())
242 msg_id = kc.execute(code, allow_stdin=True)
243 msg = kc.get_stdin_msg(block=True, timeout=TIMEOUT)
244 nt.assert_equal(msg['header']['msg_type'], u'input_request')
245 content = msg['content']
246 nt.assert_equal(content['prompt'], theprompt)
247 kc.input("1+1")
248 reply = kc.get_shell_msg(block=True, timeout=TIMEOUT)
249 nt.assert_equal(reply['content']['status'], 'ok')
250 stdout, stderr = assemble_output(iopub)
251 nt.assert_equal(stdout, "2\n")
@@ -131,6 +131,7 b' class Kernel(Configurable):'
131 # A reference to the Python builtin 'raw_input' function.
131 # A reference to the Python builtin 'raw_input' function.
132 # (i.e., __builtin__.raw_input for Python 2.7, builtins.input for Python 3)
132 # (i.e., __builtin__.raw_input for Python 2.7, builtins.input for Python 3)
133 _sys_raw_input = Any()
133 _sys_raw_input = Any()
134 _sys_eval_input = Any()
134
135
135 # set of aborted msg_ids
136 # set of aborted msg_ids
136 aborted = Set()
137 aborted = Set()
@@ -352,15 +353,18 b' class Kernel(Configurable):'
352 # raw_input in the user namespace.
353 # raw_input in the user namespace.
353 if content.get('allow_stdin', False):
354 if content.get('allow_stdin', False):
354 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
355 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
356 input = lambda prompt='': eval(raw_input(prompt))
355 else:
357 else:
356 raw_input = lambda prompt='' : self._no_raw_input()
358 raw_input = input = lambda prompt='' : self._no_raw_input()
357
359
358 if py3compat.PY3:
360 if py3compat.PY3:
359 self._sys_raw_input = __builtin__.input
361 self._sys_raw_input = __builtin__.input
360 __builtin__.input = raw_input
362 __builtin__.input = raw_input
361 else:
363 else:
362 self._sys_raw_input = __builtin__.raw_input
364 self._sys_raw_input = __builtin__.raw_input
365 self._sys_eval_input = __builtin__.input
363 __builtin__.raw_input = raw_input
366 __builtin__.raw_input = raw_input
367 __builtin__.input = input
364
368
365 # Set the parent message of the display hook and out streams.
369 # Set the parent message of the display hook and out streams.
366 shell.displayhook.set_parent(parent)
370 shell.displayhook.set_parent(parent)
@@ -403,6 +407,7 b' class Kernel(Configurable):'
403 __builtin__.input = self._sys_raw_input
407 __builtin__.input = self._sys_raw_input
404 else:
408 else:
405 __builtin__.raw_input = self._sys_raw_input
409 __builtin__.raw_input = self._sys_raw_input
410 __builtin__.input = self._sys_eval_input
406
411
407 reply_content[u'status'] = status
412 reply_content[u'status'] = status
408
413
@@ -1,6 +1,6 b''
1 {
1 {
2 "metadata": {
2 "metadata": {
3 "name": "Frontend-Kernel Model"
3 "name": ""
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "nbformat_minor": 0,
@@ -152,6 +152,21 b''
152 "cell_type": "code",
152 "cell_type": "code",
153 "collapsed": false,
153 "collapsed": false,
154 "input": [
154 "input": [
155 "# Python 3 compat\n",
156 "try:\n",
157 " raw_input\n",
158 "except NameError:\n",
159 " raw_input = input"
160 ],
161 "language": "python",
162 "metadata": {},
163 "outputs": [],
164 "prompt_number": 1
165 },
166 {
167 "cell_type": "code",
168 "collapsed": false,
169 "input": [
155 "name = raw_input(\"What is your name? \")\n",
170 "name = raw_input(\"What is your name? \")\n",
156 "name"
171 "name"
157 ],
172 ],
@@ -169,13 +184,49 b''
169 {
184 {
170 "metadata": {},
185 "metadata": {},
171 "output_type": "pyout",
186 "output_type": "pyout",
172 "prompt_number": 1,
187 "prompt_number": 2,
173 "text": [
188 "text": [
174 "u'Sir Robin'"
189 "'Sir Robin'"
175 ]
190 ]
176 }
191 }
177 ],
192 ],
178 "prompt_number": 1
193 "prompt_number": 2
194 },
195 {
196 "cell_type": "markdown",
197 "metadata": {},
198 "source": [
199 "**Python 2-only**: the eval input works as well (`input` is just `eval(raw_input(prompt))`)"
200 ]
201 },
202 {
203 "cell_type": "code",
204 "collapsed": false,
205 "input": [
206 "fingers = input(\"How many fingers? \")\n",
207 "fingers, type(fingers)"
208 ],
209 "language": "python",
210 "metadata": {},
211 "outputs": [
212 {
213 "name": "stdout",
214 "output_type": "stream",
215 "stream": "stdout",
216 "text": [
217 "How many fingers? 4\n"
218 ]
219 },
220 {
221 "metadata": {},
222 "output_type": "pyout",
223 "prompt_number": 3,
224 "text": [
225 "(4, int)"
226 ]
227 }
228 ],
229 "prompt_number": 3
179 },
230 },
180 {
231 {
181 "cell_type": "code",
232 "cell_type": "code",
@@ -195,13 +246,13 b''
195 "output_type": "pyerr",
246 "output_type": "pyerr",
196 "traceback": [
247 "traceback": [
197 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
248 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
198 "\u001b[1;32m<ipython-input-2-a5097cc0c0c5>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
249 "\u001b[1;32m<ipython-input-4-a5097cc0c0c5>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
199 "\u001b[1;32m<ipython-input-2-a5097cc0c0c5>\u001b[0m in \u001b[0;36mdiv\u001b[1;34m(x, y)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
250 "\u001b[1;32m<ipython-input-4-a5097cc0c0c5>\u001b[0m in \u001b[0;36mdiv\u001b[1;34m(x, y)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
200 "\u001b[1;31mZeroDivisionError\u001b[0m: integer division or modulo by zero"
251 "\u001b[1;31mZeroDivisionError\u001b[0m: integer division or modulo by zero"
201 ]
252 ]
202 }
253 }
203 ],
254 ],
204 "prompt_number": 2
255 "prompt_number": 4
205 },
256 },
206 {
257 {
207 "cell_type": "code",
258 "cell_type": "code",
@@ -216,7 +267,7 b''
216 "output_type": "stream",
267 "output_type": "stream",
217 "stream": "stdout",
268 "stream": "stdout",
218 "text": [
269 "text": [
219 "> \u001b[1;32m<ipython-input-2-a5097cc0c0c5>\u001b[0m(2)\u001b[0;36mdiv\u001b[1;34m()\u001b[0m\n",
270 "> \u001b[1;32m<ipython-input-4-a5097cc0c0c5>\u001b[0m(2)\u001b[0;36mdiv\u001b[1;34m()\u001b[0m\n",
220 "\u001b[1;32m 1 \u001b[1;33m\u001b[1;32mdef\u001b[0m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
271 "\u001b[1;32m 1 \u001b[1;33m\u001b[1;32mdef\u001b[0m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
221 "\u001b[0m\u001b[1;32m----> 2 \u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
272 "\u001b[0m\u001b[1;32m----> 2 \u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
222 "\u001b[0m\u001b[1;32m 3 \u001b[1;33m\u001b[1;33m\u001b[0m\u001b[0m\n",
273 "\u001b[0m\u001b[1;32m 3 \u001b[1;33m\u001b[1;33m\u001b[0m\u001b[0m\n",
@@ -262,7 +313,7 b''
262 ]
313 ]
263 }
314 }
264 ],
315 ],
265 "prompt_number": 3
316 "prompt_number": 5
266 }
317 }
267 ],
318 ],
268 "metadata": {}
319 "metadata": {}
General Comments 0
You need to be logged in to leave comments. Login now