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