##// END OF EJS Templates
sys.displayhook is now managed dynamically by display_trap.
Brian Granger -
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, name=None, config=None):
42 super(BuiltinTrap, self).__init__(parent, name, config)
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, isclass, ismethod, isfunction, istraceback, isframe, iscode
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 dhook = sys.displayhook
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