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