##// END OF EJS Templates
Add global_ns argument to embedding, for backwards compatibility.
Thomas Kluyver -
Show More
@@ -1,261 +1,270 b''
1 1 # encoding: utf-8
2 2 """
3 3 An embedded IPython shell.
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez
9 9
10 10 Notes
11 11 -----
12 12 """
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Copyright (C) 2008-2011 The IPython Development Team
16 16 #
17 17 # Distributed under the terms of the BSD License. The full license is in
18 18 # the file COPYING, distributed as part of this software.
19 19 #-----------------------------------------------------------------------------
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Imports
23 23 #-----------------------------------------------------------------------------
24 24
25 25 from __future__ import with_statement
26 26 import __main__
27 27
28 28 import sys
29 29 try:
30 30 from contextlib import nested
31 31 except:
32 32 from IPython.utils.nested_context import nested
33 import warnings
33 34
34 35 from IPython.core import ultratb
35 36 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
36 37 from IPython.frontend.terminal.ipapp import load_default_config
37 38
38 39 from IPython.utils.traitlets import Bool, CBool, Unicode
39 40 from IPython.utils.io import ask_yes_no
40 41
41 42
42 43 #-----------------------------------------------------------------------------
43 44 # Classes and functions
44 45 #-----------------------------------------------------------------------------
45 46
46 47 # This is an additional magic that is exposed in embedded shells.
47 48 def kill_embedded(self,parameter_s=''):
48 49 """%kill_embedded : deactivate for good the current embedded IPython.
49 50
50 51 This function (after asking for confirmation) sets an internal flag so that
51 52 an embedded IPython will never activate again. This is useful to
52 53 permanently disable a shell that is being called inside a loop: once you've
53 54 figured out what you needed from it, you may then kill it and the program
54 55 will then continue to run without the interactive shell interfering again.
55 56 """
56 57
57 58 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
58 59 "(y/n)? [y/N] ",'n')
59 60 if kill:
60 61 self.embedded_active = False
61 62 print "This embedded IPython will not reactivate anymore once you exit."
62 63
63 64
64 65 class InteractiveShellEmbed(TerminalInteractiveShell):
65 66
66 67 dummy_mode = Bool(False)
67 68 exit_msg = Unicode('')
68 69 embedded = CBool(True)
69 70 embedded_active = CBool(True)
70 71 # Like the base class display_banner is not configurable, but here it
71 72 # is True by default.
72 73 display_banner = CBool(True)
73 74
74 75 def __init__(self, config=None, ipython_dir=None, user_ns=None,
75 76 user_module=None, custom_exceptions=((),None),
76 77 usage=None, banner1=None, banner2=None,
77 78 display_banner=None, exit_msg=u''):
78 79
79 80 super(InteractiveShellEmbed,self).__init__(
80 81 config=config, ipython_dir=ipython_dir, user_ns=user_ns,
81 82 user_module=user_module, custom_exceptions=custom_exceptions,
82 83 usage=usage, banner1=banner1, banner2=banner2,
83 84 display_banner=display_banner
84 85 )
85 86
86 87 self.exit_msg = exit_msg
87 88 self.define_magic("kill_embedded", kill_embedded)
88 89
89 90 # don't use the ipython crash handler so that user exceptions aren't
90 91 # trapped
91 92 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
92 93 mode=self.xmode,
93 94 call_pdb=self.pdb)
94 95
95 96 def init_sys_modules(self):
96 97 pass
97 98
98 99 def __call__(self, header='', local_ns=None, module=None, dummy=None,
99 stack_depth=1):
100 stack_depth=1, global_ns=None):
100 101 """Activate the interactive interpreter.
101 102
102 103 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
103 104 the interpreter shell with the given local and global namespaces, and
104 105 optionally print a header string at startup.
105 106
106 107 The shell can be globally activated/deactivated using the
107 108 set/get_dummy_mode methods. This allows you to turn off a shell used
108 109 for debugging globally.
109 110
110 111 However, *each* time you call the shell you can override the current
111 112 state of dummy_mode with the optional keyword parameter 'dummy'. For
112 113 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
113 114 can still have a specific call work by making it as IPShell(dummy=0).
114 115
115 116 The optional keyword parameter dummy controls whether the call
116 117 actually does anything.
117 118 """
118 119
119 120 # If the user has turned it off, go away
120 121 if not self.embedded_active:
121 122 return
122 123
123 124 # Normal exits from interactive mode set this flag, so the shell can't
124 125 # re-enter (it checks this variable at the start of interactive mode).
125 126 self.exit_now = False
126 127
127 128 # Allow the dummy parameter to override the global __dummy_mode
128 129 if dummy or (dummy != 0 and self.dummy_mode):
129 130 return
130 131
131 132 if self.has_readline:
132 133 self.set_readline_completer()
133 134
134 135 # self.banner is auto computed
135 136 if header:
136 137 self.old_banner2 = self.banner2
137 138 self.banner2 = self.banner2 + '\n' + header + '\n'
138 139 else:
139 140 self.old_banner2 = ''
140 141
141 142 # Call the embedding code with a stack depth of 1 so it can skip over
142 143 # our call and get the original caller's namespaces.
143 self.mainloop(local_ns, module, stack_depth=stack_depth)
144 self.mainloop(local_ns, module, stack_depth=stack_depth, global_ns=global_ns)
144 145
145 146 self.banner2 = self.old_banner2
146 147
147 148 if self.exit_msg is not None:
148 149 print self.exit_msg
149 150
150 151 def mainloop(self, local_ns=None, module=None, stack_depth=0,
151 display_banner=None):
152 display_banner=None, global_ns=None):
152 153 """Embeds IPython into a running python program.
153 154
154 155 Input:
155 156
156 157 - header: An optional header message can be specified.
157 158
158 159 - local_ns, global_ns: working namespaces. If given as None, the
159 160 IPython-initialized one is updated with __main__.__dict__, so that
160 161 program variables become visible but user-specific configuration
161 162 remains possible.
162 163
163 164 - stack_depth: specifies how many levels in the stack to go to
164 165 looking for namespaces (when local_ns and global_ns are None). This
165 166 allows an intermediate caller to make sure that this function gets
166 167 the namespace from the intended level in the stack. By default (0)
167 168 it will get its locals and globals from the immediate caller.
168 169
169 170 Warning: it's possible to use this in a program which is being run by
170 171 IPython itself (via %run), but some funny things will happen (a few
171 172 globals get overwritten). In the future this will be cleaned up, as
172 173 there is no fundamental reason why it can't work perfectly."""
173 174
175 if (global_ns is not None) and (module is None):
176 class DummyMod(object):
177 """A dummy module object for embedded IPython."""
178 pass
179 warnings.warn("global_ns is deprecated, use module instead.", DeprecationWarning)
180 module = DummyMod()
181 module.__dict__ = global_ns
182
174 183 # Get locals and globals from caller
175 184 if (local_ns is None or module is None) and self.default_user_namespaces:
176 185 call_frame = sys._getframe(stack_depth).f_back
177 186
178 187 if local_ns is None:
179 188 local_ns = call_frame.f_locals
180 189 if module is None:
181 190 global_ns = call_frame.f_globals
182 191 module = sys.modules[global_ns['__name__']]
183 192
184 193 # Save original namespace and module so we can restore them after
185 194 # embedding; otherwise the shell doesn't shut down correctly.
186 195 orig_user_module = self.user_module
187 196 orig_user_ns = self.user_ns
188 197
189 198 # Update namespaces and fire up interpreter
190 199
191 200 # The global one is easy, we can just throw it in
192 201 if module is not None:
193 202 self.user_module = module
194 203
195 204 # But the user/local one is tricky: ipython needs it to store internal
196 205 # data, but we also need the locals. We'll throw our hidden variables
197 206 # like _ih and get_ipython() into the local namespace, but delete them
198 207 # later.
199 208 if local_ns is not None:
200 209 self.user_ns = local_ns
201 210 self.init_user_ns()
202 211
203 212 # Patch for global embedding to make sure that things don't overwrite
204 213 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
205 214 # FIXME. Test this a bit more carefully (the if.. is new)
206 215 # N.B. This can't now ever be called. Not sure what it was for.
207 216 # And now, since it wasn't called in the previous version, I'm
208 217 # commenting out these lines so they can't be called with my new changes
209 218 # --TK, 2011-12-10
210 219 #if local_ns is None and module is None:
211 220 # self.user_global_ns.update(__main__.__dict__)
212 221
213 222 # make sure the tab-completer has the correct frame information, so it
214 223 # actually completes using the frame's locals/globals
215 224 self.set_completer_frame()
216 225
217 226 with nested(self.builtin_trap, self.display_trap):
218 227 self.interact(display_banner=display_banner)
219 228
220 229 # now, purge out the local namespace of IPython's hidden variables.
221 230 if local_ns is not None:
222 231 for name in self.user_ns_hidden:
223 232 local_ns.pop(name, None)
224 233
225 234 # Restore original namespace so shell can shut down when we exit.
226 235 self.user_module = orig_user_module
227 236 self.user_ns = orig_user_ns
228 237
229 238 _embedded_shell = None
230 239
231 240
232 241 def embed(**kwargs):
233 242 """Call this to embed IPython at the current point in your program.
234 243
235 244 The first invocation of this will create an :class:`InteractiveShellEmbed`
236 245 instance and then call it. Consecutive calls just call the already
237 246 created instance.
238 247
239 248 Here is a simple example::
240 249
241 250 from IPython import embed
242 251 a = 10
243 252 b = 20
244 253 embed('First time')
245 254 c = 30
246 255 d = 40
247 256 embed
248 257
249 258 Full customization can be done by passing a :class:`Struct` in as the
250 259 config argument.
251 260 """
252 261 config = kwargs.get('config')
253 262 header = kwargs.pop('header', u'')
254 263 if config is None:
255 264 config = load_default_config()
256 265 config.InteractiveShellEmbed = config.TerminalInteractiveShell
257 266 kwargs['config'] = config
258 267 global _embedded_shell
259 268 if _embedded_shell is None:
260 269 _embedded_shell = InteractiveShellEmbed(**kwargs)
261 270 _embedded_shell(header=header, stack_depth=2)
General Comments 0
You need to be logged in to leave comments. Login now