##// END OF EJS Templates
Fix a couple of rst roles causing Sphinx warnings
Thomas Kluyver -
Show More
@@ -1,393 +1,393 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
8
9 import sys
9 import sys
10 import warnings
10 import warnings
11
11
12 from IPython.core import ultratb, compilerop
12 from IPython.core import ultratb, compilerop
13 from IPython.core import magic_arguments
13 from IPython.core import magic_arguments
14 from IPython.core.magic import Magics, magics_class, line_magic
14 from IPython.core.magic import Magics, magics_class, line_magic
15 from IPython.core.interactiveshell import DummyMod, InteractiveShell
15 from IPython.core.interactiveshell import DummyMod, InteractiveShell
16 from IPython.terminal.interactiveshell import TerminalInteractiveShell
16 from IPython.terminal.interactiveshell import TerminalInteractiveShell
17 from IPython.terminal.ipapp import load_default_config
17 from IPython.terminal.ipapp import load_default_config
18
18
19 from traitlets import Bool, CBool, Unicode
19 from traitlets import Bool, CBool, Unicode
20 from IPython.utils.io import ask_yes_no
20 from IPython.utils.io import ask_yes_no
21
21
22 class KillEmbeded(Exception):pass
22 class KillEmbeded(Exception):pass
23
23
24 # This is an additional magic that is exposed in embedded shells.
24 # This is an additional magic that is exposed in embedded shells.
25 @magics_class
25 @magics_class
26 class EmbeddedMagics(Magics):
26 class EmbeddedMagics(Magics):
27
27
28 @line_magic
28 @line_magic
29 @magic_arguments.magic_arguments()
29 @magic_arguments.magic_arguments()
30 @magic_arguments.argument('-i', '--instance', action='store_true',
30 @magic_arguments.argument('-i', '--instance', action='store_true',
31 help='Kill instance instead of call location')
31 help='Kill instance instead of call location')
32 @magic_arguments.argument('-x', '--exit', action='store_true',
32 @magic_arguments.argument('-x', '--exit', action='store_true',
33 help='Also exit the current session')
33 help='Also exit the current session')
34 @magic_arguments.argument('-y', '--yes', action='store_true',
34 @magic_arguments.argument('-y', '--yes', action='store_true',
35 help='Do not ask confirmation')
35 help='Do not ask confirmation')
36 def kill_embedded(self, parameter_s=''):
36 def kill_embedded(self, parameter_s=''):
37 """%kill_embedded : deactivate for good the current embedded IPython
37 """%kill_embedded : deactivate for good the current embedded IPython
38
38
39 This function (after asking for confirmation) sets an internal flag so
39 This function (after asking for confirmation) sets an internal flag so
40 that an embedded IPython will never activate again for the given call
40 that an embedded IPython will never activate again for the given call
41 location. This is useful to permanently disable a shell that is being
41 location. This is useful to permanently disable a shell that is being
42 called inside a loop: once you've figured out what you needed from it,
42 called inside a loop: once you've figured out what you needed from it,
43 you may then kill it and the program will then continue to run without
43 you may then kill it and the program will then continue to run without
44 the interactive shell interfering again.
44 the interactive shell interfering again.
45
45
46
46
47 Kill Instance Option
47 Kill Instance Option
48 --------------------
48 --------------------
49
49
50 If for some reasons you need to kill the location where the instance is
50 If for some reasons you need to kill the location where the instance is
51 created and not called, for example if you create a single instance in
51 created and not called, for example if you create a single instance in
52 one place and debug in many locations, you can use the ``--instance``
52 one place and debug in many locations, you can use the ``--instance``
53 option to kill this specific instance. Like for the ``call location``
53 option to kill this specific instance. Like for the ``call location``
54 killing an "instance" should work even if it is recreated within a
54 killing an "instance" should work even if it is recreated within a
55 loop.
55 loop.
56
56
57 .. note::
57 .. note::
58
58
59 This was the default behavior before IPython 5.2
59 This was the default behavior before IPython 5.2
60
60
61 """
61 """
62
62
63 args = magic_arguments.parse_argstring(self.kill_embedded, parameter_s)
63 args = magic_arguments.parse_argstring(self.kill_embedded, parameter_s)
64 print(args)
64 print(args)
65 if args.instance:
65 if args.instance:
66 # let no ask
66 # let no ask
67 if not args.yes:
67 if not args.yes:
68 kill = ask_yes_no(
68 kill = ask_yes_no(
69 "Are you sure you want to kill this embedded instance? [y/N] ", 'n')
69 "Are you sure you want to kill this embedded instance? [y/N] ", 'n')
70 else:
70 else:
71 kill = True
71 kill = True
72 if kill:
72 if kill:
73 self.shell._disable_init_location()
73 self.shell._disable_init_location()
74 print("This embedded IPython instance will not reactivate anymore "
74 print("This embedded IPython instance will not reactivate anymore "
75 "once you exit.")
75 "once you exit.")
76 else:
76 else:
77 if not args.yes:
77 if not args.yes:
78 kill = ask_yes_no(
78 kill = ask_yes_no(
79 "Are you sure you want to kill this embedded call_location? [y/N] ", 'n')
79 "Are you sure you want to kill this embedded call_location? [y/N] ", 'n')
80 else:
80 else:
81 kill = True
81 kill = True
82 if kill:
82 if kill:
83 self.shell.embedded_active = False
83 self.shell.embedded_active = False
84 print("This embedded IPython call location will not reactivate anymore "
84 print("This embedded IPython call location will not reactivate anymore "
85 "once you exit.")
85 "once you exit.")
86
86
87 if args.exit:
87 if args.exit:
88 # Ask-exit does not really ask, it just set internals flags to exit
88 # Ask-exit does not really ask, it just set internals flags to exit
89 # on next loop.
89 # on next loop.
90 self.shell.ask_exit()
90 self.shell.ask_exit()
91
91
92
92
93 @line_magic
93 @line_magic
94 def exit_raise(self, parameter_s=''):
94 def exit_raise(self, parameter_s=''):
95 """%exit_raise Make the current embedded kernel exit and raise and exception.
95 """%exit_raise Make the current embedded kernel exit and raise and exception.
96
96
97 This function sets an internal flag so that an embedded IPython will
97 This function sets an internal flag so that an embedded IPython will
98 raise a `IPython.terminal.embed.KillEmbeded` Exception on exit, and then exit the current I. This is
98 raise a `IPython.terminal.embed.KillEmbeded` Exception on exit, and then exit the current I. This is
99 useful to permanently exit a loop that create IPython embed instance.
99 useful to permanently exit a loop that create IPython embed instance.
100 """
100 """
101
101
102 self.shell.should_raise = True
102 self.shell.should_raise = True
103 self.shell.ask_exit()
103 self.shell.ask_exit()
104
104
105
105
106
106
107 class InteractiveShellEmbed(TerminalInteractiveShell):
107 class InteractiveShellEmbed(TerminalInteractiveShell):
108
108
109 dummy_mode = Bool(False)
109 dummy_mode = Bool(False)
110 exit_msg = Unicode('')
110 exit_msg = Unicode('')
111 embedded = CBool(True)
111 embedded = CBool(True)
112 should_raise = CBool(False)
112 should_raise = CBool(False)
113 # Like the base class display_banner is not configurable, but here it
113 # Like the base class display_banner is not configurable, but here it
114 # is True by default.
114 # is True by default.
115 display_banner = CBool(True)
115 display_banner = CBool(True)
116 exit_msg = Unicode()
116 exit_msg = Unicode()
117
117
118 # When embedding, by default we don't change the terminal title
118 # When embedding, by default we don't change the terminal title
119 term_title = Bool(False,
119 term_title = Bool(False,
120 help="Automatically set the terminal title"
120 help="Automatically set the terminal title"
121 ).tag(config=True)
121 ).tag(config=True)
122
122
123 _inactive_locations = set()
123 _inactive_locations = set()
124
124
125 @property
125 @property
126 def embedded_active(self):
126 def embedded_active(self):
127 return (self._call_location_id not in InteractiveShellEmbed._inactive_locations)\
127 return (self._call_location_id not in InteractiveShellEmbed._inactive_locations)\
128 and (self._init_location_id not in InteractiveShellEmbed._inactive_locations)
128 and (self._init_location_id not in InteractiveShellEmbed._inactive_locations)
129
129
130 def _disable_init_location(self):
130 def _disable_init_location(self):
131 """Disable the current Instance creation location"""
131 """Disable the current Instance creation location"""
132 InteractiveShellEmbed._inactive_locations.add(self._init_location_id)
132 InteractiveShellEmbed._inactive_locations.add(self._init_location_id)
133
133
134 @embedded_active.setter
134 @embedded_active.setter
135 def embedded_active(self, value):
135 def embedded_active(self, value):
136 if value:
136 if value:
137 InteractiveShellEmbed._inactive_locations.discard(
137 InteractiveShellEmbed._inactive_locations.discard(
138 self._call_location_id)
138 self._call_location_id)
139 InteractiveShellEmbed._inactive_locations.discard(
139 InteractiveShellEmbed._inactive_locations.discard(
140 self._init_location_id)
140 self._init_location_id)
141 else:
141 else:
142 InteractiveShellEmbed._inactive_locations.add(
142 InteractiveShellEmbed._inactive_locations.add(
143 self._call_location_id)
143 self._call_location_id)
144
144
145 def __init__(self, **kw):
145 def __init__(self, **kw):
146 if kw.get('user_global_ns', None) is not None:
146 if kw.get('user_global_ns', None) is not None:
147 raise DeprecationWarning(
147 raise DeprecationWarning(
148 "Key word argument `user_global_ns` has been replaced by `user_module` since IPython 4.0.")
148 "Key word argument `user_global_ns` has been replaced by `user_module` since IPython 4.0.")
149
149
150 clid = kw.pop('_init_location_id', None)
150 clid = kw.pop('_init_location_id', None)
151 if not clid:
151 if not clid:
152 frame = sys._getframe(1)
152 frame = sys._getframe(1)
153 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
153 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
154 self._init_location_id = clid
154 self._init_location_id = clid
155
155
156 super(InteractiveShellEmbed,self).__init__(**kw)
156 super(InteractiveShellEmbed,self).__init__(**kw)
157
157
158 # don't use the ipython crash handler so that user exceptions aren't
158 # don't use the ipython crash handler so that user exceptions aren't
159 # trapped
159 # trapped
160 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
160 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
161 mode=self.xmode,
161 mode=self.xmode,
162 call_pdb=self.pdb)
162 call_pdb=self.pdb)
163
163
164 def init_sys_modules(self):
164 def init_sys_modules(self):
165 """
165 """
166 Explicitly overwrite :any:`IPython.core.interactiveshell` to do nothing.
166 Explicitly overwrite :mod:`IPython.core.interactiveshell` to do nothing.
167 """
167 """
168 pass
168 pass
169
169
170 def init_magics(self):
170 def init_magics(self):
171 super(InteractiveShellEmbed, self).init_magics()
171 super(InteractiveShellEmbed, self).init_magics()
172 self.register_magics(EmbeddedMagics)
172 self.register_magics(EmbeddedMagics)
173
173
174 def __call__(self, header='', local_ns=None, module=None, dummy=None,
174 def __call__(self, header='', local_ns=None, module=None, dummy=None,
175 stack_depth=1, global_ns=None, compile_flags=None, **kw):
175 stack_depth=1, global_ns=None, compile_flags=None, **kw):
176 """Activate the interactive interpreter.
176 """Activate the interactive interpreter.
177
177
178 __call__(self,header='',local_ns=None,module=None,dummy=None) -> Start
178 __call__(self,header='',local_ns=None,module=None,dummy=None) -> Start
179 the interpreter shell with the given local and global namespaces, and
179 the interpreter shell with the given local and global namespaces, and
180 optionally print a header string at startup.
180 optionally print a header string at startup.
181
181
182 The shell can be globally activated/deactivated using the
182 The shell can be globally activated/deactivated using the
183 dummy_mode attribute. This allows you to turn off a shell used
183 dummy_mode attribute. This allows you to turn off a shell used
184 for debugging globally.
184 for debugging globally.
185
185
186 However, *each* time you call the shell you can override the current
186 However, *each* time you call the shell you can override the current
187 state of dummy_mode with the optional keyword parameter 'dummy'. For
187 state of dummy_mode with the optional keyword parameter 'dummy'. For
188 example, if you set dummy mode on with IPShell.dummy_mode = True, you
188 example, if you set dummy mode on with IPShell.dummy_mode = True, you
189 can still have a specific call work by making it as IPShell(dummy=False).
189 can still have a specific call work by making it as IPShell(dummy=False).
190 """
190 """
191
191
192 # we are called, set the underlying interactiveshell not to exit.
192 # we are called, set the underlying interactiveshell not to exit.
193 self.keep_running = True
193 self.keep_running = True
194
194
195 # If the user has turned it off, go away
195 # If the user has turned it off, go away
196 clid = kw.pop('_call_location_id', None)
196 clid = kw.pop('_call_location_id', None)
197 if not clid:
197 if not clid:
198 frame = sys._getframe(1)
198 frame = sys._getframe(1)
199 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
199 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
200 self._call_location_id = clid
200 self._call_location_id = clid
201
201
202 if not self.embedded_active:
202 if not self.embedded_active:
203 return
203 return
204
204
205 # Normal exits from interactive mode set this flag, so the shell can't
205 # Normal exits from interactive mode set this flag, so the shell can't
206 # re-enter (it checks this variable at the start of interactive mode).
206 # re-enter (it checks this variable at the start of interactive mode).
207 self.exit_now = False
207 self.exit_now = False
208
208
209 # Allow the dummy parameter to override the global __dummy_mode
209 # Allow the dummy parameter to override the global __dummy_mode
210 if dummy or (dummy != 0 and self.dummy_mode):
210 if dummy or (dummy != 0 and self.dummy_mode):
211 return
211 return
212
212
213 # self.banner is auto computed
213 # self.banner is auto computed
214 if header:
214 if header:
215 self.old_banner2 = self.banner2
215 self.old_banner2 = self.banner2
216 self.banner2 = self.banner2 + '\n' + header + '\n'
216 self.banner2 = self.banner2 + '\n' + header + '\n'
217 else:
217 else:
218 self.old_banner2 = ''
218 self.old_banner2 = ''
219
219
220 if self.display_banner:
220 if self.display_banner:
221 self.show_banner()
221 self.show_banner()
222
222
223 # Call the embedding code with a stack depth of 1 so it can skip over
223 # Call the embedding code with a stack depth of 1 so it can skip over
224 # our call and get the original caller's namespaces.
224 # our call and get the original caller's namespaces.
225 self.mainloop(local_ns, module, stack_depth=stack_depth,
225 self.mainloop(local_ns, module, stack_depth=stack_depth,
226 global_ns=global_ns, compile_flags=compile_flags)
226 global_ns=global_ns, compile_flags=compile_flags)
227
227
228 self.banner2 = self.old_banner2
228 self.banner2 = self.old_banner2
229
229
230 if self.exit_msg is not None:
230 if self.exit_msg is not None:
231 print(self.exit_msg)
231 print(self.exit_msg)
232
232
233 if self.should_raise:
233 if self.should_raise:
234 raise KillEmbeded('Embedded IPython raising error, as user requested.')
234 raise KillEmbeded('Embedded IPython raising error, as user requested.')
235
235
236
236
237 def mainloop(self, local_ns=None, module=None, stack_depth=0,
237 def mainloop(self, local_ns=None, module=None, stack_depth=0,
238 display_banner=None, global_ns=None, compile_flags=None):
238 display_banner=None, global_ns=None, compile_flags=None):
239 """Embeds IPython into a running python program.
239 """Embeds IPython into a running python program.
240
240
241 Parameters
241 Parameters
242 ----------
242 ----------
243
243
244 local_ns, module
244 local_ns, module
245 Working local namespace (a dict) and module (a module or similar
245 Working local namespace (a dict) and module (a module or similar
246 object). If given as None, they are automatically taken from the scope
246 object). If given as None, they are automatically taken from the scope
247 where the shell was called, so that program variables become visible.
247 where the shell was called, so that program variables become visible.
248
248
249 stack_depth : int
249 stack_depth : int
250 How many levels in the stack to go to looking for namespaces (when
250 How many levels in the stack to go to looking for namespaces (when
251 local_ns or module is None). This allows an intermediate caller to
251 local_ns or module is None). This allows an intermediate caller to
252 make sure that this function gets the namespace from the intended
252 make sure that this function gets the namespace from the intended
253 level in the stack. By default (0) it will get its locals and globals
253 level in the stack. By default (0) it will get its locals and globals
254 from the immediate caller.
254 from the immediate caller.
255
255
256 compile_flags
256 compile_flags
257 A bit field identifying the __future__ features
257 A bit field identifying the __future__ features
258 that are enabled, as passed to the builtin :func:`compile` function.
258 that are enabled, as passed to the builtin :func:`compile` function.
259 If given as None, they are automatically taken from the scope where
259 If given as None, they are automatically taken from the scope where
260 the shell was called.
260 the shell was called.
261
261
262 """
262 """
263
263
264 if (global_ns is not None) and (module is None):
264 if (global_ns is not None) and (module is None):
265 raise DeprecationWarning("'global_ns' keyword argument is deprecated, and has been removed in IPython 5.0 use `module` keyword argument instead.")
265 raise DeprecationWarning("'global_ns' keyword argument is deprecated, and has been removed in IPython 5.0 use `module` keyword argument instead.")
266
266
267 if (display_banner is not None):
267 if (display_banner is not None):
268 warnings.warn("The display_banner parameter is deprecated since IPython 4.0", DeprecationWarning)
268 warnings.warn("The display_banner parameter is deprecated since IPython 4.0", DeprecationWarning)
269
269
270 # Get locals and globals from caller
270 # Get locals and globals from caller
271 if ((local_ns is None or module is None or compile_flags is None)
271 if ((local_ns is None or module is None or compile_flags is None)
272 and self.default_user_namespaces):
272 and self.default_user_namespaces):
273 call_frame = sys._getframe(stack_depth).f_back
273 call_frame = sys._getframe(stack_depth).f_back
274
274
275 if local_ns is None:
275 if local_ns is None:
276 local_ns = call_frame.f_locals
276 local_ns = call_frame.f_locals
277 if module is None:
277 if module is None:
278 global_ns = call_frame.f_globals
278 global_ns = call_frame.f_globals
279 try:
279 try:
280 module = sys.modules[global_ns['__name__']]
280 module = sys.modules[global_ns['__name__']]
281 except KeyError:
281 except KeyError:
282 warnings.warn("Failed to get module %s" % \
282 warnings.warn("Failed to get module %s" % \
283 global_ns.get('__name__', 'unknown module')
283 global_ns.get('__name__', 'unknown module')
284 )
284 )
285 module = DummyMod()
285 module = DummyMod()
286 module.__dict__ = global_ns
286 module.__dict__ = global_ns
287 if compile_flags is None:
287 if compile_flags is None:
288 compile_flags = (call_frame.f_code.co_flags &
288 compile_flags = (call_frame.f_code.co_flags &
289 compilerop.PyCF_MASK)
289 compilerop.PyCF_MASK)
290
290
291 # Save original namespace and module so we can restore them after
291 # Save original namespace and module so we can restore them after
292 # embedding; otherwise the shell doesn't shut down correctly.
292 # embedding; otherwise the shell doesn't shut down correctly.
293 orig_user_module = self.user_module
293 orig_user_module = self.user_module
294 orig_user_ns = self.user_ns
294 orig_user_ns = self.user_ns
295 orig_compile_flags = self.compile.flags
295 orig_compile_flags = self.compile.flags
296
296
297 # Update namespaces and fire up interpreter
297 # Update namespaces and fire up interpreter
298
298
299 # The global one is easy, we can just throw it in
299 # The global one is easy, we can just throw it in
300 if module is not None:
300 if module is not None:
301 self.user_module = module
301 self.user_module = module
302
302
303 # But the user/local one is tricky: ipython needs it to store internal
303 # But the user/local one is tricky: ipython needs it to store internal
304 # data, but we also need the locals. We'll throw our hidden variables
304 # data, but we also need the locals. We'll throw our hidden variables
305 # like _ih and get_ipython() into the local namespace, but delete them
305 # like _ih and get_ipython() into the local namespace, but delete them
306 # later.
306 # later.
307 if local_ns is not None:
307 if local_ns is not None:
308 reentrant_local_ns = {k: v for (k, v) in local_ns.items() if k not in self.user_ns_hidden.keys()}
308 reentrant_local_ns = {k: v for (k, v) in local_ns.items() if k not in self.user_ns_hidden.keys()}
309 self.user_ns = reentrant_local_ns
309 self.user_ns = reentrant_local_ns
310 self.init_user_ns()
310 self.init_user_ns()
311
311
312 # Compiler flags
312 # Compiler flags
313 if compile_flags is not None:
313 if compile_flags is not None:
314 self.compile.flags = compile_flags
314 self.compile.flags = compile_flags
315
315
316 # make sure the tab-completer has the correct frame information, so it
316 # make sure the tab-completer has the correct frame information, so it
317 # actually completes using the frame's locals/globals
317 # actually completes using the frame's locals/globals
318 self.set_completer_frame()
318 self.set_completer_frame()
319
319
320 with self.builtin_trap, self.display_trap:
320 with self.builtin_trap, self.display_trap:
321 self.interact()
321 self.interact()
322
322
323 # now, purge out the local namespace of IPython's hidden variables.
323 # now, purge out the local namespace of IPython's hidden variables.
324 if local_ns is not None:
324 if local_ns is not None:
325 local_ns.update({k: v for (k, v) in self.user_ns.items() if k not in self.user_ns_hidden.keys()})
325 local_ns.update({k: v for (k, v) in self.user_ns.items() if k not in self.user_ns_hidden.keys()})
326
326
327
327
328 # Restore original namespace so shell can shut down when we exit.
328 # Restore original namespace so shell can shut down when we exit.
329 self.user_module = orig_user_module
329 self.user_module = orig_user_module
330 self.user_ns = orig_user_ns
330 self.user_ns = orig_user_ns
331 self.compile.flags = orig_compile_flags
331 self.compile.flags = orig_compile_flags
332
332
333
333
334 def embed(**kwargs):
334 def embed(**kwargs):
335 """Call this to embed IPython at the current point in your program.
335 """Call this to embed IPython at the current point in your program.
336
336
337 The first invocation of this will create an :class:`InteractiveShellEmbed`
337 The first invocation of this will create an :class:`InteractiveShellEmbed`
338 instance and then call it. Consecutive calls just call the already
338 instance and then call it. Consecutive calls just call the already
339 created instance.
339 created instance.
340
340
341 If you don't want the kernel to initialize the namespace
341 If you don't want the kernel to initialize the namespace
342 from the scope of the surrounding function,
342 from the scope of the surrounding function,
343 and/or you want to load full IPython configuration,
343 and/or you want to load full IPython configuration,
344 you probably want `IPython.start_ipython()` instead.
344 you probably want `IPython.start_ipython()` instead.
345
345
346 Here is a simple example::
346 Here is a simple example::
347
347
348 from IPython import embed
348 from IPython import embed
349 a = 10
349 a = 10
350 b = 20
350 b = 20
351 embed(header='First time')
351 embed(header='First time')
352 c = 30
352 c = 30
353 d = 40
353 d = 40
354 embed()
354 embed()
355
355
356 Full customization can be done by passing a :class:`Config` in as the
356 Full customization can be done by passing a :class:`Config` in as the
357 config argument.
357 config argument.
358 """
358 """
359 config = kwargs.get('config')
359 config = kwargs.get('config')
360 header = kwargs.pop('header', u'')
360 header = kwargs.pop('header', u'')
361 compile_flags = kwargs.pop('compile_flags', None)
361 compile_flags = kwargs.pop('compile_flags', None)
362 if config is None:
362 if config is None:
363 config = load_default_config()
363 config = load_default_config()
364 config.InteractiveShellEmbed = config.TerminalInteractiveShell
364 config.InteractiveShellEmbed = config.TerminalInteractiveShell
365 kwargs['config'] = config
365 kwargs['config'] = config
366 #save ps1/ps2 if defined
366 #save ps1/ps2 if defined
367 ps1 = None
367 ps1 = None
368 ps2 = None
368 ps2 = None
369 try:
369 try:
370 ps1 = sys.ps1
370 ps1 = sys.ps1
371 ps2 = sys.ps2
371 ps2 = sys.ps2
372 except AttributeError:
372 except AttributeError:
373 pass
373 pass
374 #save previous instance
374 #save previous instance
375 saved_shell_instance = InteractiveShell._instance
375 saved_shell_instance = InteractiveShell._instance
376 if saved_shell_instance is not None:
376 if saved_shell_instance is not None:
377 cls = type(saved_shell_instance)
377 cls = type(saved_shell_instance)
378 cls.clear_instance()
378 cls.clear_instance()
379 frame = sys._getframe(1)
379 frame = sys._getframe(1)
380 shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % (
380 shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % (
381 frame.f_code.co_filename, frame.f_lineno), **kwargs)
381 frame.f_code.co_filename, frame.f_lineno), **kwargs)
382 shell(header=header, stack_depth=2, compile_flags=compile_flags,
382 shell(header=header, stack_depth=2, compile_flags=compile_flags,
383 _call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno))
383 _call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno))
384 InteractiveShellEmbed.clear_instance()
384 InteractiveShellEmbed.clear_instance()
385 #restore previous instance
385 #restore previous instance
386 if saved_shell_instance is not None:
386 if saved_shell_instance is not None:
387 cls = type(saved_shell_instance)
387 cls = type(saved_shell_instance)
388 cls.clear_instance()
388 cls.clear_instance()
389 for subclass in cls._walk_mro():
389 for subclass in cls._walk_mro():
390 subclass._instance = saved_shell_instance
390 subclass._instance = saved_shell_instance
391 if ps1 is not None:
391 if ps1 is not None:
392 sys.ps1 = ps1
392 sys.ps1 = ps1
393 sys.ps2 = ps2
393 sys.ps2 = ps2
@@ -1,245 +1,245 b''
1 """
1 """
2 Module to define and register Terminal IPython shortcuts with
2 Module to define and register Terminal IPython shortcuts with
3 :any:`prompt_toolkit`
3 :mod:`prompt_toolkit`
4 """
4 """
5
5
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 import warnings
9 import warnings
10 import signal
10 import signal
11 import sys
11 import sys
12 from typing import Callable
12 from typing import Callable
13
13
14
14
15 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
15 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
16 from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
16 from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
17 ViInsertMode, EmacsInsertMode, HasCompletions)
17 ViInsertMode, EmacsInsertMode, HasCompletions)
18 from prompt_toolkit.filters.cli import ViMode, ViNavigationMode
18 from prompt_toolkit.filters.cli import ViMode, ViNavigationMode
19 from prompt_toolkit.keys import Keys
19 from prompt_toolkit.keys import Keys
20 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
20 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
21
21
22 from IPython.utils.decorators import undoc
22 from IPython.utils.decorators import undoc
23
23
24 @Condition
24 @Condition
25 def cursor_in_leading_ws(cli):
25 def cursor_in_leading_ws(cli):
26 before = cli.application.buffer.document.current_line_before_cursor
26 before = cli.application.buffer.document.current_line_before_cursor
27 return (not before) or before.isspace()
27 return (not before) or before.isspace()
28
28
29 def register_ipython_shortcuts(registry, shell):
29 def register_ipython_shortcuts(registry, shell):
30 """Set up the prompt_toolkit keyboard shortcuts for IPython"""
30 """Set up the prompt_toolkit keyboard shortcuts for IPython"""
31 insert_mode = ViInsertMode() | EmacsInsertMode()
31 insert_mode = ViInsertMode() | EmacsInsertMode()
32
32
33 # Ctrl+J == Enter, seemingly
33 # Ctrl+J == Enter, seemingly
34 registry.add_binding(Keys.ControlJ,
34 registry.add_binding(Keys.ControlJ,
35 filter=(HasFocus(DEFAULT_BUFFER)
35 filter=(HasFocus(DEFAULT_BUFFER)
36 & ~HasSelection()
36 & ~HasSelection()
37 & insert_mode
37 & insert_mode
38 ))(newline_or_execute_outer(shell))
38 ))(newline_or_execute_outer(shell))
39
39
40 registry.add_binding(Keys.ControlBackslash)(force_exit)
40 registry.add_binding(Keys.ControlBackslash)(force_exit)
41
41
42 registry.add_binding(Keys.ControlP,
42 registry.add_binding(Keys.ControlP,
43 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
43 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
44 ))(previous_history_or_previous_completion)
44 ))(previous_history_or_previous_completion)
45
45
46 registry.add_binding(Keys.ControlN,
46 registry.add_binding(Keys.ControlN,
47 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
47 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
48 ))(next_history_or_next_completion)
48 ))(next_history_or_next_completion)
49
49
50 registry.add_binding(Keys.ControlG,
50 registry.add_binding(Keys.ControlG,
51 filter=(HasFocus(DEFAULT_BUFFER) & HasCompletions()
51 filter=(HasFocus(DEFAULT_BUFFER) & HasCompletions()
52 ))(dismiss_completion)
52 ))(dismiss_completion)
53
53
54 registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)
54 registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)
55 )(reset_buffer)
55 )(reset_buffer)
56
56
57 registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)
57 registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)
58 )(reset_search_buffer)
58 )(reset_search_buffer)
59
59
60 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
60 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
61 registry.add_binding(Keys.ControlZ, filter=supports_suspend
61 registry.add_binding(Keys.ControlZ, filter=supports_suspend
62 )(suspend_to_bg)
62 )(suspend_to_bg)
63
63
64 # Ctrl+I == Tab
64 # Ctrl+I == Tab
65 registry.add_binding(Keys.ControlI,
65 registry.add_binding(Keys.ControlI,
66 filter=(HasFocus(DEFAULT_BUFFER)
66 filter=(HasFocus(DEFAULT_BUFFER)
67 & ~HasSelection()
67 & ~HasSelection()
68 & insert_mode
68 & insert_mode
69 & cursor_in_leading_ws
69 & cursor_in_leading_ws
70 ))(indent_buffer)
70 ))(indent_buffer)
71
71
72 registry.add_binding(Keys.ControlO,
72 registry.add_binding(Keys.ControlO,
73 filter=(HasFocus(DEFAULT_BUFFER)
73 filter=(HasFocus(DEFAULT_BUFFER)
74 & EmacsInsertMode()))(newline_autoindent_outer(shell.input_splitter))
74 & EmacsInsertMode()))(newline_autoindent_outer(shell.input_splitter))
75
75
76 registry.add_binding(Keys.F2,
76 registry.add_binding(Keys.F2,
77 filter=HasFocus(DEFAULT_BUFFER)
77 filter=HasFocus(DEFAULT_BUFFER)
78 )(open_input_in_editor)
78 )(open_input_in_editor)
79
79
80 if shell.display_completions == 'readlinelike':
80 if shell.display_completions == 'readlinelike':
81 registry.add_binding(Keys.ControlI,
81 registry.add_binding(Keys.ControlI,
82 filter=(HasFocus(DEFAULT_BUFFER)
82 filter=(HasFocus(DEFAULT_BUFFER)
83 & ~HasSelection()
83 & ~HasSelection()
84 & insert_mode
84 & insert_mode
85 & ~cursor_in_leading_ws
85 & ~cursor_in_leading_ws
86 ))(display_completions_like_readline)
86 ))(display_completions_like_readline)
87
87
88 if sys.platform == 'win32':
88 if sys.platform == 'win32':
89 registry.add_binding(Keys.ControlV,
89 registry.add_binding(Keys.ControlV,
90 filter=(
90 filter=(
91 HasFocus(
91 HasFocus(
92 DEFAULT_BUFFER) & ~ViMode()
92 DEFAULT_BUFFER) & ~ViMode()
93 ))(win_paste)
93 ))(win_paste)
94
94
95
95
96 def newline_or_execute_outer(shell):
96 def newline_or_execute_outer(shell):
97 def newline_or_execute(event):
97 def newline_or_execute(event):
98 """When the user presses return, insert a newline or execute the code."""
98 """When the user presses return, insert a newline or execute the code."""
99 b = event.current_buffer
99 b = event.current_buffer
100 d = b.document
100 d = b.document
101
101
102 if b.complete_state:
102 if b.complete_state:
103 cc = b.complete_state.current_completion
103 cc = b.complete_state.current_completion
104 if cc:
104 if cc:
105 b.apply_completion(cc)
105 b.apply_completion(cc)
106 else:
106 else:
107 b.cancel_completion()
107 b.cancel_completion()
108 return
108 return
109
109
110 before_text = d.text[:d.cursor_position]
110 before_text = d.text[:d.cursor_position]
111 status, indent = shell.input_splitter.check_complete(before_text + '\n')
111 status, indent = shell.input_splitter.check_complete(before_text + '\n')
112
112
113 if not (d.on_last_line or
113 if not (d.on_last_line or
114 d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()
114 d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()
115 ):
115 ):
116 b.insert_text('\n' + (' ' * (indent or 0)))
116 b.insert_text('\n' + (' ' * (indent or 0)))
117 return
117 return
118
118
119 if (status != 'incomplete') and b.accept_action.is_returnable:
119 if (status != 'incomplete') and b.accept_action.is_returnable:
120 b.accept_action.validate_and_handle(event.cli, b)
120 b.accept_action.validate_and_handle(event.cli, b)
121 else:
121 else:
122 b.insert_text('\n' + (' ' * (indent or 0)))
122 b.insert_text('\n' + (' ' * (indent or 0)))
123 return newline_or_execute
123 return newline_or_execute
124
124
125
125
126 def previous_history_or_previous_completion(event):
126 def previous_history_or_previous_completion(event):
127 """
127 """
128 Control-P in vi edit mode on readline is history next, unlike default prompt toolkit.
128 Control-P in vi edit mode on readline is history next, unlike default prompt toolkit.
129
129
130 If completer is open this still select previous completion.
130 If completer is open this still select previous completion.
131 """
131 """
132 event.current_buffer.auto_up()
132 event.current_buffer.auto_up()
133
133
134
134
135 def next_history_or_next_completion(event):
135 def next_history_or_next_completion(event):
136 """
136 """
137 Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit.
137 Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit.
138
138
139 If completer is open this still select next completion.
139 If completer is open this still select next completion.
140 """
140 """
141 event.current_buffer.auto_down()
141 event.current_buffer.auto_down()
142
142
143
143
144 def dismiss_completion(event):
144 def dismiss_completion(event):
145 b = event.current_buffer
145 b = event.current_buffer
146 if b.complete_state:
146 if b.complete_state:
147 b.cancel_completion()
147 b.cancel_completion()
148
148
149
149
150 def reset_buffer(event):
150 def reset_buffer(event):
151 b = event.current_buffer
151 b = event.current_buffer
152 if b.complete_state:
152 if b.complete_state:
153 b.cancel_completion()
153 b.cancel_completion()
154 else:
154 else:
155 b.reset()
155 b.reset()
156
156
157
157
158 def reset_search_buffer(event):
158 def reset_search_buffer(event):
159 if event.current_buffer.document.text:
159 if event.current_buffer.document.text:
160 event.current_buffer.reset()
160 event.current_buffer.reset()
161 else:
161 else:
162 event.cli.push_focus(DEFAULT_BUFFER)
162 event.cli.push_focus(DEFAULT_BUFFER)
163
163
164 def suspend_to_bg(event):
164 def suspend_to_bg(event):
165 event.cli.suspend_to_background()
165 event.cli.suspend_to_background()
166
166
167 def force_exit(event):
167 def force_exit(event):
168 """
168 """
169 Force exit (with a non-zero return value)
169 Force exit (with a non-zero return value)
170 """
170 """
171 sys.exit("Quit")
171 sys.exit("Quit")
172
172
173 def indent_buffer(event):
173 def indent_buffer(event):
174 event.current_buffer.insert_text(' ' * 4)
174 event.current_buffer.insert_text(' ' * 4)
175
175
176 @undoc
176 @undoc
177 def newline_with_copy_margin(event):
177 def newline_with_copy_margin(event):
178 """
178 """
179 DEPRECATED since IPython 6.0
179 DEPRECATED since IPython 6.0
180
180
181 See :any:`newline_autoindent_outer` for a replacement.
181 See :any:`newline_autoindent_outer` for a replacement.
182
182
183 Preserve margin and cursor position when using
183 Preserve margin and cursor position when using
184 Control-O to insert a newline in EMACS mode
184 Control-O to insert a newline in EMACS mode
185 """
185 """
186 warnings.warn("`newline_with_copy_margin(event)` is deprecated since IPython 6.0. "
186 warnings.warn("`newline_with_copy_margin(event)` is deprecated since IPython 6.0. "
187 "see `newline_autoindent_outer(shell)(event)` for a replacement.",
187 "see `newline_autoindent_outer(shell)(event)` for a replacement.",
188 DeprecationWarning, stacklevel=2)
188 DeprecationWarning, stacklevel=2)
189
189
190 b = event.current_buffer
190 b = event.current_buffer
191 cursor_start_pos = b.document.cursor_position_col
191 cursor_start_pos = b.document.cursor_position_col
192 b.newline(copy_margin=True)
192 b.newline(copy_margin=True)
193 b.cursor_up(count=1)
193 b.cursor_up(count=1)
194 cursor_end_pos = b.document.cursor_position_col
194 cursor_end_pos = b.document.cursor_position_col
195 if cursor_start_pos != cursor_end_pos:
195 if cursor_start_pos != cursor_end_pos:
196 pos_diff = cursor_start_pos - cursor_end_pos
196 pos_diff = cursor_start_pos - cursor_end_pos
197 b.cursor_right(count=pos_diff)
197 b.cursor_right(count=pos_diff)
198
198
199 def newline_autoindent_outer(inputsplitter) -> Callable[..., None]:
199 def newline_autoindent_outer(inputsplitter) -> Callable[..., None]:
200 """
200 """
201 Return a function suitable for inserting a indented newline after the cursor.
201 Return a function suitable for inserting a indented newline after the cursor.
202
202
203 Fancier version of deprecated ``newline_with_copy_margin`` which should
203 Fancier version of deprecated ``newline_with_copy_margin`` which should
204 compute the correct indentation of the inserted line. That is to say, indent
204 compute the correct indentation of the inserted line. That is to say, indent
205 by 4 extra space after a function definition, class definition, context
205 by 4 extra space after a function definition, class definition, context
206 manager... And dedent by 4 space after ``pass``, ``return``, ``raise ...``.
206 manager... And dedent by 4 space after ``pass``, ``return``, ``raise ...``.
207 """
207 """
208
208
209 def newline_autoindent(event):
209 def newline_autoindent(event):
210 """insert a newline after the cursor indented appropriately."""
210 """insert a newline after the cursor indented appropriately."""
211 b = event.current_buffer
211 b = event.current_buffer
212 d = b.document
212 d = b.document
213
213
214 if b.complete_state:
214 if b.complete_state:
215 b.cancel_completion()
215 b.cancel_completion()
216 text = d.text[:d.cursor_position] + '\n'
216 text = d.text[:d.cursor_position] + '\n'
217 _, indent = inputsplitter.check_complete(text)
217 _, indent = inputsplitter.check_complete(text)
218 b.insert_text('\n' + (' ' * (indent or 0)), move_cursor=False)
218 b.insert_text('\n' + (' ' * (indent or 0)), move_cursor=False)
219
219
220 return newline_autoindent
220 return newline_autoindent
221
221
222
222
223 def open_input_in_editor(event):
223 def open_input_in_editor(event):
224 event.cli.current_buffer.tempfile_suffix = ".py"
224 event.cli.current_buffer.tempfile_suffix = ".py"
225 event.cli.current_buffer.open_in_editor(event.cli)
225 event.cli.current_buffer.open_in_editor(event.cli)
226
226
227
227
228 if sys.platform == 'win32':
228 if sys.platform == 'win32':
229 from IPython.core.error import TryNext
229 from IPython.core.error import TryNext
230 from IPython.lib.clipboard import (ClipboardEmpty,
230 from IPython.lib.clipboard import (ClipboardEmpty,
231 win32_clipboard_get,
231 win32_clipboard_get,
232 tkinter_clipboard_get)
232 tkinter_clipboard_get)
233
233
234 @undoc
234 @undoc
235 def win_paste(event):
235 def win_paste(event):
236 try:
236 try:
237 text = win32_clipboard_get()
237 text = win32_clipboard_get()
238 except TryNext:
238 except TryNext:
239 try:
239 try:
240 text = tkinter_clipboard_get()
240 text = tkinter_clipboard_get()
241 except (TryNext, ClipboardEmpty):
241 except (TryNext, ClipboardEmpty):
242 return
242 return
243 except ClipboardEmpty:
243 except ClipboardEmpty:
244 return
244 return
245 event.current_buffer.insert_text(text.replace('\t', ' ' * 4))
245 event.current_buffer.insert_text(text.replace('\t', ' ' * 4))
General Comments 0
You need to be logged in to leave comments. Login now