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