##// END OF EJS Templates
reformat terminal
Matthias Bussonnier -
Show More
@@ -1,415 +1,410 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 from typing import Set
22 from typing import Set
23
23
24 class KillEmbedded(Exception):pass
24 class KillEmbedded(Exception):pass
25
25
26 # kept for backward compatibility as IPython 6 was released with
26 # kept for backward compatibility as IPython 6 was released with
27 # the typo. See https://github.com/ipython/ipython/pull/10706
27 # the typo. See https://github.com/ipython/ipython/pull/10706
28 KillEmbeded = KillEmbedded
28 KillEmbeded = KillEmbedded
29
29
30 # This is an additional magic that is exposed in embedded shells.
30 # This is an additional magic that is exposed in embedded shells.
31 @magics_class
31 @magics_class
32 class EmbeddedMagics(Magics):
32 class EmbeddedMagics(Magics):
33
33
34 @line_magic
34 @line_magic
35 @magic_arguments.magic_arguments()
35 @magic_arguments.magic_arguments()
36 @magic_arguments.argument('-i', '--instance', action='store_true',
36 @magic_arguments.argument('-i', '--instance', action='store_true',
37 help='Kill instance instead of call location')
37 help='Kill instance instead of call location')
38 @magic_arguments.argument('-x', '--exit', action='store_true',
38 @magic_arguments.argument('-x', '--exit', action='store_true',
39 help='Also exit the current session')
39 help='Also exit the current session')
40 @magic_arguments.argument('-y', '--yes', action='store_true',
40 @magic_arguments.argument('-y', '--yes', action='store_true',
41 help='Do not ask confirmation')
41 help='Do not ask confirmation')
42 def kill_embedded(self, parameter_s=''):
42 def kill_embedded(self, parameter_s=''):
43 """%kill_embedded : deactivate for good the current embedded IPython
43 """%kill_embedded : deactivate for good the current embedded IPython
44
44
45 This function (after asking for confirmation) sets an internal flag so
45 This function (after asking for confirmation) sets an internal flag so
46 that an embedded IPython will never activate again for the given call
46 that an embedded IPython will never activate again for the given call
47 location. This is useful to permanently disable a shell that is being
47 location. This is useful to permanently disable a shell that is being
48 called inside a loop: once you've figured out what you needed from it,
48 called inside a loop: once you've figured out what you needed from it,
49 you may then kill it and the program will then continue to run without
49 you may then kill it and the program will then continue to run without
50 the interactive shell interfering again.
50 the interactive shell interfering again.
51
51
52
53 Kill Instance Option:
52 Kill Instance Option:
54
53
55 If for some reasons you need to kill the location where the instance
54 If for some reasons you need to kill the location where the instance
56 is created and not called, for example if you create a single
55 is created and not called, for example if you create a single
57 instance in one place and debug in many locations, you can use the
56 instance in one place and debug in many locations, you can use the
58 ``--instance`` option to kill this specific instance. Like for the
57 ``--instance`` option to kill this specific instance. Like for the
59 ``call location`` killing an "instance" should work even if it is
58 ``call location`` killing an "instance" should work even if it is
60 recreated within a loop.
59 recreated within a loop.
61
60
62 .. note::
61 .. note::
63
62
64 This was the default behavior before IPython 5.2
63 This was the default behavior before IPython 5.2
65
64
66 """
65 """
67
66
68 args = magic_arguments.parse_argstring(self.kill_embedded, parameter_s)
67 args = magic_arguments.parse_argstring(self.kill_embedded, parameter_s)
69 print(args)
68 print(args)
70 if args.instance:
69 if args.instance:
71 # let no ask
70 # let no ask
72 if not args.yes:
71 if not args.yes:
73 kill = ask_yes_no(
72 kill = ask_yes_no(
74 "Are you sure you want to kill this embedded instance? [y/N] ", 'n')
73 "Are you sure you want to kill this embedded instance? [y/N] ", 'n')
75 else:
74 else:
76 kill = True
75 kill = True
77 if kill:
76 if kill:
78 self.shell._disable_init_location()
77 self.shell._disable_init_location()
79 print("This embedded IPython instance will not reactivate anymore "
78 print("This embedded IPython instance will not reactivate anymore "
80 "once you exit.")
79 "once you exit.")
81 else:
80 else:
82 if not args.yes:
81 if not args.yes:
83 kill = ask_yes_no(
82 kill = ask_yes_no(
84 "Are you sure you want to kill this embedded call_location? [y/N] ", 'n')
83 "Are you sure you want to kill this embedded call_location? [y/N] ", 'n')
85 else:
84 else:
86 kill = True
85 kill = True
87 if kill:
86 if kill:
88 self.shell.embedded_active = False
87 self.shell.embedded_active = False
89 print("This embedded IPython call location will not reactivate anymore "
88 print("This embedded IPython call location will not reactivate anymore "
90 "once you exit.")
89 "once you exit.")
91
90
92 if args.exit:
91 if args.exit:
93 # Ask-exit does not really ask, it just set internals flags to exit
92 # Ask-exit does not really ask, it just set internals flags to exit
94 # on next loop.
93 # on next loop.
95 self.shell.ask_exit()
94 self.shell.ask_exit()
96
95
97
96
98 @line_magic
97 @line_magic
99 def exit_raise(self, parameter_s=''):
98 def exit_raise(self, parameter_s=''):
100 """%exit_raise Make the current embedded kernel exit and raise and exception.
99 """%exit_raise Make the current embedded kernel exit and raise and exception.
101
100
102 This function sets an internal flag so that an embedded IPython will
101 This function sets an internal flag so that an embedded IPython will
103 raise a `IPython.terminal.embed.KillEmbedded` Exception on exit, and then exit the current I. This is
102 raise a `IPython.terminal.embed.KillEmbedded` Exception on exit, and then exit the current I. This is
104 useful to permanently exit a loop that create IPython embed instance.
103 useful to permanently exit a loop that create IPython embed instance.
105 """
104 """
106
105
107 self.shell.should_raise = True
106 self.shell.should_raise = True
108 self.shell.ask_exit()
107 self.shell.ask_exit()
109
108
110
109
111 class _Sentinel:
110 class _Sentinel:
112 def __init__(self, repr):
111 def __init__(self, repr):
113 assert isinstance(repr, str)
112 assert isinstance(repr, str)
114 self.repr = repr
113 self.repr = repr
115
114
116 def __repr__(self):
115 def __repr__(self):
117 return repr
116 return repr
118
117
119
118
120 class InteractiveShellEmbed(TerminalInteractiveShell):
119 class InteractiveShellEmbed(TerminalInteractiveShell):
121
120
122 dummy_mode = Bool(False)
121 dummy_mode = Bool(False)
123 exit_msg = Unicode('')
122 exit_msg = Unicode('')
124 embedded = CBool(True)
123 embedded = CBool(True)
125 should_raise = CBool(False)
124 should_raise = CBool(False)
126 # Like the base class display_banner is not configurable, but here it
125 # Like the base class display_banner is not configurable, but here it
127 # is True by default.
126 # is True by default.
128 display_banner = CBool(True)
127 display_banner = CBool(True)
129 exit_msg = Unicode()
128 exit_msg = Unicode()
130
129
131 # When embedding, by default we don't change the terminal title
130 # When embedding, by default we don't change the terminal title
132 term_title = Bool(False,
131 term_title = Bool(False,
133 help="Automatically set the terminal title"
132 help="Automatically set the terminal title"
134 ).tag(config=True)
133 ).tag(config=True)
135
134
136 _inactive_locations: Set[str] = set()
135 _inactive_locations: Set[str] = set()
137
136
138 def _disable_init_location(self):
137 def _disable_init_location(self):
139 """Disable the current Instance creation location"""
138 """Disable the current Instance creation location"""
140 InteractiveShellEmbed._inactive_locations.add(self._init_location_id)
139 InteractiveShellEmbed._inactive_locations.add(self._init_location_id)
141
140
142 @property
141 @property
143 def embedded_active(self):
142 def embedded_active(self):
144 return (self._call_location_id not in InteractiveShellEmbed._inactive_locations)\
143 return (self._call_location_id not in InteractiveShellEmbed._inactive_locations)\
145 and (self._init_location_id not in InteractiveShellEmbed._inactive_locations)
144 and (self._init_location_id not in InteractiveShellEmbed._inactive_locations)
146
145
147 @embedded_active.setter
146 @embedded_active.setter
148 def embedded_active(self, value):
147 def embedded_active(self, value):
149 if value:
148 if value:
150 InteractiveShellEmbed._inactive_locations.discard(
149 InteractiveShellEmbed._inactive_locations.discard(
151 self._call_location_id)
150 self._call_location_id)
152 InteractiveShellEmbed._inactive_locations.discard(
151 InteractiveShellEmbed._inactive_locations.discard(
153 self._init_location_id)
152 self._init_location_id)
154 else:
153 else:
155 InteractiveShellEmbed._inactive_locations.add(
154 InteractiveShellEmbed._inactive_locations.add(
156 self._call_location_id)
155 self._call_location_id)
157
156
158 def __init__(self, **kw):
157 def __init__(self, **kw):
159 assert (
158 assert (
160 "user_global_ns" not in kw
159 "user_global_ns" not in kw
161 ), "Key word argument `user_global_ns` has been replaced by `user_module` since IPython 4.0."
160 ), "Key word argument `user_global_ns` has been replaced by `user_module` since IPython 4.0."
162
161
163 clid = kw.pop('_init_location_id', None)
162 clid = kw.pop('_init_location_id', None)
164 if not clid:
163 if not clid:
165 frame = sys._getframe(1)
164 frame = sys._getframe(1)
166 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
165 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
167 self._init_location_id = clid
166 self._init_location_id = clid
168
167
169 super(InteractiveShellEmbed,self).__init__(**kw)
168 super(InteractiveShellEmbed,self).__init__(**kw)
170
169
171 # don't use the ipython crash handler so that user exceptions aren't
170 # don't use the ipython crash handler so that user exceptions aren't
172 # trapped
171 # trapped
173 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
172 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
174 mode=self.xmode,
173 mode=self.xmode,
175 call_pdb=self.pdb)
174 call_pdb=self.pdb)
176
175
177 def init_sys_modules(self):
176 def init_sys_modules(self):
178 """
177 """
179 Explicitly overwrite :mod:`IPython.core.interactiveshell` to do nothing.
178 Explicitly overwrite :mod:`IPython.core.interactiveshell` to do nothing.
180 """
179 """
181 pass
180 pass
182
181
183 def init_magics(self):
182 def init_magics(self):
184 super(InteractiveShellEmbed, self).init_magics()
183 super(InteractiveShellEmbed, self).init_magics()
185 self.register_magics(EmbeddedMagics)
184 self.register_magics(EmbeddedMagics)
186
185
187 def __call__(
186 def __call__(
188 self,
187 self,
189 header="",
188 header="",
190 local_ns=None,
189 local_ns=None,
191 module=None,
190 module=None,
192 dummy=None,
191 dummy=None,
193 stack_depth=1,
192 stack_depth=1,
194 compile_flags=None,
193 compile_flags=None,
195 **kw
194 **kw
196 ):
195 ):
197 """Activate the interactive interpreter.
196 """Activate the interactive interpreter.
198
197
199 __call__(self,header='',local_ns=None,module=None,dummy=None) -> Start
198 __call__(self,header='',local_ns=None,module=None,dummy=None) -> Start
200 the interpreter shell with the given local and global namespaces, and
199 the interpreter shell with the given local and global namespaces, and
201 optionally print a header string at startup.
200 optionally print a header string at startup.
202
201
203 The shell can be globally activated/deactivated using the
202 The shell can be globally activated/deactivated using the
204 dummy_mode attribute. This allows you to turn off a shell used
203 dummy_mode attribute. This allows you to turn off a shell used
205 for debugging globally.
204 for debugging globally.
206
205
207 However, *each* time you call the shell you can override the current
206 However, *each* time you call the shell you can override the current
208 state of dummy_mode with the optional keyword parameter 'dummy'. For
207 state of dummy_mode with the optional keyword parameter 'dummy'. For
209 example, if you set dummy mode on with IPShell.dummy_mode = True, you
208 example, if you set dummy mode on with IPShell.dummy_mode = True, you
210 can still have a specific call work by making it as IPShell(dummy=False).
209 can still have a specific call work by making it as IPShell(dummy=False).
211 """
210 """
212
211
213 # we are called, set the underlying interactiveshell not to exit.
212 # we are called, set the underlying interactiveshell not to exit.
214 self.keep_running = True
213 self.keep_running = True
215
214
216 # If the user has turned it off, go away
215 # If the user has turned it off, go away
217 clid = kw.pop('_call_location_id', None)
216 clid = kw.pop('_call_location_id', None)
218 if not clid:
217 if not clid:
219 frame = sys._getframe(1)
218 frame = sys._getframe(1)
220 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
219 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
221 self._call_location_id = clid
220 self._call_location_id = clid
222
221
223 if not self.embedded_active:
222 if not self.embedded_active:
224 return
223 return
225
224
226 # Normal exits from interactive mode set this flag, so the shell can't
225 # Normal exits from interactive mode set this flag, so the shell can't
227 # re-enter (it checks this variable at the start of interactive mode).
226 # re-enter (it checks this variable at the start of interactive mode).
228 self.exit_now = False
227 self.exit_now = False
229
228
230 # Allow the dummy parameter to override the global __dummy_mode
229 # Allow the dummy parameter to override the global __dummy_mode
231 if dummy or (dummy != 0 and self.dummy_mode):
230 if dummy or (dummy != 0 and self.dummy_mode):
232 return
231 return
233
232
234 # self.banner is auto computed
233 # self.banner is auto computed
235 if header:
234 if header:
236 self.old_banner2 = self.banner2
235 self.old_banner2 = self.banner2
237 self.banner2 = self.banner2 + '\n' + header + '\n'
236 self.banner2 = self.banner2 + '\n' + header + '\n'
238 else:
237 else:
239 self.old_banner2 = ''
238 self.old_banner2 = ''
240
239
241 if self.display_banner:
240 if self.display_banner:
242 self.show_banner()
241 self.show_banner()
243
242
244 # Call the embedding code with a stack depth of 1 so it can skip over
243 # Call the embedding code with a stack depth of 1 so it can skip over
245 # our call and get the original caller's namespaces.
244 # our call and get the original caller's namespaces.
246 self.mainloop(
245 self.mainloop(
247 local_ns, module, stack_depth=stack_depth, compile_flags=compile_flags
246 local_ns, module, stack_depth=stack_depth, compile_flags=compile_flags
248 )
247 )
249
248
250 self.banner2 = self.old_banner2
249 self.banner2 = self.old_banner2
251
250
252 if self.exit_msg is not None:
251 if self.exit_msg is not None:
253 print(self.exit_msg)
252 print(self.exit_msg)
254
253
255 if self.should_raise:
254 if self.should_raise:
256 raise KillEmbedded('Embedded IPython raising error, as user requested.')
255 raise KillEmbedded('Embedded IPython raising error, as user requested.')
257
256
258 def mainloop(
257 def mainloop(
259 self,
258 self,
260 local_ns=None,
259 local_ns=None,
261 module=None,
260 module=None,
262 stack_depth=0,
261 stack_depth=0,
263 compile_flags=None,
262 compile_flags=None,
264 ):
263 ):
265 """Embeds IPython into a running python program.
264 """Embeds IPython into a running python program.
266
265
267 Parameters
266 Parameters
268 ----------
267 ----------
269
270
271 local_ns, module
268 local_ns, module
272 Working local namespace (a dict) and module (a module or similar
269 Working local namespace (a dict) and module (a module or similar
273 object). If given as None, they are automatically taken from the scope
270 object). If given as None, they are automatically taken from the scope
274 where the shell was called, so that program variables become visible.
271 where the shell was called, so that program variables become visible.
275
276 stack_depth : int
272 stack_depth : int
277 How many levels in the stack to go to looking for namespaces (when
273 How many levels in the stack to go to looking for namespaces (when
278 local_ns or module is None). This allows an intermediate caller to
274 local_ns or module is None). This allows an intermediate caller to
279 make sure that this function gets the namespace from the intended
275 make sure that this function gets the namespace from the intended
280 level in the stack. By default (0) it will get its locals and globals
276 level in the stack. By default (0) it will get its locals and globals
281 from the immediate caller.
277 from the immediate caller.
282
283 compile_flags
278 compile_flags
284 A bit field identifying the __future__ features
279 A bit field identifying the __future__ features
285 that are enabled, as passed to the builtin :func:`compile` function.
280 that are enabled, as passed to the builtin :func:`compile` function.
286 If given as None, they are automatically taken from the scope where
281 If given as None, they are automatically taken from the scope where
287 the shell was called.
282 the shell was called.
288
283
289 """
284 """
290
285
291 # Get locals and globals from caller
286 # Get locals and globals from caller
292 if ((local_ns is None or module is None or compile_flags is None)
287 if ((local_ns is None or module is None or compile_flags is None)
293 and self.default_user_namespaces):
288 and self.default_user_namespaces):
294 call_frame = sys._getframe(stack_depth).f_back
289 call_frame = sys._getframe(stack_depth).f_back
295
290
296 if local_ns is None:
291 if local_ns is None:
297 local_ns = call_frame.f_locals
292 local_ns = call_frame.f_locals
298 if module is None:
293 if module is None:
299 global_ns = call_frame.f_globals
294 global_ns = call_frame.f_globals
300 try:
295 try:
301 module = sys.modules[global_ns['__name__']]
296 module = sys.modules[global_ns['__name__']]
302 except KeyError:
297 except KeyError:
303 warnings.warn("Failed to get module %s" % \
298 warnings.warn("Failed to get module %s" % \
304 global_ns.get('__name__', 'unknown module')
299 global_ns.get('__name__', 'unknown module')
305 )
300 )
306 module = DummyMod()
301 module = DummyMod()
307 module.__dict__ = global_ns
302 module.__dict__ = global_ns
308 if compile_flags is None:
303 if compile_flags is None:
309 compile_flags = (call_frame.f_code.co_flags &
304 compile_flags = (call_frame.f_code.co_flags &
310 compilerop.PyCF_MASK)
305 compilerop.PyCF_MASK)
311
306
312 # Save original namespace and module so we can restore them after
307 # Save original namespace and module so we can restore them after
313 # embedding; otherwise the shell doesn't shut down correctly.
308 # embedding; otherwise the shell doesn't shut down correctly.
314 orig_user_module = self.user_module
309 orig_user_module = self.user_module
315 orig_user_ns = self.user_ns
310 orig_user_ns = self.user_ns
316 orig_compile_flags = self.compile.flags
311 orig_compile_flags = self.compile.flags
317
312
318 # Update namespaces and fire up interpreter
313 # Update namespaces and fire up interpreter
319
314
320 # The global one is easy, we can just throw it in
315 # The global one is easy, we can just throw it in
321 if module is not None:
316 if module is not None:
322 self.user_module = module
317 self.user_module = module
323
318
324 # But the user/local one is tricky: ipython needs it to store internal
319 # But the user/local one is tricky: ipython needs it to store internal
325 # data, but we also need the locals. We'll throw our hidden variables
320 # data, but we also need the locals. We'll throw our hidden variables
326 # like _ih and get_ipython() into the local namespace, but delete them
321 # like _ih and get_ipython() into the local namespace, but delete them
327 # later.
322 # later.
328 if local_ns is not None:
323 if local_ns is not None:
329 reentrant_local_ns = {k: v for (k, v) in local_ns.items() if k not in self.user_ns_hidden.keys()}
324 reentrant_local_ns = {k: v for (k, v) in local_ns.items() if k not in self.user_ns_hidden.keys()}
330 self.user_ns = reentrant_local_ns
325 self.user_ns = reentrant_local_ns
331 self.init_user_ns()
326 self.init_user_ns()
332
327
333 # Compiler flags
328 # Compiler flags
334 if compile_flags is not None:
329 if compile_flags is not None:
335 self.compile.flags = compile_flags
330 self.compile.flags = compile_flags
336
331
337 # make sure the tab-completer has the correct frame information, so it
332 # make sure the tab-completer has the correct frame information, so it
338 # actually completes using the frame's locals/globals
333 # actually completes using the frame's locals/globals
339 self.set_completer_frame()
334 self.set_completer_frame()
340
335
341 with self.builtin_trap, self.display_trap:
336 with self.builtin_trap, self.display_trap:
342 self.interact()
337 self.interact()
343
338
344 # now, purge out the local namespace of IPython's hidden variables.
339 # now, purge out the local namespace of IPython's hidden variables.
345 if local_ns is not None:
340 if local_ns is not None:
346 local_ns.update({k: v for (k, v) in self.user_ns.items() if k not in self.user_ns_hidden.keys()})
341 local_ns.update({k: v for (k, v) in self.user_ns.items() if k not in self.user_ns_hidden.keys()})
347
342
348
343
349 # Restore original namespace so shell can shut down when we exit.
344 # Restore original namespace so shell can shut down when we exit.
350 self.user_module = orig_user_module
345 self.user_module = orig_user_module
351 self.user_ns = orig_user_ns
346 self.user_ns = orig_user_ns
352 self.compile.flags = orig_compile_flags
347 self.compile.flags = orig_compile_flags
353
348
354
349
355 def embed(*, header="", compile_flags=None, **kwargs):
350 def embed(*, header="", compile_flags=None, **kwargs):
356 """Call this to embed IPython at the current point in your program.
351 """Call this to embed IPython at the current point in your program.
357
352
358 The first invocation of this will create an :class:`InteractiveShellEmbed`
353 The first invocation of this will create an :class:`InteractiveShellEmbed`
359 instance and then call it. Consecutive calls just call the already
354 instance and then call it. Consecutive calls just call the already
360 created instance.
355 created instance.
361
356
362 If you don't want the kernel to initialize the namespace
357 If you don't want the kernel to initialize the namespace
363 from the scope of the surrounding function,
358 from the scope of the surrounding function,
364 and/or you want to load full IPython configuration,
359 and/or you want to load full IPython configuration,
365 you probably want `IPython.start_ipython()` instead.
360 you probably want `IPython.start_ipython()` instead.
366
361
367 Here is a simple example::
362 Here is a simple example::
368
363
369 from IPython import embed
364 from IPython import embed
370 a = 10
365 a = 10
371 b = 20
366 b = 20
372 embed(header='First time')
367 embed(header='First time')
373 c = 30
368 c = 30
374 d = 40
369 d = 40
375 embed()
370 embed()
376
371
377 Full customization can be done by passing a :class:`Config` in as the
372 Full customization can be done by passing a :class:`Config` in as the
378 config argument.
373 config argument.
379 """
374 """
380 config = kwargs.get('config')
375 config = kwargs.get('config')
381 if config is None:
376 if config is None:
382 config = load_default_config()
377 config = load_default_config()
383 config.InteractiveShellEmbed = config.TerminalInteractiveShell
378 config.InteractiveShellEmbed = config.TerminalInteractiveShell
384 kwargs['config'] = config
379 kwargs['config'] = config
385 using = kwargs.get('using', 'sync')
380 using = kwargs.get('using', 'sync')
386 if using :
381 if using :
387 kwargs['config'].update({'TerminalInteractiveShell':{'loop_runner':using, 'colors':'NoColor', 'autoawait': using!='sync'}})
382 kwargs['config'].update({'TerminalInteractiveShell':{'loop_runner':using, 'colors':'NoColor', 'autoawait': using!='sync'}})
388 #save ps1/ps2 if defined
383 #save ps1/ps2 if defined
389 ps1 = None
384 ps1 = None
390 ps2 = None
385 ps2 = None
391 try:
386 try:
392 ps1 = sys.ps1
387 ps1 = sys.ps1
393 ps2 = sys.ps2
388 ps2 = sys.ps2
394 except AttributeError:
389 except AttributeError:
395 pass
390 pass
396 #save previous instance
391 #save previous instance
397 saved_shell_instance = InteractiveShell._instance
392 saved_shell_instance = InteractiveShell._instance
398 if saved_shell_instance is not None:
393 if saved_shell_instance is not None:
399 cls = type(saved_shell_instance)
394 cls = type(saved_shell_instance)
400 cls.clear_instance()
395 cls.clear_instance()
401 frame = sys._getframe(1)
396 frame = sys._getframe(1)
402 shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % (
397 shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % (
403 frame.f_code.co_filename, frame.f_lineno), **kwargs)
398 frame.f_code.co_filename, frame.f_lineno), **kwargs)
404 shell(header=header, stack_depth=2, compile_flags=compile_flags,
399 shell(header=header, stack_depth=2, compile_flags=compile_flags,
405 _call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno))
400 _call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno))
406 InteractiveShellEmbed.clear_instance()
401 InteractiveShellEmbed.clear_instance()
407 #restore previous instance
402 #restore previous instance
408 if saved_shell_instance is not None:
403 if saved_shell_instance is not None:
409 cls = type(saved_shell_instance)
404 cls = type(saved_shell_instance)
410 cls.clear_instance()
405 cls.clear_instance()
411 for subclass in cls._walk_mro():
406 for subclass in cls._walk_mro():
412 subclass._instance = saved_shell_instance
407 subclass._instance = saved_shell_instance
413 if ps1 is not None:
408 if ps1 is not None:
414 sys.ps1 = ps1
409 sys.ps1 = ps1
415 sys.ps2 = ps2
410 sys.ps2 = ps2
@@ -1,214 +1,214 b''
1 """Extra magics for terminal use."""
1 """Extra magics for terminal use."""
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6
6
7 from logging import error
7 from logging import error
8 import os
8 import os
9 import sys
9 import sys
10
10
11 from IPython.core.error import TryNext, UsageError
11 from IPython.core.error import TryNext, UsageError
12 from IPython.core.magic import Magics, magics_class, line_magic
12 from IPython.core.magic import Magics, magics_class, line_magic
13 from IPython.lib.clipboard import ClipboardEmpty
13 from IPython.lib.clipboard import ClipboardEmpty
14 from IPython.testing.skipdoctest import skip_doctest
14 from IPython.testing.skipdoctest import skip_doctest
15 from IPython.utils.text import SList, strip_email_quotes
15 from IPython.utils.text import SList, strip_email_quotes
16 from IPython.utils import py3compat
16 from IPython.utils import py3compat
17
17
18 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
18 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
19 """ Yield pasted lines until the user enters the given sentinel value.
19 """ Yield pasted lines until the user enters the given sentinel value.
20 """
20 """
21 if not quiet:
21 if not quiet:
22 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
22 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
23 % sentinel)
23 % sentinel)
24 prompt = ":"
24 prompt = ":"
25 else:
25 else:
26 prompt = ""
26 prompt = ""
27 while True:
27 while True:
28 try:
28 try:
29 l = l_input(prompt)
29 l = l_input(prompt)
30 if l == sentinel:
30 if l == sentinel:
31 return
31 return
32 else:
32 else:
33 yield l
33 yield l
34 except EOFError:
34 except EOFError:
35 print('<EOF>')
35 print('<EOF>')
36 return
36 return
37
37
38
38
39 @magics_class
39 @magics_class
40 class TerminalMagics(Magics):
40 class TerminalMagics(Magics):
41 def __init__(self, shell):
41 def __init__(self, shell):
42 super(TerminalMagics, self).__init__(shell)
42 super(TerminalMagics, self).__init__(shell)
43
43
44 def store_or_execute(self, block, name):
44 def store_or_execute(self, block, name):
45 """ Execute a block, or store it in a variable, per the user's request.
45 """ Execute a block, or store it in a variable, per the user's request.
46 """
46 """
47 if name:
47 if name:
48 # If storing it for further editing
48 # If storing it for further editing
49 self.shell.user_ns[name] = SList(block.splitlines())
49 self.shell.user_ns[name] = SList(block.splitlines())
50 print("Block assigned to '%s'" % name)
50 print("Block assigned to '%s'" % name)
51 else:
51 else:
52 b = self.preclean_input(block)
52 b = self.preclean_input(block)
53 self.shell.user_ns['pasted_block'] = b
53 self.shell.user_ns['pasted_block'] = b
54 self.shell.using_paste_magics = True
54 self.shell.using_paste_magics = True
55 try:
55 try:
56 self.shell.run_cell(b)
56 self.shell.run_cell(b)
57 finally:
57 finally:
58 self.shell.using_paste_magics = False
58 self.shell.using_paste_magics = False
59
59
60 def preclean_input(self, block):
60 def preclean_input(self, block):
61 lines = block.splitlines()
61 lines = block.splitlines()
62 while lines and not lines[0].strip():
62 while lines and not lines[0].strip():
63 lines = lines[1:]
63 lines = lines[1:]
64 return strip_email_quotes('\n'.join(lines))
64 return strip_email_quotes('\n'.join(lines))
65
65
66 def rerun_pasted(self, name='pasted_block'):
66 def rerun_pasted(self, name='pasted_block'):
67 """ Rerun a previously pasted command.
67 """ Rerun a previously pasted command.
68 """
68 """
69 b = self.shell.user_ns.get(name)
69 b = self.shell.user_ns.get(name)
70
70
71 # Sanity checks
71 # Sanity checks
72 if b is None:
72 if b is None:
73 raise UsageError('No previous pasted block available')
73 raise UsageError('No previous pasted block available')
74 if not isinstance(b, str):
74 if not isinstance(b, str):
75 raise UsageError(
75 raise UsageError(
76 "Variable 'pasted_block' is not a string, can't execute")
76 "Variable 'pasted_block' is not a string, can't execute")
77
77
78 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
78 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
79 self.shell.run_cell(b)
79 self.shell.run_cell(b)
80
80
81 @line_magic
81 @line_magic
82 def autoindent(self, parameter_s = ''):
82 def autoindent(self, parameter_s = ''):
83 """Toggle autoindent on/off (deprecated)"""
83 """Toggle autoindent on/off (deprecated)"""
84 self.shell.set_autoindent()
84 self.shell.set_autoindent()
85 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
85 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
86
86
87 @skip_doctest
87 @skip_doctest
88 @line_magic
88 @line_magic
89 def cpaste(self, parameter_s=''):
89 def cpaste(self, parameter_s=''):
90 """Paste & execute a pre-formatted code block from clipboard.
90 """Paste & execute a pre-formatted code block from clipboard.
91
91
92 You must terminate the block with '--' (two minus-signs) or Ctrl-D
92 You must terminate the block with '--' (two minus-signs) or Ctrl-D
93 alone on the line. You can also provide your own sentinel with '%paste
93 alone on the line. You can also provide your own sentinel with '%paste
94 -s %%' ('%%' is the new sentinel for this operation).
94 -s %%' ('%%' is the new sentinel for this operation).
95
95
96 The block is dedented prior to execution to enable execution of method
96 The block is dedented prior to execution to enable execution of method
97 definitions. '>' and '+' characters at the beginning of a line are
97 definitions. '>' and '+' characters at the beginning of a line are
98 ignored, to allow pasting directly from e-mails, diff files and
98 ignored, to allow pasting directly from e-mails, diff files and
99 doctests (the '...' continuation prompt is also stripped). The
99 doctests (the '...' continuation prompt is also stripped). The
100 executed block is also assigned to variable named 'pasted_block' for
100 executed block is also assigned to variable named 'pasted_block' for
101 later editing with '%edit pasted_block'.
101 later editing with '%edit pasted_block'.
102
102
103 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
103 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
104 This assigns the pasted block to variable 'foo' as string, without
104 This assigns the pasted block to variable 'foo' as string, without
105 dedenting or executing it (preceding >>> and + is still stripped)
105 dedenting or executing it (preceding >>> and + is still stripped)
106
106
107 '%cpaste -r' re-executes the block previously entered by cpaste.
107 '%cpaste -r' re-executes the block previously entered by cpaste.
108 '%cpaste -q' suppresses any additional output messages.
108 '%cpaste -q' suppresses any additional output messages.
109
109
110 Do not be alarmed by garbled output on Windows (it's a readline bug).
110 Do not be alarmed by garbled output on Windows (it's a readline bug).
111 Just press enter and type -- (and press enter again) and the block
111 Just press enter and type -- (and press enter again) and the block
112 will be what was just pasted.
112 will be what was just pasted.
113
113
114 Shell escapes are not supported (yet).
114 Shell escapes are not supported (yet).
115
115
116 See also
116 See Also
117 --------
117 --------
118 paste: automatically pull code from clipboard.
118 paste : automatically pull code from clipboard.
119
119
120 Examples
120 Examples
121 --------
121 --------
122 ::
122 ::
123
123
124 In [8]: %cpaste
124 In [8]: %cpaste
125 Pasting code; enter '--' alone on the line to stop.
125 Pasting code; enter '--' alone on the line to stop.
126 :>>> a = ["world!", "Hello"]
126 :>>> a = ["world!", "Hello"]
127 :>>> print(" ".join(sorted(a)))
127 :>>> print(" ".join(sorted(a)))
128 :--
128 :--
129 Hello world!
129 Hello world!
130
130
131 ::
131 ::
132 In [8]: %cpaste
132 In [8]: %cpaste
133 Pasting code; enter '--' alone on the line to stop.
133 Pasting code; enter '--' alone on the line to stop.
134 :>>> %alias_magic t timeit
134 :>>> %alias_magic t timeit
135 :>>> %t -n1 pass
135 :>>> %t -n1 pass
136 :--
136 :--
137 Created `%t` as an alias for `%timeit`.
137 Created `%t` as an alias for `%timeit`.
138 Created `%%t` as an alias for `%%timeit`.
138 Created `%%t` as an alias for `%%timeit`.
139 354 ns Β± 224 ns per loop (mean Β± std. dev. of 7 runs, 1 loop each)
139 354 ns Β± 224 ns per loop (mean Β± std. dev. of 7 runs, 1 loop each)
140 """
140 """
141 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
141 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
142 if 'r' in opts:
142 if 'r' in opts:
143 self.rerun_pasted()
143 self.rerun_pasted()
144 return
144 return
145
145
146 quiet = ('q' in opts)
146 quiet = ('q' in opts)
147
147
148 sentinel = opts.get('s', u'--')
148 sentinel = opts.get('s', u'--')
149 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
149 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
150 self.store_or_execute(block, name)
150 self.store_or_execute(block, name)
151
151
152 @line_magic
152 @line_magic
153 def paste(self, parameter_s=''):
153 def paste(self, parameter_s=''):
154 """Paste & execute a pre-formatted code block from clipboard.
154 """Paste & execute a pre-formatted code block from clipboard.
155
155
156 The text is pulled directly from the clipboard without user
156 The text is pulled directly from the clipboard without user
157 intervention and printed back on the screen before execution (unless
157 intervention and printed back on the screen before execution (unless
158 the -q flag is given to force quiet mode).
158 the -q flag is given to force quiet mode).
159
159
160 The block is dedented prior to execution to enable execution of method
160 The block is dedented prior to execution to enable execution of method
161 definitions. '>' and '+' characters at the beginning of a line are
161 definitions. '>' and '+' characters at the beginning of a line are
162 ignored, to allow pasting directly from e-mails, diff files and
162 ignored, to allow pasting directly from e-mails, diff files and
163 doctests (the '...' continuation prompt is also stripped). The
163 doctests (the '...' continuation prompt is also stripped). The
164 executed block is also assigned to variable named 'pasted_block' for
164 executed block is also assigned to variable named 'pasted_block' for
165 later editing with '%edit pasted_block'.
165 later editing with '%edit pasted_block'.
166
166
167 You can also pass a variable name as an argument, e.g. '%paste foo'.
167 You can also pass a variable name as an argument, e.g. '%paste foo'.
168 This assigns the pasted block to variable 'foo' as string, without
168 This assigns the pasted block to variable 'foo' as string, without
169 executing it (preceding >>> and + is still stripped).
169 executing it (preceding >>> and + is still stripped).
170
170
171 Options:
171 Options:
172
172
173 -r: re-executes the block previously entered by cpaste.
173 -r: re-executes the block previously entered by cpaste.
174
174
175 -q: quiet mode: do not echo the pasted text back to the terminal.
175 -q: quiet mode: do not echo the pasted text back to the terminal.
176
176
177 IPython statements (magics, shell escapes) are not supported (yet).
177 IPython statements (magics, shell escapes) are not supported (yet).
178
178
179 See also
179 See Also
180 --------
180 --------
181 cpaste: manually paste code into terminal until you mark its end.
181 cpaste : manually paste code into terminal until you mark its end.
182 """
182 """
183 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
183 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
184 if 'r' in opts:
184 if 'r' in opts:
185 self.rerun_pasted()
185 self.rerun_pasted()
186 return
186 return
187 try:
187 try:
188 block = self.shell.hooks.clipboard_get()
188 block = self.shell.hooks.clipboard_get()
189 except TryNext as clipboard_exc:
189 except TryNext as clipboard_exc:
190 message = getattr(clipboard_exc, 'args')
190 message = getattr(clipboard_exc, 'args')
191 if message:
191 if message:
192 error(message[0])
192 error(message[0])
193 else:
193 else:
194 error('Could not get text from the clipboard.')
194 error('Could not get text from the clipboard.')
195 return
195 return
196 except ClipboardEmpty as e:
196 except ClipboardEmpty as e:
197 raise UsageError("The clipboard appears to be empty") from e
197 raise UsageError("The clipboard appears to be empty") from e
198
198
199 # By default, echo back to terminal unless quiet mode is requested
199 # By default, echo back to terminal unless quiet mode is requested
200 if 'q' not in opts:
200 if 'q' not in opts:
201 sys.stdout.write(self.shell.pycolorize(block))
201 sys.stdout.write(self.shell.pycolorize(block))
202 if not block.endswith("\n"):
202 if not block.endswith("\n"):
203 sys.stdout.write("\n")
203 sys.stdout.write("\n")
204 sys.stdout.write("## -- End pasted text --\n")
204 sys.stdout.write("## -- End pasted text --\n")
205
205
206 self.store_or_execute(block, name)
206 self.store_or_execute(block, name)
207
207
208 # Class-level: add a '%cls' magic only on Windows
208 # Class-level: add a '%cls' magic only on Windows
209 if sys.platform == 'win32':
209 if sys.platform == 'win32':
210 @line_magic
210 @line_magic
211 def cls(self, s):
211 def cls(self, s):
212 """Clear screen.
212 """Clear screen.
213 """
213 """
214 os.system("cls")
214 os.system("cls")
General Comments 0
You need to be logged in to leave comments. Login now