Show More
@@ -0,0 +1,62 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | # encoding: utf-8 | |
|
3 | """ | |
|
4 | A context manager for handling sys.displayhook. | |
|
5 | ||
|
6 | Authors: | |
|
7 | ||
|
8 | * Robert Kern | |
|
9 | * Brian Granger | |
|
10 | """ | |
|
11 | ||
|
12 | #----------------------------------------------------------------------------- | |
|
13 | # Copyright (C) 2008-2009 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 | ||
|
19 | #----------------------------------------------------------------------------- | |
|
20 | # Imports | |
|
21 | #----------------------------------------------------------------------------- | |
|
22 | ||
|
23 | import sys | |
|
24 | ||
|
25 | from IPython.core.component import Component | |
|
26 | ||
|
27 | #----------------------------------------------------------------------------- | |
|
28 | # Classes and functions | |
|
29 | #----------------------------------------------------------------------------- | |
|
30 | ||
|
31 | ||
|
32 | class DisplayTrap(Component): | |
|
33 | """Object to manage sys.displayhook. | |
|
34 | ||
|
35 | This came from IPython.core.kernel.display_hook, but is simplified | |
|
36 | (no callbacks or formatters) until more of the core is refactored. | |
|
37 | """ | |
|
38 | ||
|
39 | def __init__(self, parent, hook): | |
|
40 | super(DisplayTrap, self).__init__(parent, None, None) | |
|
41 | ||
|
42 | self.hook = hook | |
|
43 | self.old_hook = None | |
|
44 | ||
|
45 | def __enter__(self): | |
|
46 | self.set() | |
|
47 | return self | |
|
48 | ||
|
49 | def __exit__(self, type, value, traceback): | |
|
50 | self.unset() | |
|
51 | return True | |
|
52 | ||
|
53 | def set(self): | |
|
54 | """Set the hook.""" | |
|
55 | if sys.displayhook is not self.hook: | |
|
56 | self.old_hook = sys.displayhook | |
|
57 | sys.displayhook = self.hook | |
|
58 | ||
|
59 | def unset(self): | |
|
60 | """Unset the hook.""" | |
|
61 | sys.displayhook = self.old_hook | |
|
62 |
@@ -38,8 +38,8 b' BuiltinUndefined = BuiltinUndefined()' | |||
|
38 | 38 | class BuiltinTrap(Component): |
|
39 | 39 | shell = Instance('IPython.core.iplib.InteractiveShell') |
|
40 | 40 | |
|
41 |
def __init__(self, parent |
|
|
42 |
super(BuiltinTrap, self).__init__(parent, n |
|
|
41 | def __init__(self, parent): | |
|
42 | super(BuiltinTrap, self).__init__(parent, None, None) | |
|
43 | 43 | # Don't just grab parent!!! |
|
44 | 44 | self.shell = Component.get_instances(root=self.root, |
|
45 | 45 | klass='IPython.core.iplib.InteractiveShell')[0] |
@@ -26,6 +26,7 b' Notes' | |||
|
26 | 26 | from __future__ import with_statement |
|
27 | 27 | |
|
28 | 28 | import sys |
|
29 | from contextlib import nested | |
|
29 | 30 | |
|
30 | 31 | from IPython.core import ultratb |
|
31 | 32 | from IPython.core.iplib import InteractiveShell |
@@ -67,18 +68,14 b' class InteractiveShellEmbed(InteractiveShell):' | |||
|
67 | 68 | banner1=None, banner2=None, |
|
68 | 69 | custom_exceptions=((),None), exit_msg=''): |
|
69 | 70 | |
|
70 | # First we need to save the state of sys.displayhook and | |
|
71 | # sys.ipcompleter so we can restore it when we are done. | |
|
72 | self.save_sys_displayhook() | |
|
73 | 71 | self.save_sys_ipcompleter() |
|
74 | 72 | |
|
75 | 73 | super(InteractiveShellEmbed,self).__init__( |
|
76 | 74 | parent=parent, config=config, ipythondir=ipythondir, usage=usage, |
|
77 | 75 | user_ns=user_ns, user_global_ns=user_global_ns, |
|
78 |
banner1=banner1, banner2=banner2, |
|
|
76 | banner1=banner1, banner2=banner2, | |
|
79 | 77 | custom_exceptions=custom_exceptions) |
|
80 | 78 | |
|
81 | self.save_sys_displayhook_embed() | |
|
82 | 79 | self.exit_msg = exit_msg |
|
83 | 80 | self.define_magic("kill_embedded", kill_embedded) |
|
84 | 81 | |
@@ -88,17 +85,11 b' class InteractiveShellEmbed(InteractiveShell):' | |||
|
88 | 85 | mode=self.xmode, |
|
89 | 86 | call_pdb=self.pdb) |
|
90 | 87 | |
|
91 | self.restore_sys_displayhook() | |
|
92 | 88 | self.restore_sys_ipcompleter() |
|
93 | 89 | |
|
94 | 90 | def init_sys_modules(self): |
|
95 | 91 | pass |
|
96 | 92 | |
|
97 | def save_sys_displayhook(self): | |
|
98 | # sys.displayhook is a global, we need to save the user's original | |
|
99 | # Don't rely on __displayhook__, as the user may have changed that. | |
|
100 | self.sys_displayhook_orig = sys.displayhook | |
|
101 | ||
|
102 | 93 | def save_sys_ipcompleter(self): |
|
103 | 94 | """Save readline completer status.""" |
|
104 | 95 | try: |
@@ -107,9 +98,6 b' class InteractiveShellEmbed(InteractiveShell):' | |||
|
107 | 98 | except: |
|
108 | 99 | pass # not nested with IPython |
|
109 | 100 | |
|
110 | def restore_sys_displayhook(self): | |
|
111 | sys.displayhook = self.sys_displayhook_orig | |
|
112 | ||
|
113 | 101 | def restore_sys_ipcompleter(self): |
|
114 | 102 | """Restores the readline completer which was in place. |
|
115 | 103 | |
@@ -122,12 +110,6 b' class InteractiveShellEmbed(InteractiveShell):' | |||
|
122 | 110 | except: |
|
123 | 111 | pass |
|
124 | 112 | |
|
125 | def save_sys_displayhook_embed(self): | |
|
126 | self.sys_displayhook_embed = sys.displayhook | |
|
127 | ||
|
128 | def restore_sys_displayhook_embed(self): | |
|
129 | sys.displayhook = self.sys_displayhook_embed | |
|
130 | ||
|
131 | 113 | def __call__(self, header='', local_ns=None, global_ns=None, dummy=None, |
|
132 | 114 | stack_depth=1): |
|
133 | 115 | """Activate the interactive interpreter. |
@@ -161,8 +143,6 b' class InteractiveShellEmbed(InteractiveShell):' | |||
|
161 | 143 | if dummy or (dummy != 0 and self.dummy_mode): |
|
162 | 144 | return |
|
163 | 145 | |
|
164 | self.restore_sys_displayhook_embed() | |
|
165 | ||
|
166 | 146 | if self.has_readline: |
|
167 | 147 | self.set_completer() |
|
168 | 148 | |
@@ -174,14 +154,12 b' class InteractiveShellEmbed(InteractiveShell):' | |||
|
174 | 154 | |
|
175 | 155 | # Call the embedding code with a stack depth of 1 so it can skip over |
|
176 | 156 | # our call and get the original caller's namespaces. |
|
177 |
self.mainloop(banner, local_ns, global_ns, |
|
|
157 | self.mainloop(banner, local_ns, global_ns, | |
|
178 | 158 | stack_depth=stack_depth) |
|
179 | 159 | |
|
180 | 160 | if self.exit_msg is not None: |
|
181 | 161 | print self.exit_msg |
|
182 | ||
|
183 | # Restore global systems (display, completion) | |
|
184 | self.restore_sys_displayhook() | |
|
162 | ||
|
185 | 163 | self.restore_sys_ipcompleter() |
|
186 | 164 | |
|
187 | 165 | def mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0): |
@@ -240,7 +218,7 b' class InteractiveShellEmbed(InteractiveShell):' | |||
|
240 | 218 | # actually completes using the frame's locals/globals |
|
241 | 219 | self.set_completer_frame() |
|
242 | 220 | |
|
243 | with self.builtin_trap: | |
|
221 | with nested(self.builtin_trap, self.display_trap): | |
|
244 | 222 | self.interact(header) |
|
245 | 223 | |
|
246 | 224 | # now, purge out the user namespace from anything we might have added |
@@ -33,6 +33,7 b' import shutil' | |||
|
33 | 33 | import string |
|
34 | 34 | import sys |
|
35 | 35 | import tempfile |
|
36 | from contextlib import nested | |
|
36 | 37 | |
|
37 | 38 | from IPython.core import ultratb |
|
38 | 39 | from IPython.core import debugger, oinspect |
@@ -41,6 +42,7 b' from IPython.core import history as ipcorehist' | |||
|
41 | 42 | from IPython.core import prefilter |
|
42 | 43 | from IPython.core.autocall import IPyAutocall |
|
43 | 44 | from IPython.core.builtin_trap import BuiltinTrap |
|
45 | from IPython.core.display_trap import DisplayTrap | |
|
44 | 46 | from IPython.core.fakemodule import FakeModule, init_fakemod_dict |
|
45 | 47 | from IPython.core.logger import Logger |
|
46 | 48 | from IPython.core.magic import Magic |
@@ -940,13 +942,7 b' class InteractiveShell(Component, Magic):' | |||
|
940 | 942 | pass |
|
941 | 943 | |
|
942 | 944 | def init_displayhook(self): |
|
943 | # I don't like assigning globally to sys, because it means when | |
|
944 | # embedding instances, each embedded instance overrides the previous | |
|
945 | # choice. But sys.displayhook seems to be called internally by exec, | |
|
946 | # so I don't see a way around it. We first save the original and then | |
|
947 | # overwrite it. | |
|
948 | self.sys_displayhook = sys.displayhook | |
|
949 | sys.displayhook = self.outputcache | |
|
945 | self.display_trap = DisplayTrap(self, self.outputcache) | |
|
950 | 946 | |
|
951 | 947 | def init_reload_doctest(self): |
|
952 | 948 | # Do a proper resetting of doctest, including the necessary displayhook |
@@ -1061,7 +1057,6 b' class InteractiveShell(Component, Magic):' | |||
|
1061 | 1057 | self._orig_sys_module_state['stdin'] = sys.stdin |
|
1062 | 1058 | self._orig_sys_module_state['stdout'] = sys.stdout |
|
1063 | 1059 | self._orig_sys_module_state['stderr'] = sys.stderr |
|
1064 | self._orig_sys_module_state['displayhook'] = sys.displayhook | |
|
1065 | 1060 | self._orig_sys_module_state['excepthook'] = sys.excepthook |
|
1066 | 1061 | try: |
|
1067 | 1062 | self._orig_sys_modules_main_name = self.user_ns['__name__'] |
@@ -1251,7 +1246,7 b' class InteractiveShell(Component, Magic):' | |||
|
1251 | 1246 | error("Magic function `%s` not found." % magic_name) |
|
1252 | 1247 | else: |
|
1253 | 1248 | magic_args = self.var_expand(magic_args,1) |
|
1254 | with self.builtin_trap: | |
|
1249 | with nested(self.builtin_trap, self.display_trap): | |
|
1255 | 1250 | return fn(magic_args) |
|
1256 | 1251 | # return result |
|
1257 | 1252 | |
@@ -1348,7 +1343,7 b' class InteractiveShell(Component, Magic):' | |||
|
1348 | 1343 | |
|
1349 | 1344 | def ex(self, cmd): |
|
1350 | 1345 | """Execute a normal python statement in user namespace.""" |
|
1351 | with self.builtin_trap: | |
|
1346 | with nested(self.builtin_trap, self.display_trap): | |
|
1352 | 1347 | exec cmd in self.user_global_ns, self.user_ns |
|
1353 | 1348 | |
|
1354 | 1349 | def ev(self, expr): |
@@ -1356,7 +1351,7 b' class InteractiveShell(Component, Magic):' | |||
|
1356 | 1351 | |
|
1357 | 1352 | Returns the result of evaluation |
|
1358 | 1353 | """ |
|
1359 | with self.builtin_trap: | |
|
1354 | with nested(self.builtin_trap, self.display_trap): | |
|
1360 | 1355 | return eval(expr, self.user_global_ns, self.user_ns) |
|
1361 | 1356 | |
|
1362 | 1357 | def getoutput(self, cmd): |
@@ -1688,6 +1683,8 b' class InteractiveShell(Component, Magic):' | |||
|
1688 | 1683 | try: |
|
1689 | 1684 | f = file(err.filename) |
|
1690 | 1685 | try: |
|
1686 | # This should be inside a display_trap block and I | |
|
1687 | # think it is. | |
|
1691 | 1688 | sys.displayhook(f.read()) |
|
1692 | 1689 | finally: |
|
1693 | 1690 | f.close() |
@@ -1805,7 +1802,7 b' class InteractiveShell(Component, Magic):' | |||
|
1805 | 1802 | internally created default banner. |
|
1806 | 1803 | """ |
|
1807 | 1804 | |
|
1808 | with self.builtin_trap: | |
|
1805 | with nested(self.builtin_trap, self.display_trap): | |
|
1809 | 1806 | if self.c: # Emulate Python's -c option |
|
1810 | 1807 | self.exec_init_cmd() |
|
1811 | 1808 | |
@@ -2237,7 +2234,7 b' class InteractiveShell(Component, Magic):' | |||
|
2237 | 2234 | lines = lines.splitlines() |
|
2238 | 2235 | more = 0 |
|
2239 | 2236 | |
|
2240 | with self.builtin_trap: | |
|
2237 | with nested(self.builtin_trap, self.display_trap): | |
|
2241 | 2238 | for line in lines: |
|
2242 | 2239 | # skip blank lines so we don't mess up the prompt counter, but do |
|
2243 | 2240 | # NOT skip even a blank line if we are in a code block (more is |
@@ -69,7 +69,8 b' possible inclusion in future releases.' | |||
|
69 | 69 | # the file COPYING, distributed as part of this software. |
|
70 | 70 | #***************************************************************************** |
|
71 | 71 | |
|
72 | # Required modules | |
|
72 | from __future__ import with_statement | |
|
73 | ||
|
73 | 74 | import inspect |
|
74 | 75 | import keyword |
|
75 | 76 | import linecache |
@@ -85,16 +86,17 b' import types' | |||
|
85 | 86 | |
|
86 | 87 | # For purposes of monkeypatching inspect to fix a bug in it. |
|
87 | 88 | from inspect import getsourcefile, getfile, getmodule,\ |
|
88 |
ismodule, |
|
|
89 | ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode | |
|
89 | 90 | |
|
90 | 91 | |
|
91 | 92 | # IPython's own modules |
|
92 | 93 | # Modified pdb which doesn't damage IPython's readline handling |
|
93 | 94 | from IPython.utils import PyColorize |
|
94 | 95 | from IPython.core import debugger, ipapi |
|
96 | from IPython.core.display_trap import DisplayTrap | |
|
95 | 97 | from IPython.utils.ipstruct import Struct |
|
96 | 98 | from IPython.core.excolors import exception_colors |
|
97 | from IPython.utils.genutils import Term,uniq_stable,error,info | |
|
99 | from IPython.utils.genutils import Term, uniq_stable, error, info | |
|
98 | 100 | |
|
99 | 101 | # Globals |
|
100 | 102 | # amount of space to put line numbers before verbose tracebacks |
@@ -848,24 +850,21 b' class VerboseTB(TBTools):' | |||
|
848 | 850 | self.color_scheme_table.active_scheme_name) |
|
849 | 851 | # the system displayhook may have changed, restore the original |
|
850 | 852 | # for pdb |
|
851 |
d |
|
|
852 | sys.displayhook = sys.__displayhook__ | |
|
853 | self.pdb.reset() | |
|
854 | # Find the right frame so we don't pop up inside ipython itself | |
|
855 | if hasattr(self,'tb'): | |
|
856 | etb = self.tb | |
|
857 | else: | |
|
858 | etb = self.tb = sys.last_traceback | |
|
859 | while self.tb.tb_next is not None: | |
|
860 | self.tb = self.tb.tb_next | |
|
861 | try: | |
|
853 | display_trap = DisplayTrap(None, sys.__displayhook__) | |
|
854 | with display_trap: | |
|
855 | self.pdb.reset() | |
|
856 | # Find the right frame so we don't pop up inside ipython itself | |
|
857 | if hasattr(self,'tb'): | |
|
858 | etb = self.tb | |
|
859 | else: | |
|
860 | etb = self.tb = sys.last_traceback | |
|
861 | while self.tb.tb_next is not None: | |
|
862 | self.tb = self.tb.tb_next | |
|
862 | 863 | if etb and etb.tb_next: |
|
863 | 864 | etb = etb.tb_next |
|
864 | 865 | self.pdb.botframe = etb.tb_frame |
|
865 | 866 | self.pdb.interaction(self.tb.tb_frame, self.tb) |
|
866 | finally: | |
|
867 | sys.displayhook = dhook | |
|
868 | ||
|
867 | ||
|
869 | 868 | if hasattr(self,'tb'): |
|
870 | 869 | del self.tb |
|
871 | 870 |
General Comments 0
You need to be logged in to leave comments.
Login now