Show More
@@ -2395,7 +2395,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
2395 | def _user_obj_error(self): |
|
2395 | def _user_obj_error(self): | |
2396 | """return simple exception dict |
|
2396 | """return simple exception dict | |
2397 |
|
2397 | |||
2398 |
for use in user_ |
|
2398 | for use in user_expressions | |
2399 | """ |
|
2399 | """ | |
2400 |
|
2400 | |||
2401 | etype, evalue, tb = self._get_exc_info() |
|
2401 | etype, evalue, tb = self._get_exc_info() | |
@@ -2413,7 +2413,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
2413 | def _format_user_obj(self, obj): |
|
2413 | def _format_user_obj(self, obj): | |
2414 | """format a user object to display dict |
|
2414 | """format a user object to display dict | |
2415 |
|
2415 | |||
2416 |
for use in user_expressions |
|
2416 | for use in user_expressions | |
2417 | """ |
|
2417 | """ | |
2418 |
|
2418 | |||
2419 | data, md = self.display_formatter.format(obj) |
|
2419 | data, md = self.display_formatter.format(obj) | |
@@ -2424,30 +2424,6 b' class InteractiveShell(SingletonConfigurable):' | |||||
2424 | } |
|
2424 | } | |
2425 | return value |
|
2425 | return value | |
2426 |
|
2426 | |||
2427 | def user_variables(self, names): |
|
|||
2428 | """Get a list of variable names from the user's namespace. |
|
|||
2429 |
|
||||
2430 | Parameters |
|
|||
2431 | ---------- |
|
|||
2432 | names : list of strings |
|
|||
2433 | A list of names of variables to be read from the user namespace. |
|
|||
2434 |
|
||||
2435 | Returns |
|
|||
2436 | ------- |
|
|||
2437 | A dict, keyed by the input names and with the rich mime-type repr(s) of each value. |
|
|||
2438 | Each element will be a sub-dict of the same form as a display_data message. |
|
|||
2439 | """ |
|
|||
2440 | out = {} |
|
|||
2441 | user_ns = self.user_ns |
|
|||
2442 |
|
||||
2443 | for varname in names: |
|
|||
2444 | try: |
|
|||
2445 | value = self._format_user_obj(user_ns[varname]) |
|
|||
2446 | except: |
|
|||
2447 | value = self._user_obj_error() |
|
|||
2448 | out[varname] = value |
|
|||
2449 | return out |
|
|||
2450 |
|
||||
2451 | def user_expressions(self, expressions): |
|
2427 | def user_expressions(self, expressions): | |
2452 | """Evaluate a dict of expressions in the user's namespace. |
|
2428 | """Evaluate a dict of expressions in the user's namespace. | |
2453 |
|
2429 |
@@ -4,22 +4,11 b'' | |||||
4 | Historically the main classes in interactiveshell have been under-tested. This |
|
4 | Historically the main classes in interactiveshell have been under-tested. This | |
5 | module should grow as many single-method tests as possible to trap many of the |
|
5 | module should grow as many single-method tests as possible to trap many of the | |
6 | recurring bugs we seem to encounter with high-level interaction. |
|
6 | recurring bugs we seem to encounter with high-level interaction. | |
7 |
|
||||
8 | Authors |
|
|||
9 | ------- |
|
|||
10 | * Fernando Perez |
|
|||
11 | """ |
|
7 | """ | |
12 | #----------------------------------------------------------------------------- |
|
|||
13 | # Copyright (C) 2011 The IPython Development Team |
|
|||
14 | # |
|
|||
15 | # Distributed under the terms of the BSD License. The full license is in |
|
|||
16 | # the file COPYING, distributed as part of this software. |
|
|||
17 | #----------------------------------------------------------------------------- |
|
|||
18 |
|
8 | |||
19 | #----------------------------------------------------------------------------- |
|
9 | # Copyright (c) IPython Development Team. | |
20 | # Imports |
|
10 | # Distributed under the terms of the Modified BSD License. | |
21 | #----------------------------------------------------------------------------- |
|
11 | ||
22 | # stdlib |
|
|||
23 | import ast |
|
12 | import ast | |
24 | import os |
|
13 | import os | |
25 | import signal |
|
14 | import signal | |
@@ -33,10 +22,8 b' except ImportError:' | |||||
33 | import mock |
|
22 | import mock | |
34 | from os.path import join |
|
23 | from os.path import join | |
35 |
|
24 | |||
36 | # third-party |
|
|||
37 | import nose.tools as nt |
|
25 | import nose.tools as nt | |
38 |
|
26 | |||
39 | # Our own |
|
|||
40 | from IPython.core.inputtransformer import InputTransformer |
|
27 | from IPython.core.inputtransformer import InputTransformer | |
41 | from IPython.testing.decorators import skipif, skip_win32, onlyif_unicode_paths |
|
28 | from IPython.testing.decorators import skipif, skip_win32, onlyif_unicode_paths | |
42 | from IPython.testing import tools as tt |
|
29 | from IPython.testing import tools as tt | |
@@ -645,7 +632,7 b' def test_user_variables():' | |||||
645 |
|
632 | |||
646 | ip.user_ns['dummy'] = d = DummyRepr() |
|
633 | ip.user_ns['dummy'] = d = DummyRepr() | |
647 | keys = set(['dummy', 'doesnotexist']) |
|
634 | keys = set(['dummy', 'doesnotexist']) | |
648 | r = ip.user_variables(keys) |
|
635 | r = ip.user_expressions({ key:key for key in keys}) | |
649 |
|
636 | |||
650 | nt.assert_equal(keys, set(r.keys())) |
|
637 | nt.assert_equal(keys, set(r.keys())) | |
651 | dummy = r['dummy'] |
|
638 | dummy = r['dummy'] | |
@@ -660,7 +647,7 b' def test_user_variables():' | |||||
660 |
|
647 | |||
661 | dne = r['doesnotexist'] |
|
648 | dne = r['doesnotexist'] | |
662 | nt.assert_equal(dne['status'], 'error') |
|
649 | nt.assert_equal(dne['status'], 'error') | |
663 |
nt.assert_equal(dne['ename'], ' |
|
650 | nt.assert_equal(dne['ename'], 'NameError') | |
664 |
|
651 | |||
665 | # back to text only |
|
652 | # back to text only | |
666 | ip.display_formatter.active_types = ['text/plain'] |
|
653 | ip.display_formatter.active_types = ['text/plain'] |
@@ -302,7 +302,6 b' var IPython = (function (IPython) {' | |||||
302 | * @param {object} [options] |
|
302 | * @param {object} [options] | |
303 | * @param [options.silent=false] {Boolean} |
|
303 | * @param [options.silent=false] {Boolean} | |
304 | * @param [options.user_expressions=empty_dict] {Dict} |
|
304 | * @param [options.user_expressions=empty_dict] {Dict} | |
305 | * @param [options.user_variables=empty_list] {List od Strings} |
|
|||
306 | * @param [options.allow_stdin=false] {Boolean} true|false |
|
305 | * @param [options.allow_stdin=false] {Boolean} true|false | |
307 | * |
|
306 | * | |
308 | * @example |
|
307 | * @example | |
@@ -312,7 +311,6 b' var IPython = (function (IPython) {' | |||||
312 | * |
|
311 | * | |
313 | * options = { |
|
312 | * options = { | |
314 | * silent : true, |
|
313 | * silent : true, | |
315 | * user_variables : [], |
|
|||
316 | * user_expressions : {}, |
|
314 | * user_expressions : {}, | |
317 | * allow_stdin : false |
|
315 | * allow_stdin : false | |
318 | * } |
|
316 | * } | |
@@ -342,7 +340,6 b' var IPython = (function (IPython) {' | |||||
342 | code : code, |
|
340 | code : code, | |
343 | silent : true, |
|
341 | silent : true, | |
344 | store_history : false, |
|
342 | store_history : false, | |
345 | user_variables : [], |
|
|||
346 | user_expressions : {}, |
|
343 | user_expressions : {}, | |
347 | allow_stdin : false |
|
344 | allow_stdin : false | |
348 | }; |
|
345 | }; |
@@ -1,20 +1,10 b'' | |||||
1 | """Base classes to manage a Client's interaction with a running kernel |
|
1 | """Base classes to manage a Client's interaction with a running kernel""" | |
2 | """ |
|
|||
3 |
|
2 | |||
4 | #----------------------------------------------------------------------------- |
|
3 | # Copyright (c) IPython Development Team. | |
5 | # Copyright (C) 2013 The IPython Development Team |
|
4 | # Distributed under the terms of the Modified BSD License. | |
6 | # |
|
|||
7 | # Distributed under the terms of the BSD License. The full license is in |
|
|||
8 | # the file COPYING, distributed as part of this software. |
|
|||
9 | #----------------------------------------------------------------------------- |
|
|||
10 |
|
||||
11 | #----------------------------------------------------------------------------- |
|
|||
12 | # Imports |
|
|||
13 | #----------------------------------------------------------------------------- |
|
|||
14 |
|
5 | |||
15 | from __future__ import absolute_import |
|
6 | from __future__ import absolute_import | |
16 |
|
7 | |||
17 | # Standard library imports |
|
|||
18 | import atexit |
|
8 | import atexit | |
19 | import errno |
|
9 | import errno | |
20 | from threading import Thread |
|
10 | from threading import Thread | |
@@ -227,7 +217,7 b' class ShellChannel(ZMQSocketChannel):' | |||||
227 | raise NotImplementedError('call_handlers must be defined in a subclass.') |
|
217 | raise NotImplementedError('call_handlers must be defined in a subclass.') | |
228 |
|
218 | |||
229 | def execute(self, code, silent=False, store_history=True, |
|
219 | def execute(self, code, silent=False, store_history=True, | |
230 |
|
|
220 | user_expressions=None, allow_stdin=None): | |
231 | """Execute code in the kernel. |
|
221 | """Execute code in the kernel. | |
232 |
|
222 | |||
233 | Parameters |
|
223 | Parameters | |
@@ -243,11 +233,6 b' class ShellChannel(ZMQSocketChannel):' | |||||
243 | If set, the kernel will store command history. This is forced |
|
233 | If set, the kernel will store command history. This is forced | |
244 | to be False if silent is True. |
|
234 | to be False if silent is True. | |
245 |
|
235 | |||
246 | user_variables : list, optional |
|
|||
247 | A list of variable names to pull from the user's namespace. They |
|
|||
248 | will come back as a dict with these names as keys and their |
|
|||
249 | :func:`repr` as values. |
|
|||
250 |
|
||||
251 | user_expressions : dict, optional |
|
236 | user_expressions : dict, optional | |
252 | A dict mapping names to expressions to be evaluated in the user's |
|
237 | A dict mapping names to expressions to be evaluated in the user's | |
253 | dict. The expression values are returned as strings formatted using |
|
238 | dict. The expression values are returned as strings formatted using | |
@@ -264,8 +249,6 b' class ShellChannel(ZMQSocketChannel):' | |||||
264 | ------- |
|
249 | ------- | |
265 | The msg_id of the message sent. |
|
250 | The msg_id of the message sent. | |
266 | """ |
|
251 | """ | |
267 | if user_variables is None: |
|
|||
268 | user_variables = [] |
|
|||
269 | if user_expressions is None: |
|
252 | if user_expressions is None: | |
270 | user_expressions = {} |
|
253 | user_expressions = {} | |
271 | if allow_stdin is None: |
|
254 | if allow_stdin is None: | |
@@ -275,13 +258,11 b' class ShellChannel(ZMQSocketChannel):' | |||||
275 | # Don't waste network traffic if inputs are invalid |
|
258 | # Don't waste network traffic if inputs are invalid | |
276 | if not isinstance(code, string_types): |
|
259 | if not isinstance(code, string_types): | |
277 | raise ValueError('code %r must be a string' % code) |
|
260 | raise ValueError('code %r must be a string' % code) | |
278 | validate_string_list(user_variables) |
|
|||
279 | validate_string_dict(user_expressions) |
|
261 | validate_string_dict(user_expressions) | |
280 |
|
262 | |||
281 | # Create class for content/msg creation. Related to, but possibly |
|
263 | # Create class for content/msg creation. Related to, but possibly | |
282 | # not in Session. |
|
264 | # not in Session. | |
283 | content = dict(code=code, silent=silent, store_history=store_history, |
|
265 | content = dict(code=code, silent=silent, store_history=store_history, | |
284 | user_variables=user_variables, |
|
|||
285 | user_expressions=user_expressions, |
|
266 | user_expressions=user_expressions, | |
286 | allow_stdin=allow_stdin, |
|
267 | allow_stdin=allow_stdin, | |
287 | ) |
|
268 | ) |
@@ -1,11 +1,7 b'' | |||||
1 | """Abstract base classes for kernel client channels""" |
|
1 | """Abstract base classes for kernel client channels""" | |
2 |
|
2 | |||
3 | #----------------------------------------------------------------------------- |
|
3 | # Copyright (c) IPython Development Team. | |
4 | # Copyright (C) 2013 The IPython Development Team |
|
4 | # Distributed under the terms of the Modified BSD License. | |
5 | # |
|
|||
6 | # Distributed under the terms of the BSD License. The full license is in |
|
|||
7 | # the file COPYING, distributed as part of this software. |
|
|||
8 | #----------------------------------------------------------------------------- |
|
|||
9 |
|
5 | |||
10 | import abc |
|
6 | import abc | |
11 |
|
7 | |||
@@ -42,7 +38,7 b' class ShellChannelABC(ChannelABC):' | |||||
42 |
|
38 | |||
43 | @abc.abstractmethod |
|
39 | @abc.abstractmethod | |
44 | def execute(self, code, silent=False, store_history=True, |
|
40 | def execute(self, code, silent=False, store_history=True, | |
45 |
|
|
41 | user_expressions=None, allow_stdin=None): | |
46 | pass |
|
42 | pass | |
47 |
|
43 | |||
48 | @abc.abstractmethod |
|
44 | @abc.abstractmethod |
@@ -1,23 +1,13 b'' | |||||
1 |
""" |
|
1 | """A kernel client for in-process kernels.""" | |
2 |
|
2 | |||
3 | #----------------------------------------------------------------------------- |
|
3 | # Copyright (c) IPython Development Team. | |
4 | # Copyright (C) 2012 The IPython Development Team |
|
4 | # Distributed under the terms of the Modified BSD License. | |
5 | # |
|
|||
6 | # Distributed under the terms of the BSD License. The full license is in |
|
|||
7 | # the file COPYING, distributed as part of this software. |
|
|||
8 | #----------------------------------------------------------------------------- |
|
|||
9 |
|
||||
10 | #----------------------------------------------------------------------------- |
|
|||
11 | # Imports |
|
|||
12 | #----------------------------------------------------------------------------- |
|
|||
13 |
|
5 | |||
14 | # IPython imports |
|
|||
15 | from IPython.kernel.channelsabc import ( |
|
6 | from IPython.kernel.channelsabc import ( | |
16 | ShellChannelABC, IOPubChannelABC, |
|
7 | ShellChannelABC, IOPubChannelABC, | |
17 | HBChannelABC, StdInChannelABC, |
|
8 | HBChannelABC, StdInChannelABC, | |
18 | ) |
|
9 | ) | |
19 |
|
10 | |||
20 | # Local imports |
|
|||
21 | from .socket import DummySocket |
|
11 | from .socket import DummySocket | |
22 |
|
12 | |||
23 | #----------------------------------------------------------------------------- |
|
13 | #----------------------------------------------------------------------------- | |
@@ -94,11 +84,10 b' class InProcessShellChannel(InProcessChannel):' | |||||
94 | #-------------------------------------------------------------------------- |
|
84 | #-------------------------------------------------------------------------- | |
95 |
|
85 | |||
96 | def execute(self, code, silent=False, store_history=True, |
|
86 | def execute(self, code, silent=False, store_history=True, | |
97 |
|
|
87 | user_expressions={}, allow_stdin=None): | |
98 | if allow_stdin is None: |
|
88 | if allow_stdin is None: | |
99 | allow_stdin = self.allow_stdin |
|
89 | allow_stdin = self.allow_stdin | |
100 | content = dict(code=code, silent=silent, store_history=store_history, |
|
90 | content = dict(code=code, silent=silent, store_history=store_history, | |
101 | user_variables=user_variables, |
|
|||
102 | user_expressions=user_expressions, |
|
91 | user_expressions=user_expressions, | |
103 | allow_stdin=allow_stdin) |
|
92 | allow_stdin=allow_stdin) | |
104 | msg = self.client.session.msg('execute_request', content) |
|
93 | msg = self.client.session.msg('execute_request', content) |
@@ -75,7 +75,8 b' class RMessage(Reference):' | |||||
75 | def check(self, d): |
|
75 | def check(self, d): | |
76 | super(RMessage, self).check(d) |
|
76 | super(RMessage, self).check(d) | |
77 | RHeader().check(self.header) |
|
77 | RHeader().check(self.header) | |
78 |
|
|
78 | if self.parent_header: | |
|
79 | RHeader().check(self.parent_header) | |||
79 |
|
80 | |||
80 | class RHeader(Reference): |
|
81 | class RHeader(Reference): | |
81 | msg_id = Unicode() |
|
82 | msg_id = Unicode() | |
@@ -99,7 +100,6 b' class ExecuteReply(Reference):' | |||||
99 |
|
100 | |||
100 | class ExecuteReplyOkay(Reference): |
|
101 | class ExecuteReplyOkay(Reference): | |
101 | payload = List(Dict) |
|
102 | payload = List(Dict) | |
102 | user_variables = Dict() |
|
|||
103 | user_expressions = Dict() |
|
103 | user_expressions = Dict() | |
104 |
|
104 | |||
105 |
|
105 | |||
@@ -294,28 +294,6 b' def test_execute_inc():' | |||||
294 | nt.assert_equal(count_2, count+1) |
|
294 | nt.assert_equal(count_2, count+1) | |
295 |
|
295 | |||
296 |
|
296 | |||
297 | def test_user_variables(): |
|
|||
298 | flush_channels() |
|
|||
299 |
|
||||
300 | msg_id, reply = execute(code='x=1', user_variables=['x']) |
|
|||
301 | user_variables = reply['user_variables'] |
|
|||
302 | nt.assert_equal(user_variables, {u'x': { |
|
|||
303 | u'status': u'ok', |
|
|||
304 | u'data': {u'text/plain': u'1'}, |
|
|||
305 | u'metadata': {}, |
|
|||
306 | }}) |
|
|||
307 |
|
||||
308 |
|
||||
309 | def test_user_variables_fail(): |
|
|||
310 | flush_channels() |
|
|||
311 |
|
||||
312 | msg_id, reply = execute(code='x=1', user_variables=['nosuchname']) |
|
|||
313 | user_variables = reply['user_variables'] |
|
|||
314 | foo = user_variables['nosuchname'] |
|
|||
315 | nt.assert_equal(foo['status'], 'error') |
|
|||
316 | nt.assert_equal(foo['ename'], 'KeyError') |
|
|||
317 |
|
||||
318 |
|
||||
319 | def test_user_expressions(): |
|
297 | def test_user_expressions(): | |
320 | flush_channels() |
|
298 | flush_channels() | |
321 |
|
299 |
@@ -424,16 +424,12 b' class Kernel(Configurable):' | |||||
424 |
|
424 | |||
425 |
|
425 | |||
426 | # At this point, we can tell whether the main code execution succeeded |
|
426 | # At this point, we can tell whether the main code execution succeeded | |
427 |
# or not. If it did, we proceed to evaluate user_ |
|
427 | # or not. If it did, we proceed to evaluate user_expressions | |
428 | if reply_content['status'] == 'ok': |
|
428 | if reply_content['status'] == 'ok': | |
429 | reply_content[u'user_variables'] = \ |
|
|||
430 | shell.user_variables(content.get(u'user_variables', [])) |
|
|||
431 | reply_content[u'user_expressions'] = \ |
|
429 | reply_content[u'user_expressions'] = \ | |
432 | shell.user_expressions(content.get(u'user_expressions', {})) |
|
430 | shell.user_expressions(content.get(u'user_expressions', {})) | |
433 | else: |
|
431 | else: | |
434 |
# If there was an error, don't even try to compute |
|
432 | # If there was an error, don't even try to compute expressions | |
435 | # expressions |
|
|||
436 | reply_content[u'user_variables'] = {} |
|
|||
437 | reply_content[u'user_expressions'] = {} |
|
433 | reply_content[u'user_expressions'] = {} | |
438 |
|
434 | |||
439 | # Payloads should be retrieved regardless of outcome, so we can both |
|
435 | # Payloads should be retrieved regardless of outcome, so we can both |
@@ -1285,7 +1285,7 b' class Client(HasTraits):' | |||||
1285 | if not isinstance(metadata, dict): |
|
1285 | if not isinstance(metadata, dict): | |
1286 | raise TypeError("metadata must be dict, not %s" % type(metadata)) |
|
1286 | raise TypeError("metadata must be dict, not %s" % type(metadata)) | |
1287 |
|
1287 | |||
1288 |
content = dict(code=code, silent=bool(silent), |
|
1288 | content = dict(code=code, silent=bool(silent), user_expressions={}) | |
1289 |
|
1289 | |||
1290 |
|
1290 | |||
1291 | msg = self.session.send(socket, "execute_request", content=content, ident=ident, |
|
1291 | msg = self.session.send(socket, "execute_request", content=content, ident=ident, |
General Comments 0
You need to be logged in to leave comments.
Login now