##// END OF EJS Templates
Fix a couple of warnings/errors in doc builds.
Matthias Bussonnier -
Show More
@@ -1,393 +1,392 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 class KillEmbeded(Exception):pass
23 23
24 24 # This is an additional magic that is exposed in embedded shells.
25 25 @magics_class
26 26 class EmbeddedMagics(Magics):
27 27
28 28 @line_magic
29 29 @magic_arguments.magic_arguments()
30 30 @magic_arguments.argument('-i', '--instance', action='store_true',
31 31 help='Kill instance instead of call location')
32 32 @magic_arguments.argument('-x', '--exit', action='store_true',
33 33 help='Also exit the current session')
34 34 @magic_arguments.argument('-y', '--yes', action='store_true',
35 35 help='Do not ask confirmation')
36 36 def kill_embedded(self, parameter_s=''):
37 37 """%kill_embedded : deactivate for good the current embedded IPython
38 38
39 39 This function (after asking for confirmation) sets an internal flag so
40 40 that an embedded IPython will never activate again for the given call
41 41 location. This is useful to permanently disable a shell that is being
42 42 called inside a loop: once you've figured out what you needed from it,
43 43 you may then kill it and the program will then continue to run without
44 44 the interactive shell interfering again.
45 45
46 46
47 Kill Instance Option
48 --------------------
49
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
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``
54 killing an "instance" should work even if it is recreated within a
55 loop.
47 Kill Instance Option:
48
49 If for some reasons you need to kill the location where the instance
50 is created and not called, for example if you create a single
51 instance in one place and debug in many locations, you can use the
52 ``--instance`` option to kill this specific instance. Like for the
53 ``call location`` killing an "instance" should work even if it is
54 recreated within a loop.
56 55
57 56 .. note::
58 57
59 58 This was the default behavior before IPython 5.2
60 59
61 60 """
62 61
63 62 args = magic_arguments.parse_argstring(self.kill_embedded, parameter_s)
64 63 print(args)
65 64 if args.instance:
66 65 # let no ask
67 66 if not args.yes:
68 67 kill = ask_yes_no(
69 68 "Are you sure you want to kill this embedded instance? [y/N] ", 'n')
70 69 else:
71 70 kill = True
72 71 if kill:
73 72 self.shell._disable_init_location()
74 73 print("This embedded IPython instance will not reactivate anymore "
75 74 "once you exit.")
76 75 else:
77 76 if not args.yes:
78 77 kill = ask_yes_no(
79 78 "Are you sure you want to kill this embedded call_location? [y/N] ", 'n')
80 79 else:
81 80 kill = True
82 81 if kill:
83 82 self.shell.embedded_active = False
84 83 print("This embedded IPython call location will not reactivate anymore "
85 84 "once you exit.")
86 85
87 86 if args.exit:
88 87 # Ask-exit does not really ask, it just set internals flags to exit
89 88 # on next loop.
90 89 self.shell.ask_exit()
91 90
92 91
93 92 @line_magic
94 93 def exit_raise(self, parameter_s=''):
95 94 """%exit_raise Make the current embedded kernel exit and raise and exception.
96 95
97 96 This function sets an internal flag so that an embedded IPython will
98 97 raise a `IPython.terminal.embed.KillEmbeded` Exception on exit, and then exit the current I. This is
99 98 useful to permanently exit a loop that create IPython embed instance.
100 99 """
101 100
102 101 self.shell.should_raise = True
103 102 self.shell.ask_exit()
104 103
105 104
106 105
107 106 class InteractiveShellEmbed(TerminalInteractiveShell):
108 107
109 108 dummy_mode = Bool(False)
110 109 exit_msg = Unicode('')
111 110 embedded = CBool(True)
112 111 should_raise = CBool(False)
113 112 # Like the base class display_banner is not configurable, but here it
114 113 # is True by default.
115 114 display_banner = CBool(True)
116 115 exit_msg = Unicode()
117 116
118 117 # When embedding, by default we don't change the terminal title
119 118 term_title = Bool(False,
120 119 help="Automatically set the terminal title"
121 120 ).tag(config=True)
122 121
123 122 _inactive_locations = set()
124 123
125 124 @property
126 125 def embedded_active(self):
127 126 return (self._call_location_id not in InteractiveShellEmbed._inactive_locations)\
128 127 and (self._init_location_id not in InteractiveShellEmbed._inactive_locations)
129 128
130 129 def _disable_init_location(self):
131 130 """Disable the current Instance creation location"""
132 131 InteractiveShellEmbed._inactive_locations.add(self._init_location_id)
133 132
134 133 @embedded_active.setter
135 134 def embedded_active(self, value):
136 135 if value:
137 136 InteractiveShellEmbed._inactive_locations.discard(
138 137 self._call_location_id)
139 138 InteractiveShellEmbed._inactive_locations.discard(
140 139 self._init_location_id)
141 140 else:
142 141 InteractiveShellEmbed._inactive_locations.add(
143 142 self._call_location_id)
144 143
145 144 def __init__(self, **kw):
146 145 if kw.get('user_global_ns', None) is not None:
147 146 raise DeprecationWarning(
148 147 "Key word argument `user_global_ns` has been replaced by `user_module` since IPython 4.0.")
149 148
150 149 clid = kw.pop('_init_location_id', None)
151 150 if not clid:
152 151 frame = sys._getframe(1)
153 152 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
154 153 self._init_location_id = clid
155 154
156 155 super(InteractiveShellEmbed,self).__init__(**kw)
157 156
158 157 # don't use the ipython crash handler so that user exceptions aren't
159 158 # trapped
160 159 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
161 160 mode=self.xmode,
162 161 call_pdb=self.pdb)
163 162
164 163 def init_sys_modules(self):
165 164 """
166 165 Explicitly overwrite :mod:`IPython.core.interactiveshell` to do nothing.
167 166 """
168 167 pass
169 168
170 169 def init_magics(self):
171 170 super(InteractiveShellEmbed, self).init_magics()
172 171 self.register_magics(EmbeddedMagics)
173 172
174 173 def __call__(self, header='', local_ns=None, module=None, dummy=None,
175 174 stack_depth=1, global_ns=None, compile_flags=None, **kw):
176 175 """Activate the interactive interpreter.
177 176
178 177 __call__(self,header='',local_ns=None,module=None,dummy=None) -> Start
179 178 the interpreter shell with the given local and global namespaces, and
180 179 optionally print a header string at startup.
181 180
182 181 The shell can be globally activated/deactivated using the
183 182 dummy_mode attribute. This allows you to turn off a shell used
184 183 for debugging globally.
185 184
186 185 However, *each* time you call the shell you can override the current
187 186 state of dummy_mode with the optional keyword parameter 'dummy'. For
188 187 example, if you set dummy mode on with IPShell.dummy_mode = True, you
189 188 can still have a specific call work by making it as IPShell(dummy=False).
190 189 """
191 190
192 191 # we are called, set the underlying interactiveshell not to exit.
193 192 self.keep_running = True
194 193
195 194 # If the user has turned it off, go away
196 195 clid = kw.pop('_call_location_id', None)
197 196 if not clid:
198 197 frame = sys._getframe(1)
199 198 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
200 199 self._call_location_id = clid
201 200
202 201 if not self.embedded_active:
203 202 return
204 203
205 204 # Normal exits from interactive mode set this flag, so the shell can't
206 205 # re-enter (it checks this variable at the start of interactive mode).
207 206 self.exit_now = False
208 207
209 208 # Allow the dummy parameter to override the global __dummy_mode
210 209 if dummy or (dummy != 0 and self.dummy_mode):
211 210 return
212 211
213 212 # self.banner is auto computed
214 213 if header:
215 214 self.old_banner2 = self.banner2
216 215 self.banner2 = self.banner2 + '\n' + header + '\n'
217 216 else:
218 217 self.old_banner2 = ''
219 218
220 219 if self.display_banner:
221 220 self.show_banner()
222 221
223 222 # Call the embedding code with a stack depth of 1 so it can skip over
224 223 # our call and get the original caller's namespaces.
225 224 self.mainloop(local_ns, module, stack_depth=stack_depth,
226 225 global_ns=global_ns, compile_flags=compile_flags)
227 226
228 227 self.banner2 = self.old_banner2
229 228
230 229 if self.exit_msg is not None:
231 230 print(self.exit_msg)
232 231
233 232 if self.should_raise:
234 233 raise KillEmbeded('Embedded IPython raising error, as user requested.')
235 234
236 235
237 236 def mainloop(self, local_ns=None, module=None, stack_depth=0,
238 237 display_banner=None, global_ns=None, compile_flags=None):
239 238 """Embeds IPython into a running python program.
240 239
241 240 Parameters
242 241 ----------
243 242
244 243 local_ns, module
245 244 Working local namespace (a dict) and module (a module or similar
246 245 object). If given as None, they are automatically taken from the scope
247 246 where the shell was called, so that program variables become visible.
248 247
249 248 stack_depth : int
250 249 How many levels in the stack to go to looking for namespaces (when
251 250 local_ns or module is None). This allows an intermediate caller to
252 251 make sure that this function gets the namespace from the intended
253 252 level in the stack. By default (0) it will get its locals and globals
254 253 from the immediate caller.
255 254
256 255 compile_flags
257 256 A bit field identifying the __future__ features
258 257 that are enabled, as passed to the builtin :func:`compile` function.
259 258 If given as None, they are automatically taken from the scope where
260 259 the shell was called.
261 260
262 261 """
263 262
264 263 if (global_ns is not None) and (module is None):
265 264 raise DeprecationWarning("'global_ns' keyword argument is deprecated, and has been removed in IPython 5.0 use `module` keyword argument instead.")
266 265
267 266 if (display_banner is not None):
268 267 warnings.warn("The display_banner parameter is deprecated since IPython 4.0", DeprecationWarning)
269 268
270 269 # Get locals and globals from caller
271 270 if ((local_ns is None or module is None or compile_flags is None)
272 271 and self.default_user_namespaces):
273 272 call_frame = sys._getframe(stack_depth).f_back
274 273
275 274 if local_ns is None:
276 275 local_ns = call_frame.f_locals
277 276 if module is None:
278 277 global_ns = call_frame.f_globals
279 278 try:
280 279 module = sys.modules[global_ns['__name__']]
281 280 except KeyError:
282 281 warnings.warn("Failed to get module %s" % \
283 282 global_ns.get('__name__', 'unknown module')
284 283 )
285 284 module = DummyMod()
286 285 module.__dict__ = global_ns
287 286 if compile_flags is None:
288 287 compile_flags = (call_frame.f_code.co_flags &
289 288 compilerop.PyCF_MASK)
290 289
291 290 # Save original namespace and module so we can restore them after
292 291 # embedding; otherwise the shell doesn't shut down correctly.
293 292 orig_user_module = self.user_module
294 293 orig_user_ns = self.user_ns
295 294 orig_compile_flags = self.compile.flags
296 295
297 296 # Update namespaces and fire up interpreter
298 297
299 298 # The global one is easy, we can just throw it in
300 299 if module is not None:
301 300 self.user_module = module
302 301
303 302 # But the user/local one is tricky: ipython needs it to store internal
304 303 # data, but we also need the locals. We'll throw our hidden variables
305 304 # like _ih and get_ipython() into the local namespace, but delete them
306 305 # later.
307 306 if local_ns is not None:
308 307 reentrant_local_ns = {k: v for (k, v) in local_ns.items() if k not in self.user_ns_hidden.keys()}
309 308 self.user_ns = reentrant_local_ns
310 309 self.init_user_ns()
311 310
312 311 # Compiler flags
313 312 if compile_flags is not None:
314 313 self.compile.flags = compile_flags
315 314
316 315 # make sure the tab-completer has the correct frame information, so it
317 316 # actually completes using the frame's locals/globals
318 317 self.set_completer_frame()
319 318
320 319 with self.builtin_trap, self.display_trap:
321 320 self.interact()
322 321
323 322 # now, purge out the local namespace of IPython's hidden variables.
324 323 if local_ns is not None:
325 324 local_ns.update({k: v for (k, v) in self.user_ns.items() if k not in self.user_ns_hidden.keys()})
326 325
327 326
328 327 # Restore original namespace so shell can shut down when we exit.
329 328 self.user_module = orig_user_module
330 329 self.user_ns = orig_user_ns
331 330 self.compile.flags = orig_compile_flags
332 331
333 332
334 333 def embed(**kwargs):
335 334 """Call this to embed IPython at the current point in your program.
336 335
337 336 The first invocation of this will create an :class:`InteractiveShellEmbed`
338 337 instance and then call it. Consecutive calls just call the already
339 338 created instance.
340 339
341 340 If you don't want the kernel to initialize the namespace
342 341 from the scope of the surrounding function,
343 342 and/or you want to load full IPython configuration,
344 343 you probably want `IPython.start_ipython()` instead.
345 344
346 345 Here is a simple example::
347 346
348 347 from IPython import embed
349 348 a = 10
350 349 b = 20
351 350 embed(header='First time')
352 351 c = 30
353 352 d = 40
354 353 embed()
355 354
356 355 Full customization can be done by passing a :class:`Config` in as the
357 356 config argument.
358 357 """
359 358 config = kwargs.get('config')
360 359 header = kwargs.pop('header', u'')
361 360 compile_flags = kwargs.pop('compile_flags', None)
362 361 if config is None:
363 362 config = load_default_config()
364 363 config.InteractiveShellEmbed = config.TerminalInteractiveShell
365 364 kwargs['config'] = config
366 365 #save ps1/ps2 if defined
367 366 ps1 = None
368 367 ps2 = None
369 368 try:
370 369 ps1 = sys.ps1
371 370 ps2 = sys.ps2
372 371 except AttributeError:
373 372 pass
374 373 #save previous instance
375 374 saved_shell_instance = InteractiveShell._instance
376 375 if saved_shell_instance is not None:
377 376 cls = type(saved_shell_instance)
378 377 cls.clear_instance()
379 378 frame = sys._getframe(1)
380 379 shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % (
381 380 frame.f_code.co_filename, frame.f_lineno), **kwargs)
382 381 shell(header=header, stack_depth=2, compile_flags=compile_flags,
383 382 _call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno))
384 383 InteractiveShellEmbed.clear_instance()
385 384 #restore previous instance
386 385 if saved_shell_instance is not None:
387 386 cls = type(saved_shell_instance)
388 387 cls.clear_instance()
389 388 for subclass in cls._walk_mro():
390 389 subclass._instance = saved_shell_instance
391 390 if ps1 is not None:
392 391 sys.ps1 = ps1
393 392 sys.ps2 = ps2
@@ -1,518 +1,516 b''
1 1 """IPython terminal interface using prompt_toolkit"""
2 2
3 3 import os
4 4 import sys
5 5 import warnings
6 6 from warnings import warn
7 7
8 8 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
9 9 from IPython.utils import io
10 10 from IPython.utils.py3compat import cast_unicode_py2, input
11 11 from IPython.utils.terminal import toggle_set_term_title, set_term_title
12 12 from IPython.utils.process import abbrev_cwd
13 13 from traitlets import Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum, Union
14 14
15 15 from prompt_toolkit.document import Document
16 16 from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
17 17 from prompt_toolkit.filters import (HasFocus, Condition, IsDone)
18 18 from prompt_toolkit.history import InMemoryHistory
19 19 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout, create_output
20 20 from prompt_toolkit.interface import CommandLineInterface
21 21 from prompt_toolkit.key_binding.manager import KeyBindingManager
22 22 from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
23 23 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
24 24
25 25 from pygments.styles import get_style_by_name, get_all_styles
26 26 from pygments.style import Style
27 27 from pygments.token import Token
28 28
29 29 from .debugger import TerminalPdb, Pdb
30 30 from .magics import TerminalMagics
31 31 from .pt_inputhooks import get_inputhook_name_and_func
32 32 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
33 33 from .ptutils import IPythonPTCompleter, IPythonPTLexer
34 34 from .shortcuts import register_ipython_shortcuts
35 35
36 36 DISPLAY_BANNER_DEPRECATED = object()
37 37
38 38
39 39 class _NoStyle(Style): pass
40 40
41 41
42 42
43 43 _style_overrides_light_bg = {
44 44 Token.Prompt: '#0000ff',
45 45 Token.PromptNum: '#0000ee bold',
46 46 Token.OutPrompt: '#cc0000',
47 47 Token.OutPromptNum: '#bb0000 bold',
48 48 }
49 49
50 50 _style_overrides_linux = {
51 51 Token.Prompt: '#00cc00',
52 52 Token.PromptNum: '#00bb00 bold',
53 53 Token.OutPrompt: '#cc0000',
54 54 Token.OutPromptNum: '#bb0000 bold',
55 55 }
56 56
57 57
58 58
59 59 def get_default_editor():
60 60 try:
61 61 return os.environ['EDITOR']
62 62 except KeyError:
63 63 pass
64 64 except UnicodeError:
65 65 warn("$EDITOR environment variable is not pure ASCII. Using platform "
66 66 "default editor.")
67 67
68 68 if os.name == 'posix':
69 69 return 'vi' # the only one guaranteed to be there!
70 70 else:
71 71 return 'notepad' # same in Windows!
72 72
73 73 # conservatively check for tty
74 74 # overridden streams can result in things like:
75 75 # - sys.stdin = None
76 76 # - no isatty method
77 77 for _name in ('stdin', 'stdout', 'stderr'):
78 78 _stream = getattr(sys, _name)
79 79 if not _stream or not hasattr(_stream, 'isatty') or not _stream.isatty():
80 80 _is_tty = False
81 81 break
82 82 else:
83 83 _is_tty = True
84 84
85 85
86 86 _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty)
87 87
88 88 class TerminalInteractiveShell(InteractiveShell):
89 89 space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
90 90 'to reserve for the completion menu'
91 91 ).tag(config=True)
92 92
93 93 def _space_for_menu_changed(self, old, new):
94 94 self._update_layout()
95 95
96 96 pt_cli = None
97 97 debugger_history = None
98 98 _pt_app = None
99 99
100 100 simple_prompt = Bool(_use_simple_prompt,
101 101 help="""Use `raw_input` for the REPL, without completion, multiline input, and prompt colors.
102 102
103 103 Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are:
104 104 IPython own testing machinery, and emacs inferior-shell integration through elpy.
105 105
106 106 This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT`
107 environment variable is set, or the current terminal is not a tty.
108
109 """
107 environment variable is set, or the current terminal is not a tty."""
110 108 ).tag(config=True)
111 109
112 110 @property
113 111 def debugger_cls(self):
114 112 return Pdb if self.simple_prompt else TerminalPdb
115 113
116 114 confirm_exit = Bool(True,
117 115 help="""
118 116 Set to confirm when you try to exit IPython with an EOF (Control-D
119 117 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
120 118 you can force a direct exit without any confirmation.""",
121 119 ).tag(config=True)
122 120
123 121 editing_mode = Unicode('emacs',
124 122 help="Shortcut style to use at the prompt. 'vi' or 'emacs'.",
125 123 ).tag(config=True)
126 124
127 125 mouse_support = Bool(False,
128 126 help="Enable mouse support in the prompt"
129 127 ).tag(config=True)
130 128
131 129 highlighting_style = Union([Unicode('legacy'), Type(klass=Style)],
132 130 help="""The name or class of a Pygments style to use for syntax
133 131 highlighting: \n %s""" % ', '.join(get_all_styles())
134 132 ).tag(config=True)
135 133
136 134
137 135 @observe('highlighting_style')
138 136 @observe('colors')
139 137 def _highlighting_style_changed(self, change):
140 138 self.refresh_style()
141 139
142 140 def refresh_style(self):
143 141 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
144 142
145 143
146 144 highlighting_style_overrides = Dict(
147 145 help="Override highlighting format for specific tokens"
148 146 ).tag(config=True)
149 147
150 148 true_color = Bool(False,
151 149 help=("Use 24bit colors instead of 256 colors in prompt highlighting. "
152 150 "If your terminal supports true color, the following command "
153 151 "should print 'TRUECOLOR' in orange: "
154 152 "printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"")
155 153 ).tag(config=True)
156 154
157 155 editor = Unicode(get_default_editor(),
158 156 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
159 157 ).tag(config=True)
160 158
161 159 prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True)
162 160
163 161 prompts = Instance(Prompts)
164 162
165 163 @default('prompts')
166 164 def _prompts_default(self):
167 165 return self.prompts_class(self)
168 166
169 167 @observe('prompts')
170 168 def _(self, change):
171 169 self._update_layout()
172 170
173 171 @default('displayhook_class')
174 172 def _displayhook_class_default(self):
175 173 return RichPromptDisplayHook
176 174
177 175 term_title = Bool(True,
178 176 help="Automatically set the terminal title"
179 177 ).tag(config=True)
180 178
181 179 display_completions = Enum(('column', 'multicolumn','readlinelike'),
182 180 help= ( "Options for displaying tab completions, 'column', 'multicolumn', and "
183 181 "'readlinelike'. These options are for `prompt_toolkit`, see "
184 182 "`prompt_toolkit` documentation for more information."
185 183 ),
186 184 default_value='multicolumn').tag(config=True)
187 185
188 186 highlight_matching_brackets = Bool(True,
189 187 help="Highlight matching brackets.",
190 188 ).tag(config=True)
191 189
192 190 extra_open_editor_shortcuts = Bool(False,
193 191 help="Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. "
194 192 "This is in addition to the F2 binding, which is always enabled."
195 193 ).tag(config=True)
196 194
197 195 @observe('term_title')
198 196 def init_term_title(self, change=None):
199 197 # Enable or disable the terminal title.
200 198 if self.term_title:
201 199 toggle_set_term_title(True)
202 200 set_term_title('IPython: ' + abbrev_cwd())
203 201 else:
204 202 toggle_set_term_title(False)
205 203
206 204 def init_display_formatter(self):
207 205 super(TerminalInteractiveShell, self).init_display_formatter()
208 206 # terminal only supports plain text
209 207 self.display_formatter.active_types = ['text/plain']
210 208 # disable `_ipython_display_`
211 209 self.display_formatter.ipython_display_formatter.enabled = False
212 210
213 211 def init_prompt_toolkit_cli(self):
214 212 if self.simple_prompt:
215 213 # Fall back to plain non-interactive output for tests.
216 214 # This is very limited, and only accepts a single line.
217 215 def prompt():
218 216 return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
219 217 self.prompt_for_code = prompt
220 218 return
221 219
222 220 # Set up keyboard shortcuts
223 221 kbmanager = KeyBindingManager.for_prompt(
224 222 enable_open_in_editor=self.extra_open_editor_shortcuts,
225 223 )
226 224 register_ipython_shortcuts(kbmanager.registry, self)
227 225
228 226 # Pre-populate history from IPython's history database
229 227 history = InMemoryHistory()
230 228 last_cell = u""
231 229 for __, ___, cell in self.history_manager.get_tail(self.history_load_length,
232 230 include_latest=True):
233 231 # Ignore blank lines and consecutive duplicates
234 232 cell = cell.rstrip()
235 233 if cell and (cell != last_cell):
236 234 history.append(cell)
237 235 last_cell = cell
238 236
239 237 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
240 238 style = DynamicStyle(lambda: self._style)
241 239
242 240 editing_mode = getattr(EditingMode, self.editing_mode.upper())
243 241
244 242 def patch_stdout(**kwargs):
245 243 return self.pt_cli.patch_stdout_context(**kwargs)
246 244
247 245 self._pt_app = create_prompt_application(
248 246 editing_mode=editing_mode,
249 247 key_bindings_registry=kbmanager.registry,
250 248 history=history,
251 249 completer=IPythonPTCompleter(shell=self,
252 250 patch_stdout=patch_stdout),
253 251 enable_history_search=True,
254 252 style=style,
255 253 mouse_support=self.mouse_support,
256 254 **self._layout_options()
257 255 )
258 256 self._eventloop = create_eventloop(self.inputhook)
259 257 self.pt_cli = CommandLineInterface(
260 258 self._pt_app, eventloop=self._eventloop,
261 259 output=create_output(true_color=self.true_color))
262 260
263 261 def _make_style_from_name_or_cls(self, name_or_cls):
264 262 """
265 263 Small wrapper that make an IPython compatible style from a style name
266 264
267 265 We need that to add style for prompt ... etc.
268 266 """
269 267 style_overrides = {}
270 268 if name_or_cls == 'legacy':
271 269 legacy = self.colors.lower()
272 270 if legacy == 'linux':
273 271 style_cls = get_style_by_name('monokai')
274 272 style_overrides = _style_overrides_linux
275 273 elif legacy == 'lightbg':
276 274 style_overrides = _style_overrides_light_bg
277 275 style_cls = get_style_by_name('pastie')
278 276 elif legacy == 'neutral':
279 277 # The default theme needs to be visible on both a dark background
280 278 # and a light background, because we can't tell what the terminal
281 279 # looks like. These tweaks to the default theme help with that.
282 280 style_cls = get_style_by_name('default')
283 281 style_overrides.update({
284 282 Token.Number: '#007700',
285 283 Token.Operator: 'noinherit',
286 284 Token.String: '#BB6622',
287 285 Token.Name.Function: '#2080D0',
288 286 Token.Name.Class: 'bold #2080D0',
289 287 Token.Name.Namespace: 'bold #2080D0',
290 288 Token.Prompt: '#009900',
291 289 Token.PromptNum: '#00ff00 bold',
292 290 Token.OutPrompt: '#990000',
293 291 Token.OutPromptNum: '#ff0000 bold',
294 292 })
295 293
296 294 # Hack: Due to limited color support on the Windows console
297 295 # the prompt colors will be wrong without this
298 296 if os.name == 'nt':
299 297 style_overrides.update({
300 298 Token.Prompt: '#ansidarkgreen',
301 299 Token.PromptNum: '#ansigreen bold',
302 300 Token.OutPrompt: '#ansidarkred',
303 301 Token.OutPromptNum: '#ansired bold',
304 302 })
305 303 elif legacy =='nocolor':
306 304 style_cls=_NoStyle
307 305 style_overrides = {}
308 306 else :
309 307 raise ValueError('Got unknown colors: ', legacy)
310 308 else :
311 309 if isinstance(name_or_cls, str):
312 310 style_cls = get_style_by_name(name_or_cls)
313 311 else:
314 312 style_cls = name_or_cls
315 313 style_overrides = {
316 314 Token.Prompt: '#009900',
317 315 Token.PromptNum: '#00ff00 bold',
318 316 Token.OutPrompt: '#990000',
319 317 Token.OutPromptNum: '#ff0000 bold',
320 318 }
321 319 style_overrides.update(self.highlighting_style_overrides)
322 320 style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
323 321 style_dict=style_overrides)
324 322
325 323 return style
326 324
327 325 def _layout_options(self):
328 326 """
329 327 Return the current layout option for the current Terminal InteractiveShell
330 328 """
331 329 return {
332 330 'lexer':IPythonPTLexer(),
333 331 'reserve_space_for_menu':self.space_for_menu,
334 332 'get_prompt_tokens':self.prompts.in_prompt_tokens,
335 333 'get_continuation_tokens':self.prompts.continuation_prompt_tokens,
336 334 'multiline':True,
337 335 'display_completions_in_columns': (self.display_completions == 'multicolumn'),
338 336
339 337 # Highlight matching brackets, but only when this setting is
340 338 # enabled, and only when the DEFAULT_BUFFER has the focus.
341 339 'extra_input_processors': [ConditionalProcessor(
342 340 processor=HighlightMatchingBracketProcessor(chars='[](){}'),
343 341 filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() &
344 342 Condition(lambda cli: self.highlight_matching_brackets))],
345 343 }
346 344
347 345 def _update_layout(self):
348 346 """
349 347 Ask for a re computation of the application layout, if for example ,
350 348 some configuration options have changed.
351 349 """
352 350 if self._pt_app:
353 351 self._pt_app.layout = create_prompt_layout(**self._layout_options())
354 352
355 353 def prompt_for_code(self):
356 354 document = self.pt_cli.run(
357 355 pre_run=self.pre_prompt, reset_current_buffer=True)
358 356 return document.text
359 357
360 358 def enable_win_unicode_console(self):
361 359 if sys.version_info >= (3, 6):
362 360 # Since PEP 528, Python uses the unicode APIs for the Windows
363 361 # console by default, so WUC shouldn't be needed.
364 362 return
365 363
366 364 import win_unicode_console
367 365 win_unicode_console.enable()
368 366
369 367 def init_io(self):
370 368 if sys.platform not in {'win32', 'cli'}:
371 369 return
372 370
373 371 self.enable_win_unicode_console()
374 372
375 373 import colorama
376 374 colorama.init()
377 375
378 376 # For some reason we make these wrappers around stdout/stderr.
379 377 # For now, we need to reset them so all output gets coloured.
380 378 # https://github.com/ipython/ipython/issues/8669
381 379 # io.std* are deprecated, but don't show our own deprecation warnings
382 380 # during initialization of the deprecated API.
383 381 with warnings.catch_warnings():
384 382 warnings.simplefilter('ignore', DeprecationWarning)
385 383 io.stdout = io.IOStream(sys.stdout)
386 384 io.stderr = io.IOStream(sys.stderr)
387 385
388 386 def init_magics(self):
389 387 super(TerminalInteractiveShell, self).init_magics()
390 388 self.register_magics(TerminalMagics)
391 389
392 390 def init_alias(self):
393 391 # The parent class defines aliases that can be safely used with any
394 392 # frontend.
395 393 super(TerminalInteractiveShell, self).init_alias()
396 394
397 395 # Now define aliases that only make sense on the terminal, because they
398 396 # need direct access to the console in a way that we can't emulate in
399 397 # GUI or web frontend
400 398 if os.name == 'posix':
401 399 for cmd in ['clear', 'more', 'less', 'man']:
402 400 self.alias_manager.soft_define_alias(cmd, cmd)
403 401
404 402
405 403 def __init__(self, *args, **kwargs):
406 404 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
407 405 self.init_prompt_toolkit_cli()
408 406 self.init_term_title()
409 407 self.keep_running = True
410 408
411 409 self.debugger_history = InMemoryHistory()
412 410
413 411 def ask_exit(self):
414 412 self.keep_running = False
415 413
416 414 rl_next_input = None
417 415
418 416 def pre_prompt(self):
419 417 if self.rl_next_input:
420 418 # We can't set the buffer here, because it will be reset just after
421 419 # this. Adding a callable to pre_run_callables does what we need
422 420 # after the buffer is reset.
423 421 s = cast_unicode_py2(self.rl_next_input)
424 422 def set_doc():
425 423 self.pt_cli.application.buffer.document = Document(s)
426 424 if hasattr(self.pt_cli, 'pre_run_callables'):
427 425 self.pt_cli.pre_run_callables.append(set_doc)
428 426 else:
429 427 # Older version of prompt_toolkit; it's OK to set the document
430 428 # directly here.
431 429 set_doc()
432 430 self.rl_next_input = None
433 431
434 432 def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED):
435 433
436 434 if display_banner is not DISPLAY_BANNER_DEPRECATED:
437 435 warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
438 436
439 437 self.keep_running = True
440 438 while self.keep_running:
441 439 print(self.separate_in, end='')
442 440
443 441 try:
444 442 code = self.prompt_for_code()
445 443 except EOFError:
446 444 if (not self.confirm_exit) \
447 445 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
448 446 self.ask_exit()
449 447
450 448 else:
451 449 if code:
452 450 self.run_cell(code, store_history=True)
453 451
454 452 def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED):
455 453 # An extra layer of protection in case someone mashing Ctrl-C breaks
456 454 # out of our internal code.
457 455 if display_banner is not DISPLAY_BANNER_DEPRECATED:
458 456 warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
459 457 while True:
460 458 try:
461 459 self.interact()
462 460 break
463 461 except KeyboardInterrupt as e:
464 462 print("\n%s escaped interact()\n" % type(e).__name__)
465 463 finally:
466 464 # An interrupt during the eventloop will mess up the
467 465 # internal state of the prompt_toolkit library.
468 466 # Stopping the eventloop fixes this, see
469 467 # https://github.com/ipython/ipython/pull/9867
470 468 if hasattr(self, '_eventloop'):
471 469 self._eventloop.stop()
472 470
473 471 _inputhook = None
474 472 def inputhook(self, context):
475 473 if self._inputhook is not None:
476 474 self._inputhook(context)
477 475
478 476 active_eventloop = None
479 477 def enable_gui(self, gui=None):
480 478 if gui:
481 479 self.active_eventloop, self._inputhook =\
482 480 get_inputhook_name_and_func(gui)
483 481 else:
484 482 self.active_eventloop = self._inputhook = None
485 483
486 484 # Run !system commands directly, not through pipes, so terminal programs
487 485 # work correctly.
488 486 system = InteractiveShell.system_raw
489 487
490 488 def auto_rewrite_input(self, cmd):
491 489 """Overridden from the parent class to use fancy rewriting prompt"""
492 490 if not self.show_rewritten_input:
493 491 return
494 492
495 493 tokens = self.prompts.rewrite_prompt_tokens()
496 494 if self.pt_cli:
497 495 self.pt_cli.print_tokens(tokens)
498 496 print(cmd)
499 497 else:
500 498 prompt = ''.join(s for t, s in tokens)
501 499 print(prompt, cmd, sep='')
502 500
503 501 _prompts_before = None
504 502 def switch_doctest_mode(self, mode):
505 503 """Switch prompts to classic for %doctest_mode"""
506 504 if mode:
507 505 self._prompts_before = self.prompts
508 506 self.prompts = ClassicPrompts(self)
509 507 elif self._prompts_before:
510 508 self.prompts = self._prompts_before
511 509 self._prompts_before = None
512 510 self._update_layout()
513 511
514 512
515 513 InteractiveShellABC.register(TerminalInteractiveShell)
516 514
517 515 if __name__ == '__main__':
518 516 TerminalInteractiveShell.instance().interact()
@@ -1,594 +1,595 b''
1 1 """Patched version of standard library tokenize, to deal with various bugs.
2 2
3 3 Based on Python 3.2 code.
4 4
5 5 Patches:
6 6
7 7 - Gareth Rees' patch for Python issue #12691 (untokenizing)
8 8 - Except we don't encode the output of untokenize
9 9 - Python 2 compatible syntax, so that it can be byte-compiled at installation
10 10 - Newlines in comments and blank lines should be either NL or NEWLINE, depending
11 11 on whether they are in a multi-line statement. Filed as Python issue #17061.
12 12 - Export generate_tokens & TokenError
13 13 - u and rb literals are allowed under Python 3.3 and above.
14 14
15 15 ------------------------------------------------------------------------------
16 16 Tokenization help for Python programs.
17 17
18 18 tokenize(readline) is a generator that breaks a stream of bytes into
19 19 Python tokens. It decodes the bytes according to PEP-0263 for
20 20 determining source file encoding.
21 21
22 22 It accepts a readline-like method which is called repeatedly to get the
23 23 next line of input (or b"" for EOF). It generates 5-tuples with these
24 24 members:
25 25
26 26 the token type (see token.py)
27 27 the token (a string)
28 28 the starting (row, column) indices of the token (a 2-tuple of ints)
29 29 the ending (row, column) indices of the token (a 2-tuple of ints)
30 30 the original line (string)
31 31
32 32 It is designed to match the working of the Python tokenizer exactly, except
33 33 that it produces COMMENT tokens for comments and gives type OP for all
34 34 operators. Additionally, all token lists start with an ENCODING token
35 35 which tells you which encoding was used to decode the bytes stream.
36 36 """
37 37
38 38 __author__ = 'Ka-Ping Yee <ping@lfw.org>'
39 39 __credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, '
40 40 'Skip Montanaro, Raymond Hettinger, Trent Nelson, '
41 41 'Michael Foord')
42 42 import builtins
43 43 import re
44 44 import sys
45 45 from token import *
46 46 from codecs import lookup, BOM_UTF8
47 47 import collections
48 48 from io import TextIOWrapper
49 49 cookie_re = re.compile("coding[:=]\s*([-\w.]+)")
50 50
51 51 import token
52 52 __all__ = token.__all__ + ["COMMENT", "tokenize", "detect_encoding",
53 53 "NL", "untokenize", "ENCODING", "TokenInfo"]
54 54 del token
55 55
56 56 __all__ += ["generate_tokens", "TokenError"]
57 57
58 58 COMMENT = N_TOKENS
59 59 tok_name[COMMENT] = 'COMMENT'
60 60 NL = N_TOKENS + 1
61 61 tok_name[NL] = 'NL'
62 62 ENCODING = N_TOKENS + 2
63 63 tok_name[ENCODING] = 'ENCODING'
64 64 N_TOKENS += 3
65 65
66 66 class TokenInfo(collections.namedtuple('TokenInfo', 'type string start end line')):
67 67 def __repr__(self):
68 68 annotated_type = '%d (%s)' % (self.type, tok_name[self.type])
69 69 return ('TokenInfo(type=%s, string=%r, start=%r, end=%r, line=%r)' %
70 70 self._replace(type=annotated_type))
71 71
72 72 def group(*choices): return '(' + '|'.join(choices) + ')'
73 73 def any(*choices): return group(*choices) + '*'
74 74 def maybe(*choices): return group(*choices) + '?'
75 75
76 76 # Note: we use unicode matching for names ("\w") but ascii matching for
77 77 # number literals.
78 78 Whitespace = r'[ \f\t]*'
79 79 Comment = r'#[^\r\n]*'
80 80 Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment)
81 81 Name = r'\w+'
82 82
83 83 Hexnumber = r'0[xX][0-9a-fA-F]+'
84 84 Binnumber = r'0[bB][01]+'
85 85 Octnumber = r'0[oO][0-7]+'
86 86 Decnumber = r'(?:0+|[1-9][0-9]*)'
87 87 Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber)
88 88 Exponent = r'[eE][-+]?[0-9]+'
89 89 Pointfloat = group(r'[0-9]+\.[0-9]*', r'\.[0-9]+') + maybe(Exponent)
90 90 Expfloat = r'[0-9]+' + Exponent
91 91 Floatnumber = group(Pointfloat, Expfloat)
92 92 Imagnumber = group(r'[0-9]+[jJ]', Floatnumber + r'[jJ]')
93 93 Number = group(Imagnumber, Floatnumber, Intnumber)
94 94
95 95 if sys.version_info.minor >= 3:
96 96 StringPrefix = r'(?:[bB][rR]?|[rR][bB]?|[uU])?'
97 97 else:
98 98 StringPrefix = r'(?:[bB]?[rR]?)?'
99 99
100 100 # Tail end of ' string.
101 101 Single = r"[^'\\]*(?:\\.[^'\\]*)*'"
102 102 # Tail end of " string.
103 103 Double = r'[^"\\]*(?:\\.[^"\\]*)*"'
104 104 # Tail end of ''' string.
105 105 Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''"
106 106 # Tail end of """ string.
107 107 Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""'
108 108 Triple = group(StringPrefix + "'''", StringPrefix + '"""')
109 109 # Single-line ' or " string.
110 110 String = group(StringPrefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*'",
111 111 StringPrefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*"')
112 112
113 113 # Because of leftmost-then-longest match semantics, be sure to put the
114 114 # longest operators first (e.g., if = came before ==, == would get
115 115 # recognized as two instances of =).
116 116 Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"!=",
117 117 r"//=?", r"->",
118 118 r"[+\-*/%&|^=<>]=?",
119 119 r"~")
120 120
121 121 Bracket = '[][(){}]'
122 122 Special = group(r'\r?\n', r'\.\.\.', r'[:;.,@]')
123 123 Funny = group(Operator, Bracket, Special)
124 124
125 125 PlainToken = group(Number, Funny, String, Name)
126 126 Token = Ignore + PlainToken
127 127
128 128 # First (or only) line of ' or " string.
129 129 ContStr = group(StringPrefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*" +
130 130 group("'", r'\\\r?\n'),
131 131 StringPrefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*' +
132 132 group('"', r'\\\r?\n'))
133 133 PseudoExtras = group(r'\\\r?\n', Comment, Triple)
134 134 PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name)
135 135
136 136 def _compile(expr):
137 137 return re.compile(expr, re.UNICODE)
138 138
139 139 tokenprog, pseudoprog, single3prog, double3prog = map(
140 140 _compile, (Token, PseudoToken, Single3, Double3))
141 141 endprogs = {"'": _compile(Single), '"': _compile(Double),
142 142 "'''": single3prog, '"""': double3prog,
143 143 "r'''": single3prog, 'r"""': double3prog,
144 144 "b'''": single3prog, 'b"""': double3prog,
145 145 "R'''": single3prog, 'R"""': double3prog,
146 146 "B'''": single3prog, 'B"""': double3prog,
147 147 "br'''": single3prog, 'br"""': double3prog,
148 148 "bR'''": single3prog, 'bR"""': double3prog,
149 149 "Br'''": single3prog, 'Br"""': double3prog,
150 150 "BR'''": single3prog, 'BR"""': double3prog,
151 151 'r': None, 'R': None, 'b': None, 'B': None}
152 152
153 153 triple_quoted = {}
154 154 for t in ("'''", '"""',
155 155 "r'''", 'r"""', "R'''", 'R"""',
156 156 "b'''", 'b"""', "B'''", 'B"""',
157 157 "br'''", 'br"""', "Br'''", 'Br"""',
158 158 "bR'''", 'bR"""', "BR'''", 'BR"""'):
159 159 triple_quoted[t] = t
160 160 single_quoted = {}
161 161 for t in ("'", '"',
162 162 "r'", 'r"', "R'", 'R"',
163 163 "b'", 'b"', "B'", 'B"',
164 164 "br'", 'br"', "Br'", 'Br"',
165 165 "bR'", 'bR"', "BR'", 'BR"' ):
166 166 single_quoted[t] = t
167 167
168 168 if sys.version_info.minor >= 3:
169 169 # Python 3.3
170 170 for _prefix in ['rb', 'rB', 'Rb', 'RB', 'u', 'U']:
171 171 _t2 = _prefix+'"""'
172 172 endprogs[_t2] = double3prog
173 173 triple_quoted[_t2] = _t2
174 174 _t1 = _prefix + "'''"
175 175 endprogs[_t1] = single3prog
176 176 triple_quoted[_t1] = _t1
177 177 single_quoted[_prefix+'"'] = _prefix+'"'
178 178 single_quoted[_prefix+"'"] = _prefix+"'"
179 179 del _prefix, _t2, _t1
180 180 endprogs['u'] = None
181 181 endprogs['U'] = None
182 182
183 183 del _compile
184 184
185 185 tabsize = 8
186 186
187 187 class TokenError(Exception): pass
188 188
189 189 class StopTokenizing(Exception): pass
190 190
191 191
192 192 class Untokenizer:
193 193
194 194 def __init__(self):
195 195 self.tokens = []
196 196 self.prev_row = 1
197 197 self.prev_col = 0
198 198 self.encoding = 'utf-8'
199 199
200 200 def add_whitespace(self, tok_type, start):
201 201 row, col = start
202 202 assert row >= self.prev_row
203 203 col_offset = col - self.prev_col
204 204 if col_offset > 0:
205 205 self.tokens.append(" " * col_offset)
206 206 elif row > self.prev_row and tok_type not in (NEWLINE, NL, ENDMARKER):
207 207 # Line was backslash-continued.
208 208 self.tokens.append(" ")
209 209
210 210 def untokenize(self, tokens):
211 211 iterable = iter(tokens)
212 212 for t in iterable:
213 213 if len(t) == 2:
214 214 self.compat(t, iterable)
215 215 break
216 216 tok_type, token, start, end = t[:4]
217 217 if tok_type == ENCODING:
218 218 self.encoding = token
219 219 continue
220 220 self.add_whitespace(tok_type, start)
221 221 self.tokens.append(token)
222 222 self.prev_row, self.prev_col = end
223 223 if tok_type in (NEWLINE, NL):
224 224 self.prev_row += 1
225 225 self.prev_col = 0
226 226 return "".join(self.tokens)
227 227
228 228 def compat(self, token, iterable):
229 229 # This import is here to avoid problems when the itertools
230 230 # module is not built yet and tokenize is imported.
231 231 from itertools import chain
232 232 startline = False
233 233 prevstring = False
234 234 indents = []
235 235 toks_append = self.tokens.append
236 236
237 237 for tok in chain([token], iterable):
238 238 toknum, tokval = tok[:2]
239 239 if toknum == ENCODING:
240 240 self.encoding = tokval
241 241 continue
242 242
243 243 if toknum in (NAME, NUMBER):
244 244 tokval += ' '
245 245
246 246 # Insert a space between two consecutive strings
247 247 if toknum == STRING:
248 248 if prevstring:
249 249 tokval = ' ' + tokval
250 250 prevstring = True
251 251 else:
252 252 prevstring = False
253 253
254 254 if toknum == INDENT:
255 255 indents.append(tokval)
256 256 continue
257 257 elif toknum == DEDENT:
258 258 indents.pop()
259 259 continue
260 260 elif toknum in (NEWLINE, NL):
261 261 startline = True
262 262 elif startline and indents:
263 263 toks_append(indents[-1])
264 264 startline = False
265 265 toks_append(tokval)
266 266
267 267
268 268 def untokenize(tokens):
269 269 """
270 270 Convert ``tokens`` (an iterable) back into Python source code. Return
271 271 a bytes object, encoded using the encoding specified by the last
272 272 ENCODING token in ``tokens``, or UTF-8 if no ENCODING token is found.
273 273
274 274 The result is guaranteed to tokenize back to match the input so that
275 275 the conversion is lossless and round-trips are assured. The
276 276 guarantee applies only to the token type and token string as the
277 277 spacing between tokens (column positions) may change.
278 278
279 279 :func:`untokenize` has two modes. If the input tokens are sequences
280 280 of length 2 (``type``, ``string``) then spaces are added as necessary to
281 281 preserve the round-trip property.
282 282
283 283 If the input tokens are sequences of length 4 or more (``type``,
284 284 ``string``, ``start``, ``end``), as returned by :func:`tokenize`, then
285 285 spaces are added so that each token appears in the result at the
286 286 position indicated by ``start`` and ``end``, if possible.
287 287 """
288 288 return Untokenizer().untokenize(tokens)
289 289
290 290
291 291 def _get_normal_name(orig_enc):
292 292 """Imitates get_normal_name in tokenizer.c."""
293 293 # Only care about the first 12 characters.
294 294 enc = orig_enc[:12].lower().replace("_", "-")
295 295 if enc == "utf-8" or enc.startswith("utf-8-"):
296 296 return "utf-8"
297 297 if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
298 298 enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
299 299 return "iso-8859-1"
300 300 return orig_enc
301 301
302 302 def detect_encoding(readline):
303 303 """
304 304 The detect_encoding() function is used to detect the encoding that should
305 305 be used to decode a Python source file. It requires one argment, readline,
306 306 in the same way as the tokenize() generator.
307 307
308 308 It will call readline a maximum of twice, and return the encoding used
309 309 (as a string) and a list of any lines (left as bytes) it has read in.
310 310
311 311 It detects the encoding from the presence of a utf-8 bom or an encoding
312 312 cookie as specified in pep-0263. If both a bom and a cookie are present,
313 313 but disagree, a SyntaxError will be raised. If the encoding cookie is an
314 314 invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
315 315 'utf-8-sig' is returned.
316 316
317 317 If no encoding is specified, then the default of 'utf-8' will be returned.
318 318 """
319 319 bom_found = False
320 320 encoding = None
321 321 default = 'utf-8'
322 322 def read_or_stop():
323 323 try:
324 324 return readline()
325 325 except StopIteration:
326 326 return b''
327 327
328 328 def find_cookie(line):
329 329 try:
330 330 # Decode as UTF-8. Either the line is an encoding declaration,
331 331 # in which case it should be pure ASCII, or it must be UTF-8
332 332 # per default encoding.
333 333 line_string = line.decode('utf-8')
334 334 except UnicodeDecodeError:
335 335 raise SyntaxError("invalid or missing encoding declaration")
336 336
337 337 matches = cookie_re.findall(line_string)
338 338 if not matches:
339 339 return None
340 340 encoding = _get_normal_name(matches[0])
341 341 try:
342 342 codec = lookup(encoding)
343 343 except LookupError:
344 344 # This behaviour mimics the Python interpreter
345 345 raise SyntaxError("unknown encoding: " + encoding)
346 346
347 347 if bom_found:
348 348 if encoding != 'utf-8':
349 349 # This behaviour mimics the Python interpreter
350 350 raise SyntaxError('encoding problem: utf-8')
351 351 encoding += '-sig'
352 352 return encoding
353 353
354 354 first = read_or_stop()
355 355 if first.startswith(BOM_UTF8):
356 356 bom_found = True
357 357 first = first[3:]
358 358 default = 'utf-8-sig'
359 359 if not first:
360 360 return default, []
361 361
362 362 encoding = find_cookie(first)
363 363 if encoding:
364 364 return encoding, [first]
365 365
366 366 second = read_or_stop()
367 367 if not second:
368 368 return default, [first]
369 369
370 370 encoding = find_cookie(second)
371 371 if encoding:
372 372 return encoding, [first, second]
373 373
374 374 return default, [first, second]
375 375
376 376
377 377 def open(filename):
378 378 """Open a file in read only mode using the encoding detected by
379 379 detect_encoding().
380 380 """
381 381 buffer = builtins.open(filename, 'rb')
382 382 encoding, lines = detect_encoding(buffer.readline)
383 383 buffer.seek(0)
384 384 text = TextIOWrapper(buffer, encoding, line_buffering=True)
385 385 text.mode = 'r'
386 386 return text
387 387
388 388
389 389 def tokenize(readline):
390 390 """
391 391 The tokenize() generator requires one argment, readline, which
392 392 must be a callable object which provides the same interface as the
393 393 readline() method of built-in file objects. Each call to the function
394 394 should return one line of input as bytes. Alternately, readline
395 can be a callable function terminating with StopIteration:
395 can be a callable function terminating with :class:`StopIteration`::
396
396 397 readline = open(myfile, 'rb').__next__ # Example of alternate readline
397 398
398 399 The generator produces 5-tuples with these members: the token type; the
399 400 token string; a 2-tuple (srow, scol) of ints specifying the row and
400 401 column where the token begins in the source; a 2-tuple (erow, ecol) of
401 402 ints specifying the row and column where the token ends in the source;
402 403 and the line on which the token was found. The line passed is the
403 404 logical line; continuation lines are included.
404 405
405 406 The first token sequence will always be an ENCODING token
406 407 which tells you which encoding was used to decode the bytes stream.
407 408 """
408 409 # This import is here to avoid problems when the itertools module is not
409 410 # built yet and tokenize is imported.
410 411 from itertools import chain, repeat
411 412 encoding, consumed = detect_encoding(readline)
412 413 rl_gen = iter(readline, b"")
413 414 empty = repeat(b"")
414 415 return _tokenize(chain(consumed, rl_gen, empty).__next__, encoding)
415 416
416 417
417 418 def _tokenize(readline, encoding):
418 419 lnum = parenlev = continued = 0
419 420 numchars = '0123456789'
420 421 contstr, needcont = '', 0
421 422 contline = None
422 423 indents = [0]
423 424
424 425 if encoding is not None:
425 426 if encoding == "utf-8-sig":
426 427 # BOM will already have been stripped.
427 428 encoding = "utf-8"
428 429 yield TokenInfo(ENCODING, encoding, (0, 0), (0, 0), '')
429 430 while True: # loop over lines in stream
430 431 try:
431 432 line = readline()
432 433 except StopIteration:
433 434 line = b''
434 435
435 436 if encoding is not None:
436 437 line = line.decode(encoding)
437 438 lnum += 1
438 439 pos, max = 0, len(line)
439 440
440 441 if contstr: # continued string
441 442 if not line:
442 443 raise TokenError("EOF in multi-line string", strstart)
443 444 endmatch = endprog.match(line)
444 445 if endmatch:
445 446 pos = end = endmatch.end(0)
446 447 yield TokenInfo(STRING, contstr + line[:end],
447 448 strstart, (lnum, end), contline + line)
448 449 contstr, needcont = '', 0
449 450 contline = None
450 451 elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n':
451 452 yield TokenInfo(ERRORTOKEN, contstr + line,
452 453 strstart, (lnum, len(line)), contline)
453 454 contstr = ''
454 455 contline = None
455 456 continue
456 457 else:
457 458 contstr = contstr + line
458 459 contline = contline + line
459 460 continue
460 461
461 462 elif parenlev == 0 and not continued: # new statement
462 463 if not line: break
463 464 column = 0
464 465 while pos < max: # measure leading whitespace
465 466 if line[pos] == ' ':
466 467 column += 1
467 468 elif line[pos] == '\t':
468 469 column = (column//tabsize + 1)*tabsize
469 470 elif line[pos] == '\f':
470 471 column = 0
471 472 else:
472 473 break
473 474 pos += 1
474 475 if pos == max:
475 476 break
476 477
477 478 if line[pos] in '#\r\n': # skip comments or blank lines
478 479 if line[pos] == '#':
479 480 comment_token = line[pos:].rstrip('\r\n')
480 481 nl_pos = pos + len(comment_token)
481 482 yield TokenInfo(COMMENT, comment_token,
482 483 (lnum, pos), (lnum, pos + len(comment_token)), line)
483 484 yield TokenInfo(NEWLINE, line[nl_pos:],
484 485 (lnum, nl_pos), (lnum, len(line)), line)
485 486 else:
486 487 yield TokenInfo(NEWLINE, line[pos:],
487 488 (lnum, pos), (lnum, len(line)), line)
488 489 continue
489 490
490 491 if column > indents[-1]: # count indents or dedents
491 492 indents.append(column)
492 493 yield TokenInfo(INDENT, line[:pos], (lnum, 0), (lnum, pos), line)
493 494 while column < indents[-1]:
494 495 if column not in indents:
495 496 raise IndentationError(
496 497 "unindent does not match any outer indentation level",
497 498 ("<tokenize>", lnum, pos, line))
498 499 indents = indents[:-1]
499 500 yield TokenInfo(DEDENT, '', (lnum, pos), (lnum, pos), line)
500 501
501 502 else: # continued statement
502 503 if not line:
503 504 raise TokenError("EOF in multi-line statement", (lnum, 0))
504 505 continued = 0
505 506
506 507 while pos < max:
507 508 pseudomatch = pseudoprog.match(line, pos)
508 509 if pseudomatch: # scan for tokens
509 510 start, end = pseudomatch.span(1)
510 511 spos, epos, pos = (lnum, start), (lnum, end), end
511 512 token, initial = line[start:end], line[start]
512 513
513 514 if (initial in numchars or # ordinary number
514 515 (initial == '.' and token != '.' and token != '...')):
515 516 yield TokenInfo(NUMBER, token, spos, epos, line)
516 517 elif initial in '\r\n':
517 518 yield TokenInfo(NL if parenlev > 0 else NEWLINE,
518 519 token, spos, epos, line)
519 520 elif initial == '#':
520 521 assert not token.endswith("\n")
521 522 yield TokenInfo(COMMENT, token, spos, epos, line)
522 523 elif token in triple_quoted:
523 524 endprog = endprogs[token]
524 525 endmatch = endprog.match(line, pos)
525 526 if endmatch: # all on one line
526 527 pos = endmatch.end(0)
527 528 token = line[start:pos]
528 529 yield TokenInfo(STRING, token, spos, (lnum, pos), line)
529 530 else:
530 531 strstart = (lnum, start) # multiple lines
531 532 contstr = line[start:]
532 533 contline = line
533 534 break
534 535 elif initial in single_quoted or \
535 536 token[:2] in single_quoted or \
536 537 token[:3] in single_quoted:
537 538 if token[-1] == '\n': # continued string
538 539 strstart = (lnum, start)
539 540 endprog = (endprogs[initial] or endprogs[token[1]] or
540 541 endprogs[token[2]])
541 542 contstr, needcont = line[start:], 1
542 543 contline = line
543 544 break
544 545 else: # ordinary string
545 546 yield TokenInfo(STRING, token, spos, epos, line)
546 547 elif initial.isidentifier(): # ordinary name
547 548 yield TokenInfo(NAME, token, spos, epos, line)
548 549 elif initial == '\\': # continued stmt
549 550 continued = 1
550 551 else:
551 552 if initial in '([{':
552 553 parenlev += 1
553 554 elif initial in ')]}':
554 555 parenlev -= 1
555 556 yield TokenInfo(OP, token, spos, epos, line)
556 557 else:
557 558 yield TokenInfo(ERRORTOKEN, line[pos],
558 559 (lnum, pos), (lnum, pos+1), line)
559 560 pos += 1
560 561
561 562 for indent in indents[1:]: # pop remaining indent levels
562 563 yield TokenInfo(DEDENT, '', (lnum, 0), (lnum, 0), '')
563 564 yield TokenInfo(ENDMARKER, '', (lnum, 0), (lnum, 0), '')
564 565
565 566
566 567 # An undocumented, backwards compatible, API for all the places in the standard
567 568 # library that expect to be able to use tokenize with strings
568 569 def generate_tokens(readline):
569 570 return _tokenize(readline, None)
570 571
571 572 if __name__ == "__main__":
572 573 # Quick sanity check
573 574 s = b'''def parseline(self, line):
574 575 """Parse the line into a command name and a string containing
575 576 the arguments. Returns a tuple containing (command, args, line).
576 577 'command' and 'args' may be None if the line couldn't be parsed.
577 578 """
578 579 line = line.strip()
579 580 if not line:
580 581 return None, None, line
581 582 elif line[0] == '?':
582 583 line = 'help ' + line[1:]
583 584 elif line[0] == '!':
584 585 if hasattr(self, 'do_shell'):
585 586 line = 'shell ' + line[1:]
586 587 else:
587 588 return None, None, line
588 589 i, n = 0, len(line)
589 590 while i < n and line[i] in self.identchars: i = i+1
590 591 cmd, arg = line[:i], line[i:].strip()
591 592 return cmd, arg, line
592 593 '''
593 594 for tok in tokenize(iter(s.splitlines()).__next__):
594 595 print(tok)
@@ -1,127 +1,127 b''
1 1 """Token-related utilities"""
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 collections import namedtuple
8 8 from io import StringIO
9 9 from keyword import iskeyword
10 10
11 11 from . import tokenize2
12 12 from .py3compat import cast_unicode_py2
13 13
14 14 Token = namedtuple('Token', ['token', 'text', 'start', 'end', 'line'])
15 15
16 16 def generate_tokens(readline):
17 17 """wrap generate_tokens to catch EOF errors"""
18 18 try:
19 19 for token in tokenize2.generate_tokens(readline):
20 20 yield token
21 21 except tokenize2.TokenError:
22 22 # catch EOF error
23 23 return
24 24
25 25 def line_at_cursor(cell, cursor_pos=0):
26 26 """Return the line in a cell at a given cursor position
27 27
28 28 Used for calling line-based APIs that don't support multi-line input, yet.
29 29
30 30 Parameters
31 31 ----------
32 32
33 33 cell: str
34 34 multiline block of text
35 35 cursor_pos: integer
36 36 the cursor position
37 37
38 38 Returns
39 39 -------
40 40
41 (line, offset): (text, integer)
41 (line, offset): (string, integer)
42 42 The line with the current cursor, and the character offset of the start of the line.
43 43 """
44 44 offset = 0
45 45 lines = cell.splitlines(True)
46 46 for line in lines:
47 47 next_offset = offset + len(line)
48 48 if next_offset >= cursor_pos:
49 49 break
50 50 offset = next_offset
51 51 else:
52 52 line = ""
53 53 return (line, offset)
54 54
55 55 def token_at_cursor(cell, cursor_pos=0):
56 56 """Get the token at a given cursor
57 57
58 58 Used for introspection.
59 59
60 60 Function calls are prioritized, so the token for the callable will be returned
61 61 if the cursor is anywhere inside the call.
62 62
63 63 Parameters
64 64 ----------
65 65
66 66 cell : unicode
67 67 A block of Python code
68 68 cursor_pos : int
69 69 The location of the cursor in the block where the token should be found
70 70 """
71 71 cell = cast_unicode_py2(cell)
72 72 names = []
73 73 tokens = []
74 74 call_names = []
75 75
76 76 offsets = {1: 0} # lines start at 1
77 77 for tup in generate_tokens(StringIO(cell).readline):
78 78
79 79 tok = Token(*tup)
80 80
81 81 # token, text, start, end, line = tup
82 82 start_line, start_col = tok.start
83 83 end_line, end_col = tok.end
84 84 if end_line + 1 not in offsets:
85 85 # keep track of offsets for each line
86 86 lines = tok.line.splitlines(True)
87 87 for lineno, line in enumerate(lines, start_line + 1):
88 88 if lineno not in offsets:
89 89 offsets[lineno] = offsets[lineno-1] + len(line)
90 90
91 91 offset = offsets[start_line]
92 92 # allow '|foo' to find 'foo' at the beginning of a line
93 93 boundary = cursor_pos + 1 if start_col == 0 else cursor_pos
94 94 if offset + start_col >= boundary:
95 95 # current token starts after the cursor,
96 96 # don't consume it
97 97 break
98 98
99 99 if tok.token == tokenize2.NAME and not iskeyword(tok.text):
100 100 if names and tokens and tokens[-1].token == tokenize2.OP and tokens[-1].text == '.':
101 101 names[-1] = "%s.%s" % (names[-1], tok.text)
102 102 else:
103 103 names.append(tok.text)
104 104 elif tok.token == tokenize2.OP:
105 105 if tok.text == '=' and names:
106 106 # don't inspect the lhs of an assignment
107 107 names.pop(-1)
108 108 if tok.text == '(' and names:
109 109 # if we are inside a function call, inspect the function
110 110 call_names.append(names[-1])
111 111 elif tok.text == ')' and call_names:
112 112 call_names.pop(-1)
113 113
114 114 tokens.append(tok)
115 115
116 116 if offsets[end_line] + end_col > cursor_pos:
117 117 # we found the cursor, stop reading
118 118 break
119 119
120 120 if call_names:
121 121 return call_names[-1]
122 122 elif names:
123 123 return names[-1]
124 124 else:
125 125 return ''
126 126
127 127
@@ -1,230 +1,230 b''
1 1 =======================
2 2 Specific config details
3 3 =======================
4 4
5 5 .. _custom_prompts:
6 6
7 7 Custom Prompts
8 8 ==============
9 9
10 10 .. versionchanged:: 5.0
11 11
12 12 From IPython 5, prompts are produced as a list of Pygments tokens, which are
13 13 tuples of (token_type, text). You can customise prompts by writing a method
14 14 which generates a list of tokens.
15 15
16 16 There are four kinds of prompt:
17 17
18 18 * The **in** prompt is shown before the first line of input
19 19 (default like ``In [1]:``).
20 20 * The **continuation** prompt is shown before further lines of input
21 21 (default like ``...:``).
22 22 * The **rewrite** prompt is shown to highlight how special syntax has been
23 23 interpreted (default like ``----->``).
24 24 * The **out** prompt is shown before the result from evaluating the input
25 25 (default like ``Out[1]:``).
26 26
27 27 Custom prompts are supplied together as a class. If you want to customise only
28 28 some of the prompts, inherit from :class:`IPython.terminal.prompts.Prompts`,
29 29 which defines the defaults. The required interface is like this:
30 30
31 31 .. class:: MyPrompts(shell)
32 32
33 33 Prompt style definition. *shell* is a reference to the
34 34 :class:`~.TerminalInteractiveShell` instance.
35 35
36 36 .. method:: in_prompt_tokens(cli=None)
37 37 continuation_prompt_tokens(self, cli=None, width=None)
38 38 rewrite_prompt_tokens()
39 39 out_prompt_tokens()
40 40
41 41 Return the respective prompts as lists of ``(token_type, text)`` tuples.
42 42
43 43 For continuation prompts, *width* is an integer representing the width of
44 44 the prompt area in terminal columns.
45 45
46 46 *cli*, where used, is the prompt_toolkit ``CommandLineInterface`` instance.
47 47 This is mainly for compatibility with the API prompt_toolkit expects.
48 48
49 49 Here is an example Prompt class that will show the current working directory
50 50 in the input prompt:
51 51
52 52 .. code-block:: python
53 53
54 54 from IPython.terminal.prompts import Prompts, Token
55 55 import os
56 56
57 57 class MyPrompt(Prompts):
58 58 def in_prompt_tokens(self, cli=None):
59 59 return [(Token, os.getcwd()),
60 60 (Token.Prompt, ' >>>')]
61 61
62 62 To set the new prompt, assign it to the ``prompts`` attribute of the IPython
63 63 shell:
64 64
65 65 .. code-block:: python
66 66
67 67 In [2]: ip = get_ipython()
68 68 ...: ip.prompts = MyPrompt(ip)
69 69
70 70 /home/bob >>> # it works
71 71
72 72 See ``IPython/example/utils/cwd_prompt.py`` for an example of how to write an
73 73 extensions to customise prompts.
74 74
75 75 Inside IPython or in a startup script, you can use a custom prompts class
76 76 by setting ``get_ipython().prompts`` to an *instance* of the class.
77 77 In configuration, ``TerminalInteractiveShell.prompts_class`` may be set to
78 78 either the class object, or a string of its full importable name.
79 79
80 80 To include invisible terminal control sequences in a prompt, use
81 81 ``Token.ZeroWidthEscape`` as the token type. Tokens with this type are ignored
82 82 when calculating the width.
83 83
84 84 Colours in the prompt are determined by the token types and the highlighting
85 85 style; see below for more details. The tokens used in the default prompts are
86 86 ``Prompt``, ``PromptNum``, ``OutPrompt`` and ``OutPromptNum``.
87 87
88 88 .. _termcolour:
89 89
90 90 Terminal Colors
91 91 ===============
92 92
93 93 .. versionchanged:: 5.0
94 94
95 95 There are two main configuration options controlling colours.
96 96
97 97 ``InteractiveShell.colors`` sets the colour of tracebacks and object info (the
98 98 output from e.g. ``zip?``). It may also affect other things if the option below
99 99 is set to ``'legacy'``. It has four case-insensitive values:
100 100 ``'nocolor', 'neutral', 'linux', 'lightbg'``. The default is *neutral*, which
101 101 should be legible on either dark or light terminal backgrounds. *linux* is
102 102 optimised for dark backgrounds and *lightbg* for light ones.
103 103
104 104 ``TerminalInteractiveShell.highlighting_style`` determines prompt colours and
105 105 syntax highlighting. It takes the name (as a string) or class (as a subclass of
106 106 ``pygments.style.Style``) of a Pygments style, or the special value ``'legacy'``
107 107 to pick a style in accordance with ``InteractiveShell.colors``.
108 108
109 109 You can see the Pygments styles available on your system by running::
110 110
111 111 import pygments
112 112 list(pygments.styles.get_all_styles())
113 113
114 114 Additionally, ``TerminalInteractiveShell.highlighting_style_overrides`` can override
115 115 specific styles in the highlighting. It should be a dictionary mapping Pygments
116 116 token types to strings defining the style. See `Pygments' documentation
117 117 <http://pygments.org/docs/styles/#creating-own-styles>`__ for the language used
118 118 to define styles.
119 119
120 120 Colors in the pager
121 121 -------------------
122 122
123 123 On some systems, the default pager has problems with ANSI colour codes.
124 124 To configure your default pager to allow these:
125 125
126 126 1. Set the environment PAGER variable to ``less``.
127 127 2. Set the environment LESS variable to ``-r`` (plus any other options
128 128 you always want to pass to less by default). This tells less to
129 129 properly interpret control sequences, which is how color
130 130 information is given to your terminal.
131 131
132 132 .. _editors:
133 133
134 134 Editor configuration
135 135 ====================
136 136
137 137 IPython can integrate with text editors in a number of different ways:
138 138
139 139 * Editors (such as `(X)Emacs`_, vim_ and TextMate_) can
140 140 send code to IPython for execution.
141 141
142 142 * IPython's ``%edit`` magic command can open an editor of choice to edit
143 143 a code block.
144 144
145 145 The %edit command (and its alias %ed) will invoke the editor set in your
146 146 environment as :envvar:`EDITOR`. If this variable is not set, it will default
147 147 to vi under Linux/Unix and to notepad under Windows. You may want to set this
148 148 variable properly and to a lightweight editor which doesn't take too long to
149 149 start (that is, something other than a new instance of Emacs). This way you
150 150 can edit multi-line code quickly and with the power of a real editor right
151 151 inside IPython.
152 152
153 153 You can also control the editor by setting :attr:`TerminalInteractiveShell.editor`
154 154 in :file:`ipython_config.py`.
155 155
156 156 Vim
157 157 ---
158 158
159 159 Paul Ivanov's `vim-ipython <https://github.com/ivanov/vim-ipython>`_ provides
160 160 powerful IPython integration for vim.
161 161
162 162 .. _emacs:
163 163
164 164 (X)Emacs
165 165 --------
166 166
167 167 If you are a dedicated Emacs user, and want to use Emacs when IPython's
168 168 ``%edit`` magic command is called you should set up the Emacs server so that
169 169 new requests are handled by the original process. This means that almost no
170 170 time is spent in handling the request (assuming an Emacs process is already
171 171 running). For this to work, you need to set your EDITOR environment variable
172 172 to 'emacsclient'. The code below, supplied by Francois Pinard, can then be
173 173 used in your :file:`.emacs` file to enable the server:
174 174
175 175 .. code-block:: common-lisp
176 176
177 177 (defvar server-buffer-clients)
178 178 (when (and (fboundp 'server-start) (string-equal (getenv "TERM") 'xterm))
179 179 (server-start)
180 180 (defun fp-kill-server-with-buffer-routine ()
181 181 (and server-buffer-clients (server-done)))
182 182 (add-hook 'kill-buffer-hook 'fp-kill-server-with-buffer-routine))
183 183
184 184 Thanks to the work of Alexander Schmolck and Prabhu Ramachandran,
185 185 currently (X)Emacs and IPython get along very well in other ways.
186 186
187 187 With (X)EMacs >= 24, You can enable IPython in python-mode with:
188 188
189 189 .. code-block:: common-lisp
190 190
191 191 (require 'python)
192 192 (setq python-shell-interpreter "ipython")
193 193
194 194 .. _`(X)Emacs`: http://www.gnu.org/software/emacs/
195 195 .. _TextMate: http://macromates.com/
196 196 .. _vim: http://www.vim.org/
197 197
198 .. _custom_keyboard_shortcuts
198 .. _custom_keyboard_shortcuts:
199 199
200 200 Keyboard Shortcuts
201 201 ==================
202 202
203 203 .. versionchanged:: 5.0
204 204
205 205 You can customise keyboard shortcuts for terminal IPython. Put code like this in
206 206 a :ref:`startup file <startup_files>`::
207 207
208 208 from IPython import get_ipython
209 209 from prompt_toolkit.enums import DEFAULT_BUFFER
210 210 from prompt_toolkit.keys import Keys
211 211 from prompt_toolkit.filters import HasFocus, HasSelection, ViInsertMode, EmacsInsertMode
212 212
213 213 ip = get_ipython()
214 214 insert_mode = ViInsertMode() | EmacsInsertMode()
215 215
216 216 def insert_unexpected(event):
217 217 buf = event.current_buffer
218 218 buf.insert_text('The Spanish Inquisition')
219 219
220 220 # Register the shortcut if IPython is using prompt_toolkit
221 221 if getattr(ip, 'pt_cli'):
222 222 registry = ip.pt_cli.application.key_bindings_registry
223 223 registry.add_binding(Keys.ControlN,
224 224 filter=(HasFocus(DEFAULT_BUFFER)
225 225 & ~HasSelection()
226 226 & insert_mode))(insert_unexpected)
227 227
228 228 For more information on filters and what you can do with the ``event`` object,
229 229 `see the prompt_toolkit docs
230 230 <http://python-prompt-toolkit.readthedocs.io/en/latest/pages/building_prompts.html#adding-custom-key-bindings>`__.
@@ -1,175 +1,176 b''
1 1 =====================
2 2 Development version
3 3 =====================
4 4
5 5 This document describes in-flight development work.
6 6
7 7 .. warning::
8 8
9 9 Please do not edit this file by hand (doing so will likely cause merge
10 10 conflicts for other Pull Requests). Instead, create a new file in the
11 11 `docs/source/whatsnew/pr` folder
12 12
13 13 IPython 6.0
14 14 ===========
15 15
16 16 Released .... ...., 2017
17 17
18 18 IPython 6 feature a major improvement in the completion machinery which is now
19 19 capable of completing non-executed code. It is also the first version of IPython
20 20 to stop compatibility with Python 2, which is still supported on the bugfix only
21 21 5.x branch. Read below to have a non-exhaustive list of new features.
22 22
23 23 Make sure you have pip > 9.0 before upgrading.
24 24 You should be able to update by using:
25 25
26 26 .. code::
27 27
28 28 pip install ipython --upgrade
29 29
30 30 New completion API and Interface
31 31 --------------------------------
32 32
33 33 The completer Completion API has seen an overhaul, and the new completer have
34 34 plenty of improvement both from the end users of terminal IPython or for
35 35 consumers of the API.
36 36
37 37 This new API is capable of pulling completions from :any:`jedi`, thus allowing
38 38 type inference on non-executed code. If :any:`jedi` is installed completion like
39 39 the following are now becoming possible without code evaluation:
40 40
41 41 >>> data = ['Number of users', 123_456]
42 42 ... data[0].<tab>
43 43
44 44 That is to say, IPython is now capable of inferring that `data[0]` is a string,
45 45 and will suggest completions like `.capitalize`. The completion power of IPython
46 46 will increase with new Jedi releases, and a number of bugs and more completions
47 47 are already available on development version of :any:`jedi` if you are curious.
48 48
49 49 With the help of prompt toolkit, types of completions can be shown in the
50 50 completer interface:
51 51
52 52 .. image:: ../_images/jedi_type_inference_60.png
53 53 :alt: Jedi showing ability to do type inference
54 54 :align: center
55 :width: 400px
55 56 :target: ../_images/jedi_type_inference_60.png
56 57
57 58 The appearance of the completer is controlled by the
58 59 ``c.TerminalInteractiveShell.display_completions`` option that will show the
59 60 type differently depending on the value among ``'column'``, ``'multicolumn'``
60 61 and ``'readlinelike'``
61 62
62 63 The use of Jedi also full fill a number of request and fix a number of bugs
63 64 like case insensitive completion, completion after division operator: See
64 65 :ghpull:`10182`.
65 66
66 Extra patches and updates will be needed to the :any:`ipykernel` package for
67 Extra patches and updates will be needed to the :mod:`ipykernel` package for
67 68 this feature to be available to other clients like jupyter Notebook, Lab,
68 69 Nteract, Hydrogen...
69 70
70 71 The use of Jedi can is barely noticeable on recent enough machines, but can be
71 72 feel on older ones, in cases were Jedi behavior need to be adjusted, the amount
72 73 of time given to Jedi to compute type inference can be adjusted with
73 74 ``c.IPCompleter.jedi_compute_type_timeout``, with object whose type were not
74 75 inferred will be shown as ``<unknown>``. Jedi can also be completely deactivated
75 76 by using the ``c.Completer.use_jedi=False`` option.
76 77
77 78
78 79 The old ``Completer.complete()`` API is waiting deprecation and should be
79 80 replaced replaced by ``Completer.completions()`` in a near future. Feedback on
80 81 the current state of the API and suggestions welcome.
81 82
82 83 Python 3 only codebase
83 84 ----------------------
84 85
85 86 One of the large challenges in IPython 6.0 has been the adoption of a pure
86 87 Python 3 code base, which lead us to great length to upstream patches in pip,
87 88 pypi and warehouse to make sure Python 2 system still upgrade to the latest
88 89 compatible Python version compatible.
89 90
90 91 We remind our Python 2 users that IPython 5 is still compatible with Python 2.7,
91 92 still maintained and get regular releases. Using pip 9+, upgrading IPython will
92 93 automatically upgrade to the latest version compatible with your system.
93 94
94 95 .. warning::
95 96
96 97 If you are on a system using an older verison of pip on Python 2, pip may
97 98 still install IPython 6.0 on your system, and IPython will refuse to start.
98 99 You can fix this by ugrading pip, and reinstalling ipython, or forcing pip to
99 100 install an earlier version: ``pip install 'ipython<6'``
100 101
101 102 The ability to use only Python 3 on the code base of IPython has bring a number
102 103 of advantage. Most of the newly written code make use of `optional function type
103 104 anotation <https://www.python.org/dev/peps/pep-0484/>`_ leading to clearer code
104 105 and better documentation.
105 106
106 107 The total size of the repository has also for a first time between releases
107 108 (excluding the big split for 4.0) decreased by about 1500 lines, potentially
108 109 quite a bit more codewide as some documents like this one are append only and
109 110 are about 300 lines long.
110 111
111 112 The removal as of Python2/Python3 shim layer has made the code quite clearer and
112 113 more idiomatic in a number of location, and much friendlier to work with and
113 114 understand. We hope to further embrace Python 3 capability in the next release
114 115 cycle and introduce more of the Python 3 only idioms (yield from, kwarg only,
115 116 general unpacking) in the code base of IPython, and see if we can take advantage
116 117 of these as well to improve user experience with better error messages and
117 118 hints.
118 119
119 120
120 121 Miscs improvements
121 122 ------------------
122 123
123 124
124 125 - The :cellmagic:`capture` magic can now capture the result of a cell (from an
125 126 expression on the last line), as well as printed and displayed output.
126 127 :ghpull:`9851`.
127 128
128 129 - Pressing Ctrl-Z in the terminal debugger now suspends IPython, as it already
129 130 does in the main terminal prompt.
130 131
131 132 - autoreload can now reload ``Enum``. See :ghissue:`10232` and :ghpull:`10316`
132 133
133 134 - IPython.display has gained a :any:`GeoJSON <IPython.display.GeoJSON>` object.
134 135 :ghpull:`10288` and :ghpull:`10253`
135 136
136 137 .. DO NOT EDIT THIS LINE BEFORE RELEASE. FEATURE INSERTION POINT.
137 138
138 139
139 140 Functions Deprecated in 6.x Development cycle
140 141 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141 142
142 143 - Loading extensions from ``ipython_extension_dir`` print a warning that this
143 144 location is pending deprecation. This should only affect users still having
144 145 extensions installed with ``%install_ext`` which has been deprecated since
145 146 IPython 4.0, and removed in 5.0. Extensions still present in
146 147 ``ipython_extension_dir`` may shadow more recently installed versions using
147 148 pip. It is thus recommended to clean ``ipython_extension_dir`` of any
148 149 extension now available as a package.
149 150
150 151
151 152 - ``IPython.utils.warn`` was deprecated in IPython 4.0, and has now been removed.
152 153 instead of ``IPython.utils.warn`` inbuilt :any:`warnings` module is used.
153 154
154 155
155 156 - The function `IPython.core.oinspect.py:call_tip` is unused, was marked as
156 157 Deprecated (raising a Deprecation Warning) and marked for later removal
157 158 :ghpull:`10104`
158 159
159 160 Backwards incompatible changes
160 161 ------------------------------
161 162
162 163 Functions Removed in 6.x Development cycle
163 164 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
164 165
165 166 The following functions have been removed in the
166 167 development cycle marked for Milestone 6.0.
167 168
168 169 - ``IPython/utils/process.py`` - ``is_cmd_found``
169 170 - ``IPython/utils/process.py`` - ``pycmd2argv``
170 171
171 172 - The `--deep-reload` flag and the corresponding options to inject `dreload` or
172 173 `reload` into the interactive namespace have been removed. You have to
173 174 explicitly import `reload` from `IPython.lib.deepreload` to use it.
174 175
175 176 .. DO NOT EDIT THIS LINE BEFORE RELEASE. INCOMPAT INSERTION POINT.
General Comments 0
You need to be logged in to leave comments. Login now