##// END OF EJS Templates
Don't change terminal title for embedded IPython...
Thomas Kluyver -
Show More
@@ -1,321 +1,326 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An embedded IPython shell.
3 An embedded IPython shell.
4 """
4 """
5 # Copyright (c) IPython Development Team.
5 # Copyright (c) IPython Development Team.
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7
7
8 from __future__ import with_statement
8 from __future__ import with_statement
9 from __future__ import print_function
9 from __future__ import print_function
10
10
11 import sys
11 import sys
12 import warnings
12 import warnings
13
13
14 from IPython.core import ultratb, compilerop
14 from IPython.core import ultratb, compilerop
15 from IPython.core.magic import Magics, magics_class, line_magic
15 from IPython.core.magic import Magics, magics_class, line_magic
16 from IPython.core.interactiveshell import DummyMod, InteractiveShell
16 from IPython.core.interactiveshell import DummyMod, InteractiveShell
17 from IPython.terminal.interactiveshell import TerminalInteractiveShell
17 from IPython.terminal.interactiveshell import TerminalInteractiveShell
18 from IPython.terminal.ipapp import load_default_config
18 from IPython.terminal.ipapp import load_default_config
19
19
20 from traitlets import Bool, CBool, Unicode
20 from traitlets import Bool, CBool, Unicode
21 from IPython.utils.io import ask_yes_no
21 from IPython.utils.io import ask_yes_no
22
22
23 class KillEmbeded(Exception):pass
23 class KillEmbeded(Exception):pass
24
24
25 # This is an additional magic that is exposed in embedded shells.
25 # This is an additional magic that is exposed in embedded shells.
26 @magics_class
26 @magics_class
27 class EmbeddedMagics(Magics):
27 class EmbeddedMagics(Magics):
28
28
29 @line_magic
29 @line_magic
30 def kill_embedded(self, parameter_s=''):
30 def kill_embedded(self, parameter_s=''):
31 """%kill_embedded : deactivate for good the current embedded IPython.
31 """%kill_embedded : deactivate for good the current embedded IPython.
32
32
33 This function (after asking for confirmation) sets an internal flag so
33 This function (after asking for confirmation) sets an internal flag so
34 that an embedded IPython will never activate again. This is useful to
34 that an embedded IPython will never activate again. This is useful to
35 permanently disable a shell that is being called inside a loop: once
35 permanently disable a shell that is being called inside a loop: once
36 you've figured out what you needed from it, you may then kill it and
36 you've figured out what you needed from it, you may then kill it and
37 the program will then continue to run without the interactive shell
37 the program will then continue to run without the interactive shell
38 interfering again.
38 interfering again.
39 """
39 """
40
40
41 kill = ask_yes_no("Are you sure you want to kill this embedded instance? [y/N] ",'n')
41 kill = ask_yes_no("Are you sure you want to kill this embedded instance? [y/N] ",'n')
42 if kill:
42 if kill:
43 self.shell.embedded_active = False
43 self.shell.embedded_active = False
44 print ("This embedded IPython will not reactivate anymore "
44 print ("This embedded IPython will not reactivate anymore "
45 "once you exit.")
45 "once you exit.")
46
46
47
47
48 @line_magic
48 @line_magic
49 def exit_raise(self, parameter_s=''):
49 def exit_raise(self, parameter_s=''):
50 """%exit_raise Make the current embedded kernel exit and raise and exception.
50 """%exit_raise Make the current embedded kernel exit and raise and exception.
51
51
52 This function sets an internal flag so that an embedded IPython will
52 This function sets an internal flag so that an embedded IPython will
53 raise a `IPython.terminal.embed.KillEmbeded` Exception on exit, and then exit the current I. This is
53 raise a `IPython.terminal.embed.KillEmbeded` Exception on exit, and then exit the current I. This is
54 useful to permanently exit a loop that create IPython embed instance.
54 useful to permanently exit a loop that create IPython embed instance.
55 """
55 """
56
56
57 self.shell.should_raise = True
57 self.shell.should_raise = True
58 self.shell.ask_exit()
58 self.shell.ask_exit()
59
59
60
60
61
61
62 class InteractiveShellEmbed(TerminalInteractiveShell):
62 class InteractiveShellEmbed(TerminalInteractiveShell):
63
63
64 dummy_mode = Bool(False)
64 dummy_mode = Bool(False)
65 exit_msg = Unicode('')
65 exit_msg = Unicode('')
66 embedded = CBool(True)
66 embedded = CBool(True)
67 should_raise = CBool(False)
67 should_raise = CBool(False)
68 # Like the base class display_banner is not configurable, but here it
68 # Like the base class display_banner is not configurable, but here it
69 # is True by default.
69 # is True by default.
70 display_banner = CBool(True)
70 display_banner = CBool(True)
71 exit_msg = Unicode()
71 exit_msg = Unicode()
72
72
73 # When embedding, by default we don't change the terminal title
74 term_title = Bool(False,
75 help="Automatically set the terminal title"
76 ).tag(config=True)
77
73 _inactive_locations = set()
78 _inactive_locations = set()
74
79
75 @property
80 @property
76 def embedded_active(self):
81 def embedded_active(self):
77 return self._call_location_id not in InteractiveShellEmbed._inactive_locations
82 return self._call_location_id not in InteractiveShellEmbed._inactive_locations
78
83
79 @embedded_active.setter
84 @embedded_active.setter
80 def embedded_active(self, value):
85 def embedded_active(self, value):
81 if value :
86 if value :
82 if self._call_location_id in InteractiveShellEmbed._inactive_locations:
87 if self._call_location_id in InteractiveShellEmbed._inactive_locations:
83 InteractiveShellEmbed._inactive_locations.remove(self._call_location_id)
88 InteractiveShellEmbed._inactive_locations.remove(self._call_location_id)
84 else:
89 else:
85 InteractiveShellEmbed._inactive_locations.add(self._call_location_id)
90 InteractiveShellEmbed._inactive_locations.add(self._call_location_id)
86
91
87 def __init__(self, **kw):
92 def __init__(self, **kw):
88
93
89
94
90 if kw.get('user_global_ns', None) is not None:
95 if kw.get('user_global_ns', None) is not None:
91 raise DeprecationWarning("Key word argument `user_global_ns` has been replaced by `user_module` since IPython 4.0.")
96 raise DeprecationWarning("Key word argument `user_global_ns` has been replaced by `user_module` since IPython 4.0.")
92
97
93 self._call_location_id = kw.pop('_call_location_id', None)
98 self._call_location_id = kw.pop('_call_location_id', None)
94
99
95 super(InteractiveShellEmbed,self).__init__(**kw)
100 super(InteractiveShellEmbed,self).__init__(**kw)
96
101
97 if not self._call_location_id:
102 if not self._call_location_id:
98 frame = sys._getframe(1)
103 frame = sys._getframe(1)
99 self._call_location_id = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
104 self._call_location_id = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
100 # don't use the ipython crash handler so that user exceptions aren't
105 # don't use the ipython crash handler so that user exceptions aren't
101 # trapped
106 # trapped
102 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
107 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
103 mode=self.xmode,
108 mode=self.xmode,
104 call_pdb=self.pdb)
109 call_pdb=self.pdb)
105
110
106 def init_sys_modules(self):
111 def init_sys_modules(self):
107 pass
112 pass
108
113
109 def init_magics(self):
114 def init_magics(self):
110 super(InteractiveShellEmbed, self).init_magics()
115 super(InteractiveShellEmbed, self).init_magics()
111 self.register_magics(EmbeddedMagics)
116 self.register_magics(EmbeddedMagics)
112
117
113 def __call__(self, header='', local_ns=None, module=None, dummy=None,
118 def __call__(self, header='', local_ns=None, module=None, dummy=None,
114 stack_depth=1, global_ns=None, compile_flags=None):
119 stack_depth=1, global_ns=None, compile_flags=None):
115 """Activate the interactive interpreter.
120 """Activate the interactive interpreter.
116
121
117 __call__(self,header='',local_ns=None,module=None,dummy=None) -> Start
122 __call__(self,header='',local_ns=None,module=None,dummy=None) -> Start
118 the interpreter shell with the given local and global namespaces, and
123 the interpreter shell with the given local and global namespaces, and
119 optionally print a header string at startup.
124 optionally print a header string at startup.
120
125
121 The shell can be globally activated/deactivated using the
126 The shell can be globally activated/deactivated using the
122 dummy_mode attribute. This allows you to turn off a shell used
127 dummy_mode attribute. This allows you to turn off a shell used
123 for debugging globally.
128 for debugging globally.
124
129
125 However, *each* time you call the shell you can override the current
130 However, *each* time you call the shell you can override the current
126 state of dummy_mode with the optional keyword parameter 'dummy'. For
131 state of dummy_mode with the optional keyword parameter 'dummy'. For
127 example, if you set dummy mode on with IPShell.dummy_mode = True, you
132 example, if you set dummy mode on with IPShell.dummy_mode = True, you
128 can still have a specific call work by making it as IPShell(dummy=False).
133 can still have a specific call work by making it as IPShell(dummy=False).
129 """
134 """
130
135
131 # If the user has turned it off, go away
136 # If the user has turned it off, go away
132 if not self.embedded_active:
137 if not self.embedded_active:
133 return
138 return
134
139
135 # Normal exits from interactive mode set this flag, so the shell can't
140 # Normal exits from interactive mode set this flag, so the shell can't
136 # re-enter (it checks this variable at the start of interactive mode).
141 # re-enter (it checks this variable at the start of interactive mode).
137 self.exit_now = False
142 self.exit_now = False
138
143
139 # Allow the dummy parameter to override the global __dummy_mode
144 # Allow the dummy parameter to override the global __dummy_mode
140 if dummy or (dummy != 0 and self.dummy_mode):
145 if dummy or (dummy != 0 and self.dummy_mode):
141 return
146 return
142
147
143 # self.banner is auto computed
148 # self.banner is auto computed
144 if header:
149 if header:
145 self.old_banner2 = self.banner2
150 self.old_banner2 = self.banner2
146 self.banner2 = self.banner2 + '\n' + header + '\n'
151 self.banner2 = self.banner2 + '\n' + header + '\n'
147 else:
152 else:
148 self.old_banner2 = ''
153 self.old_banner2 = ''
149
154
150 if self.display_banner:
155 if self.display_banner:
151 self.show_banner()
156 self.show_banner()
152
157
153 # Call the embedding code with a stack depth of 1 so it can skip over
158 # Call the embedding code with a stack depth of 1 so it can skip over
154 # our call and get the original caller's namespaces.
159 # our call and get the original caller's namespaces.
155 self.mainloop(local_ns, module, stack_depth=stack_depth,
160 self.mainloop(local_ns, module, stack_depth=stack_depth,
156 global_ns=global_ns, compile_flags=compile_flags)
161 global_ns=global_ns, compile_flags=compile_flags)
157
162
158 self.banner2 = self.old_banner2
163 self.banner2 = self.old_banner2
159
164
160 if self.exit_msg is not None:
165 if self.exit_msg is not None:
161 print(self.exit_msg)
166 print(self.exit_msg)
162
167
163 if self.should_raise:
168 if self.should_raise:
164 raise KillEmbeded('Embedded IPython raising error, as user requested.')
169 raise KillEmbeded('Embedded IPython raising error, as user requested.')
165
170
166
171
167 def mainloop(self, local_ns=None, module=None, stack_depth=0,
172 def mainloop(self, local_ns=None, module=None, stack_depth=0,
168 display_banner=None, global_ns=None, compile_flags=None):
173 display_banner=None, global_ns=None, compile_flags=None):
169 """Embeds IPython into a running python program.
174 """Embeds IPython into a running python program.
170
175
171 Parameters
176 Parameters
172 ----------
177 ----------
173
178
174 local_ns, module
179 local_ns, module
175 Working local namespace (a dict) and module (a module or similar
180 Working local namespace (a dict) and module (a module or similar
176 object). If given as None, they are automatically taken from the scope
181 object). If given as None, they are automatically taken from the scope
177 where the shell was called, so that program variables become visible.
182 where the shell was called, so that program variables become visible.
178
183
179 stack_depth : int
184 stack_depth : int
180 How many levels in the stack to go to looking for namespaces (when
185 How many levels in the stack to go to looking for namespaces (when
181 local_ns or module is None). This allows an intermediate caller to
186 local_ns or module is None). This allows an intermediate caller to
182 make sure that this function gets the namespace from the intended
187 make sure that this function gets the namespace from the intended
183 level in the stack. By default (0) it will get its locals and globals
188 level in the stack. By default (0) it will get its locals and globals
184 from the immediate caller.
189 from the immediate caller.
185
190
186 compile_flags
191 compile_flags
187 A bit field identifying the __future__ features
192 A bit field identifying the __future__ features
188 that are enabled, as passed to the builtin :func:`compile` function.
193 that are enabled, as passed to the builtin :func:`compile` function.
189 If given as None, they are automatically taken from the scope where
194 If given as None, they are automatically taken from the scope where
190 the shell was called.
195 the shell was called.
191
196
192 """
197 """
193
198
194 if (global_ns is not None) and (module is None):
199 if (global_ns is not None) and (module is None):
195 raise DeprecationWarning("'global_ns' keyword argument is deprecated, and has been removed in IPython 5.0 use `module` keyword argument instead.")
200 raise DeprecationWarning("'global_ns' keyword argument is deprecated, and has been removed in IPython 5.0 use `module` keyword argument instead.")
196
201
197 if (display_banner is not None):
202 if (display_banner is not None):
198 warnings.warn("The display_banner parameter is deprecated since IPython 4.0", DeprecationWarning)
203 warnings.warn("The display_banner parameter is deprecated since IPython 4.0", DeprecationWarning)
199
204
200 # Get locals and globals from caller
205 # Get locals and globals from caller
201 if ((local_ns is None or module is None or compile_flags is None)
206 if ((local_ns is None or module is None or compile_flags is None)
202 and self.default_user_namespaces):
207 and self.default_user_namespaces):
203 call_frame = sys._getframe(stack_depth).f_back
208 call_frame = sys._getframe(stack_depth).f_back
204
209
205 if local_ns is None:
210 if local_ns is None:
206 local_ns = call_frame.f_locals
211 local_ns = call_frame.f_locals
207 if module is None:
212 if module is None:
208 global_ns = call_frame.f_globals
213 global_ns = call_frame.f_globals
209 try:
214 try:
210 module = sys.modules[global_ns['__name__']]
215 module = sys.modules[global_ns['__name__']]
211 except KeyError:
216 except KeyError:
212 warnings.warn("Failed to get module %s" % \
217 warnings.warn("Failed to get module %s" % \
213 global_ns.get('__name__', 'unknown module')
218 global_ns.get('__name__', 'unknown module')
214 )
219 )
215 module = DummyMod()
220 module = DummyMod()
216 module.__dict__ = global_ns
221 module.__dict__ = global_ns
217 if compile_flags is None:
222 if compile_flags is None:
218 compile_flags = (call_frame.f_code.co_flags &
223 compile_flags = (call_frame.f_code.co_flags &
219 compilerop.PyCF_MASK)
224 compilerop.PyCF_MASK)
220
225
221 # Save original namespace and module so we can restore them after
226 # Save original namespace and module so we can restore them after
222 # embedding; otherwise the shell doesn't shut down correctly.
227 # embedding; otherwise the shell doesn't shut down correctly.
223 orig_user_module = self.user_module
228 orig_user_module = self.user_module
224 orig_user_ns = self.user_ns
229 orig_user_ns = self.user_ns
225 orig_compile_flags = self.compile.flags
230 orig_compile_flags = self.compile.flags
226
231
227 # Update namespaces and fire up interpreter
232 # Update namespaces and fire up interpreter
228
233
229 # The global one is easy, we can just throw it in
234 # The global one is easy, we can just throw it in
230 if module is not None:
235 if module is not None:
231 self.user_module = module
236 self.user_module = module
232
237
233 # But the user/local one is tricky: ipython needs it to store internal
238 # But the user/local one is tricky: ipython needs it to store internal
234 # data, but we also need the locals. We'll throw our hidden variables
239 # data, but we also need the locals. We'll throw our hidden variables
235 # like _ih and get_ipython() into the local namespace, but delete them
240 # like _ih and get_ipython() into the local namespace, but delete them
236 # later.
241 # later.
237 if local_ns is not None:
242 if local_ns is not None:
238 reentrant_local_ns = {k: v for (k, v) in local_ns.items() if k not in self.user_ns_hidden.keys()}
243 reentrant_local_ns = {k: v for (k, v) in local_ns.items() if k not in self.user_ns_hidden.keys()}
239 self.user_ns = reentrant_local_ns
244 self.user_ns = reentrant_local_ns
240 self.init_user_ns()
245 self.init_user_ns()
241
246
242 # Compiler flags
247 # Compiler flags
243 if compile_flags is not None:
248 if compile_flags is not None:
244 self.compile.flags = compile_flags
249 self.compile.flags = compile_flags
245
250
246 # make sure the tab-completer has the correct frame information, so it
251 # make sure the tab-completer has the correct frame information, so it
247 # actually completes using the frame's locals/globals
252 # actually completes using the frame's locals/globals
248 self.set_completer_frame()
253 self.set_completer_frame()
249
254
250 with self.builtin_trap, self.display_trap:
255 with self.builtin_trap, self.display_trap:
251 self.interact()
256 self.interact()
252
257
253 # now, purge out the local namespace of IPython's hidden variables.
258 # now, purge out the local namespace of IPython's hidden variables.
254 if local_ns is not None:
259 if local_ns is not None:
255 local_ns.update({k: v for (k, v) in self.user_ns.items() if k not in self.user_ns_hidden.keys()})
260 local_ns.update({k: v for (k, v) in self.user_ns.items() if k not in self.user_ns_hidden.keys()})
256
261
257
262
258 # Restore original namespace so shell can shut down when we exit.
263 # Restore original namespace so shell can shut down when we exit.
259 self.user_module = orig_user_module
264 self.user_module = orig_user_module
260 self.user_ns = orig_user_ns
265 self.user_ns = orig_user_ns
261 self.compile.flags = orig_compile_flags
266 self.compile.flags = orig_compile_flags
262
267
263
268
264 def embed(**kwargs):
269 def embed(**kwargs):
265 """Call this to embed IPython at the current point in your program.
270 """Call this to embed IPython at the current point in your program.
266
271
267 The first invocation of this will create an :class:`InteractiveShellEmbed`
272 The first invocation of this will create an :class:`InteractiveShellEmbed`
268 instance and then call it. Consecutive calls just call the already
273 instance and then call it. Consecutive calls just call the already
269 created instance.
274 created instance.
270
275
271 If you don't want the kernel to initialize the namespace
276 If you don't want the kernel to initialize the namespace
272 from the scope of the surrounding function,
277 from the scope of the surrounding function,
273 and/or you want to load full IPython configuration,
278 and/or you want to load full IPython configuration,
274 you probably want `IPython.start_ipython()` instead.
279 you probably want `IPython.start_ipython()` instead.
275
280
276 Here is a simple example::
281 Here is a simple example::
277
282
278 from IPython import embed
283 from IPython import embed
279 a = 10
284 a = 10
280 b = 20
285 b = 20
281 embed(header='First time')
286 embed(header='First time')
282 c = 30
287 c = 30
283 d = 40
288 d = 40
284 embed()
289 embed()
285
290
286 Full customization can be done by passing a :class:`Config` in as the
291 Full customization can be done by passing a :class:`Config` in as the
287 config argument.
292 config argument.
288 """
293 """
289 config = kwargs.get('config')
294 config = kwargs.get('config')
290 header = kwargs.pop('header', u'')
295 header = kwargs.pop('header', u'')
291 compile_flags = kwargs.pop('compile_flags', None)
296 compile_flags = kwargs.pop('compile_flags', None)
292 if config is None:
297 if config is None:
293 config = load_default_config()
298 config = load_default_config()
294 config.InteractiveShellEmbed = config.TerminalInteractiveShell
299 config.InteractiveShellEmbed = config.TerminalInteractiveShell
295 kwargs['config'] = config
300 kwargs['config'] = config
296 #save ps1/ps2 if defined
301 #save ps1/ps2 if defined
297 ps1 = None
302 ps1 = None
298 ps2 = None
303 ps2 = None
299 try:
304 try:
300 ps1 = sys.ps1
305 ps1 = sys.ps1
301 ps2 = sys.ps2
306 ps2 = sys.ps2
302 except AttributeError:
307 except AttributeError:
303 pass
308 pass
304 #save previous instance
309 #save previous instance
305 saved_shell_instance = InteractiveShell._instance
310 saved_shell_instance = InteractiveShell._instance
306 if saved_shell_instance is not None:
311 if saved_shell_instance is not None:
307 cls = type(saved_shell_instance)
312 cls = type(saved_shell_instance)
308 cls.clear_instance()
313 cls.clear_instance()
309 frame = sys._getframe(1)
314 frame = sys._getframe(1)
310 shell = InteractiveShellEmbed.instance(_call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno), **kwargs)
315 shell = InteractiveShellEmbed.instance(_call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno), **kwargs)
311 shell(header=header, stack_depth=2, compile_flags=compile_flags)
316 shell(header=header, stack_depth=2, compile_flags=compile_flags)
312 InteractiveShellEmbed.clear_instance()
317 InteractiveShellEmbed.clear_instance()
313 #restore previous instance
318 #restore previous instance
314 if saved_shell_instance is not None:
319 if saved_shell_instance is not None:
315 cls = type(saved_shell_instance)
320 cls = type(saved_shell_instance)
316 cls.clear_instance()
321 cls.clear_instance()
317 for subclass in cls._walk_mro():
322 for subclass in cls._walk_mro():
318 subclass._instance = saved_shell_instance
323 subclass._instance = saved_shell_instance
319 if ps1 is not None:
324 if ps1 is not None:
320 sys.ps1 = ps1
325 sys.ps1 = ps1
321 sys.ps2 = ps2
326 sys.ps2 = ps2
General Comments 0
You need to be logged in to leave comments. Login now