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