Show More
@@ -2395,7 +2395,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2395 | 2395 | def _user_obj_error(self): |
|
2396 | 2396 | """return simple exception dict |
|
2397 | 2397 | |
|
2398 |
for use in user_ |
|
|
2398 | for use in user_expressions | |
|
2399 | 2399 | """ |
|
2400 | 2400 | |
|
2401 | 2401 | etype, evalue, tb = self._get_exc_info() |
@@ -2413,7 +2413,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2413 | 2413 | def _format_user_obj(self, obj): |
|
2414 | 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 | 2419 | data, md = self.display_formatter.format(obj) |
@@ -2424,30 +2424,6 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2424 | 2424 | } |
|
2425 | 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 | 2427 | def user_expressions(self, expressions): |
|
2452 | 2428 | """Evaluate a dict of expressions in the user's namespace. |
|
2453 | 2429 |
@@ -4,22 +4,11 b'' | |||
|
4 | 4 | Historically the main classes in interactiveshell have been under-tested. This |
|
5 | 5 | module should grow as many single-method tests as possible to trap many of the |
|
6 | 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 | #----------------------------------------------------------------------------- | |
|
20 | # Imports | |
|
21 | #----------------------------------------------------------------------------- | |
|
22 | # stdlib | |
|
9 | # Copyright (c) IPython Development Team. | |
|
10 | # Distributed under the terms of the Modified BSD License. | |
|
11 | ||
|
23 | 12 | import ast |
|
24 | 13 | import os |
|
25 | 14 | import signal |
@@ -33,10 +22,8 b' except ImportError:' | |||
|
33 | 22 | import mock |
|
34 | 23 | from os.path import join |
|
35 | 24 | |
|
36 | # third-party | |
|
37 | 25 | import nose.tools as nt |
|
38 | 26 | |
|
39 | # Our own | |
|
40 | 27 | from IPython.core.inputtransformer import InputTransformer |
|
41 | 28 | from IPython.testing.decorators import skipif, skip_win32, onlyif_unicode_paths |
|
42 | 29 | from IPython.testing import tools as tt |
@@ -645,7 +632,7 b' def test_user_variables():' | |||
|
645 | 632 | |
|
646 | 633 | ip.user_ns['dummy'] = d = DummyRepr() |
|
647 | 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 | 637 | nt.assert_equal(keys, set(r.keys())) |
|
651 | 638 | dummy = r['dummy'] |
@@ -660,7 +647,7 b' def test_user_variables():' | |||
|
660 | 647 | |
|
661 | 648 | dne = r['doesnotexist'] |
|
662 | 649 | nt.assert_equal(dne['status'], 'error') |
|
663 |
nt.assert_equal(dne['ename'], ' |
|
|
650 | nt.assert_equal(dne['ename'], 'NameError') | |
|
664 | 651 | |
|
665 | 652 | # back to text only |
|
666 | 653 | ip.display_formatter.active_types = ['text/plain'] |
@@ -302,7 +302,6 b' var IPython = (function (IPython) {' | |||
|
302 | 302 | * @param {object} [options] |
|
303 | 303 | * @param [options.silent=false] {Boolean} |
|
304 | 304 | * @param [options.user_expressions=empty_dict] {Dict} |
|
305 | * @param [options.user_variables=empty_list] {List od Strings} | |
|
306 | 305 | * @param [options.allow_stdin=false] {Boolean} true|false |
|
307 | 306 | * |
|
308 | 307 | * @example |
@@ -312,7 +311,6 b' var IPython = (function (IPython) {' | |||
|
312 | 311 | * |
|
313 | 312 | * options = { |
|
314 | 313 | * silent : true, |
|
315 | * user_variables : [], | |
|
316 | 314 | * user_expressions : {}, |
|
317 | 315 | * allow_stdin : false |
|
318 | 316 | * } |
@@ -342,7 +340,6 b' var IPython = (function (IPython) {' | |||
|
342 | 340 | code : code, |
|
343 | 341 | silent : true, |
|
344 | 342 | store_history : false, |
|
345 | user_variables : [], | |
|
346 | 343 | user_expressions : {}, |
|
347 | 344 | allow_stdin : false |
|
348 | 345 | }; |
@@ -1,20 +1,10 b'' | |||
|
1 | """Base classes to manage a Client's interaction with a running kernel | |
|
2 | """ | |
|
1 | """Base classes to manage a Client's interaction with a running kernel""" | |
|
3 | 2 | |
|
4 | #----------------------------------------------------------------------------- | |
|
5 | # Copyright (C) 2013 The IPython Development Team | |
|
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 | #----------------------------------------------------------------------------- | |
|
3 | # Copyright (c) IPython Development Team. | |
|
4 | # Distributed under the terms of the Modified BSD License. | |
|
14 | 5 | |
|
15 | 6 | from __future__ import absolute_import |
|
16 | 7 | |
|
17 | # Standard library imports | |
|
18 | 8 | import atexit |
|
19 | 9 | import errno |
|
20 | 10 | from threading import Thread |
@@ -227,7 +217,7 b' class ShellChannel(ZMQSocketChannel):' | |||
|
227 | 217 | raise NotImplementedError('call_handlers must be defined in a subclass.') |
|
228 | 218 | |
|
229 | 219 | def execute(self, code, silent=False, store_history=True, |
|
230 |
|
|
|
220 | user_expressions=None, allow_stdin=None): | |
|
231 | 221 | """Execute code in the kernel. |
|
232 | 222 | |
|
233 | 223 | Parameters |
@@ -243,11 +233,6 b' class ShellChannel(ZMQSocketChannel):' | |||
|
243 | 233 | If set, the kernel will store command history. This is forced |
|
244 | 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 | 236 | user_expressions : dict, optional |
|
252 | 237 | A dict mapping names to expressions to be evaluated in the user's |
|
253 | 238 | dict. The expression values are returned as strings formatted using |
@@ -264,8 +249,6 b' class ShellChannel(ZMQSocketChannel):' | |||
|
264 | 249 | ------- |
|
265 | 250 | The msg_id of the message sent. |
|
266 | 251 | """ |
|
267 | if user_variables is None: | |
|
268 | user_variables = [] | |
|
269 | 252 | if user_expressions is None: |
|
270 | 253 | user_expressions = {} |
|
271 | 254 | if allow_stdin is None: |
@@ -275,13 +258,11 b' class ShellChannel(ZMQSocketChannel):' | |||
|
275 | 258 | # Don't waste network traffic if inputs are invalid |
|
276 | 259 | if not isinstance(code, string_types): |
|
277 | 260 | raise ValueError('code %r must be a string' % code) |
|
278 | validate_string_list(user_variables) | |
|
279 | 261 | validate_string_dict(user_expressions) |
|
280 | 262 | |
|
281 | 263 | # Create class for content/msg creation. Related to, but possibly |
|
282 | 264 | # not in Session. |
|
283 | 265 | content = dict(code=code, silent=silent, store_history=store_history, |
|
284 | user_variables=user_variables, | |
|
285 | 266 | user_expressions=user_expressions, |
|
286 | 267 | allow_stdin=allow_stdin, |
|
287 | 268 | ) |
@@ -1,11 +1,7 b'' | |||
|
1 | 1 | """Abstract base classes for kernel client channels""" |
|
2 | 2 | |
|
3 | #----------------------------------------------------------------------------- | |
|
4 | # Copyright (C) 2013 The IPython Development Team | |
|
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 | #----------------------------------------------------------------------------- | |
|
3 | # Copyright (c) IPython Development Team. | |
|
4 | # Distributed under the terms of the Modified BSD License. | |
|
9 | 5 | |
|
10 | 6 | import abc |
|
11 | 7 | |
@@ -42,7 +38,7 b' class ShellChannelABC(ChannelABC):' | |||
|
42 | 38 | |
|
43 | 39 | @abc.abstractmethod |
|
44 | 40 | def execute(self, code, silent=False, store_history=True, |
|
45 |
|
|
|
41 | user_expressions=None, allow_stdin=None): | |
|
46 | 42 | pass |
|
47 | 43 | |
|
48 | 44 | @abc.abstractmethod |
@@ -1,23 +1,13 b'' | |||
|
1 |
""" |
|
|
1 | """A kernel client for in-process kernels.""" | |
|
2 | 2 | |
|
3 | #----------------------------------------------------------------------------- | |
|
4 | # Copyright (C) 2012 The IPython Development Team | |
|
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 | #----------------------------------------------------------------------------- | |
|
3 | # Copyright (c) IPython Development Team. | |
|
4 | # Distributed under the terms of the Modified BSD License. | |
|
13 | 5 | |
|
14 | # IPython imports | |
|
15 | 6 | from IPython.kernel.channelsabc import ( |
|
16 | 7 | ShellChannelABC, IOPubChannelABC, |
|
17 | 8 | HBChannelABC, StdInChannelABC, |
|
18 | 9 | ) |
|
19 | 10 | |
|
20 | # Local imports | |
|
21 | 11 | from .socket import DummySocket |
|
22 | 12 | |
|
23 | 13 | #----------------------------------------------------------------------------- |
@@ -94,11 +84,10 b' class InProcessShellChannel(InProcessChannel):' | |||
|
94 | 84 | #-------------------------------------------------------------------------- |
|
95 | 85 | |
|
96 | 86 | def execute(self, code, silent=False, store_history=True, |
|
97 |
|
|
|
87 | user_expressions={}, allow_stdin=None): | |
|
98 | 88 | if allow_stdin is None: |
|
99 | 89 | allow_stdin = self.allow_stdin |
|
100 | 90 | content = dict(code=code, silent=silent, store_history=store_history, |
|
101 | user_variables=user_variables, | |
|
102 | 91 | user_expressions=user_expressions, |
|
103 | 92 | allow_stdin=allow_stdin) |
|
104 | 93 | msg = self.client.session.msg('execute_request', content) |
@@ -75,7 +75,8 b' class RMessage(Reference):' | |||
|
75 | 75 | def check(self, d): |
|
76 | 76 | super(RMessage, self).check(d) |
|
77 | 77 | RHeader().check(self.header) |
|
78 |
|
|
|
78 | if self.parent_header: | |
|
79 | RHeader().check(self.parent_header) | |
|
79 | 80 | |
|
80 | 81 | class RHeader(Reference): |
|
81 | 82 | msg_id = Unicode() |
@@ -99,7 +100,6 b' class ExecuteReply(Reference):' | |||
|
99 | 100 | |
|
100 | 101 | class ExecuteReplyOkay(Reference): |
|
101 | 102 | payload = List(Dict) |
|
102 | user_variables = Dict() | |
|
103 | 103 | user_expressions = Dict() |
|
104 | 104 | |
|
105 | 105 | |
@@ -294,28 +294,6 b' def test_execute_inc():' | |||
|
294 | 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 | 297 | def test_user_expressions(): |
|
320 | 298 | flush_channels() |
|
321 | 299 |
@@ -424,16 +424,12 b' class Kernel(Configurable):' | |||
|
424 | 424 | |
|
425 | 425 | |
|
426 | 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 | 428 | if reply_content['status'] == 'ok': |
|
429 | reply_content[u'user_variables'] = \ | |
|
430 | shell.user_variables(content.get(u'user_variables', [])) | |
|
431 | 429 | reply_content[u'user_expressions'] = \ |
|
432 | 430 | shell.user_expressions(content.get(u'user_expressions', {})) |
|
433 | 431 | else: |
|
434 |
# If there was an error, don't even try to compute |
|
|
435 | # expressions | |
|
436 | reply_content[u'user_variables'] = {} | |
|
432 | # If there was an error, don't even try to compute expressions | |
|
437 | 433 | reply_content[u'user_expressions'] = {} |
|
438 | 434 | |
|
439 | 435 | # Payloads should be retrieved regardless of outcome, so we can both |
@@ -1285,7 +1285,7 b' class Client(HasTraits):' | |||
|
1285 | 1285 | if not isinstance(metadata, dict): |
|
1286 | 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 | 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