Show More
@@ -2360,9 +2360,37 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2360 | 2360 | # Things related to extracting values/expressions from kernel and user_ns |
|
2361 | 2361 | #------------------------------------------------------------------------- |
|
2362 | 2362 | |
|
2363 |
def _s |
|
|
2364 | etype, value = sys.exc_info()[:2] | |
|
2365 | return u'[ERROR] {e.__name__}: {v}'.format(e=etype, v=value) | |
|
2363 | def _user_obj_error(self): | |
|
2364 | """return simple exception dict | |
|
2365 | ||
|
2366 | for use in user_variables / expressions | |
|
2367 | """ | |
|
2368 | ||
|
2369 | etype, evalue, tb = self._get_exc_info() | |
|
2370 | stb = self.InteractiveTB.get_exception_only(etype, evalue) | |
|
2371 | ||
|
2372 | exc_info = { | |
|
2373 | u'status' : 'error', | |
|
2374 | u'traceback' : stb, | |
|
2375 | u'ename' : unicode(etype.__name__), | |
|
2376 | u'evalue' : py3compat.safe_unicode(evalue), | |
|
2377 | } | |
|
2378 | ||
|
2379 | return exc_info | |
|
2380 | ||
|
2381 | def _format_user_obj(self, obj): | |
|
2382 | """format a user object to display dict | |
|
2383 | ||
|
2384 | for use in user_expressions / variables | |
|
2385 | """ | |
|
2386 | ||
|
2387 | data, md = self.display_formatter.format(obj) | |
|
2388 | value = { | |
|
2389 | 'status' : 'ok', | |
|
2390 | 'data' : data, | |
|
2391 | 'metadata' : md, | |
|
2392 | } | |
|
2393 | return value | |
|
2366 | 2394 | |
|
2367 | 2395 | def user_variables(self, names): |
|
2368 | 2396 | """Get a list of variable names from the user's namespace. |
@@ -2374,15 +2402,17 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2374 | 2402 | |
|
2375 | 2403 | Returns |
|
2376 | 2404 | ------- |
|
2377 | A dict, keyed by the input names and with the repr() of each value. | |
|
2405 | A dict, keyed by the input names and with the rich mime-type repr(s) of each value. | |
|
2406 | Each element will be a sub-dict of the same form as a display_data message. | |
|
2378 | 2407 | """ |
|
2379 | 2408 | out = {} |
|
2380 | 2409 | user_ns = self.user_ns |
|
2410 | ||
|
2381 | 2411 | for varname in names: |
|
2382 | 2412 | try: |
|
2383 |
value = re |
|
|
2413 | value = self._format_user_obj(user_ns[varname]) | |
|
2384 | 2414 | except: |
|
2385 |
value = self._s |
|
|
2415 | value = self._user_obj_error() | |
|
2386 | 2416 | out[varname] = value |
|
2387 | 2417 | return out |
|
2388 | 2418 | |
@@ -2398,17 +2428,18 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2398 | 2428 | |
|
2399 | 2429 | Returns |
|
2400 | 2430 | ------- |
|
2401 |
A dict, keyed like the input expressions dict, with the r |
|
|
2402 | value. | |
|
2431 | A dict, keyed like the input expressions dict, with the rich mime-typed | |
|
2432 | display_data of each value. | |
|
2403 | 2433 | """ |
|
2404 | 2434 | out = {} |
|
2405 | 2435 | user_ns = self.user_ns |
|
2406 | 2436 | global_ns = self.user_global_ns |
|
2437 | ||
|
2407 | 2438 | for key, expr in expressions.iteritems(): |
|
2408 | 2439 | try: |
|
2409 |
value = re |
|
|
2440 | value = self._format_user_obj(eval(expr, global_ns, user_ns)) | |
|
2410 | 2441 | except: |
|
2411 |
value = self._s |
|
|
2442 | value = self._user_obj_error() | |
|
2412 | 2443 | out[key] = value |
|
2413 | 2444 | return out |
|
2414 | 2445 |
@@ -578,3 +578,72 b' class TestAstTransformError(unittest.TestCase):' | |||
|
578 | 578 | def test__IPYTHON__(): |
|
579 | 579 | # This shouldn't raise a NameError, that's all |
|
580 | 580 | __IPYTHON__ |
|
581 | ||
|
582 | ||
|
583 | class DummyRepr(object): | |
|
584 | def __repr__(self): | |
|
585 | return "DummyRepr" | |
|
586 | ||
|
587 | def _repr_html_(self): | |
|
588 | return "<b>dummy</b>" | |
|
589 | ||
|
590 | def _repr_javascript_(self): | |
|
591 | return "console.log('hi');", {'key': 'value'} | |
|
592 | ||
|
593 | ||
|
594 | def test_user_variables(): | |
|
595 | # enable all formatters | |
|
596 | ip.display_formatter.active_types = ip.display_formatter.format_types | |
|
597 | ||
|
598 | ip.user_ns['dummy'] = d = DummyRepr() | |
|
599 | keys = ['dummy', 'doesnotexist'] | |
|
600 | r = ip.user_variables(keys) | |
|
601 | ||
|
602 | nt.assert_equal(keys, list(r.keys())) | |
|
603 | dummy = r['dummy'] | |
|
604 | nt.assert_equal(['status', 'data', 'metadata'], list(dummy.keys())) | |
|
605 | nt.assert_equal(dummy['status'], 'ok') | |
|
606 | data = dummy['data'] | |
|
607 | metadata = dummy['metadata'] | |
|
608 | nt.assert_equal(data.get('text/html'), d._repr_html_()) | |
|
609 | js, jsmd = d._repr_javascript_() | |
|
610 | nt.assert_equal(data.get('application/javascript'), js) | |
|
611 | nt.assert_equal(metadata.get('application/javascript'), jsmd) | |
|
612 | ||
|
613 | dne = r['doesnotexist'] | |
|
614 | nt.assert_equal(dne['status'], 'error') | |
|
615 | nt.assert_equal(dne['ename'], 'KeyError') | |
|
616 | ||
|
617 | # back to text only | |
|
618 | ip.display_formatter.active_types = ['text/plain'] | |
|
619 | ||
|
620 | def test_user_expression(): | |
|
621 | # enable all formatters | |
|
622 | ip.display_formatter.active_types = ip.display_formatter.format_types | |
|
623 | query = { | |
|
624 | 'a' : '1 + 2', | |
|
625 | 'b' : '1/0', | |
|
626 | } | |
|
627 | r = ip.user_expressions(query) | |
|
628 | import pprint | |
|
629 | pprint.pprint(r) | |
|
630 | nt.assert_equal(r.keys(), query.keys()) | |
|
631 | a = r['a'] | |
|
632 | nt.assert_equal(['status', 'data', 'metadata'], list(a.keys())) | |
|
633 | nt.assert_equal(a['status'], 'ok') | |
|
634 | data = a['data'] | |
|
635 | metadata = a['metadata'] | |
|
636 | nt.assert_equal(data.get('text/plain'), '3') | |
|
637 | ||
|
638 | b = r['b'] | |
|
639 | nt.assert_equal(b['status'], 'error') | |
|
640 | nt.assert_equal(b['ename'], 'ZeroDivisionError') | |
|
641 | ||
|
642 | # back to text only | |
|
643 | ip.display_formatter.active_types = ['text/plain'] | |
|
644 | ||
|
645 | ||
|
646 | ||
|
647 | ||
|
648 | ||
|
649 |
General Comments 0
You need to be logged in to leave comments.
Login now