##// END OF EJS Templates
ENH: support for `PySide6` in `%gui` (#13864)...
Matthias Bussonnier -
r28120:0374cf80 merge
parent child Browse files
Show More
@@ -0,0 +1,50 b''
1 import os
2 import importlib
3
4 import pytest
5
6 from IPython.terminal.pt_inputhooks import set_qt_api, get_inputhook_name_and_func
7
8
9 guis_avail = []
10
11
12 def _get_qt_vers():
13 """If any version of Qt is available, this will populate `guis_avail` with 'qt' and 'qtx'. Due
14 to the import mechanism, we can't import multiple versions of Qt in one session."""
15 for gui in ["qt", "qt6", "qt5"]:
16 print(f"Trying {gui}")
17 try:
18 set_qt_api(gui)
19 importlib.import_module("IPython.terminal.pt_inputhooks.qt")
20 guis_avail.append(gui)
21 if "QT_API" in os.environ.keys():
22 del os.environ["QT_API"]
23 except ImportError:
24 pass # that version of Qt isn't available.
25 except RuntimeError:
26 pass # the version of IPython doesn't know what to do with this Qt version.
27
28
29 _get_qt_vers()
30
31
32 @pytest.mark.skipif(
33 len(guis_avail) == 0, reason="No viable version of PyQt or PySide installed."
34 )
35 def test_inputhook_qt():
36 gui = guis_avail[0]
37
38 # Choose a qt version and get the input hook function. This will import Qt...
39 get_inputhook_name_and_func(gui)
40
41 # ...and now we're stuck with this version of Qt for good; can't switch.
42 for not_gui in ["qt6", "qt5"]:
43 if not_gui not in guis_avail:
44 break
45
46 with pytest.raises(ImportError):
47 get_inputhook_name_and_func(not_gui)
48
49 # A gui of 'qt' means "best available", or in this case, the last one that was used.
50 get_inputhook_name_and_func("qt")
@@ -1,661 +1,663 b''
1 """Implementation of basic magic functions."""
1 """Implementation of basic magic functions."""
2
2
3
3
4 from logging import error
4 from logging import error
5 import io
5 import io
6 import os
6 import os
7 from pprint import pformat
7 from pprint import pformat
8 import sys
8 import sys
9 from warnings import warn
9 from warnings import warn
10
10
11 from traitlets.utils.importstring import import_item
11 from traitlets.utils.importstring import import_item
12 from IPython.core import magic_arguments, page
12 from IPython.core import magic_arguments, page
13 from IPython.core.error import UsageError
13 from IPython.core.error import UsageError
14 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
14 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
15 from IPython.utils.text import format_screen, dedent, indent
15 from IPython.utils.text import format_screen, dedent, indent
16 from IPython.testing.skipdoctest import skip_doctest
16 from IPython.testing.skipdoctest import skip_doctest
17 from IPython.utils.ipstruct import Struct
17 from IPython.utils.ipstruct import Struct
18
18
19
19
20 class MagicsDisplay(object):
20 class MagicsDisplay(object):
21 def __init__(self, magics_manager, ignore=None):
21 def __init__(self, magics_manager, ignore=None):
22 self.ignore = ignore if ignore else []
22 self.ignore = ignore if ignore else []
23 self.magics_manager = magics_manager
23 self.magics_manager = magics_manager
24
24
25 def _lsmagic(self):
25 def _lsmagic(self):
26 """The main implementation of the %lsmagic"""
26 """The main implementation of the %lsmagic"""
27 mesc = magic_escapes['line']
27 mesc = magic_escapes['line']
28 cesc = magic_escapes['cell']
28 cesc = magic_escapes['cell']
29 mman = self.magics_manager
29 mman = self.magics_manager
30 magics = mman.lsmagic()
30 magics = mman.lsmagic()
31 out = ['Available line magics:',
31 out = ['Available line magics:',
32 mesc + (' '+mesc).join(sorted([m for m,v in magics['line'].items() if (v not in self.ignore)])),
32 mesc + (' '+mesc).join(sorted([m for m,v in magics['line'].items() if (v not in self.ignore)])),
33 '',
33 '',
34 'Available cell magics:',
34 'Available cell magics:',
35 cesc + (' '+cesc).join(sorted([m for m,v in magics['cell'].items() if (v not in self.ignore)])),
35 cesc + (' '+cesc).join(sorted([m for m,v in magics['cell'].items() if (v not in self.ignore)])),
36 '',
36 '',
37 mman.auto_status()]
37 mman.auto_status()]
38 return '\n'.join(out)
38 return '\n'.join(out)
39
39
40 def _repr_pretty_(self, p, cycle):
40 def _repr_pretty_(self, p, cycle):
41 p.text(self._lsmagic())
41 p.text(self._lsmagic())
42
42
43 def __str__(self):
43 def __str__(self):
44 return self._lsmagic()
44 return self._lsmagic()
45
45
46 def _jsonable(self):
46 def _jsonable(self):
47 """turn magics dict into jsonable dict of the same structure
47 """turn magics dict into jsonable dict of the same structure
48
48
49 replaces object instances with their class names as strings
49 replaces object instances with their class names as strings
50 """
50 """
51 magic_dict = {}
51 magic_dict = {}
52 mman = self.magics_manager
52 mman = self.magics_manager
53 magics = mman.lsmagic()
53 magics = mman.lsmagic()
54 for key, subdict in magics.items():
54 for key, subdict in magics.items():
55 d = {}
55 d = {}
56 magic_dict[key] = d
56 magic_dict[key] = d
57 for name, obj in subdict.items():
57 for name, obj in subdict.items():
58 try:
58 try:
59 classname = obj.__self__.__class__.__name__
59 classname = obj.__self__.__class__.__name__
60 except AttributeError:
60 except AttributeError:
61 classname = 'Other'
61 classname = 'Other'
62
62
63 d[name] = classname
63 d[name] = classname
64 return magic_dict
64 return magic_dict
65
65
66 def _repr_json_(self):
66 def _repr_json_(self):
67 return self._jsonable()
67 return self._jsonable()
68
68
69
69
70 @magics_class
70 @magics_class
71 class BasicMagics(Magics):
71 class BasicMagics(Magics):
72 """Magics that provide central IPython functionality.
72 """Magics that provide central IPython functionality.
73
73
74 These are various magics that don't fit into specific categories but that
74 These are various magics that don't fit into specific categories but that
75 are all part of the base 'IPython experience'."""
75 are all part of the base 'IPython experience'."""
76
76
77 @skip_doctest
77 @skip_doctest
78 @magic_arguments.magic_arguments()
78 @magic_arguments.magic_arguments()
79 @magic_arguments.argument(
79 @magic_arguments.argument(
80 '-l', '--line', action='store_true',
80 '-l', '--line', action='store_true',
81 help="""Create a line magic alias."""
81 help="""Create a line magic alias."""
82 )
82 )
83 @magic_arguments.argument(
83 @magic_arguments.argument(
84 '-c', '--cell', action='store_true',
84 '-c', '--cell', action='store_true',
85 help="""Create a cell magic alias."""
85 help="""Create a cell magic alias."""
86 )
86 )
87 @magic_arguments.argument(
87 @magic_arguments.argument(
88 'name',
88 'name',
89 help="""Name of the magic to be created."""
89 help="""Name of the magic to be created."""
90 )
90 )
91 @magic_arguments.argument(
91 @magic_arguments.argument(
92 'target',
92 'target',
93 help="""Name of the existing line or cell magic."""
93 help="""Name of the existing line or cell magic."""
94 )
94 )
95 @magic_arguments.argument(
95 @magic_arguments.argument(
96 '-p', '--params', default=None,
96 '-p', '--params', default=None,
97 help="""Parameters passed to the magic function."""
97 help="""Parameters passed to the magic function."""
98 )
98 )
99 @line_magic
99 @line_magic
100 def alias_magic(self, line=''):
100 def alias_magic(self, line=''):
101 """Create an alias for an existing line or cell magic.
101 """Create an alias for an existing line or cell magic.
102
102
103 Examples
103 Examples
104 --------
104 --------
105 ::
105 ::
106
106
107 In [1]: %alias_magic t timeit
107 In [1]: %alias_magic t timeit
108 Created `%t` as an alias for `%timeit`.
108 Created `%t` as an alias for `%timeit`.
109 Created `%%t` as an alias for `%%timeit`.
109 Created `%%t` as an alias for `%%timeit`.
110
110
111 In [2]: %t -n1 pass
111 In [2]: %t -n1 pass
112 1 loops, best of 3: 954 ns per loop
112 1 loops, best of 3: 954 ns per loop
113
113
114 In [3]: %%t -n1
114 In [3]: %%t -n1
115 ...: pass
115 ...: pass
116 ...:
116 ...:
117 1 loops, best of 3: 954 ns per loop
117 1 loops, best of 3: 954 ns per loop
118
118
119 In [4]: %alias_magic --cell whereami pwd
119 In [4]: %alias_magic --cell whereami pwd
120 UsageError: Cell magic function `%%pwd` not found.
120 UsageError: Cell magic function `%%pwd` not found.
121 In [5]: %alias_magic --line whereami pwd
121 In [5]: %alias_magic --line whereami pwd
122 Created `%whereami` as an alias for `%pwd`.
122 Created `%whereami` as an alias for `%pwd`.
123
123
124 In [6]: %whereami
124 In [6]: %whereami
125 Out[6]: u'/home/testuser'
125 Out[6]: u'/home/testuser'
126
126
127 In [7]: %alias_magic h history "-p -l 30" --line
127 In [7]: %alias_magic h history "-p -l 30" --line
128 Created `%h` as an alias for `%history -l 30`.
128 Created `%h` as an alias for `%history -l 30`.
129 """
129 """
130
130
131 args = magic_arguments.parse_argstring(self.alias_magic, line)
131 args = magic_arguments.parse_argstring(self.alias_magic, line)
132 shell = self.shell
132 shell = self.shell
133 mman = self.shell.magics_manager
133 mman = self.shell.magics_manager
134 escs = ''.join(magic_escapes.values())
134 escs = ''.join(magic_escapes.values())
135
135
136 target = args.target.lstrip(escs)
136 target = args.target.lstrip(escs)
137 name = args.name.lstrip(escs)
137 name = args.name.lstrip(escs)
138
138
139 params = args.params
139 params = args.params
140 if (params and
140 if (params and
141 ((params.startswith('"') and params.endswith('"'))
141 ((params.startswith('"') and params.endswith('"'))
142 or (params.startswith("'") and params.endswith("'")))):
142 or (params.startswith("'") and params.endswith("'")))):
143 params = params[1:-1]
143 params = params[1:-1]
144
144
145 # Find the requested magics.
145 # Find the requested magics.
146 m_line = shell.find_magic(target, 'line')
146 m_line = shell.find_magic(target, 'line')
147 m_cell = shell.find_magic(target, 'cell')
147 m_cell = shell.find_magic(target, 'cell')
148 if args.line and m_line is None:
148 if args.line and m_line is None:
149 raise UsageError('Line magic function `%s%s` not found.' %
149 raise UsageError('Line magic function `%s%s` not found.' %
150 (magic_escapes['line'], target))
150 (magic_escapes['line'], target))
151 if args.cell and m_cell is None:
151 if args.cell and m_cell is None:
152 raise UsageError('Cell magic function `%s%s` not found.' %
152 raise UsageError('Cell magic function `%s%s` not found.' %
153 (magic_escapes['cell'], target))
153 (magic_escapes['cell'], target))
154
154
155 # If --line and --cell are not specified, default to the ones
155 # If --line and --cell are not specified, default to the ones
156 # that are available.
156 # that are available.
157 if not args.line and not args.cell:
157 if not args.line and not args.cell:
158 if not m_line and not m_cell:
158 if not m_line and not m_cell:
159 raise UsageError(
159 raise UsageError(
160 'No line or cell magic with name `%s` found.' % target
160 'No line or cell magic with name `%s` found.' % target
161 )
161 )
162 args.line = bool(m_line)
162 args.line = bool(m_line)
163 args.cell = bool(m_cell)
163 args.cell = bool(m_cell)
164
164
165 params_str = "" if params is None else " " + params
165 params_str = "" if params is None else " " + params
166
166
167 if args.line:
167 if args.line:
168 mman.register_alias(name, target, 'line', params)
168 mman.register_alias(name, target, 'line', params)
169 print('Created `%s%s` as an alias for `%s%s%s`.' % (
169 print('Created `%s%s` as an alias for `%s%s%s`.' % (
170 magic_escapes['line'], name,
170 magic_escapes['line'], name,
171 magic_escapes['line'], target, params_str))
171 magic_escapes['line'], target, params_str))
172
172
173 if args.cell:
173 if args.cell:
174 mman.register_alias(name, target, 'cell', params)
174 mman.register_alias(name, target, 'cell', params)
175 print('Created `%s%s` as an alias for `%s%s%s`.' % (
175 print('Created `%s%s` as an alias for `%s%s%s`.' % (
176 magic_escapes['cell'], name,
176 magic_escapes['cell'], name,
177 magic_escapes['cell'], target, params_str))
177 magic_escapes['cell'], target, params_str))
178
178
179 @line_magic
179 @line_magic
180 def lsmagic(self, parameter_s=''):
180 def lsmagic(self, parameter_s=''):
181 """List currently available magic functions."""
181 """List currently available magic functions."""
182 return MagicsDisplay(self.shell.magics_manager, ignore=[])
182 return MagicsDisplay(self.shell.magics_manager, ignore=[])
183
183
184 def _magic_docs(self, brief=False, rest=False):
184 def _magic_docs(self, brief=False, rest=False):
185 """Return docstrings from magic functions."""
185 """Return docstrings from magic functions."""
186 mman = self.shell.magics_manager
186 mman = self.shell.magics_manager
187 docs = mman.lsmagic_docs(brief, missing='No documentation')
187 docs = mman.lsmagic_docs(brief, missing='No documentation')
188
188
189 if rest:
189 if rest:
190 format_string = '**%s%s**::\n\n%s\n\n'
190 format_string = '**%s%s**::\n\n%s\n\n'
191 else:
191 else:
192 format_string = '%s%s:\n%s\n'
192 format_string = '%s%s:\n%s\n'
193
193
194 return ''.join(
194 return ''.join(
195 [format_string % (magic_escapes['line'], fname,
195 [format_string % (magic_escapes['line'], fname,
196 indent(dedent(fndoc)))
196 indent(dedent(fndoc)))
197 for fname, fndoc in sorted(docs['line'].items())]
197 for fname, fndoc in sorted(docs['line'].items())]
198 +
198 +
199 [format_string % (magic_escapes['cell'], fname,
199 [format_string % (magic_escapes['cell'], fname,
200 indent(dedent(fndoc)))
200 indent(dedent(fndoc)))
201 for fname, fndoc in sorted(docs['cell'].items())]
201 for fname, fndoc in sorted(docs['cell'].items())]
202 )
202 )
203
203
204 @line_magic
204 @line_magic
205 def magic(self, parameter_s=''):
205 def magic(self, parameter_s=''):
206 """Print information about the magic function system.
206 """Print information about the magic function system.
207
207
208 Supported formats: -latex, -brief, -rest
208 Supported formats: -latex, -brief, -rest
209 """
209 """
210
210
211 mode = ''
211 mode = ''
212 try:
212 try:
213 mode = parameter_s.split()[0][1:]
213 mode = parameter_s.split()[0][1:]
214 except IndexError:
214 except IndexError:
215 pass
215 pass
216
216
217 brief = (mode == 'brief')
217 brief = (mode == 'brief')
218 rest = (mode == 'rest')
218 rest = (mode == 'rest')
219 magic_docs = self._magic_docs(brief, rest)
219 magic_docs = self._magic_docs(brief, rest)
220
220
221 if mode == 'latex':
221 if mode == 'latex':
222 print(self.format_latex(magic_docs))
222 print(self.format_latex(magic_docs))
223 return
223 return
224 else:
224 else:
225 magic_docs = format_screen(magic_docs)
225 magic_docs = format_screen(magic_docs)
226
226
227 out = ["""
227 out = ["""
228 IPython's 'magic' functions
228 IPython's 'magic' functions
229 ===========================
229 ===========================
230
230
231 The magic function system provides a series of functions which allow you to
231 The magic function system provides a series of functions which allow you to
232 control the behavior of IPython itself, plus a lot of system-type
232 control the behavior of IPython itself, plus a lot of system-type
233 features. There are two kinds of magics, line-oriented and cell-oriented.
233 features. There are two kinds of magics, line-oriented and cell-oriented.
234
234
235 Line magics are prefixed with the % character and work much like OS
235 Line magics are prefixed with the % character and work much like OS
236 command-line calls: they get as an argument the rest of the line, where
236 command-line calls: they get as an argument the rest of the line, where
237 arguments are passed without parentheses or quotes. For example, this will
237 arguments are passed without parentheses or quotes. For example, this will
238 time the given statement::
238 time the given statement::
239
239
240 %timeit range(1000)
240 %timeit range(1000)
241
241
242 Cell magics are prefixed with a double %%, and they are functions that get as
242 Cell magics are prefixed with a double %%, and they are functions that get as
243 an argument not only the rest of the line, but also the lines below it in a
243 an argument not only the rest of the line, but also the lines below it in a
244 separate argument. These magics are called with two arguments: the rest of the
244 separate argument. These magics are called with two arguments: the rest of the
245 call line and the body of the cell, consisting of the lines below the first.
245 call line and the body of the cell, consisting of the lines below the first.
246 For example::
246 For example::
247
247
248 %%timeit x = numpy.random.randn((100, 100))
248 %%timeit x = numpy.random.randn((100, 100))
249 numpy.linalg.svd(x)
249 numpy.linalg.svd(x)
250
250
251 will time the execution of the numpy svd routine, running the assignment of x
251 will time the execution of the numpy svd routine, running the assignment of x
252 as part of the setup phase, which is not timed.
252 as part of the setup phase, which is not timed.
253
253
254 In a line-oriented client (the terminal or Qt console IPython), starting a new
254 In a line-oriented client (the terminal or Qt console IPython), starting a new
255 input with %% will automatically enter cell mode, and IPython will continue
255 input with %% will automatically enter cell mode, and IPython will continue
256 reading input until a blank line is given. In the notebook, simply type the
256 reading input until a blank line is given. In the notebook, simply type the
257 whole cell as one entity, but keep in mind that the %% escape can only be at
257 whole cell as one entity, but keep in mind that the %% escape can only be at
258 the very start of the cell.
258 the very start of the cell.
259
259
260 NOTE: If you have 'automagic' enabled (via the command line option or with the
260 NOTE: If you have 'automagic' enabled (via the command line option or with the
261 %automagic function), you don't need to type in the % explicitly for line
261 %automagic function), you don't need to type in the % explicitly for line
262 magics; cell magics always require an explicit '%%' escape. By default,
262 magics; cell magics always require an explicit '%%' escape. By default,
263 IPython ships with automagic on, so you should only rarely need the % escape.
263 IPython ships with automagic on, so you should only rarely need the % escape.
264
264
265 Example: typing '%cd mydir' (without the quotes) changes your working directory
265 Example: typing '%cd mydir' (without the quotes) changes your working directory
266 to 'mydir', if it exists.
266 to 'mydir', if it exists.
267
267
268 For a list of the available magic functions, use %lsmagic. For a description
268 For a list of the available magic functions, use %lsmagic. For a description
269 of any of them, type %magic_name?, e.g. '%cd?'.
269 of any of them, type %magic_name?, e.g. '%cd?'.
270
270
271 Currently the magic system has the following functions:""",
271 Currently the magic system has the following functions:""",
272 magic_docs,
272 magic_docs,
273 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
273 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
274 str(self.lsmagic()),
274 str(self.lsmagic()),
275 ]
275 ]
276 page.page('\n'.join(out))
276 page.page('\n'.join(out))
277
277
278
278
279 @line_magic
279 @line_magic
280 def page(self, parameter_s=''):
280 def page(self, parameter_s=''):
281 """Pretty print the object and display it through a pager.
281 """Pretty print the object and display it through a pager.
282
282
283 %page [options] OBJECT
283 %page [options] OBJECT
284
284
285 If no object is given, use _ (last output).
285 If no object is given, use _ (last output).
286
286
287 Options:
287 Options:
288
288
289 -r: page str(object), don't pretty-print it."""
289 -r: page str(object), don't pretty-print it."""
290
290
291 # After a function contributed by Olivier Aubert, slightly modified.
291 # After a function contributed by Olivier Aubert, slightly modified.
292
292
293 # Process options/args
293 # Process options/args
294 opts, args = self.parse_options(parameter_s, 'r')
294 opts, args = self.parse_options(parameter_s, 'r')
295 raw = 'r' in opts
295 raw = 'r' in opts
296
296
297 oname = args and args or '_'
297 oname = args and args or '_'
298 info = self.shell._ofind(oname)
298 info = self.shell._ofind(oname)
299 if info['found']:
299 if info['found']:
300 if raw:
300 if raw:
301 txt = str(info["obj"])
301 txt = str(info["obj"])
302 else:
302 else:
303 txt = pformat(info["obj"])
303 txt = pformat(info["obj"])
304 page.page(txt)
304 page.page(txt)
305 else:
305 else:
306 print('Object `%s` not found' % oname)
306 print('Object `%s` not found' % oname)
307
307
308 @line_magic
308 @line_magic
309 def pprint(self, parameter_s=''):
309 def pprint(self, parameter_s=''):
310 """Toggle pretty printing on/off."""
310 """Toggle pretty printing on/off."""
311 ptformatter = self.shell.display_formatter.formatters['text/plain']
311 ptformatter = self.shell.display_formatter.formatters['text/plain']
312 ptformatter.pprint = bool(1 - ptformatter.pprint)
312 ptformatter.pprint = bool(1 - ptformatter.pprint)
313 print('Pretty printing has been turned',
313 print('Pretty printing has been turned',
314 ['OFF','ON'][ptformatter.pprint])
314 ['OFF','ON'][ptformatter.pprint])
315
315
316 @line_magic
316 @line_magic
317 def colors(self, parameter_s=''):
317 def colors(self, parameter_s=''):
318 """Switch color scheme for prompts, info system and exception handlers.
318 """Switch color scheme for prompts, info system and exception handlers.
319
319
320 Currently implemented schemes: NoColor, Linux, LightBG.
320 Currently implemented schemes: NoColor, Linux, LightBG.
321
321
322 Color scheme names are not case-sensitive.
322 Color scheme names are not case-sensitive.
323
323
324 Examples
324 Examples
325 --------
325 --------
326 To get a plain black and white terminal::
326 To get a plain black and white terminal::
327
327
328 %colors nocolor
328 %colors nocolor
329 """
329 """
330 def color_switch_err(name):
330 def color_switch_err(name):
331 warn('Error changing %s color schemes.\n%s' %
331 warn('Error changing %s color schemes.\n%s' %
332 (name, sys.exc_info()[1]), stacklevel=2)
332 (name, sys.exc_info()[1]), stacklevel=2)
333
333
334
334
335 new_scheme = parameter_s.strip()
335 new_scheme = parameter_s.strip()
336 if not new_scheme:
336 if not new_scheme:
337 raise UsageError(
337 raise UsageError(
338 "%colors: you must specify a color scheme. See '%colors?'")
338 "%colors: you must specify a color scheme. See '%colors?'")
339 # local shortcut
339 # local shortcut
340 shell = self.shell
340 shell = self.shell
341
341
342 # Set shell colour scheme
342 # Set shell colour scheme
343 try:
343 try:
344 shell.colors = new_scheme
344 shell.colors = new_scheme
345 shell.refresh_style()
345 shell.refresh_style()
346 except:
346 except:
347 color_switch_err('shell')
347 color_switch_err('shell')
348
348
349 # Set exception colors
349 # Set exception colors
350 try:
350 try:
351 shell.InteractiveTB.set_colors(scheme = new_scheme)
351 shell.InteractiveTB.set_colors(scheme = new_scheme)
352 shell.SyntaxTB.set_colors(scheme = new_scheme)
352 shell.SyntaxTB.set_colors(scheme = new_scheme)
353 except:
353 except:
354 color_switch_err('exception')
354 color_switch_err('exception')
355
355
356 # Set info (for 'object?') colors
356 # Set info (for 'object?') colors
357 if shell.color_info:
357 if shell.color_info:
358 try:
358 try:
359 shell.inspector.set_active_scheme(new_scheme)
359 shell.inspector.set_active_scheme(new_scheme)
360 except:
360 except:
361 color_switch_err('object inspector')
361 color_switch_err('object inspector')
362 else:
362 else:
363 shell.inspector.set_active_scheme('NoColor')
363 shell.inspector.set_active_scheme('NoColor')
364
364
365 @line_magic
365 @line_magic
366 def xmode(self, parameter_s=''):
366 def xmode(self, parameter_s=''):
367 """Switch modes for the exception handlers.
367 """Switch modes for the exception handlers.
368
368
369 Valid modes: Plain, Context, Verbose, and Minimal.
369 Valid modes: Plain, Context, Verbose, and Minimal.
370
370
371 If called without arguments, acts as a toggle.
371 If called without arguments, acts as a toggle.
372
372
373 When in verbose mode the value `--show` (and `--hide`)
373 When in verbose mode the value `--show` (and `--hide`)
374 will respectively show (or hide) frames with ``__tracebackhide__ =
374 will respectively show (or hide) frames with ``__tracebackhide__ =
375 True`` value set.
375 True`` value set.
376 """
376 """
377
377
378 def xmode_switch_err(name):
378 def xmode_switch_err(name):
379 warn('Error changing %s exception modes.\n%s' %
379 warn('Error changing %s exception modes.\n%s' %
380 (name,sys.exc_info()[1]))
380 (name,sys.exc_info()[1]))
381
381
382 shell = self.shell
382 shell = self.shell
383 if parameter_s.strip() == "--show":
383 if parameter_s.strip() == "--show":
384 shell.InteractiveTB.skip_hidden = False
384 shell.InteractiveTB.skip_hidden = False
385 return
385 return
386 if parameter_s.strip() == "--hide":
386 if parameter_s.strip() == "--hide":
387 shell.InteractiveTB.skip_hidden = True
387 shell.InteractiveTB.skip_hidden = True
388 return
388 return
389
389
390 new_mode = parameter_s.strip().capitalize()
390 new_mode = parameter_s.strip().capitalize()
391 try:
391 try:
392 shell.InteractiveTB.set_mode(mode=new_mode)
392 shell.InteractiveTB.set_mode(mode=new_mode)
393 print('Exception reporting mode:',shell.InteractiveTB.mode)
393 print('Exception reporting mode:',shell.InteractiveTB.mode)
394 except:
394 except:
395 xmode_switch_err('user')
395 xmode_switch_err('user')
396
396
397 @line_magic
397 @line_magic
398 def quickref(self, arg):
398 def quickref(self, arg):
399 """ Show a quick reference sheet """
399 """ Show a quick reference sheet """
400 from IPython.core.usage import quick_reference
400 from IPython.core.usage import quick_reference
401 qr = quick_reference + self._magic_docs(brief=True)
401 qr = quick_reference + self._magic_docs(brief=True)
402 page.page(qr)
402 page.page(qr)
403
403
404 @line_magic
404 @line_magic
405 def doctest_mode(self, parameter_s=''):
405 def doctest_mode(self, parameter_s=''):
406 """Toggle doctest mode on and off.
406 """Toggle doctest mode on and off.
407
407
408 This mode is intended to make IPython behave as much as possible like a
408 This mode is intended to make IPython behave as much as possible like a
409 plain Python shell, from the perspective of how its prompts, exceptions
409 plain Python shell, from the perspective of how its prompts, exceptions
410 and output look. This makes it easy to copy and paste parts of a
410 and output look. This makes it easy to copy and paste parts of a
411 session into doctests. It does so by:
411 session into doctests. It does so by:
412
412
413 - Changing the prompts to the classic ``>>>`` ones.
413 - Changing the prompts to the classic ``>>>`` ones.
414 - Changing the exception reporting mode to 'Plain'.
414 - Changing the exception reporting mode to 'Plain'.
415 - Disabling pretty-printing of output.
415 - Disabling pretty-printing of output.
416
416
417 Note that IPython also supports the pasting of code snippets that have
417 Note that IPython also supports the pasting of code snippets that have
418 leading '>>>' and '...' prompts in them. This means that you can paste
418 leading '>>>' and '...' prompts in them. This means that you can paste
419 doctests from files or docstrings (even if they have leading
419 doctests from files or docstrings (even if they have leading
420 whitespace), and the code will execute correctly. You can then use
420 whitespace), and the code will execute correctly. You can then use
421 '%history -t' to see the translated history; this will give you the
421 '%history -t' to see the translated history; this will give you the
422 input after removal of all the leading prompts and whitespace, which
422 input after removal of all the leading prompts and whitespace, which
423 can be pasted back into an editor.
423 can be pasted back into an editor.
424
424
425 With these features, you can switch into this mode easily whenever you
425 With these features, you can switch into this mode easily whenever you
426 need to do testing and changes to doctests, without having to leave
426 need to do testing and changes to doctests, without having to leave
427 your existing IPython session.
427 your existing IPython session.
428 """
428 """
429
429
430 # Shorthands
430 # Shorthands
431 shell = self.shell
431 shell = self.shell
432 meta = shell.meta
432 meta = shell.meta
433 disp_formatter = self.shell.display_formatter
433 disp_formatter = self.shell.display_formatter
434 ptformatter = disp_formatter.formatters['text/plain']
434 ptformatter = disp_formatter.formatters['text/plain']
435 # dstore is a data store kept in the instance metadata bag to track any
435 # dstore is a data store kept in the instance metadata bag to track any
436 # changes we make, so we can undo them later.
436 # changes we make, so we can undo them later.
437 dstore = meta.setdefault('doctest_mode',Struct())
437 dstore = meta.setdefault('doctest_mode',Struct())
438 save_dstore = dstore.setdefault
438 save_dstore = dstore.setdefault
439
439
440 # save a few values we'll need to recover later
440 # save a few values we'll need to recover later
441 mode = save_dstore('mode',False)
441 mode = save_dstore('mode',False)
442 save_dstore('rc_pprint',ptformatter.pprint)
442 save_dstore('rc_pprint',ptformatter.pprint)
443 save_dstore('xmode',shell.InteractiveTB.mode)
443 save_dstore('xmode',shell.InteractiveTB.mode)
444 save_dstore('rc_separate_out',shell.separate_out)
444 save_dstore('rc_separate_out',shell.separate_out)
445 save_dstore('rc_separate_out2',shell.separate_out2)
445 save_dstore('rc_separate_out2',shell.separate_out2)
446 save_dstore('rc_separate_in',shell.separate_in)
446 save_dstore('rc_separate_in',shell.separate_in)
447 save_dstore('rc_active_types',disp_formatter.active_types)
447 save_dstore('rc_active_types',disp_formatter.active_types)
448
448
449 if not mode:
449 if not mode:
450 # turn on
450 # turn on
451
451
452 # Prompt separators like plain python
452 # Prompt separators like plain python
453 shell.separate_in = ''
453 shell.separate_in = ''
454 shell.separate_out = ''
454 shell.separate_out = ''
455 shell.separate_out2 = ''
455 shell.separate_out2 = ''
456
456
457
457
458 ptformatter.pprint = False
458 ptformatter.pprint = False
459 disp_formatter.active_types = ['text/plain']
459 disp_formatter.active_types = ['text/plain']
460
460
461 shell.magic('xmode Plain')
461 shell.magic('xmode Plain')
462 else:
462 else:
463 # turn off
463 # turn off
464 shell.separate_in = dstore.rc_separate_in
464 shell.separate_in = dstore.rc_separate_in
465
465
466 shell.separate_out = dstore.rc_separate_out
466 shell.separate_out = dstore.rc_separate_out
467 shell.separate_out2 = dstore.rc_separate_out2
467 shell.separate_out2 = dstore.rc_separate_out2
468
468
469 ptformatter.pprint = dstore.rc_pprint
469 ptformatter.pprint = dstore.rc_pprint
470 disp_formatter.active_types = dstore.rc_active_types
470 disp_formatter.active_types = dstore.rc_active_types
471
471
472 shell.magic('xmode ' + dstore.xmode)
472 shell.magic('xmode ' + dstore.xmode)
473
473
474 # mode here is the state before we switch; switch_doctest_mode takes
474 # mode here is the state before we switch; switch_doctest_mode takes
475 # the mode we're switching to.
475 # the mode we're switching to.
476 shell.switch_doctest_mode(not mode)
476 shell.switch_doctest_mode(not mode)
477
477
478 # Store new mode and inform
478 # Store new mode and inform
479 dstore.mode = bool(not mode)
479 dstore.mode = bool(not mode)
480 mode_label = ['OFF','ON'][dstore.mode]
480 mode_label = ['OFF','ON'][dstore.mode]
481 print('Doctest mode is:', mode_label)
481 print('Doctest mode is:', mode_label)
482
482
483 @line_magic
483 @line_magic
484 def gui(self, parameter_s=''):
484 def gui(self, parameter_s=''):
485 """Enable or disable IPython GUI event loop integration.
485 """Enable or disable IPython GUI event loop integration.
486
486
487 %gui [GUINAME]
487 %gui [GUINAME]
488
488
489 This magic replaces IPython's threaded shells that were activated
489 This magic replaces IPython's threaded shells that were activated
490 using the (pylab/wthread/etc.) command line flags. GUI toolkits
490 using the (pylab/wthread/etc.) command line flags. GUI toolkits
491 can now be enabled at runtime and keyboard
491 can now be enabled at runtime and keyboard
492 interrupts should work without any problems. The following toolkits
492 interrupts should work without any problems. The following toolkits
493 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
493 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
494
494
495 %gui wx # enable wxPython event loop integration
495 %gui wx # enable wxPython event loop integration
496 %gui qt4|qt # enable PyQt4 event loop integration
496 %gui qt # enable PyQt/PySide event loop integration
497 %gui qt5 # enable PyQt5 event loop integration
497 # with the latest version available.
498 %gui qt6 # enable PyQt6/PySide6 event loop integration
499 %gui qt5 # enable PyQt5/PySide2 event loop integration
498 %gui gtk # enable PyGTK event loop integration
500 %gui gtk # enable PyGTK event loop integration
499 %gui gtk3 # enable Gtk3 event loop integration
501 %gui gtk3 # enable Gtk3 event loop integration
500 %gui gtk4 # enable Gtk4 event loop integration
502 %gui gtk4 # enable Gtk4 event loop integration
501 %gui tk # enable Tk event loop integration
503 %gui tk # enable Tk event loop integration
502 %gui osx # enable Cocoa event loop integration
504 %gui osx # enable Cocoa event loop integration
503 # (requires %matplotlib 1.1)
505 # (requires %matplotlib 1.1)
504 %gui # disable all event loop integration
506 %gui # disable all event loop integration
505
507
506 WARNING: after any of these has been called you can simply create
508 WARNING: after any of these has been called you can simply create
507 an application object, but DO NOT start the event loop yourself, as
509 an application object, but DO NOT start the event loop yourself, as
508 we have already handled that.
510 we have already handled that.
509 """
511 """
510 opts, arg = self.parse_options(parameter_s, '')
512 opts, arg = self.parse_options(parameter_s, '')
511 if arg=='': arg = None
513 if arg=='': arg = None
512 try:
514 try:
513 return self.shell.enable_gui(arg)
515 return self.shell.enable_gui(arg)
514 except Exception as e:
516 except Exception as e:
515 # print simple error message, rather than traceback if we can't
517 # print simple error message, rather than traceback if we can't
516 # hook up the GUI
518 # hook up the GUI
517 error(str(e))
519 error(str(e))
518
520
519 @skip_doctest
521 @skip_doctest
520 @line_magic
522 @line_magic
521 def precision(self, s=''):
523 def precision(self, s=''):
522 """Set floating point precision for pretty printing.
524 """Set floating point precision for pretty printing.
523
525
524 Can set either integer precision or a format string.
526 Can set either integer precision or a format string.
525
527
526 If numpy has been imported and precision is an int,
528 If numpy has been imported and precision is an int,
527 numpy display precision will also be set, via ``numpy.set_printoptions``.
529 numpy display precision will also be set, via ``numpy.set_printoptions``.
528
530
529 If no argument is given, defaults will be restored.
531 If no argument is given, defaults will be restored.
530
532
531 Examples
533 Examples
532 --------
534 --------
533 ::
535 ::
534
536
535 In [1]: from math import pi
537 In [1]: from math import pi
536
538
537 In [2]: %precision 3
539 In [2]: %precision 3
538 Out[2]: u'%.3f'
540 Out[2]: u'%.3f'
539
541
540 In [3]: pi
542 In [3]: pi
541 Out[3]: 3.142
543 Out[3]: 3.142
542
544
543 In [4]: %precision %i
545 In [4]: %precision %i
544 Out[4]: u'%i'
546 Out[4]: u'%i'
545
547
546 In [5]: pi
548 In [5]: pi
547 Out[5]: 3
549 Out[5]: 3
548
550
549 In [6]: %precision %e
551 In [6]: %precision %e
550 Out[6]: u'%e'
552 Out[6]: u'%e'
551
553
552 In [7]: pi**10
554 In [7]: pi**10
553 Out[7]: 9.364805e+04
555 Out[7]: 9.364805e+04
554
556
555 In [8]: %precision
557 In [8]: %precision
556 Out[8]: u'%r'
558 Out[8]: u'%r'
557
559
558 In [9]: pi**10
560 In [9]: pi**10
559 Out[9]: 93648.047476082982
561 Out[9]: 93648.047476082982
560 """
562 """
561 ptformatter = self.shell.display_formatter.formatters['text/plain']
563 ptformatter = self.shell.display_formatter.formatters['text/plain']
562 ptformatter.float_precision = s
564 ptformatter.float_precision = s
563 return ptformatter.float_format
565 return ptformatter.float_format
564
566
565 @magic_arguments.magic_arguments()
567 @magic_arguments.magic_arguments()
566 @magic_arguments.argument(
568 @magic_arguments.argument(
567 'filename', type=str,
569 'filename', type=str,
568 help='Notebook name or filename'
570 help='Notebook name or filename'
569 )
571 )
570 @line_magic
572 @line_magic
571 def notebook(self, s):
573 def notebook(self, s):
572 """Export and convert IPython notebooks.
574 """Export and convert IPython notebooks.
573
575
574 This function can export the current IPython history to a notebook file.
576 This function can export the current IPython history to a notebook file.
575 For example, to export the history to "foo.ipynb" do "%notebook foo.ipynb".
577 For example, to export the history to "foo.ipynb" do "%notebook foo.ipynb".
576 """
578 """
577 args = magic_arguments.parse_argstring(self.notebook, s)
579 args = magic_arguments.parse_argstring(self.notebook, s)
578 outfname = os.path.expanduser(args.filename)
580 outfname = os.path.expanduser(args.filename)
579
581
580 from nbformat import write, v4
582 from nbformat import write, v4
581
583
582 cells = []
584 cells = []
583 hist = list(self.shell.history_manager.get_range())
585 hist = list(self.shell.history_manager.get_range())
584 if(len(hist)<=1):
586 if(len(hist)<=1):
585 raise ValueError('History is empty, cannot export')
587 raise ValueError('History is empty, cannot export')
586 for session, execution_count, source in hist[:-1]:
588 for session, execution_count, source in hist[:-1]:
587 cells.append(v4.new_code_cell(
589 cells.append(v4.new_code_cell(
588 execution_count=execution_count,
590 execution_count=execution_count,
589 source=source
591 source=source
590 ))
592 ))
591 nb = v4.new_notebook(cells=cells)
593 nb = v4.new_notebook(cells=cells)
592 with io.open(outfname, "w", encoding="utf-8") as f:
594 with io.open(outfname, "w", encoding="utf-8") as f:
593 write(nb, f, version=4)
595 write(nb, f, version=4)
594
596
595 @magics_class
597 @magics_class
596 class AsyncMagics(BasicMagics):
598 class AsyncMagics(BasicMagics):
597
599
598 @line_magic
600 @line_magic
599 def autoawait(self, parameter_s):
601 def autoawait(self, parameter_s):
600 """
602 """
601 Allow to change the status of the autoawait option.
603 Allow to change the status of the autoawait option.
602
604
603 This allow you to set a specific asynchronous code runner.
605 This allow you to set a specific asynchronous code runner.
604
606
605 If no value is passed, print the currently used asynchronous integration
607 If no value is passed, print the currently used asynchronous integration
606 and whether it is activated.
608 and whether it is activated.
607
609
608 It can take a number of value evaluated in the following order:
610 It can take a number of value evaluated in the following order:
609
611
610 - False/false/off deactivate autoawait integration
612 - False/false/off deactivate autoawait integration
611 - True/true/on activate autoawait integration using configured default
613 - True/true/on activate autoawait integration using configured default
612 loop
614 loop
613 - asyncio/curio/trio activate autoawait integration and use integration
615 - asyncio/curio/trio activate autoawait integration and use integration
614 with said library.
616 with said library.
615
617
616 - `sync` turn on the pseudo-sync integration (mostly used for
618 - `sync` turn on the pseudo-sync integration (mostly used for
617 `IPython.embed()` which does not run IPython with a real eventloop and
619 `IPython.embed()` which does not run IPython with a real eventloop and
618 deactivate running asynchronous code. Turning on Asynchronous code with
620 deactivate running asynchronous code. Turning on Asynchronous code with
619 the pseudo sync loop is undefined behavior and may lead IPython to crash.
621 the pseudo sync loop is undefined behavior and may lead IPython to crash.
620
622
621 If the passed parameter does not match any of the above and is a python
623 If the passed parameter does not match any of the above and is a python
622 identifier, get said object from user namespace and set it as the
624 identifier, get said object from user namespace and set it as the
623 runner, and activate autoawait.
625 runner, and activate autoawait.
624
626
625 If the object is a fully qualified object name, attempt to import it and
627 If the object is a fully qualified object name, attempt to import it and
626 set it as the runner, and activate autoawait.
628 set it as the runner, and activate autoawait.
627
629
628 The exact behavior of autoawait is experimental and subject to change
630 The exact behavior of autoawait is experimental and subject to change
629 across version of IPython and Python.
631 across version of IPython and Python.
630 """
632 """
631
633
632 param = parameter_s.strip()
634 param = parameter_s.strip()
633 d = {True: "on", False: "off"}
635 d = {True: "on", False: "off"}
634
636
635 if not param:
637 if not param:
636 print("IPython autoawait is `{}`, and set to use `{}`".format(
638 print("IPython autoawait is `{}`, and set to use `{}`".format(
637 d[self.shell.autoawait],
639 d[self.shell.autoawait],
638 self.shell.loop_runner
640 self.shell.loop_runner
639 ))
641 ))
640 return None
642 return None
641
643
642 if param.lower() in ('false', 'off'):
644 if param.lower() in ('false', 'off'):
643 self.shell.autoawait = False
645 self.shell.autoawait = False
644 return None
646 return None
645 if param.lower() in ('true', 'on'):
647 if param.lower() in ('true', 'on'):
646 self.shell.autoawait = True
648 self.shell.autoawait = True
647 return None
649 return None
648
650
649 if param in self.shell.loop_runner_map:
651 if param in self.shell.loop_runner_map:
650 self.shell.loop_runner, self.shell.autoawait = self.shell.loop_runner_map[param]
652 self.shell.loop_runner, self.shell.autoawait = self.shell.loop_runner_map[param]
651 return None
653 return None
652
654
653 if param in self.shell.user_ns :
655 if param in self.shell.user_ns :
654 self.shell.loop_runner = self.shell.user_ns[param]
656 self.shell.loop_runner = self.shell.user_ns[param]
655 self.shell.autoawait = True
657 self.shell.autoawait = True
656 return None
658 return None
657
659
658 runner = import_item(param)
660 runner = import_item(param)
659
661
660 self.shell.loop_runner = runner
662 self.shell.loop_runner = runner
661 self.shell.autoawait = True
663 self.shell.autoawait = True
@@ -1,128 +1,124 b''
1 """ Import Qt in a manner suitable for an IPython kernel.
1 """ Import Qt in a manner suitable for an IPython kernel.
2
2
3 This is the import used for the `gui=qt` or `matplotlib=qt` initialization.
3 This is the import used for the `gui=qt` or `matplotlib=qt` initialization.
4
4
5 Import Priority:
5 Import Priority:
6
6
7 if Qt has been imported anywhere else:
7 if Qt has been imported anywhere else:
8 use that
8 use that
9
9
10 if matplotlib has been imported and doesn't support v2 (<= 1.0.1):
10 if matplotlib has been imported and doesn't support v2 (<= 1.0.1):
11 use PyQt4 @v1
11 use PyQt4 @v1
12
12
13 Next, ask QT_API env variable
13 Next, ask QT_API env variable
14
14
15 if QT_API not set:
15 if QT_API not set:
16 ask matplotlib what it's using. If Qt4Agg or Qt5Agg, then use the
16 ask matplotlib what it's using. If Qt4Agg or Qt5Agg, then use the
17 version matplotlib is configured with
17 version matplotlib is configured with
18
18
19 else: (matplotlib said nothing)
19 else: (matplotlib said nothing)
20 # this is the default path - nobody told us anything
20 # this is the default path - nobody told us anything
21 try in this order:
21 try in this order:
22 PyQt default version, PySide, PyQt5
22 PyQt default version, PySide, PyQt5
23 else:
23 else:
24 use what QT_API says
24 use what QT_API says
25
25
26 Note that %gui's implementation will always set a `QT_API`, see
27 `IPython.terminal.pt_inputhooks.get_inputhook_name_and_func`
28
26 """
29 """
27 # NOTE: This is no longer an external, third-party module, and should be
30 # NOTE: This is no longer an external, third-party module, and should be
28 # considered part of IPython. For compatibility however, it is being kept in
31 # considered part of IPython. For compatibility however, it is being kept in
29 # IPython/external.
32 # IPython/external.
30
33
31 import os
34 import os
32 import sys
35 import sys
33
36
34 from IPython.external.qt_loaders import (
37 from IPython.external.qt_loaders import (
35 load_qt,
38 load_qt,
36 loaded_api,
39 loaded_api,
37 enum_factory,
40 enum_factory,
38 # QT6
41 # QT6
39 QT_API_PYQT6,
42 QT_API_PYQT6,
40 QT_API_PYSIDE6,
43 QT_API_PYSIDE6,
41 # QT5
44 # QT5
42 QT_API_PYQT5,
45 QT_API_PYQT5,
43 QT_API_PYSIDE2,
46 QT_API_PYSIDE2,
44 # QT4
47 # QT4
45 QT_API_PYQTv1,
46 QT_API_PYQT,
48 QT_API_PYQT,
47 QT_API_PYSIDE,
49 QT_API_PYSIDE,
48 # default
50 # default
49 QT_API_PYQT_DEFAULT,
51 QT_API_PYQT_DEFAULT,
50 )
52 )
51
53
52 _qt_apis = (
54 _qt_apis = (
53 # QT6
55 # QT6
54 QT_API_PYQT6,
56 QT_API_PYQT6,
55 QT_API_PYSIDE6,
57 QT_API_PYSIDE6,
56 # QT5
58 # QT5
57 QT_API_PYQT5,
59 QT_API_PYQT5,
58 QT_API_PYSIDE2,
60 QT_API_PYSIDE2,
59 # QT4
60 QT_API_PYQTv1,
61 QT_API_PYQT,
62 QT_API_PYSIDE,
63 # default
61 # default
64 QT_API_PYQT_DEFAULT,
62 QT_API_PYQT_DEFAULT,
65 )
63 )
66
64
67
65
68 def matplotlib_options(mpl):
66 def matplotlib_options(mpl):
69 """Constraints placed on an imported matplotlib."""
67 """Constraints placed on an imported matplotlib."""
70 if mpl is None:
68 if mpl is None:
71 return
69 return
72 backend = mpl.rcParams.get('backend', None)
70 backend = mpl.rcParams.get('backend', None)
73 if backend == 'Qt4Agg':
71 if backend == 'Qt4Agg':
74 mpqt = mpl.rcParams.get('backend.qt4', None)
72 mpqt = mpl.rcParams.get('backend.qt4', None)
75 if mpqt is None:
73 if mpqt is None:
76 return None
74 return None
77 if mpqt.lower() == 'pyside':
75 if mpqt.lower() == 'pyside':
78 return [QT_API_PYSIDE]
76 return [QT_API_PYSIDE]
79 elif mpqt.lower() == 'pyqt4':
77 elif mpqt.lower() == 'pyqt4':
80 return [QT_API_PYQT_DEFAULT]
78 return [QT_API_PYQT_DEFAULT]
81 elif mpqt.lower() == 'pyqt4v2':
79 elif mpqt.lower() == 'pyqt4v2':
82 return [QT_API_PYQT]
80 return [QT_API_PYQT]
83 raise ImportError("unhandled value for backend.qt4 from matplotlib: %r" %
81 raise ImportError("unhandled value for backend.qt4 from matplotlib: %r" %
84 mpqt)
82 mpqt)
85 elif backend == 'Qt5Agg':
83 elif backend == 'Qt5Agg':
86 mpqt = mpl.rcParams.get('backend.qt5', None)
84 mpqt = mpl.rcParams.get('backend.qt5', None)
87 if mpqt is None:
85 if mpqt is None:
88 return None
86 return None
89 if mpqt.lower() == 'pyqt5':
87 if mpqt.lower() == 'pyqt5':
90 return [QT_API_PYQT5]
88 return [QT_API_PYQT5]
91 raise ImportError("unhandled value for backend.qt5 from matplotlib: %r" %
89 raise ImportError("unhandled value for backend.qt5 from matplotlib: %r" %
92 mpqt)
90 mpqt)
93
91
94 def get_options():
92 def get_options():
95 """Return a list of acceptable QT APIs, in decreasing order of preference."""
93 """Return a list of acceptable QT APIs, in decreasing order of preference."""
96 #already imported Qt somewhere. Use that
94 #already imported Qt somewhere. Use that
97 loaded = loaded_api()
95 loaded = loaded_api()
98 if loaded is not None:
96 if loaded is not None:
99 return [loaded]
97 return [loaded]
100
98
101 mpl = sys.modules.get('matplotlib', None)
99 mpl = sys.modules.get("matplotlib", None)
102
100
103 if mpl is not None and tuple(mpl.__version__.split(".")) < ("1", "0", "2"):
101 if mpl is not None and tuple(mpl.__version__.split(".")) < ("1", "0", "2"):
104 # 1.0.1 only supports PyQt4 v1
102 # 1.0.1 only supports PyQt4 v1
105 return [QT_API_PYQT_DEFAULT]
103 return [QT_API_PYQT_DEFAULT]
106
104
107 qt_api = os.environ.get('QT_API', None)
105 qt_api = os.environ.get('QT_API', None)
108 if qt_api is None:
106 if qt_api is None:
109 #no ETS variable. Ask mpl, then use default fallback path
107 #no ETS variable. Ask mpl, then use default fallback path
110 return matplotlib_options(mpl) or [
108 return matplotlib_options(mpl) or [
111 QT_API_PYQT_DEFAULT,
109 QT_API_PYQT_DEFAULT,
112 QT_API_PYQT6,
110 QT_API_PYQT6,
113 QT_API_PYSIDE6,
111 QT_API_PYSIDE6,
114 QT_API_PYQT5,
112 QT_API_PYQT5,
115 QT_API_PYSIDE2,
113 QT_API_PYSIDE2,
116 QT_API_PYQT,
117 QT_API_PYSIDE,
118 ]
114 ]
119 elif qt_api not in _qt_apis:
115 elif qt_api not in _qt_apis:
120 raise RuntimeError("Invalid Qt API %r, valid values are: %r" %
116 raise RuntimeError("Invalid Qt API %r, valid values are: %r" %
121 (qt_api, ', '.join(_qt_apis)))
117 (qt_api, ', '.join(_qt_apis)))
122 else:
118 else:
123 return [qt_api]
119 return [qt_api]
124
120
125
121
126 api_opts = get_options()
122 api_opts = get_options()
127 QtCore, QtGui, QtSvg, QT_API = load_qt(api_opts)
123 QtCore, QtGui, QtSvg, QT_API = load_qt(api_opts)
128 enum_helper = enum_factory(QT_API, QtCore)
124 enum_helper = enum_factory(QT_API, QtCore)
@@ -1,399 +1,405 b''
1 """
1 """
2 This module contains factory functions that attempt
2 This module contains factory functions that attempt
3 to return Qt submodules from the various python Qt bindings.
3 to return Qt submodules from the various python Qt bindings.
4
4
5 It also protects against double-importing Qt with different
5 It also protects against double-importing Qt with different
6 bindings, which is unstable and likely to crash
6 bindings, which is unstable and likely to crash
7
7
8 This is used primarily by qt and qt_for_kernel, and shouldn't
8 This is used primarily by qt and qt_for_kernel, and shouldn't
9 be accessed directly from the outside
9 be accessed directly from the outside
10 """
10 """
11 import importlib.abc
11 import importlib.abc
12 import sys
12 import sys
13 import types
13 import types
14 from functools import partial, lru_cache
14 from functools import partial, lru_cache
15 import operator
15 import operator
16
16
17 # ### Available APIs.
17 # ### Available APIs.
18 # Qt6
18 # Qt6
19 QT_API_PYQT6 = "pyqt6"
19 QT_API_PYQT6 = "pyqt6"
20 QT_API_PYSIDE6 = "pyside6"
20 QT_API_PYSIDE6 = "pyside6"
21
21
22 # Qt5
22 # Qt5
23 QT_API_PYQT5 = 'pyqt5'
23 QT_API_PYQT5 = 'pyqt5'
24 QT_API_PYSIDE2 = 'pyside2'
24 QT_API_PYSIDE2 = 'pyside2'
25
25
26 # Qt4
26 # Qt4
27 # NOTE: Here for legacy matplotlib compatibility, but not really supported on the IPython side.
27 QT_API_PYQT = "pyqt" # Force version 2
28 QT_API_PYQT = "pyqt" # Force version 2
28 QT_API_PYQTv1 = "pyqtv1" # Force version 2
29 QT_API_PYQTv1 = "pyqtv1" # Force version 2
29 QT_API_PYSIDE = "pyside"
30 QT_API_PYSIDE = "pyside"
30
31
31 QT_API_PYQT_DEFAULT = "pyqtdefault" # use system default for version 1 vs. 2
32 QT_API_PYQT_DEFAULT = "pyqtdefault" # use system default for version 1 vs. 2
32
33
33 api_to_module = {
34 api_to_module = {
34 # Qt6
35 # Qt6
35 QT_API_PYQT6: "PyQt6",
36 QT_API_PYQT6: "PyQt6",
36 QT_API_PYSIDE6: "PySide6",
37 QT_API_PYSIDE6: "PySide6",
37 # Qt5
38 # Qt5
38 QT_API_PYQT5: "PyQt5",
39 QT_API_PYQT5: "PyQt5",
39 QT_API_PYSIDE2: "PySide2",
40 QT_API_PYSIDE2: "PySide2",
40 # Qt4
41 # Qt4
41 QT_API_PYSIDE: "PySide",
42 QT_API_PYSIDE: "PySide",
42 QT_API_PYQT: "PyQt4",
43 QT_API_PYQT: "PyQt4",
43 QT_API_PYQTv1: "PyQt4",
44 QT_API_PYQTv1: "PyQt4",
44 # default
45 # default
45 QT_API_PYQT_DEFAULT: "PyQt6",
46 QT_API_PYQT_DEFAULT: "PyQt6",
46 }
47 }
47
48
48
49
49 class ImportDenier(importlib.abc.MetaPathFinder):
50 class ImportDenier(importlib.abc.MetaPathFinder):
50 """Import Hook that will guard against bad Qt imports
51 """Import Hook that will guard against bad Qt imports
51 once IPython commits to a specific binding
52 once IPython commits to a specific binding
52 """
53 """
53
54
54 def __init__(self):
55 def __init__(self):
55 self.__forbidden = set()
56 self.__forbidden = set()
56
57
57 def forbid(self, module_name):
58 def forbid(self, module_name):
58 sys.modules.pop(module_name, None)
59 sys.modules.pop(module_name, None)
59 self.__forbidden.add(module_name)
60 self.__forbidden.add(module_name)
60
61
61 def find_spec(self, fullname, path, target=None):
62 def find_spec(self, fullname, path, target=None):
62 if path:
63 if path:
63 return
64 return
64 if fullname in self.__forbidden:
65 if fullname in self.__forbidden:
65 raise ImportError(
66 raise ImportError(
66 """
67 """
67 Importing %s disabled by IPython, which has
68 Importing %s disabled by IPython, which has
68 already imported an Incompatible QT Binding: %s
69 already imported an Incompatible QT Binding: %s
69 """
70 """
70 % (fullname, loaded_api())
71 % (fullname, loaded_api())
71 )
72 )
72
73
73
74
74 ID = ImportDenier()
75 ID = ImportDenier()
75 sys.meta_path.insert(0, ID)
76 sys.meta_path.insert(0, ID)
76
77
77
78
78 def commit_api(api):
79 def commit_api(api):
79 """Commit to a particular API, and trigger ImportErrors on subsequent
80 """Commit to a particular API, and trigger ImportErrors on subsequent
80 dangerous imports"""
81 dangerous imports"""
81 modules = set(api_to_module.values())
82 modules = set(api_to_module.values())
82
83
83 modules.remove(api_to_module[api])
84 modules.remove(api_to_module[api])
84 for mod in modules:
85 for mod in modules:
85 ID.forbid(mod)
86 ID.forbid(mod)
86
87
87
88
88 def loaded_api():
89 def loaded_api():
89 """Return which API is loaded, if any
90 """Return which API is loaded, if any
90
91
91 If this returns anything besides None,
92 If this returns anything besides None,
92 importing any other Qt binding is unsafe.
93 importing any other Qt binding is unsafe.
93
94
94 Returns
95 Returns
95 -------
96 -------
96 None, 'pyside6', 'pyqt6', 'pyside2', 'pyside', 'pyqt', 'pyqt5', 'pyqtv1'
97 None, 'pyside6', 'pyqt6', 'pyside2', 'pyside', 'pyqt', 'pyqt5', 'pyqtv1'
97 """
98 """
98 if sys.modules.get("PyQt6.QtCore"):
99 if sys.modules.get("PyQt6.QtCore"):
99 return QT_API_PYQT6
100 return QT_API_PYQT6
100 elif sys.modules.get("PySide6.QtCore"):
101 elif sys.modules.get("PySide6.QtCore"):
101 return QT_API_PYSIDE6
102 return QT_API_PYSIDE6
102 elif sys.modules.get("PyQt5.QtCore"):
103 elif sys.modules.get("PyQt5.QtCore"):
103 return QT_API_PYQT5
104 return QT_API_PYQT5
104 elif sys.modules.get("PySide2.QtCore"):
105 elif sys.modules.get("PySide2.QtCore"):
105 return QT_API_PYSIDE2
106 return QT_API_PYSIDE2
106 elif sys.modules.get("PyQt4.QtCore"):
107 elif sys.modules.get("PyQt4.QtCore"):
107 if qtapi_version() == 2:
108 if qtapi_version() == 2:
108 return QT_API_PYQT
109 return QT_API_PYQT
109 else:
110 else:
110 return QT_API_PYQTv1
111 return QT_API_PYQTv1
111 elif sys.modules.get("PySide.QtCore"):
112 elif sys.modules.get("PySide.QtCore"):
112 return QT_API_PYSIDE
113 return QT_API_PYSIDE
113
114
114 return None
115 return None
115
116
116
117
117 def has_binding(api):
118 def has_binding(api):
118 """Safely check for PyQt4/5, PySide or PySide2, without importing submodules
119 """Safely check for PyQt4/5, PySide or PySide2, without importing submodules
119
120
120 Parameters
121 Parameters
121 ----------
122 ----------
122 api : str [ 'pyqtv1' | 'pyqt' | 'pyqt5' | 'pyside' | 'pyside2' | 'pyqtdefault']
123 api : str [ 'pyqtv1' | 'pyqt' | 'pyqt5' | 'pyside' | 'pyside2' | 'pyqtdefault']
123 Which module to check for
124 Which module to check for
124
125
125 Returns
126 Returns
126 -------
127 -------
127 True if the relevant module appears to be importable
128 True if the relevant module appears to be importable
128 """
129 """
129 module_name = api_to_module[api]
130 module_name = api_to_module[api]
130 from importlib.util import find_spec
131 from importlib.util import find_spec
131
132
132 required = ['QtCore', 'QtGui', 'QtSvg']
133 required = ['QtCore', 'QtGui', 'QtSvg']
133 if api in (QT_API_PYQT5, QT_API_PYSIDE2, QT_API_PYQT6, QT_API_PYSIDE6):
134 if api in (QT_API_PYQT5, QT_API_PYSIDE2, QT_API_PYQT6, QT_API_PYSIDE6):
134 # QT5 requires QtWidgets too
135 # QT5 requires QtWidgets too
135 required.append('QtWidgets')
136 required.append('QtWidgets')
136
137
137 for submod in required:
138 for submod in required:
138 try:
139 try:
139 spec = find_spec('%s.%s' % (module_name, submod))
140 spec = find_spec('%s.%s' % (module_name, submod))
140 except ImportError:
141 except ImportError:
141 # Package (e.g. PyQt5) not found
142 # Package (e.g. PyQt5) not found
142 return False
143 return False
143 else:
144 else:
144 if spec is None:
145 if spec is None:
145 # Submodule (e.g. PyQt5.QtCore) not found
146 # Submodule (e.g. PyQt5.QtCore) not found
146 return False
147 return False
147
148
148 if api == QT_API_PYSIDE:
149 if api == QT_API_PYSIDE:
149 # We can also safely check PySide version
150 # We can also safely check PySide version
150 import PySide
151 import PySide
151
152
152 return PySide.__version_info__ >= (1, 0, 3)
153 return PySide.__version_info__ >= (1, 0, 3)
153
154
154 return True
155 return True
155
156
156
157
157 def qtapi_version():
158 def qtapi_version():
158 """Return which QString API has been set, if any
159 """Return which QString API has been set, if any
159
160
160 Returns
161 Returns
161 -------
162 -------
162 The QString API version (1 or 2), or None if not set
163 The QString API version (1 or 2), or None if not set
163 """
164 """
164 try:
165 try:
165 import sip
166 import sip
166 except ImportError:
167 except ImportError:
167 # as of PyQt5 5.11, sip is no longer available as a top-level
168 # as of PyQt5 5.11, sip is no longer available as a top-level
168 # module and needs to be imported from the PyQt5 namespace
169 # module and needs to be imported from the PyQt5 namespace
169 try:
170 try:
170 from PyQt5 import sip
171 from PyQt5 import sip
171 except ImportError:
172 except ImportError:
172 return
173 return
173 try:
174 try:
174 return sip.getapi('QString')
175 return sip.getapi('QString')
175 except ValueError:
176 except ValueError:
176 return
177 return
177
178
178
179
179 def can_import(api):
180 def can_import(api):
180 """Safely query whether an API is importable, without importing it"""
181 """Safely query whether an API is importable, without importing it"""
181 if not has_binding(api):
182 if not has_binding(api):
182 return False
183 return False
183
184
184 current = loaded_api()
185 current = loaded_api()
185 if api == QT_API_PYQT_DEFAULT:
186 if api == QT_API_PYQT_DEFAULT:
186 return current in [QT_API_PYQT6, None]
187 return current in [QT_API_PYQT6, None]
187 else:
188 else:
188 return current in [api, None]
189 return current in [api, None]
189
190
190
191
191 def import_pyqt4(version=2):
192 def import_pyqt4(version=2):
192 """
193 """
193 Import PyQt4
194 Import PyQt4
194
195
195 Parameters
196 Parameters
196 ----------
197 ----------
197 version : 1, 2, or None
198 version : 1, 2, or None
198 Which QString/QVariant API to use. Set to None to use the system
199 Which QString/QVariant API to use. Set to None to use the system
199 default
200 default
200 ImportErrors raised within this function are non-recoverable
201 ImportErrors raised within this function are non-recoverable
201 """
202 """
202 # The new-style string API (version=2) automatically
203 # The new-style string API (version=2) automatically
203 # converts QStrings to Unicode Python strings. Also, automatically unpacks
204 # converts QStrings to Unicode Python strings. Also, automatically unpacks
204 # QVariants to their underlying objects.
205 # QVariants to their underlying objects.
205 import sip
206 import sip
206
207
207 if version is not None:
208 if version is not None:
208 sip.setapi('QString', version)
209 sip.setapi('QString', version)
209 sip.setapi('QVariant', version)
210 sip.setapi('QVariant', version)
210
211
211 from PyQt4 import QtGui, QtCore, QtSvg
212 from PyQt4 import QtGui, QtCore, QtSvg
212
213
213 if QtCore.PYQT_VERSION < 0x040700:
214 if QtCore.PYQT_VERSION < 0x040700:
214 raise ImportError("IPython requires PyQt4 >= 4.7, found %s" %
215 raise ImportError("IPython requires PyQt4 >= 4.7, found %s" %
215 QtCore.PYQT_VERSION_STR)
216 QtCore.PYQT_VERSION_STR)
216
217
217 # Alias PyQt-specific functions for PySide compatibility.
218 # Alias PyQt-specific functions for PySide compatibility.
218 QtCore.Signal = QtCore.pyqtSignal
219 QtCore.Signal = QtCore.pyqtSignal
219 QtCore.Slot = QtCore.pyqtSlot
220 QtCore.Slot = QtCore.pyqtSlot
220
221
221 # query for the API version (in case version == None)
222 # query for the API version (in case version == None)
222 version = sip.getapi('QString')
223 version = sip.getapi('QString')
223 api = QT_API_PYQTv1 if version == 1 else QT_API_PYQT
224 api = QT_API_PYQTv1 if version == 1 else QT_API_PYQT
224 return QtCore, QtGui, QtSvg, api
225 return QtCore, QtGui, QtSvg, api
225
226
226
227
227 def import_pyqt5():
228 def import_pyqt5():
228 """
229 """
229 Import PyQt5
230 Import PyQt5
230
231
231 ImportErrors raised within this function are non-recoverable
232 ImportErrors raised within this function are non-recoverable
232 """
233 """
233
234
234 from PyQt5 import QtCore, QtSvg, QtWidgets, QtGui
235 from PyQt5 import QtCore, QtSvg, QtWidgets, QtGui
235
236
236 # Alias PyQt-specific functions for PySide compatibility.
237 # Alias PyQt-specific functions for PySide compatibility.
237 QtCore.Signal = QtCore.pyqtSignal
238 QtCore.Signal = QtCore.pyqtSignal
238 QtCore.Slot = QtCore.pyqtSlot
239 QtCore.Slot = QtCore.pyqtSlot
239
240
240 # Join QtGui and QtWidgets for Qt4 compatibility.
241 # Join QtGui and QtWidgets for Qt4 compatibility.
241 QtGuiCompat = types.ModuleType('QtGuiCompat')
242 QtGuiCompat = types.ModuleType('QtGuiCompat')
242 QtGuiCompat.__dict__.update(QtGui.__dict__)
243 QtGuiCompat.__dict__.update(QtGui.__dict__)
243 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
244 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
244
245
245 api = QT_API_PYQT5
246 api = QT_API_PYQT5
246 return QtCore, QtGuiCompat, QtSvg, api
247 return QtCore, QtGuiCompat, QtSvg, api
247
248
248
249
249 def import_pyqt6():
250 def import_pyqt6():
250 """
251 """
251 Import PyQt6
252 Import PyQt6
252
253
253 ImportErrors raised within this function are non-recoverable
254 ImportErrors raised within this function are non-recoverable
254 """
255 """
255
256
256 from PyQt6 import QtCore, QtSvg, QtWidgets, QtGui
257 from PyQt6 import QtCore, QtSvg, QtWidgets, QtGui
257
258
258 # Alias PyQt-specific functions for PySide compatibility.
259 # Alias PyQt-specific functions for PySide compatibility.
259 QtCore.Signal = QtCore.pyqtSignal
260 QtCore.Signal = QtCore.pyqtSignal
260 QtCore.Slot = QtCore.pyqtSlot
261 QtCore.Slot = QtCore.pyqtSlot
261
262
262 # Join QtGui and QtWidgets for Qt4 compatibility.
263 # Join QtGui and QtWidgets for Qt4 compatibility.
263 QtGuiCompat = types.ModuleType("QtGuiCompat")
264 QtGuiCompat = types.ModuleType("QtGuiCompat")
264 QtGuiCompat.__dict__.update(QtGui.__dict__)
265 QtGuiCompat.__dict__.update(QtGui.__dict__)
265 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
266 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
266
267
267 api = QT_API_PYQT6
268 api = QT_API_PYQT6
268 return QtCore, QtGuiCompat, QtSvg, api
269 return QtCore, QtGuiCompat, QtSvg, api
269
270
270
271
271 def import_pyside():
272 def import_pyside():
272 """
273 """
273 Import PySide
274 Import PySide
274
275
275 ImportErrors raised within this function are non-recoverable
276 ImportErrors raised within this function are non-recoverable
276 """
277 """
277 from PySide import QtGui, QtCore, QtSvg
278 from PySide import QtGui, QtCore, QtSvg
278 return QtCore, QtGui, QtSvg, QT_API_PYSIDE
279 return QtCore, QtGui, QtSvg, QT_API_PYSIDE
279
280
280 def import_pyside2():
281 def import_pyside2():
281 """
282 """
282 Import PySide2
283 Import PySide2
283
284
284 ImportErrors raised within this function are non-recoverable
285 ImportErrors raised within this function are non-recoverable
285 """
286 """
286 from PySide2 import QtGui, QtCore, QtSvg, QtWidgets, QtPrintSupport
287 from PySide2 import QtGui, QtCore, QtSvg, QtWidgets, QtPrintSupport
287
288
288 # Join QtGui and QtWidgets for Qt4 compatibility.
289 # Join QtGui and QtWidgets for Qt4 compatibility.
289 QtGuiCompat = types.ModuleType('QtGuiCompat')
290 QtGuiCompat = types.ModuleType('QtGuiCompat')
290 QtGuiCompat.__dict__.update(QtGui.__dict__)
291 QtGuiCompat.__dict__.update(QtGui.__dict__)
291 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
292 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
292 QtGuiCompat.__dict__.update(QtPrintSupport.__dict__)
293 QtGuiCompat.__dict__.update(QtPrintSupport.__dict__)
293
294
294 return QtCore, QtGuiCompat, QtSvg, QT_API_PYSIDE2
295 return QtCore, QtGuiCompat, QtSvg, QT_API_PYSIDE2
295
296
296
297
297 def import_pyside6():
298 def import_pyside6():
298 """
299 """
299 Import PySide6
300 Import PySide6
300
301
301 ImportErrors raised within this function are non-recoverable
302 ImportErrors raised within this function are non-recoverable
302 """
303 """
303 from PySide6 import QtGui, QtCore, QtSvg, QtWidgets, QtPrintSupport
304 from PySide6 import QtGui, QtCore, QtSvg, QtWidgets, QtPrintSupport
304
305
305 # Join QtGui and QtWidgets for Qt4 compatibility.
306 # Join QtGui and QtWidgets for Qt4 compatibility.
306 QtGuiCompat = types.ModuleType("QtGuiCompat")
307 QtGuiCompat = types.ModuleType("QtGuiCompat")
307 QtGuiCompat.__dict__.update(QtGui.__dict__)
308 QtGuiCompat.__dict__.update(QtGui.__dict__)
308 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
309 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
309 QtGuiCompat.__dict__.update(QtPrintSupport.__dict__)
310 QtGuiCompat.__dict__.update(QtPrintSupport.__dict__)
310
311
311 return QtCore, QtGuiCompat, QtSvg, QT_API_PYSIDE6
312 return QtCore, QtGuiCompat, QtSvg, QT_API_PYSIDE6
312
313
313
314
314 def load_qt(api_options):
315 def load_qt(api_options):
315 """
316 """
316 Attempt to import Qt, given a preference list
317 Attempt to import Qt, given a preference list
317 of permissible bindings
318 of permissible bindings
318
319
319 It is safe to call this function multiple times.
320 It is safe to call this function multiple times.
320
321
321 Parameters
322 Parameters
322 ----------
323 ----------
323 api_options : List of strings
324 api_options : List of strings
324 The order of APIs to try. Valid items are 'pyside', 'pyside2',
325 The order of APIs to try. Valid items are 'pyside', 'pyside2',
325 'pyqt', 'pyqt5', 'pyqtv1' and 'pyqtdefault'
326 'pyqt', 'pyqt5', 'pyqtv1' and 'pyqtdefault'
326
327
327 Returns
328 Returns
328 -------
329 -------
329 A tuple of QtCore, QtGui, QtSvg, QT_API
330 A tuple of QtCore, QtGui, QtSvg, QT_API
330 The first three are the Qt modules. The last is the
331 The first three are the Qt modules. The last is the
331 string indicating which module was loaded.
332 string indicating which module was loaded.
332
333
333 Raises
334 Raises
334 ------
335 ------
335 ImportError, if it isn't possible to import any requested
336 ImportError, if it isn't possible to import any requested
336 bindings (either because they aren't installed, or because
337 bindings (either because they aren't installed, or because
337 an incompatible library has already been installed)
338 an incompatible library has already been installed)
338 """
339 """
339 loaders = {
340 loaders = {
340 # Qt6
341 # Qt6
341 QT_API_PYQT6: import_pyqt6,
342 QT_API_PYQT6: import_pyqt6,
342 QT_API_PYSIDE6: import_pyside6,
343 QT_API_PYSIDE6: import_pyside6,
343 # Qt5
344 # Qt5
344 QT_API_PYQT5: import_pyqt5,
345 QT_API_PYQT5: import_pyqt5,
345 QT_API_PYSIDE2: import_pyside2,
346 QT_API_PYSIDE2: import_pyside2,
346 # Qt4
347 # Qt4
347 QT_API_PYSIDE: import_pyside,
348 QT_API_PYSIDE: import_pyside,
348 QT_API_PYQT: import_pyqt4,
349 QT_API_PYQT: import_pyqt4,
349 QT_API_PYQTv1: partial(import_pyqt4, version=1),
350 QT_API_PYQTv1: partial(import_pyqt4, version=1),
350 # default
351 # default
351 QT_API_PYQT_DEFAULT: import_pyqt6,
352 QT_API_PYQT_DEFAULT: import_pyqt6,
352 }
353 }
353
354
354 for api in api_options:
355 for api in api_options:
355
356
356 if api not in loaders:
357 if api not in loaders:
357 raise RuntimeError(
358 raise RuntimeError(
358 "Invalid Qt API %r, valid values are: %s" %
359 "Invalid Qt API %r, valid values are: %s" %
359 (api, ", ".join(["%r" % k for k in loaders.keys()])))
360 (api, ", ".join(["%r" % k for k in loaders.keys()])))
360
361
361 if not can_import(api):
362 if not can_import(api):
362 continue
363 continue
363
364
364 #cannot safely recover from an ImportError during this
365 #cannot safely recover from an ImportError during this
365 result = loaders[api]()
366 result = loaders[api]()
366 api = result[-1] # changed if api = QT_API_PYQT_DEFAULT
367 api = result[-1] # changed if api = QT_API_PYQT_DEFAULT
367 commit_api(api)
368 commit_api(api)
368 return result
369 return result
369 else:
370 else:
370 raise ImportError("""
371 raise ImportError(
372 """
371 Could not load requested Qt binding. Please ensure that
373 Could not load requested Qt binding. Please ensure that
372 PyQt4 >= 4.7, PyQt5, PySide >= 1.0.3 or PySide2 is available,
374 PyQt4 >= 4.7, PyQt5, PyQt6, PySide >= 1.0.3, PySide2, or
373 and only one is imported per session.
375 PySide6 is available, and only one is imported per session.
374
376
375 Currently-imported Qt library: %r
377 Currently-imported Qt library: %r
376 PyQt4 available (requires QtCore, QtGui, QtSvg): %s
377 PyQt5 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
378 PyQt5 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
378 PySide >= 1.0.3 installed: %s
379 PyQt6 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
379 PySide2 installed: %s
380 PySide2 installed: %s
381 PySide6 installed: %s
380 Tried to load: %r
382 Tried to load: %r
381 """ % (loaded_api(),
383 """
382 has_binding(QT_API_PYQT),
384 % (
383 has_binding(QT_API_PYQT5),
385 loaded_api(),
384 has_binding(QT_API_PYSIDE),
386 has_binding(QT_API_PYQT5),
385 has_binding(QT_API_PYSIDE2),
387 has_binding(QT_API_PYQT6),
386 api_options))
388 has_binding(QT_API_PYSIDE2),
389 has_binding(QT_API_PYSIDE6),
390 api_options,
391 )
392 )
387
393
388
394
389 def enum_factory(QT_API, QtCore):
395 def enum_factory(QT_API, QtCore):
390 """Construct an enum helper to account for PyQt5 <-> PyQt6 changes."""
396 """Construct an enum helper to account for PyQt5 <-> PyQt6 changes."""
391
397
392 @lru_cache(None)
398 @lru_cache(None)
393 def _enum(name):
399 def _enum(name):
394 # foo.bar.Enum.Entry (PyQt6) <=> foo.bar.Entry (non-PyQt6).
400 # foo.bar.Enum.Entry (PyQt6) <=> foo.bar.Entry (non-PyQt6).
395 return operator.attrgetter(
401 return operator.attrgetter(
396 name if QT_API == QT_API_PYQT6 else name.rpartition(".")[0]
402 name if QT_API == QT_API_PYQT6 else name.rpartition(".")[0]
397 )(sys.modules[QtCore.__package__])
403 )(sys.modules[QtCore.__package__])
398
404
399 return _enum
405 return _enum
@@ -1,155 +1,155 b''
1 # coding: utf-8
1 # coding: utf-8
2 """
2 """
3 Support for creating GUI apps and starting event loops.
3 Support for creating GUI apps and starting event loops.
4
4
5 IPython's GUI integration allows interactive plotting and GUI usage in IPython
5 IPython's GUI integration allows interactive plotting and GUI usage in IPython
6 session. IPython has two different types of GUI integration:
6 session. IPython has two different types of GUI integration:
7
7
8 1. The terminal based IPython supports GUI event loops through Python's
8 1. The terminal based IPython supports GUI event loops through Python's
9 PyOS_InputHook. PyOS_InputHook is a hook that Python calls periodically
9 PyOS_InputHook. PyOS_InputHook is a hook that Python calls periodically
10 whenever raw_input is waiting for a user to type code. We implement GUI
10 whenever raw_input is waiting for a user to type code. We implement GUI
11 support in the terminal by setting PyOS_InputHook to a function that
11 support in the terminal by setting PyOS_InputHook to a function that
12 iterates the event loop for a short while. It is important to note that
12 iterates the event loop for a short while. It is important to note that
13 in this situation, the real GUI event loop is NOT run in the normal
13 in this situation, the real GUI event loop is NOT run in the normal
14 manner, so you can't use the normal means to detect that it is running.
14 manner, so you can't use the normal means to detect that it is running.
15 2. In the two process IPython kernel/frontend, the GUI event loop is run in
15 2. In the two process IPython kernel/frontend, the GUI event loop is run in
16 the kernel. In this case, the event loop is run in the normal manner by
16 the kernel. In this case, the event loop is run in the normal manner by
17 calling the function or method of the GUI toolkit that starts the event
17 calling the function or method of the GUI toolkit that starts the event
18 loop.
18 loop.
19
19
20 In addition to starting the GUI event loops in one of these two ways, IPython
20 In addition to starting the GUI event loops in one of these two ways, IPython
21 will *always* create an appropriate GUI application object when GUi
21 will *always* create an appropriate GUI application object when GUi
22 integration is enabled.
22 integration is enabled.
23
23
24 If you want your GUI apps to run in IPython you need to do two things:
24 If you want your GUI apps to run in IPython you need to do two things:
25
25
26 1. Test to see if there is already an existing main application object. If
26 1. Test to see if there is already an existing main application object. If
27 there is, you should use it. If there is not an existing application object
27 there is, you should use it. If there is not an existing application object
28 you should create one.
28 you should create one.
29 2. Test to see if the GUI event loop is running. If it is, you should not
29 2. Test to see if the GUI event loop is running. If it is, you should not
30 start it. If the event loop is not running you may start it.
30 start it. If the event loop is not running you may start it.
31
31
32 This module contains functions for each toolkit that perform these things
32 This module contains functions for each toolkit that perform these things
33 in a consistent manner. Because of how PyOS_InputHook runs the event loop
33 in a consistent manner. Because of how PyOS_InputHook runs the event loop
34 you cannot detect if the event loop is running using the traditional calls
34 you cannot detect if the event loop is running using the traditional calls
35 (such as ``wx.GetApp.IsMainLoopRunning()`` in wxPython). If PyOS_InputHook is
35 (such as ``wx.GetApp.IsMainLoopRunning()`` in wxPython). If PyOS_InputHook is
36 set These methods will return a false negative. That is, they will say the
36 set These methods will return a false negative. That is, they will say the
37 event loop is not running, when is actually is. To work around this limitation
37 event loop is not running, when is actually is. To work around this limitation
38 we proposed the following informal protocol:
38 we proposed the following informal protocol:
39
39
40 * Whenever someone starts the event loop, they *must* set the ``_in_event_loop``
40 * Whenever someone starts the event loop, they *must* set the ``_in_event_loop``
41 attribute of the main application object to ``True``. This should be done
41 attribute of the main application object to ``True``. This should be done
42 regardless of how the event loop is actually run.
42 regardless of how the event loop is actually run.
43 * Whenever someone stops the event loop, they *must* set the ``_in_event_loop``
43 * Whenever someone stops the event loop, they *must* set the ``_in_event_loop``
44 attribute of the main application object to ``False``.
44 attribute of the main application object to ``False``.
45 * If you want to see if the event loop is running, you *must* use ``hasattr``
45 * If you want to see if the event loop is running, you *must* use ``hasattr``
46 to see if ``_in_event_loop`` attribute has been set. If it is set, you
46 to see if ``_in_event_loop`` attribute has been set. If it is set, you
47 *must* use its value. If it has not been set, you can query the toolkit
47 *must* use its value. If it has not been set, you can query the toolkit
48 in the normal manner.
48 in the normal manner.
49 * If you want GUI support and no one else has created an application or
49 * If you want GUI support and no one else has created an application or
50 started the event loop you *must* do this. We don't want projects to
50 started the event loop you *must* do this. We don't want projects to
51 attempt to defer these things to someone else if they themselves need it.
51 attempt to defer these things to someone else if they themselves need it.
52
52
53 The functions below implement this logic for each GUI toolkit. If you need
53 The functions below implement this logic for each GUI toolkit. If you need
54 to create custom application subclasses, you will likely have to modify this
54 to create custom application subclasses, you will likely have to modify this
55 code for your own purposes. This code can be copied into your own project
55 code for your own purposes. This code can be copied into your own project
56 so you don't have to depend on IPython.
56 so you don't have to depend on IPython.
57
57
58 """
58 """
59
59
60 # Copyright (c) IPython Development Team.
60 # Copyright (c) IPython Development Team.
61 # Distributed under the terms of the Modified BSD License.
61 # Distributed under the terms of the Modified BSD License.
62
62
63 from IPython.core.getipython import get_ipython
63 from IPython.core.getipython import get_ipython
64
64
65 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
66 # wx
66 # wx
67 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
68
68
69 def get_app_wx(*args, **kwargs):
69 def get_app_wx(*args, **kwargs):
70 """Create a new wx app or return an exiting one."""
70 """Create a new wx app or return an exiting one."""
71 import wx
71 import wx
72 app = wx.GetApp()
72 app = wx.GetApp()
73 if app is None:
73 if app is None:
74 if 'redirect' not in kwargs:
74 if 'redirect' not in kwargs:
75 kwargs['redirect'] = False
75 kwargs['redirect'] = False
76 app = wx.PySimpleApp(*args, **kwargs)
76 app = wx.PySimpleApp(*args, **kwargs)
77 return app
77 return app
78
78
79 def is_event_loop_running_wx(app=None):
79 def is_event_loop_running_wx(app=None):
80 """Is the wx event loop running."""
80 """Is the wx event loop running."""
81 # New way: check attribute on shell instance
81 # New way: check attribute on shell instance
82 ip = get_ipython()
82 ip = get_ipython()
83 if ip is not None:
83 if ip is not None:
84 if ip.active_eventloop and ip.active_eventloop == 'wx':
84 if ip.active_eventloop and ip.active_eventloop == 'wx':
85 return True
85 return True
86 # Fall through to checking the application, because Wx has a native way
86 # Fall through to checking the application, because Wx has a native way
87 # to check if the event loop is running, unlike Qt.
87 # to check if the event loop is running, unlike Qt.
88
88
89 # Old way: check Wx application
89 # Old way: check Wx application
90 if app is None:
90 if app is None:
91 app = get_app_wx()
91 app = get_app_wx()
92 if hasattr(app, '_in_event_loop'):
92 if hasattr(app, '_in_event_loop'):
93 return app._in_event_loop
93 return app._in_event_loop
94 else:
94 else:
95 return app.IsMainLoopRunning()
95 return app.IsMainLoopRunning()
96
96
97 def start_event_loop_wx(app=None):
97 def start_event_loop_wx(app=None):
98 """Start the wx event loop in a consistent manner."""
98 """Start the wx event loop in a consistent manner."""
99 if app is None:
99 if app is None:
100 app = get_app_wx()
100 app = get_app_wx()
101 if not is_event_loop_running_wx(app):
101 if not is_event_loop_running_wx(app):
102 app._in_event_loop = True
102 app._in_event_loop = True
103 app.MainLoop()
103 app.MainLoop()
104 app._in_event_loop = False
104 app._in_event_loop = False
105 else:
105 else:
106 app._in_event_loop = True
106 app._in_event_loop = True
107
107
108 #-----------------------------------------------------------------------------
108 #-----------------------------------------------------------------------------
109 # qt4
109 # Qt
110 #-----------------------------------------------------------------------------
110 #-----------------------------------------------------------------------------
111
111
112 def get_app_qt4(*args, **kwargs):
112 def get_app_qt4(*args, **kwargs):
113 """Create a new qt4 app or return an existing one."""
113 """Create a new Qt app or return an existing one."""
114 from IPython.external.qt_for_kernel import QtGui
114 from IPython.external.qt_for_kernel import QtGui
115 app = QtGui.QApplication.instance()
115 app = QtGui.QApplication.instance()
116 if app is None:
116 if app is None:
117 if not args:
117 if not args:
118 args = ([''],)
118 args = ([""],)
119 app = QtGui.QApplication(*args, **kwargs)
119 app = QtGui.QApplication(*args, **kwargs)
120 return app
120 return app
121
121
122 def is_event_loop_running_qt4(app=None):
122 def is_event_loop_running_qt4(app=None):
123 """Is the qt4 event loop running."""
123 """Is the qt event loop running."""
124 # New way: check attribute on shell instance
124 # New way: check attribute on shell instance
125 ip = get_ipython()
125 ip = get_ipython()
126 if ip is not None:
126 if ip is not None:
127 return ip.active_eventloop and ip.active_eventloop.startswith('qt')
127 return ip.active_eventloop and ip.active_eventloop.startswith('qt')
128
128
129 # Old way: check attribute on QApplication singleton
129 # Old way: check attribute on QApplication singleton
130 if app is None:
130 if app is None:
131 app = get_app_qt4([''])
131 app = get_app_qt4([""])
132 if hasattr(app, '_in_event_loop'):
132 if hasattr(app, '_in_event_loop'):
133 return app._in_event_loop
133 return app._in_event_loop
134 else:
134 else:
135 # Does qt4 provide a other way to detect this?
135 # Does qt provide a other way to detect this?
136 return False
136 return False
137
137
138 def start_event_loop_qt4(app=None):
138 def start_event_loop_qt4(app=None):
139 """Start the qt4 event loop in a consistent manner."""
139 """Start the qt event loop in a consistent manner."""
140 if app is None:
140 if app is None:
141 app = get_app_qt4([''])
141 app = get_app_qt4([""])
142 if not is_event_loop_running_qt4(app):
142 if not is_event_loop_running_qt4(app):
143 app._in_event_loop = True
143 app._in_event_loop = True
144 app.exec_()
144 app.exec_()
145 app._in_event_loop = False
145 app._in_event_loop = False
146 else:
146 else:
147 app._in_event_loop = True
147 app._in_event_loop = True
148
148
149 #-----------------------------------------------------------------------------
149 #-----------------------------------------------------------------------------
150 # Tk
150 # Tk
151 #-----------------------------------------------------------------------------
151 #-----------------------------------------------------------------------------
152
152
153 #-----------------------------------------------------------------------------
153 #-----------------------------------------------------------------------------
154 # gtk
154 # gtk
155 #-----------------------------------------------------------------------------
155 #-----------------------------------------------------------------------------
@@ -1,973 +1,978 b''
1 """IPython terminal interface using prompt_toolkit"""
1 """IPython terminal interface using prompt_toolkit"""
2
2
3 import asyncio
3 import asyncio
4 import os
4 import os
5 import sys
5 import sys
6 from warnings import warn
6 from warnings import warn
7 from typing import Union as UnionType
7 from typing import Union as UnionType
8
8
9 from IPython.core.async_helpers import get_asyncio_loop
9 from IPython.core.async_helpers import get_asyncio_loop
10 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
10 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
11 from IPython.utils.py3compat import input
11 from IPython.utils.py3compat import input
12 from IPython.utils.terminal import toggle_set_term_title, set_term_title, restore_term_title
12 from IPython.utils.terminal import toggle_set_term_title, set_term_title, restore_term_title
13 from IPython.utils.process import abbrev_cwd
13 from IPython.utils.process import abbrev_cwd
14 from traitlets import (
14 from traitlets import (
15 Bool,
15 Bool,
16 Unicode,
16 Unicode,
17 Dict,
17 Dict,
18 Integer,
18 Integer,
19 List,
19 List,
20 observe,
20 observe,
21 Instance,
21 Instance,
22 Type,
22 Type,
23 default,
23 default,
24 Enum,
24 Enum,
25 Union,
25 Union,
26 Any,
26 Any,
27 validate,
27 validate,
28 Float,
28 Float,
29 )
29 )
30
30
31 from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
31 from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
32 from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
32 from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
33 from prompt_toolkit.filters import HasFocus, Condition, IsDone
33 from prompt_toolkit.filters import HasFocus, Condition, IsDone
34 from prompt_toolkit.formatted_text import PygmentsTokens
34 from prompt_toolkit.formatted_text import PygmentsTokens
35 from prompt_toolkit.history import History
35 from prompt_toolkit.history import History
36 from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
36 from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
37 from prompt_toolkit.output import ColorDepth
37 from prompt_toolkit.output import ColorDepth
38 from prompt_toolkit.patch_stdout import patch_stdout
38 from prompt_toolkit.patch_stdout import patch_stdout
39 from prompt_toolkit.shortcuts import PromptSession, CompleteStyle, print_formatted_text
39 from prompt_toolkit.shortcuts import PromptSession, CompleteStyle, print_formatted_text
40 from prompt_toolkit.styles import DynamicStyle, merge_styles
40 from prompt_toolkit.styles import DynamicStyle, merge_styles
41 from prompt_toolkit.styles.pygments import style_from_pygments_cls, style_from_pygments_dict
41 from prompt_toolkit.styles.pygments import style_from_pygments_cls, style_from_pygments_dict
42 from prompt_toolkit import __version__ as ptk_version
42 from prompt_toolkit import __version__ as ptk_version
43
43
44 from pygments.styles import get_style_by_name
44 from pygments.styles import get_style_by_name
45 from pygments.style import Style
45 from pygments.style import Style
46 from pygments.token import Token
46 from pygments.token import Token
47
47
48 from .debugger import TerminalPdb, Pdb
48 from .debugger import TerminalPdb, Pdb
49 from .magics import TerminalMagics
49 from .magics import TerminalMagics
50 from .pt_inputhooks import get_inputhook_name_and_func
50 from .pt_inputhooks import get_inputhook_name_and_func
51 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
51 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
52 from .ptutils import IPythonPTCompleter, IPythonPTLexer
52 from .ptutils import IPythonPTCompleter, IPythonPTLexer
53 from .shortcuts import (
53 from .shortcuts import (
54 create_ipython_shortcuts,
54 create_ipython_shortcuts,
55 create_identifier,
55 create_identifier,
56 RuntimeBinding,
56 RuntimeBinding,
57 add_binding,
57 add_binding,
58 )
58 )
59 from .shortcuts.filters import KEYBINDING_FILTERS, filter_from_string
59 from .shortcuts.filters import KEYBINDING_FILTERS, filter_from_string
60 from .shortcuts.auto_suggest import (
60 from .shortcuts.auto_suggest import (
61 NavigableAutoSuggestFromHistory,
61 NavigableAutoSuggestFromHistory,
62 AppendAutoSuggestionInAnyLine,
62 AppendAutoSuggestionInAnyLine,
63 )
63 )
64
64
65 PTK3 = ptk_version.startswith('3.')
65 PTK3 = ptk_version.startswith('3.')
66
66
67
67
68 class _NoStyle(Style): pass
68 class _NoStyle(Style): pass
69
69
70
70
71
71
72 _style_overrides_light_bg = {
72 _style_overrides_light_bg = {
73 Token.Prompt: '#ansibrightblue',
73 Token.Prompt: '#ansibrightblue',
74 Token.PromptNum: '#ansiblue bold',
74 Token.PromptNum: '#ansiblue bold',
75 Token.OutPrompt: '#ansibrightred',
75 Token.OutPrompt: '#ansibrightred',
76 Token.OutPromptNum: '#ansired bold',
76 Token.OutPromptNum: '#ansired bold',
77 }
77 }
78
78
79 _style_overrides_linux = {
79 _style_overrides_linux = {
80 Token.Prompt: '#ansibrightgreen',
80 Token.Prompt: '#ansibrightgreen',
81 Token.PromptNum: '#ansigreen bold',
81 Token.PromptNum: '#ansigreen bold',
82 Token.OutPrompt: '#ansibrightred',
82 Token.OutPrompt: '#ansibrightred',
83 Token.OutPromptNum: '#ansired bold',
83 Token.OutPromptNum: '#ansired bold',
84 }
84 }
85
85
86 def get_default_editor():
86 def get_default_editor():
87 try:
87 try:
88 return os.environ['EDITOR']
88 return os.environ['EDITOR']
89 except KeyError:
89 except KeyError:
90 pass
90 pass
91 except UnicodeError:
91 except UnicodeError:
92 warn("$EDITOR environment variable is not pure ASCII. Using platform "
92 warn("$EDITOR environment variable is not pure ASCII. Using platform "
93 "default editor.")
93 "default editor.")
94
94
95 if os.name == 'posix':
95 if os.name == 'posix':
96 return 'vi' # the only one guaranteed to be there!
96 return 'vi' # the only one guaranteed to be there!
97 else:
97 else:
98 return 'notepad' # same in Windows!
98 return 'notepad' # same in Windows!
99
99
100 # conservatively check for tty
100 # conservatively check for tty
101 # overridden streams can result in things like:
101 # overridden streams can result in things like:
102 # - sys.stdin = None
102 # - sys.stdin = None
103 # - no isatty method
103 # - no isatty method
104 for _name in ('stdin', 'stdout', 'stderr'):
104 for _name in ('stdin', 'stdout', 'stderr'):
105 _stream = getattr(sys, _name)
105 _stream = getattr(sys, _name)
106 try:
106 try:
107 if not _stream or not hasattr(_stream, "isatty") or not _stream.isatty():
107 if not _stream or not hasattr(_stream, "isatty") or not _stream.isatty():
108 _is_tty = False
108 _is_tty = False
109 break
109 break
110 except ValueError:
110 except ValueError:
111 # stream is closed
111 # stream is closed
112 _is_tty = False
112 _is_tty = False
113 break
113 break
114 else:
114 else:
115 _is_tty = True
115 _is_tty = True
116
116
117
117
118 _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty)
118 _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty)
119
119
120 def black_reformat_handler(text_before_cursor):
120 def black_reformat_handler(text_before_cursor):
121 """
121 """
122 We do not need to protect against error,
122 We do not need to protect against error,
123 this is taken care at a higher level where any reformat error is ignored.
123 this is taken care at a higher level where any reformat error is ignored.
124 Indeed we may call reformatting on incomplete code.
124 Indeed we may call reformatting on incomplete code.
125 """
125 """
126 import black
126 import black
127
127
128 formatted_text = black.format_str(text_before_cursor, mode=black.FileMode())
128 formatted_text = black.format_str(text_before_cursor, mode=black.FileMode())
129 if not text_before_cursor.endswith("\n") and formatted_text.endswith("\n"):
129 if not text_before_cursor.endswith("\n") and formatted_text.endswith("\n"):
130 formatted_text = formatted_text[:-1]
130 formatted_text = formatted_text[:-1]
131 return formatted_text
131 return formatted_text
132
132
133
133
134 def yapf_reformat_handler(text_before_cursor):
134 def yapf_reformat_handler(text_before_cursor):
135 from yapf.yapflib import file_resources
135 from yapf.yapflib import file_resources
136 from yapf.yapflib import yapf_api
136 from yapf.yapflib import yapf_api
137
137
138 style_config = file_resources.GetDefaultStyleForDir(os.getcwd())
138 style_config = file_resources.GetDefaultStyleForDir(os.getcwd())
139 formatted_text, was_formatted = yapf_api.FormatCode(
139 formatted_text, was_formatted = yapf_api.FormatCode(
140 text_before_cursor, style_config=style_config
140 text_before_cursor, style_config=style_config
141 )
141 )
142 if was_formatted:
142 if was_formatted:
143 if not text_before_cursor.endswith("\n") and formatted_text.endswith("\n"):
143 if not text_before_cursor.endswith("\n") and formatted_text.endswith("\n"):
144 formatted_text = formatted_text[:-1]
144 formatted_text = formatted_text[:-1]
145 return formatted_text
145 return formatted_text
146 else:
146 else:
147 return text_before_cursor
147 return text_before_cursor
148
148
149
149
150 class PtkHistoryAdapter(History):
150 class PtkHistoryAdapter(History):
151 """
151 """
152 Prompt toolkit has it's own way of handling history, Where it assumes it can
152 Prompt toolkit has it's own way of handling history, Where it assumes it can
153 Push/pull from history.
153 Push/pull from history.
154
154
155 """
155 """
156
156
157 def __init__(self, shell):
157 def __init__(self, shell):
158 super().__init__()
158 super().__init__()
159 self.shell = shell
159 self.shell = shell
160 self._refresh()
160 self._refresh()
161
161
162 def append_string(self, string):
162 def append_string(self, string):
163 # we rely on sql for that.
163 # we rely on sql for that.
164 self._loaded = False
164 self._loaded = False
165 self._refresh()
165 self._refresh()
166
166
167 def _refresh(self):
167 def _refresh(self):
168 if not self._loaded:
168 if not self._loaded:
169 self._loaded_strings = list(self.load_history_strings())
169 self._loaded_strings = list(self.load_history_strings())
170
170
171 def load_history_strings(self):
171 def load_history_strings(self):
172 last_cell = ""
172 last_cell = ""
173 res = []
173 res = []
174 for __, ___, cell in self.shell.history_manager.get_tail(
174 for __, ___, cell in self.shell.history_manager.get_tail(
175 self.shell.history_load_length, include_latest=True
175 self.shell.history_load_length, include_latest=True
176 ):
176 ):
177 # Ignore blank lines and consecutive duplicates
177 # Ignore blank lines and consecutive duplicates
178 cell = cell.rstrip()
178 cell = cell.rstrip()
179 if cell and (cell != last_cell):
179 if cell and (cell != last_cell):
180 res.append(cell)
180 res.append(cell)
181 last_cell = cell
181 last_cell = cell
182 yield from res[::-1]
182 yield from res[::-1]
183
183
184 def store_string(self, string: str) -> None:
184 def store_string(self, string: str) -> None:
185 pass
185 pass
186
186
187 class TerminalInteractiveShell(InteractiveShell):
187 class TerminalInteractiveShell(InteractiveShell):
188 mime_renderers = Dict().tag(config=True)
188 mime_renderers = Dict().tag(config=True)
189
189
190 space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
190 space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
191 'to reserve for the tab completion menu, '
191 'to reserve for the tab completion menu, '
192 'search history, ...etc, the height of '
192 'search history, ...etc, the height of '
193 'these menus will at most this value. '
193 'these menus will at most this value. '
194 'Increase it is you prefer long and skinny '
194 'Increase it is you prefer long and skinny '
195 'menus, decrease for short and wide.'
195 'menus, decrease for short and wide.'
196 ).tag(config=True)
196 ).tag(config=True)
197
197
198 pt_app: UnionType[PromptSession, None] = None
198 pt_app: UnionType[PromptSession, None] = None
199 auto_suggest: UnionType[
199 auto_suggest: UnionType[
200 AutoSuggestFromHistory, NavigableAutoSuggestFromHistory, None
200 AutoSuggestFromHistory, NavigableAutoSuggestFromHistory, None
201 ] = None
201 ] = None
202 debugger_history = None
202 debugger_history = None
203
203
204 debugger_history_file = Unicode(
204 debugger_history_file = Unicode(
205 "~/.pdbhistory", help="File in which to store and read history"
205 "~/.pdbhistory", help="File in which to store and read history"
206 ).tag(config=True)
206 ).tag(config=True)
207
207
208 simple_prompt = Bool(_use_simple_prompt,
208 simple_prompt = Bool(_use_simple_prompt,
209 help="""Use `raw_input` for the REPL, without completion and prompt colors.
209 help="""Use `raw_input` for the REPL, without completion and prompt colors.
210
210
211 Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are:
211 Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are:
212 IPython own testing machinery, and emacs inferior-shell integration through elpy.
212 IPython own testing machinery, and emacs inferior-shell integration through elpy.
213
213
214 This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT`
214 This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT`
215 environment variable is set, or the current terminal is not a tty."""
215 environment variable is set, or the current terminal is not a tty."""
216 ).tag(config=True)
216 ).tag(config=True)
217
217
218 @property
218 @property
219 def debugger_cls(self):
219 def debugger_cls(self):
220 return Pdb if self.simple_prompt else TerminalPdb
220 return Pdb if self.simple_prompt else TerminalPdb
221
221
222 confirm_exit = Bool(True,
222 confirm_exit = Bool(True,
223 help="""
223 help="""
224 Set to confirm when you try to exit IPython with an EOF (Control-D
224 Set to confirm when you try to exit IPython with an EOF (Control-D
225 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
225 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
226 you can force a direct exit without any confirmation.""",
226 you can force a direct exit without any confirmation.""",
227 ).tag(config=True)
227 ).tag(config=True)
228
228
229 editing_mode = Unicode('emacs',
229 editing_mode = Unicode('emacs',
230 help="Shortcut style to use at the prompt. 'vi' or 'emacs'.",
230 help="Shortcut style to use at the prompt. 'vi' or 'emacs'.",
231 ).tag(config=True)
231 ).tag(config=True)
232
232
233 emacs_bindings_in_vi_insert_mode = Bool(
233 emacs_bindings_in_vi_insert_mode = Bool(
234 True,
234 True,
235 help="Add shortcuts from 'emacs' insert mode to 'vi' insert mode.",
235 help="Add shortcuts from 'emacs' insert mode to 'vi' insert mode.",
236 ).tag(config=True)
236 ).tag(config=True)
237
237
238 modal_cursor = Bool(
238 modal_cursor = Bool(
239 True,
239 True,
240 help="""
240 help="""
241 Cursor shape changes depending on vi mode: beam in vi insert mode,
241 Cursor shape changes depending on vi mode: beam in vi insert mode,
242 block in nav mode, underscore in replace mode.""",
242 block in nav mode, underscore in replace mode.""",
243 ).tag(config=True)
243 ).tag(config=True)
244
244
245 ttimeoutlen = Float(
245 ttimeoutlen = Float(
246 0.01,
246 0.01,
247 help="""The time in milliseconds that is waited for a key code
247 help="""The time in milliseconds that is waited for a key code
248 to complete.""",
248 to complete.""",
249 ).tag(config=True)
249 ).tag(config=True)
250
250
251 timeoutlen = Float(
251 timeoutlen = Float(
252 0.5,
252 0.5,
253 help="""The time in milliseconds that is waited for a mapped key
253 help="""The time in milliseconds that is waited for a mapped key
254 sequence to complete.""",
254 sequence to complete.""",
255 ).tag(config=True)
255 ).tag(config=True)
256
256
257 autoformatter = Unicode(
257 autoformatter = Unicode(
258 None,
258 None,
259 help="Autoformatter to reformat Terminal code. Can be `'black'`, `'yapf'` or `None`",
259 help="Autoformatter to reformat Terminal code. Can be `'black'`, `'yapf'` or `None`",
260 allow_none=True
260 allow_none=True
261 ).tag(config=True)
261 ).tag(config=True)
262
262
263 auto_match = Bool(
263 auto_match = Bool(
264 False,
264 False,
265 help="""
265 help="""
266 Automatically add/delete closing bracket or quote when opening bracket or quote is entered/deleted.
266 Automatically add/delete closing bracket or quote when opening bracket or quote is entered/deleted.
267 Brackets: (), [], {}
267 Brackets: (), [], {}
268 Quotes: '', \"\"
268 Quotes: '', \"\"
269 """,
269 """,
270 ).tag(config=True)
270 ).tag(config=True)
271
271
272 mouse_support = Bool(False,
272 mouse_support = Bool(False,
273 help="Enable mouse support in the prompt\n(Note: prevents selecting text with the mouse)"
273 help="Enable mouse support in the prompt\n(Note: prevents selecting text with the mouse)"
274 ).tag(config=True)
274 ).tag(config=True)
275
275
276 # We don't load the list of styles for the help string, because loading
276 # We don't load the list of styles for the help string, because loading
277 # Pygments plugins takes time and can cause unexpected errors.
277 # Pygments plugins takes time and can cause unexpected errors.
278 highlighting_style = Union([Unicode('legacy'), Type(klass=Style)],
278 highlighting_style = Union([Unicode('legacy'), Type(klass=Style)],
279 help="""The name or class of a Pygments style to use for syntax
279 help="""The name or class of a Pygments style to use for syntax
280 highlighting. To see available styles, run `pygmentize -L styles`."""
280 highlighting. To see available styles, run `pygmentize -L styles`."""
281 ).tag(config=True)
281 ).tag(config=True)
282
282
283 @validate('editing_mode')
283 @validate('editing_mode')
284 def _validate_editing_mode(self, proposal):
284 def _validate_editing_mode(self, proposal):
285 if proposal['value'].lower() == 'vim':
285 if proposal['value'].lower() == 'vim':
286 proposal['value']= 'vi'
286 proposal['value']= 'vi'
287 elif proposal['value'].lower() == 'default':
287 elif proposal['value'].lower() == 'default':
288 proposal['value']= 'emacs'
288 proposal['value']= 'emacs'
289
289
290 if hasattr(EditingMode, proposal['value'].upper()):
290 if hasattr(EditingMode, proposal['value'].upper()):
291 return proposal['value'].lower()
291 return proposal['value'].lower()
292
292
293 return self.editing_mode
293 return self.editing_mode
294
294
295
295
296 @observe('editing_mode')
296 @observe('editing_mode')
297 def _editing_mode(self, change):
297 def _editing_mode(self, change):
298 if self.pt_app:
298 if self.pt_app:
299 self.pt_app.editing_mode = getattr(EditingMode, change.new.upper())
299 self.pt_app.editing_mode = getattr(EditingMode, change.new.upper())
300
300
301 def _set_formatter(self, formatter):
301 def _set_formatter(self, formatter):
302 if formatter is None:
302 if formatter is None:
303 self.reformat_handler = lambda x:x
303 self.reformat_handler = lambda x:x
304 elif formatter == 'black':
304 elif formatter == 'black':
305 self.reformat_handler = black_reformat_handler
305 self.reformat_handler = black_reformat_handler
306 elif formatter == "yapf":
306 elif formatter == "yapf":
307 self.reformat_handler = yapf_reformat_handler
307 self.reformat_handler = yapf_reformat_handler
308 else:
308 else:
309 raise ValueError
309 raise ValueError
310
310
311 @observe("autoformatter")
311 @observe("autoformatter")
312 def _autoformatter_changed(self, change):
312 def _autoformatter_changed(self, change):
313 formatter = change.new
313 formatter = change.new
314 self._set_formatter(formatter)
314 self._set_formatter(formatter)
315
315
316 @observe('highlighting_style')
316 @observe('highlighting_style')
317 @observe('colors')
317 @observe('colors')
318 def _highlighting_style_changed(self, change):
318 def _highlighting_style_changed(self, change):
319 self.refresh_style()
319 self.refresh_style()
320
320
321 def refresh_style(self):
321 def refresh_style(self):
322 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
322 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
323
323
324
324
325 highlighting_style_overrides = Dict(
325 highlighting_style_overrides = Dict(
326 help="Override highlighting format for specific tokens"
326 help="Override highlighting format for specific tokens"
327 ).tag(config=True)
327 ).tag(config=True)
328
328
329 true_color = Bool(False,
329 true_color = Bool(False,
330 help="""Use 24bit colors instead of 256 colors in prompt highlighting.
330 help="""Use 24bit colors instead of 256 colors in prompt highlighting.
331 If your terminal supports true color, the following command should
331 If your terminal supports true color, the following command should
332 print ``TRUECOLOR`` in orange::
332 print ``TRUECOLOR`` in orange::
333
333
334 printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"
334 printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"
335 """,
335 """,
336 ).tag(config=True)
336 ).tag(config=True)
337
337
338 editor = Unicode(get_default_editor(),
338 editor = Unicode(get_default_editor(),
339 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
339 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
340 ).tag(config=True)
340 ).tag(config=True)
341
341
342 prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True)
342 prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True)
343
343
344 prompts = Instance(Prompts)
344 prompts = Instance(Prompts)
345
345
346 @default('prompts')
346 @default('prompts')
347 def _prompts_default(self):
347 def _prompts_default(self):
348 return self.prompts_class(self)
348 return self.prompts_class(self)
349
349
350 # @observe('prompts')
350 # @observe('prompts')
351 # def _(self, change):
351 # def _(self, change):
352 # self._update_layout()
352 # self._update_layout()
353
353
354 @default('displayhook_class')
354 @default('displayhook_class')
355 def _displayhook_class_default(self):
355 def _displayhook_class_default(self):
356 return RichPromptDisplayHook
356 return RichPromptDisplayHook
357
357
358 term_title = Bool(True,
358 term_title = Bool(True,
359 help="Automatically set the terminal title"
359 help="Automatically set the terminal title"
360 ).tag(config=True)
360 ).tag(config=True)
361
361
362 term_title_format = Unicode("IPython: {cwd}",
362 term_title_format = Unicode("IPython: {cwd}",
363 help="Customize the terminal title format. This is a python format string. " +
363 help="Customize the terminal title format. This is a python format string. " +
364 "Available substitutions are: {cwd}."
364 "Available substitutions are: {cwd}."
365 ).tag(config=True)
365 ).tag(config=True)
366
366
367 display_completions = Enum(('column', 'multicolumn','readlinelike'),
367 display_completions = Enum(('column', 'multicolumn','readlinelike'),
368 help= ( "Options for displaying tab completions, 'column', 'multicolumn', and "
368 help= ( "Options for displaying tab completions, 'column', 'multicolumn', and "
369 "'readlinelike'. These options are for `prompt_toolkit`, see "
369 "'readlinelike'. These options are for `prompt_toolkit`, see "
370 "`prompt_toolkit` documentation for more information."
370 "`prompt_toolkit` documentation for more information."
371 ),
371 ),
372 default_value='multicolumn').tag(config=True)
372 default_value='multicolumn').tag(config=True)
373
373
374 highlight_matching_brackets = Bool(True,
374 highlight_matching_brackets = Bool(True,
375 help="Highlight matching brackets.",
375 help="Highlight matching brackets.",
376 ).tag(config=True)
376 ).tag(config=True)
377
377
378 extra_open_editor_shortcuts = Bool(False,
378 extra_open_editor_shortcuts = Bool(False,
379 help="Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. "
379 help="Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. "
380 "This is in addition to the F2 binding, which is always enabled."
380 "This is in addition to the F2 binding, which is always enabled."
381 ).tag(config=True)
381 ).tag(config=True)
382
382
383 handle_return = Any(None,
383 handle_return = Any(None,
384 help="Provide an alternative handler to be called when the user presses "
384 help="Provide an alternative handler to be called when the user presses "
385 "Return. This is an advanced option intended for debugging, which "
385 "Return. This is an advanced option intended for debugging, which "
386 "may be changed or removed in later releases."
386 "may be changed or removed in later releases."
387 ).tag(config=True)
387 ).tag(config=True)
388
388
389 enable_history_search = Bool(True,
389 enable_history_search = Bool(True,
390 help="Allows to enable/disable the prompt toolkit history search"
390 help="Allows to enable/disable the prompt toolkit history search"
391 ).tag(config=True)
391 ).tag(config=True)
392
392
393 autosuggestions_provider = Unicode(
393 autosuggestions_provider = Unicode(
394 "NavigableAutoSuggestFromHistory",
394 "NavigableAutoSuggestFromHistory",
395 help="Specifies from which source automatic suggestions are provided. "
395 help="Specifies from which source automatic suggestions are provided. "
396 "Can be set to ``'NavigableAutoSuggestFromHistory'`` (:kbd:`up` and "
396 "Can be set to ``'NavigableAutoSuggestFromHistory'`` (:kbd:`up` and "
397 ":kbd:`down` swap suggestions), ``'AutoSuggestFromHistory'``, "
397 ":kbd:`down` swap suggestions), ``'AutoSuggestFromHistory'``, "
398 " or ``None`` to disable automatic suggestions. "
398 " or ``None`` to disable automatic suggestions. "
399 "Default is `'NavigableAutoSuggestFromHistory`'.",
399 "Default is `'NavigableAutoSuggestFromHistory`'.",
400 allow_none=True,
400 allow_none=True,
401 ).tag(config=True)
401 ).tag(config=True)
402
402
403 def _set_autosuggestions(self, provider):
403 def _set_autosuggestions(self, provider):
404 # disconnect old handler
404 # disconnect old handler
405 if self.auto_suggest and isinstance(
405 if self.auto_suggest and isinstance(
406 self.auto_suggest, NavigableAutoSuggestFromHistory
406 self.auto_suggest, NavigableAutoSuggestFromHistory
407 ):
407 ):
408 self.auto_suggest.disconnect()
408 self.auto_suggest.disconnect()
409 if provider is None:
409 if provider is None:
410 self.auto_suggest = None
410 self.auto_suggest = None
411 elif provider == "AutoSuggestFromHistory":
411 elif provider == "AutoSuggestFromHistory":
412 self.auto_suggest = AutoSuggestFromHistory()
412 self.auto_suggest = AutoSuggestFromHistory()
413 elif provider == "NavigableAutoSuggestFromHistory":
413 elif provider == "NavigableAutoSuggestFromHistory":
414 self.auto_suggest = NavigableAutoSuggestFromHistory()
414 self.auto_suggest = NavigableAutoSuggestFromHistory()
415 else:
415 else:
416 raise ValueError("No valid provider.")
416 raise ValueError("No valid provider.")
417 if self.pt_app:
417 if self.pt_app:
418 self.pt_app.auto_suggest = self.auto_suggest
418 self.pt_app.auto_suggest = self.auto_suggest
419
419
420 @observe("autosuggestions_provider")
420 @observe("autosuggestions_provider")
421 def _autosuggestions_provider_changed(self, change):
421 def _autosuggestions_provider_changed(self, change):
422 provider = change.new
422 provider = change.new
423 self._set_autosuggestions(provider)
423 self._set_autosuggestions(provider)
424
424
425 shortcuts = List(
425 shortcuts = List(
426 trait=Dict(
426 trait=Dict(
427 key_trait=Enum(
427 key_trait=Enum(
428 [
428 [
429 "command",
429 "command",
430 "match_keys",
430 "match_keys",
431 "match_filter",
431 "match_filter",
432 "new_keys",
432 "new_keys",
433 "new_filter",
433 "new_filter",
434 "create",
434 "create",
435 ]
435 ]
436 ),
436 ),
437 per_key_traits={
437 per_key_traits={
438 "command": Unicode(),
438 "command": Unicode(),
439 "match_keys": List(Unicode()),
439 "match_keys": List(Unicode()),
440 "match_filter": Unicode(),
440 "match_filter": Unicode(),
441 "new_keys": List(Unicode()),
441 "new_keys": List(Unicode()),
442 "new_filter": Unicode(),
442 "new_filter": Unicode(),
443 "create": Bool(False),
443 "create": Bool(False),
444 },
444 },
445 ),
445 ),
446 help="""Add, disable or modifying shortcuts.
446 help="""Add, disable or modifying shortcuts.
447
447
448 Each entry on the list should be a dictionary with ``command`` key
448 Each entry on the list should be a dictionary with ``command`` key
449 identifying the target function executed by the shortcut and at least
449 identifying the target function executed by the shortcut and at least
450 one of the following:
450 one of the following:
451
451
452 - ``match_keys``: list of keys used to match an existing shortcut,
452 - ``match_keys``: list of keys used to match an existing shortcut,
453 - ``match_filter``: shortcut filter used to match an existing shortcut,
453 - ``match_filter``: shortcut filter used to match an existing shortcut,
454 - ``new_keys``: list of keys to set,
454 - ``new_keys``: list of keys to set,
455 - ``new_filter``: a new shortcut filter to set
455 - ``new_filter``: a new shortcut filter to set
456
456
457 The filters have to be composed of pre-defined verbs and joined by one
457 The filters have to be composed of pre-defined verbs and joined by one
458 of the following conjunctions: ``&`` (and), ``|`` (or), ``~`` (not).
458 of the following conjunctions: ``&`` (and), ``|`` (or), ``~`` (not).
459 The pre-defined verbs are:
459 The pre-defined verbs are:
460
460
461 {}
461 {}
462
462
463
463
464 To disable a shortcut set ``new_keys`` to an empty list.
464 To disable a shortcut set ``new_keys`` to an empty list.
465 To add a shortcut add key ``create`` with value ``True``.
465 To add a shortcut add key ``create`` with value ``True``.
466
466
467 When modifying/disabling shortcuts, ``match_keys``/``match_filter`` can
467 When modifying/disabling shortcuts, ``match_keys``/``match_filter`` can
468 be omitted if the provided specification uniquely identifies a shortcut
468 be omitted if the provided specification uniquely identifies a shortcut
469 to be modified/disabled. When modifying a shortcut ``new_filter`` or
469 to be modified/disabled. When modifying a shortcut ``new_filter`` or
470 ``new_keys`` can be omitted which will result in reuse of the existing
470 ``new_keys`` can be omitted which will result in reuse of the existing
471 filter/keys.
471 filter/keys.
472
472
473 Only shortcuts defined in IPython (and not default prompt-toolkit
473 Only shortcuts defined in IPython (and not default prompt-toolkit
474 shortcuts) can be modified or disabled. The full list of shortcuts,
474 shortcuts) can be modified or disabled. The full list of shortcuts,
475 command identifiers and filters is available under
475 command identifiers and filters is available under
476 :ref:`terminal-shortcuts-list`.
476 :ref:`terminal-shortcuts-list`.
477 """.format(
477 """.format(
478 "\n ".join([f"- `{k}`" for k in KEYBINDING_FILTERS])
478 "\n ".join([f"- `{k}`" for k in KEYBINDING_FILTERS])
479 ),
479 ),
480 ).tag(config=True)
480 ).tag(config=True)
481
481
482 @observe("shortcuts")
482 @observe("shortcuts")
483 def _shortcuts_changed(self, change):
483 def _shortcuts_changed(self, change):
484 if self.pt_app:
484 if self.pt_app:
485 self.pt_app.key_bindings = self._merge_shortcuts(user_shortcuts=change.new)
485 self.pt_app.key_bindings = self._merge_shortcuts(user_shortcuts=change.new)
486
486
487 def _merge_shortcuts(self, user_shortcuts):
487 def _merge_shortcuts(self, user_shortcuts):
488 # rebuild the bindings list from scratch
488 # rebuild the bindings list from scratch
489 key_bindings = create_ipython_shortcuts(self)
489 key_bindings = create_ipython_shortcuts(self)
490
490
491 # for now we only allow adding shortcuts for commands which are already
491 # for now we only allow adding shortcuts for commands which are already
492 # registered; this is a security precaution.
492 # registered; this is a security precaution.
493 known_commands = {
493 known_commands = {
494 create_identifier(binding.handler): binding.handler
494 create_identifier(binding.handler): binding.handler
495 for binding in key_bindings.bindings
495 for binding in key_bindings.bindings
496 }
496 }
497 shortcuts_to_skip = []
497 shortcuts_to_skip = []
498 shortcuts_to_add = []
498 shortcuts_to_add = []
499
499
500 for shortcut in user_shortcuts:
500 for shortcut in user_shortcuts:
501 command_id = shortcut["command"]
501 command_id = shortcut["command"]
502 if command_id not in known_commands:
502 if command_id not in known_commands:
503 allowed_commands = "\n - ".join(known_commands)
503 allowed_commands = "\n - ".join(known_commands)
504 raise ValueError(
504 raise ValueError(
505 f"{command_id} is not a known shortcut command."
505 f"{command_id} is not a known shortcut command."
506 f" Allowed commands are: \n - {allowed_commands}"
506 f" Allowed commands are: \n - {allowed_commands}"
507 )
507 )
508 old_keys = shortcut.get("match_keys", None)
508 old_keys = shortcut.get("match_keys", None)
509 old_filter = (
509 old_filter = (
510 filter_from_string(shortcut["match_filter"])
510 filter_from_string(shortcut["match_filter"])
511 if "match_filter" in shortcut
511 if "match_filter" in shortcut
512 else None
512 else None
513 )
513 )
514 matching = [
514 matching = [
515 binding
515 binding
516 for binding in key_bindings.bindings
516 for binding in key_bindings.bindings
517 if (
517 if (
518 (old_filter is None or binding.filter == old_filter)
518 (old_filter is None or binding.filter == old_filter)
519 and (old_keys is None or [k for k in binding.keys] == old_keys)
519 and (old_keys is None or [k for k in binding.keys] == old_keys)
520 and create_identifier(binding.handler) == command_id
520 and create_identifier(binding.handler) == command_id
521 )
521 )
522 ]
522 ]
523
523
524 new_keys = shortcut.get("new_keys", None)
524 new_keys = shortcut.get("new_keys", None)
525 new_filter = shortcut.get("new_filter", None)
525 new_filter = shortcut.get("new_filter", None)
526
526
527 command = known_commands[command_id]
527 command = known_commands[command_id]
528
528
529 creating_new = shortcut.get("create", False)
529 creating_new = shortcut.get("create", False)
530 modifying_existing = not creating_new and (
530 modifying_existing = not creating_new and (
531 new_keys is not None or new_filter
531 new_keys is not None or new_filter
532 )
532 )
533
533
534 if creating_new and new_keys == []:
534 if creating_new and new_keys == []:
535 raise ValueError("Cannot add a shortcut without keys")
535 raise ValueError("Cannot add a shortcut without keys")
536
536
537 if modifying_existing:
537 if modifying_existing:
538 specification = {
538 specification = {
539 key: shortcut[key]
539 key: shortcut[key]
540 for key in ["command", "filter"]
540 for key in ["command", "filter"]
541 if key in shortcut
541 if key in shortcut
542 }
542 }
543 if len(matching) == 0:
543 if len(matching) == 0:
544 raise ValueError(f"No shortcuts matching {specification} found")
544 raise ValueError(f"No shortcuts matching {specification} found")
545 elif len(matching) > 1:
545 elif len(matching) > 1:
546 raise ValueError(
546 raise ValueError(
547 f"Multiple shortcuts matching {specification} found,"
547 f"Multiple shortcuts matching {specification} found,"
548 f" please add keys/filter to select one of: {matching}"
548 f" please add keys/filter to select one of: {matching}"
549 )
549 )
550
550
551 matched = matching[0]
551 matched = matching[0]
552 old_filter = matched.filter
552 old_filter = matched.filter
553 old_keys = list(matched.keys)
553 old_keys = list(matched.keys)
554 shortcuts_to_skip.append(
554 shortcuts_to_skip.append(
555 RuntimeBinding(
555 RuntimeBinding(
556 command,
556 command,
557 keys=old_keys,
557 keys=old_keys,
558 filter=old_filter,
558 filter=old_filter,
559 )
559 )
560 )
560 )
561
561
562 if new_keys != []:
562 if new_keys != []:
563 shortcuts_to_add.append(
563 shortcuts_to_add.append(
564 RuntimeBinding(
564 RuntimeBinding(
565 command,
565 command,
566 keys=new_keys or old_keys,
566 keys=new_keys or old_keys,
567 filter=filter_from_string(new_filter)
567 filter=filter_from_string(new_filter)
568 if new_filter is not None
568 if new_filter is not None
569 else (
569 else (
570 old_filter
570 old_filter
571 if old_filter is not None
571 if old_filter is not None
572 else filter_from_string("always")
572 else filter_from_string("always")
573 ),
573 ),
574 )
574 )
575 )
575 )
576
576
577 # rebuild the bindings list from scratch
577 # rebuild the bindings list from scratch
578 key_bindings = create_ipython_shortcuts(self, skip=shortcuts_to_skip)
578 key_bindings = create_ipython_shortcuts(self, skip=shortcuts_to_skip)
579 for binding in shortcuts_to_add:
579 for binding in shortcuts_to_add:
580 add_binding(key_bindings, binding)
580 add_binding(key_bindings, binding)
581
581
582 return key_bindings
582 return key_bindings
583
583
584 prompt_includes_vi_mode = Bool(True,
584 prompt_includes_vi_mode = Bool(True,
585 help="Display the current vi mode (when using vi editing mode)."
585 help="Display the current vi mode (when using vi editing mode)."
586 ).tag(config=True)
586 ).tag(config=True)
587
587
588 @observe('term_title')
588 @observe('term_title')
589 def init_term_title(self, change=None):
589 def init_term_title(self, change=None):
590 # Enable or disable the terminal title.
590 # Enable or disable the terminal title.
591 if self.term_title and _is_tty:
591 if self.term_title and _is_tty:
592 toggle_set_term_title(True)
592 toggle_set_term_title(True)
593 set_term_title(self.term_title_format.format(cwd=abbrev_cwd()))
593 set_term_title(self.term_title_format.format(cwd=abbrev_cwd()))
594 else:
594 else:
595 toggle_set_term_title(False)
595 toggle_set_term_title(False)
596
596
597 def restore_term_title(self):
597 def restore_term_title(self):
598 if self.term_title and _is_tty:
598 if self.term_title and _is_tty:
599 restore_term_title()
599 restore_term_title()
600
600
601 def init_display_formatter(self):
601 def init_display_formatter(self):
602 super(TerminalInteractiveShell, self).init_display_formatter()
602 super(TerminalInteractiveShell, self).init_display_formatter()
603 # terminal only supports plain text
603 # terminal only supports plain text
604 self.display_formatter.active_types = ["text/plain"]
604 self.display_formatter.active_types = ["text/plain"]
605
605
606 def init_prompt_toolkit_cli(self):
606 def init_prompt_toolkit_cli(self):
607 if self.simple_prompt:
607 if self.simple_prompt:
608 # Fall back to plain non-interactive output for tests.
608 # Fall back to plain non-interactive output for tests.
609 # This is very limited.
609 # This is very limited.
610 def prompt():
610 def prompt():
611 prompt_text = "".join(x[1] for x in self.prompts.in_prompt_tokens())
611 prompt_text = "".join(x[1] for x in self.prompts.in_prompt_tokens())
612 lines = [input(prompt_text)]
612 lines = [input(prompt_text)]
613 prompt_continuation = "".join(x[1] for x in self.prompts.continuation_prompt_tokens())
613 prompt_continuation = "".join(x[1] for x in self.prompts.continuation_prompt_tokens())
614 while self.check_complete('\n'.join(lines))[0] == 'incomplete':
614 while self.check_complete('\n'.join(lines))[0] == 'incomplete':
615 lines.append( input(prompt_continuation) )
615 lines.append( input(prompt_continuation) )
616 return '\n'.join(lines)
616 return '\n'.join(lines)
617 self.prompt_for_code = prompt
617 self.prompt_for_code = prompt
618 return
618 return
619
619
620 # Set up keyboard shortcuts
620 # Set up keyboard shortcuts
621 key_bindings = self._merge_shortcuts(user_shortcuts=self.shortcuts)
621 key_bindings = self._merge_shortcuts(user_shortcuts=self.shortcuts)
622
622
623 # Pre-populate history from IPython's history database
623 # Pre-populate history from IPython's history database
624 history = PtkHistoryAdapter(self)
624 history = PtkHistoryAdapter(self)
625
625
626 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
626 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
627 self.style = DynamicStyle(lambda: self._style)
627 self.style = DynamicStyle(lambda: self._style)
628
628
629 editing_mode = getattr(EditingMode, self.editing_mode.upper())
629 editing_mode = getattr(EditingMode, self.editing_mode.upper())
630
630
631 self.pt_loop = asyncio.new_event_loop()
631 self.pt_loop = asyncio.new_event_loop()
632 self.pt_app = PromptSession(
632 self.pt_app = PromptSession(
633 auto_suggest=self.auto_suggest,
633 auto_suggest=self.auto_suggest,
634 editing_mode=editing_mode,
634 editing_mode=editing_mode,
635 key_bindings=key_bindings,
635 key_bindings=key_bindings,
636 history=history,
636 history=history,
637 completer=IPythonPTCompleter(shell=self),
637 completer=IPythonPTCompleter(shell=self),
638 enable_history_search=self.enable_history_search,
638 enable_history_search=self.enable_history_search,
639 style=self.style,
639 style=self.style,
640 include_default_pygments_style=False,
640 include_default_pygments_style=False,
641 mouse_support=self.mouse_support,
641 mouse_support=self.mouse_support,
642 enable_open_in_editor=self.extra_open_editor_shortcuts,
642 enable_open_in_editor=self.extra_open_editor_shortcuts,
643 color_depth=self.color_depth,
643 color_depth=self.color_depth,
644 tempfile_suffix=".py",
644 tempfile_suffix=".py",
645 **self._extra_prompt_options(),
645 **self._extra_prompt_options(),
646 )
646 )
647 if isinstance(self.auto_suggest, NavigableAutoSuggestFromHistory):
647 if isinstance(self.auto_suggest, NavigableAutoSuggestFromHistory):
648 self.auto_suggest.connect(self.pt_app)
648 self.auto_suggest.connect(self.pt_app)
649
649
650 def _make_style_from_name_or_cls(self, name_or_cls):
650 def _make_style_from_name_or_cls(self, name_or_cls):
651 """
651 """
652 Small wrapper that make an IPython compatible style from a style name
652 Small wrapper that make an IPython compatible style from a style name
653
653
654 We need that to add style for prompt ... etc.
654 We need that to add style for prompt ... etc.
655 """
655 """
656 style_overrides = {}
656 style_overrides = {}
657 if name_or_cls == 'legacy':
657 if name_or_cls == 'legacy':
658 legacy = self.colors.lower()
658 legacy = self.colors.lower()
659 if legacy == 'linux':
659 if legacy == 'linux':
660 style_cls = get_style_by_name('monokai')
660 style_cls = get_style_by_name('monokai')
661 style_overrides = _style_overrides_linux
661 style_overrides = _style_overrides_linux
662 elif legacy == 'lightbg':
662 elif legacy == 'lightbg':
663 style_overrides = _style_overrides_light_bg
663 style_overrides = _style_overrides_light_bg
664 style_cls = get_style_by_name('pastie')
664 style_cls = get_style_by_name('pastie')
665 elif legacy == 'neutral':
665 elif legacy == 'neutral':
666 # The default theme needs to be visible on both a dark background
666 # The default theme needs to be visible on both a dark background
667 # and a light background, because we can't tell what the terminal
667 # and a light background, because we can't tell what the terminal
668 # looks like. These tweaks to the default theme help with that.
668 # looks like. These tweaks to the default theme help with that.
669 style_cls = get_style_by_name('default')
669 style_cls = get_style_by_name('default')
670 style_overrides.update({
670 style_overrides.update({
671 Token.Number: '#ansigreen',
671 Token.Number: '#ansigreen',
672 Token.Operator: 'noinherit',
672 Token.Operator: 'noinherit',
673 Token.String: '#ansiyellow',
673 Token.String: '#ansiyellow',
674 Token.Name.Function: '#ansiblue',
674 Token.Name.Function: '#ansiblue',
675 Token.Name.Class: 'bold #ansiblue',
675 Token.Name.Class: 'bold #ansiblue',
676 Token.Name.Namespace: 'bold #ansiblue',
676 Token.Name.Namespace: 'bold #ansiblue',
677 Token.Name.Variable.Magic: '#ansiblue',
677 Token.Name.Variable.Magic: '#ansiblue',
678 Token.Prompt: '#ansigreen',
678 Token.Prompt: '#ansigreen',
679 Token.PromptNum: '#ansibrightgreen bold',
679 Token.PromptNum: '#ansibrightgreen bold',
680 Token.OutPrompt: '#ansired',
680 Token.OutPrompt: '#ansired',
681 Token.OutPromptNum: '#ansibrightred bold',
681 Token.OutPromptNum: '#ansibrightred bold',
682 })
682 })
683
683
684 # Hack: Due to limited color support on the Windows console
684 # Hack: Due to limited color support on the Windows console
685 # the prompt colors will be wrong without this
685 # the prompt colors will be wrong without this
686 if os.name == 'nt':
686 if os.name == 'nt':
687 style_overrides.update({
687 style_overrides.update({
688 Token.Prompt: '#ansidarkgreen',
688 Token.Prompt: '#ansidarkgreen',
689 Token.PromptNum: '#ansigreen bold',
689 Token.PromptNum: '#ansigreen bold',
690 Token.OutPrompt: '#ansidarkred',
690 Token.OutPrompt: '#ansidarkred',
691 Token.OutPromptNum: '#ansired bold',
691 Token.OutPromptNum: '#ansired bold',
692 })
692 })
693 elif legacy =='nocolor':
693 elif legacy =='nocolor':
694 style_cls=_NoStyle
694 style_cls=_NoStyle
695 style_overrides = {}
695 style_overrides = {}
696 else :
696 else :
697 raise ValueError('Got unknown colors: ', legacy)
697 raise ValueError('Got unknown colors: ', legacy)
698 else :
698 else :
699 if isinstance(name_or_cls, str):
699 if isinstance(name_or_cls, str):
700 style_cls = get_style_by_name(name_or_cls)
700 style_cls = get_style_by_name(name_or_cls)
701 else:
701 else:
702 style_cls = name_or_cls
702 style_cls = name_or_cls
703 style_overrides = {
703 style_overrides = {
704 Token.Prompt: '#ansigreen',
704 Token.Prompt: '#ansigreen',
705 Token.PromptNum: '#ansibrightgreen bold',
705 Token.PromptNum: '#ansibrightgreen bold',
706 Token.OutPrompt: '#ansired',
706 Token.OutPrompt: '#ansired',
707 Token.OutPromptNum: '#ansibrightred bold',
707 Token.OutPromptNum: '#ansibrightred bold',
708 }
708 }
709 style_overrides.update(self.highlighting_style_overrides)
709 style_overrides.update(self.highlighting_style_overrides)
710 style = merge_styles([
710 style = merge_styles([
711 style_from_pygments_cls(style_cls),
711 style_from_pygments_cls(style_cls),
712 style_from_pygments_dict(style_overrides),
712 style_from_pygments_dict(style_overrides),
713 ])
713 ])
714
714
715 return style
715 return style
716
716
717 @property
717 @property
718 def pt_complete_style(self):
718 def pt_complete_style(self):
719 return {
719 return {
720 'multicolumn': CompleteStyle.MULTI_COLUMN,
720 'multicolumn': CompleteStyle.MULTI_COLUMN,
721 'column': CompleteStyle.COLUMN,
721 'column': CompleteStyle.COLUMN,
722 'readlinelike': CompleteStyle.READLINE_LIKE,
722 'readlinelike': CompleteStyle.READLINE_LIKE,
723 }[self.display_completions]
723 }[self.display_completions]
724
724
725 @property
725 @property
726 def color_depth(self):
726 def color_depth(self):
727 return (ColorDepth.TRUE_COLOR if self.true_color else None)
727 return (ColorDepth.TRUE_COLOR if self.true_color else None)
728
728
729 def _extra_prompt_options(self):
729 def _extra_prompt_options(self):
730 """
730 """
731 Return the current layout option for the current Terminal InteractiveShell
731 Return the current layout option for the current Terminal InteractiveShell
732 """
732 """
733 def get_message():
733 def get_message():
734 return PygmentsTokens(self.prompts.in_prompt_tokens())
734 return PygmentsTokens(self.prompts.in_prompt_tokens())
735
735
736 if self.editing_mode == 'emacs':
736 if self.editing_mode == 'emacs':
737 # with emacs mode the prompt is (usually) static, so we call only
737 # with emacs mode the prompt is (usually) static, so we call only
738 # the function once. With VI mode it can toggle between [ins] and
738 # the function once. With VI mode it can toggle between [ins] and
739 # [nor] so we can't precompute.
739 # [nor] so we can't precompute.
740 # here I'm going to favor the default keybinding which almost
740 # here I'm going to favor the default keybinding which almost
741 # everybody uses to decrease CPU usage.
741 # everybody uses to decrease CPU usage.
742 # if we have issues with users with custom Prompts we can see how to
742 # if we have issues with users with custom Prompts we can see how to
743 # work around this.
743 # work around this.
744 get_message = get_message()
744 get_message = get_message()
745
745
746 options = {
746 options = {
747 "complete_in_thread": False,
747 "complete_in_thread": False,
748 "lexer": IPythonPTLexer(),
748 "lexer": IPythonPTLexer(),
749 "reserve_space_for_menu": self.space_for_menu,
749 "reserve_space_for_menu": self.space_for_menu,
750 "message": get_message,
750 "message": get_message,
751 "prompt_continuation": (
751 "prompt_continuation": (
752 lambda width, lineno, is_soft_wrap: PygmentsTokens(
752 lambda width, lineno, is_soft_wrap: PygmentsTokens(
753 self.prompts.continuation_prompt_tokens(width)
753 self.prompts.continuation_prompt_tokens(width)
754 )
754 )
755 ),
755 ),
756 "multiline": True,
756 "multiline": True,
757 "complete_style": self.pt_complete_style,
757 "complete_style": self.pt_complete_style,
758 "input_processors": [
758 "input_processors": [
759 # Highlight matching brackets, but only when this setting is
759 # Highlight matching brackets, but only when this setting is
760 # enabled, and only when the DEFAULT_BUFFER has the focus.
760 # enabled, and only when the DEFAULT_BUFFER has the focus.
761 ConditionalProcessor(
761 ConditionalProcessor(
762 processor=HighlightMatchingBracketProcessor(chars="[](){}"),
762 processor=HighlightMatchingBracketProcessor(chars="[](){}"),
763 filter=HasFocus(DEFAULT_BUFFER)
763 filter=HasFocus(DEFAULT_BUFFER)
764 & ~IsDone()
764 & ~IsDone()
765 & Condition(lambda: self.highlight_matching_brackets),
765 & Condition(lambda: self.highlight_matching_brackets),
766 ),
766 ),
767 # Show auto-suggestion in lines other than the last line.
767 # Show auto-suggestion in lines other than the last line.
768 ConditionalProcessor(
768 ConditionalProcessor(
769 processor=AppendAutoSuggestionInAnyLine(),
769 processor=AppendAutoSuggestionInAnyLine(),
770 filter=HasFocus(DEFAULT_BUFFER)
770 filter=HasFocus(DEFAULT_BUFFER)
771 & ~IsDone()
771 & ~IsDone()
772 & Condition(
772 & Condition(
773 lambda: isinstance(
773 lambda: isinstance(
774 self.auto_suggest, NavigableAutoSuggestFromHistory
774 self.auto_suggest, NavigableAutoSuggestFromHistory
775 )
775 )
776 ),
776 ),
777 ),
777 ),
778 ],
778 ],
779 }
779 }
780 if not PTK3:
780 if not PTK3:
781 options['inputhook'] = self.inputhook
781 options['inputhook'] = self.inputhook
782
782
783 return options
783 return options
784
784
785 def prompt_for_code(self):
785 def prompt_for_code(self):
786 if self.rl_next_input:
786 if self.rl_next_input:
787 default = self.rl_next_input
787 default = self.rl_next_input
788 self.rl_next_input = None
788 self.rl_next_input = None
789 else:
789 else:
790 default = ''
790 default = ''
791
791
792 # In order to make sure that asyncio code written in the
792 # In order to make sure that asyncio code written in the
793 # interactive shell doesn't interfere with the prompt, we run the
793 # interactive shell doesn't interfere with the prompt, we run the
794 # prompt in a different event loop.
794 # prompt in a different event loop.
795 # If we don't do this, people could spawn coroutine with a
795 # If we don't do this, people could spawn coroutine with a
796 # while/true inside which will freeze the prompt.
796 # while/true inside which will freeze the prompt.
797
797
798 policy = asyncio.get_event_loop_policy()
798 policy = asyncio.get_event_loop_policy()
799 old_loop = get_asyncio_loop()
799 old_loop = get_asyncio_loop()
800
800
801 # FIXME: prompt_toolkit is using the deprecated `asyncio.get_event_loop`
801 # FIXME: prompt_toolkit is using the deprecated `asyncio.get_event_loop`
802 # to get the current event loop.
802 # to get the current event loop.
803 # This will probably be replaced by an attribute or input argument,
803 # This will probably be replaced by an attribute or input argument,
804 # at which point we can stop calling the soon-to-be-deprecated `set_event_loop` here.
804 # at which point we can stop calling the soon-to-be-deprecated `set_event_loop` here.
805 if old_loop is not self.pt_loop:
805 if old_loop is not self.pt_loop:
806 policy.set_event_loop(self.pt_loop)
806 policy.set_event_loop(self.pt_loop)
807 try:
807 try:
808 with patch_stdout(raw=True):
808 with patch_stdout(raw=True):
809 text = self.pt_app.prompt(
809 text = self.pt_app.prompt(
810 default=default,
810 default=default,
811 **self._extra_prompt_options())
811 **self._extra_prompt_options())
812 finally:
812 finally:
813 # Restore the original event loop.
813 # Restore the original event loop.
814 if old_loop is not None and old_loop is not self.pt_loop:
814 if old_loop is not None and old_loop is not self.pt_loop:
815 policy.set_event_loop(old_loop)
815 policy.set_event_loop(old_loop)
816
816
817 return text
817 return text
818
818
819 def enable_win_unicode_console(self):
819 def enable_win_unicode_console(self):
820 # Since IPython 7.10 doesn't support python < 3.6 and PEP 528, Python uses the unicode APIs for the Windows
820 # Since IPython 7.10 doesn't support python < 3.6 and PEP 528, Python uses the unicode APIs for the Windows
821 # console by default, so WUC shouldn't be needed.
821 # console by default, so WUC shouldn't be needed.
822 warn("`enable_win_unicode_console` is deprecated since IPython 7.10, does not do anything and will be removed in the future",
822 warn("`enable_win_unicode_console` is deprecated since IPython 7.10, does not do anything and will be removed in the future",
823 DeprecationWarning,
823 DeprecationWarning,
824 stacklevel=2)
824 stacklevel=2)
825
825
826 def init_io(self):
826 def init_io(self):
827 if sys.platform not in {'win32', 'cli'}:
827 if sys.platform not in {'win32', 'cli'}:
828 return
828 return
829
829
830 import colorama
830 import colorama
831 colorama.init()
831 colorama.init()
832
832
833 def init_magics(self):
833 def init_magics(self):
834 super(TerminalInteractiveShell, self).init_magics()
834 super(TerminalInteractiveShell, self).init_magics()
835 self.register_magics(TerminalMagics)
835 self.register_magics(TerminalMagics)
836
836
837 def init_alias(self):
837 def init_alias(self):
838 # The parent class defines aliases that can be safely used with any
838 # The parent class defines aliases that can be safely used with any
839 # frontend.
839 # frontend.
840 super(TerminalInteractiveShell, self).init_alias()
840 super(TerminalInteractiveShell, self).init_alias()
841
841
842 # Now define aliases that only make sense on the terminal, because they
842 # Now define aliases that only make sense on the terminal, because they
843 # need direct access to the console in a way that we can't emulate in
843 # need direct access to the console in a way that we can't emulate in
844 # GUI or web frontend
844 # GUI or web frontend
845 if os.name == 'posix':
845 if os.name == 'posix':
846 for cmd in ('clear', 'more', 'less', 'man'):
846 for cmd in ('clear', 'more', 'less', 'man'):
847 self.alias_manager.soft_define_alias(cmd, cmd)
847 self.alias_manager.soft_define_alias(cmd, cmd)
848
848
849
849
850 def __init__(self, *args, **kwargs) -> None:
850 def __init__(self, *args, **kwargs) -> None:
851 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
851 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
852 self._set_autosuggestions(self.autosuggestions_provider)
852 self._set_autosuggestions(self.autosuggestions_provider)
853 self.init_prompt_toolkit_cli()
853 self.init_prompt_toolkit_cli()
854 self.init_term_title()
854 self.init_term_title()
855 self.keep_running = True
855 self.keep_running = True
856 self._set_formatter(self.autoformatter)
856 self._set_formatter(self.autoformatter)
857
857
858
858
859 def ask_exit(self):
859 def ask_exit(self):
860 self.keep_running = False
860 self.keep_running = False
861
861
862 rl_next_input = None
862 rl_next_input = None
863
863
864 def interact(self):
864 def interact(self):
865 self.keep_running = True
865 self.keep_running = True
866 while self.keep_running:
866 while self.keep_running:
867 print(self.separate_in, end='')
867 print(self.separate_in, end='')
868
868
869 try:
869 try:
870 code = self.prompt_for_code()
870 code = self.prompt_for_code()
871 except EOFError:
871 except EOFError:
872 if (not self.confirm_exit) \
872 if (not self.confirm_exit) \
873 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
873 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
874 self.ask_exit()
874 self.ask_exit()
875
875
876 else:
876 else:
877 if code:
877 if code:
878 self.run_cell(code, store_history=True)
878 self.run_cell(code, store_history=True)
879
879
880 def mainloop(self):
880 def mainloop(self):
881 # An extra layer of protection in case someone mashing Ctrl-C breaks
881 # An extra layer of protection in case someone mashing Ctrl-C breaks
882 # out of our internal code.
882 # out of our internal code.
883 while True:
883 while True:
884 try:
884 try:
885 self.interact()
885 self.interact()
886 break
886 break
887 except KeyboardInterrupt as e:
887 except KeyboardInterrupt as e:
888 print("\n%s escaped interact()\n" % type(e).__name__)
888 print("\n%s escaped interact()\n" % type(e).__name__)
889 finally:
889 finally:
890 # An interrupt during the eventloop will mess up the
890 # An interrupt during the eventloop will mess up the
891 # internal state of the prompt_toolkit library.
891 # internal state of the prompt_toolkit library.
892 # Stopping the eventloop fixes this, see
892 # Stopping the eventloop fixes this, see
893 # https://github.com/ipython/ipython/pull/9867
893 # https://github.com/ipython/ipython/pull/9867
894 if hasattr(self, '_eventloop'):
894 if hasattr(self, '_eventloop'):
895 self._eventloop.stop()
895 self._eventloop.stop()
896
896
897 self.restore_term_title()
897 self.restore_term_title()
898
898
899 # try to call some at-exit operation optimistically as some things can't
899 # try to call some at-exit operation optimistically as some things can't
900 # be done during interpreter shutdown. this is technically inaccurate as
900 # be done during interpreter shutdown. this is technically inaccurate as
901 # this make mainlool not re-callable, but that should be a rare if not
901 # this make mainlool not re-callable, but that should be a rare if not
902 # in existent use case.
902 # in existent use case.
903
903
904 self._atexit_once()
904 self._atexit_once()
905
905
906
906
907 _inputhook = None
907 _inputhook = None
908 def inputhook(self, context):
908 def inputhook(self, context):
909 if self._inputhook is not None:
909 if self._inputhook is not None:
910 self._inputhook(context)
910 self._inputhook(context)
911
911
912 active_eventloop = None
912 active_eventloop = None
913 def enable_gui(self, gui=None):
913 def enable_gui(self, gui=None):
914 if self._inputhook is not None and gui is not None:
915 warn(
916 f"Shell was already running a gui event loop for {self.active_eventloop}; switching to {gui}."
917 )
914 if gui and (gui not in {"inline", "webagg"}):
918 if gui and (gui not in {"inline", "webagg"}):
919 # This hook runs with each cycle of the `prompt_toolkit`'s event loop.
915 self.active_eventloop, self._inputhook = get_inputhook_name_and_func(gui)
920 self.active_eventloop, self._inputhook = get_inputhook_name_and_func(gui)
916 else:
921 else:
917 self.active_eventloop = self._inputhook = None
922 self.active_eventloop = self._inputhook = None
918
923
919 # For prompt_toolkit 3.0. We have to create an asyncio event loop with
924 # For prompt_toolkit 3.0. We have to create an asyncio event loop with
920 # this inputhook.
925 # this inputhook.
921 if PTK3:
926 if PTK3:
922 import asyncio
927 import asyncio
923 from prompt_toolkit.eventloop import new_eventloop_with_inputhook
928 from prompt_toolkit.eventloop import new_eventloop_with_inputhook
924
929
925 if gui == 'asyncio':
930 if gui == 'asyncio':
926 # When we integrate the asyncio event loop, run the UI in the
931 # When we integrate the asyncio event loop, run the UI in the
927 # same event loop as the rest of the code. don't use an actual
932 # same event loop as the rest of the code. don't use an actual
928 # input hook. (Asyncio is not made for nesting event loops.)
933 # input hook. (Asyncio is not made for nesting event loops.)
929 self.pt_loop = get_asyncio_loop()
934 self.pt_loop = get_asyncio_loop()
930
935
931 elif self._inputhook:
936 elif self._inputhook:
932 # If an inputhook was set, create a new asyncio event loop with
937 # If an inputhook was set, create a new asyncio event loop with
933 # this inputhook for the prompt.
938 # this inputhook for the prompt.
934 self.pt_loop = new_eventloop_with_inputhook(self._inputhook)
939 self.pt_loop = new_eventloop_with_inputhook(self._inputhook)
935 else:
940 else:
936 # When there's no inputhook, run the prompt in a separate
941 # When there's no inputhook, run the prompt in a separate
937 # asyncio event loop.
942 # asyncio event loop.
938 self.pt_loop = asyncio.new_event_loop()
943 self.pt_loop = asyncio.new_event_loop()
939
944
940 # Run !system commands directly, not through pipes, so terminal programs
945 # Run !system commands directly, not through pipes, so terminal programs
941 # work correctly.
946 # work correctly.
942 system = InteractiveShell.system_raw
947 system = InteractiveShell.system_raw
943
948
944 def auto_rewrite_input(self, cmd):
949 def auto_rewrite_input(self, cmd):
945 """Overridden from the parent class to use fancy rewriting prompt"""
950 """Overridden from the parent class to use fancy rewriting prompt"""
946 if not self.show_rewritten_input:
951 if not self.show_rewritten_input:
947 return
952 return
948
953
949 tokens = self.prompts.rewrite_prompt_tokens()
954 tokens = self.prompts.rewrite_prompt_tokens()
950 if self.pt_app:
955 if self.pt_app:
951 print_formatted_text(PygmentsTokens(tokens), end='',
956 print_formatted_text(PygmentsTokens(tokens), end='',
952 style=self.pt_app.app.style)
957 style=self.pt_app.app.style)
953 print(cmd)
958 print(cmd)
954 else:
959 else:
955 prompt = ''.join(s for t, s in tokens)
960 prompt = ''.join(s for t, s in tokens)
956 print(prompt, cmd, sep='')
961 print(prompt, cmd, sep='')
957
962
958 _prompts_before = None
963 _prompts_before = None
959 def switch_doctest_mode(self, mode):
964 def switch_doctest_mode(self, mode):
960 """Switch prompts to classic for %doctest_mode"""
965 """Switch prompts to classic for %doctest_mode"""
961 if mode:
966 if mode:
962 self._prompts_before = self.prompts
967 self._prompts_before = self.prompts
963 self.prompts = ClassicPrompts(self)
968 self.prompts = ClassicPrompts(self)
964 elif self._prompts_before:
969 elif self._prompts_before:
965 self.prompts = self._prompts_before
970 self.prompts = self._prompts_before
966 self._prompts_before = None
971 self._prompts_before = None
967 # self._update_layout()
972 # self._update_layout()
968
973
969
974
970 InteractiveShellABC.register(TerminalInteractiveShell)
975 InteractiveShellABC.register(TerminalInteractiveShell)
971
976
972 if __name__ == '__main__':
977 if __name__ == '__main__':
973 TerminalInteractiveShell.instance().interact()
978 TerminalInteractiveShell.instance().interact()
@@ -1,62 +1,132 b''
1 import importlib
1 import importlib
2 import os
2 import os
3
3
4 aliases = {
4 aliases = {
5 'qt4': 'qt',
5 'qt4': 'qt',
6 'gtk2': 'gtk',
6 'gtk2': 'gtk',
7 }
7 }
8
8
9 backends = [
9 backends = [
10 "qt",
10 "qt",
11 "qt4",
12 "qt5",
11 "qt5",
13 "qt6",
12 "qt6",
14 "gtk",
13 "gtk",
15 "gtk2",
14 "gtk2",
16 "gtk3",
15 "gtk3",
17 "gtk4",
16 "gtk4",
18 "tk",
17 "tk",
19 "wx",
18 "wx",
20 "pyglet",
19 "pyglet",
21 "glut",
20 "glut",
22 "osx",
21 "osx",
23 "asyncio",
22 "asyncio",
24 ]
23 ]
25
24
26 registered = {}
25 registered = {}
27
26
28 def register(name, inputhook):
27 def register(name, inputhook):
29 """Register the function *inputhook* as an event loop integration."""
28 """Register the function *inputhook* as an event loop integration."""
30 registered[name] = inputhook
29 registered[name] = inputhook
31
30
32
31
33 class UnknownBackend(KeyError):
32 class UnknownBackend(KeyError):
34 def __init__(self, name):
33 def __init__(self, name):
35 self.name = name
34 self.name = name
36
35
37 def __str__(self):
36 def __str__(self):
38 return ("No event loop integration for {!r}. "
37 return ("No event loop integration for {!r}. "
39 "Supported event loops are: {}").format(self.name,
38 "Supported event loops are: {}").format(self.name,
40 ', '.join(backends + sorted(registered)))
39 ', '.join(backends + sorted(registered)))
41
40
42
41
42 def set_qt_api(gui):
43 """Sets the `QT_API` environment variable if it isn't already set."""
44
45 qt_api = os.environ.get("QT_API", None)
46
47 from IPython.external.qt_loaders import (
48 QT_API_PYQT,
49 QT_API_PYQT5,
50 QT_API_PYQT6,
51 QT_API_PYSIDE,
52 QT_API_PYSIDE2,
53 QT_API_PYSIDE6,
54 QT_API_PYQTv1,
55 loaded_api,
56 )
57
58 loaded = loaded_api()
59
60 qt_env2gui = {
61 QT_API_PYSIDE: "qt4",
62 QT_API_PYQTv1: "qt4",
63 QT_API_PYQT: "qt4",
64 QT_API_PYSIDE2: "qt5",
65 QT_API_PYQT5: "qt5",
66 QT_API_PYSIDE6: "qt6",
67 QT_API_PYQT6: "qt6",
68 }
69 if loaded is not None and gui != "qt":
70 if qt_env2gui[loaded] != gui:
71 print(
72 f"Cannot switch Qt versions for this session; must use {qt_env2gui[loaded]}."
73 )
74 return
75
76 if qt_api is not None and gui != "qt":
77 if qt_env2gui[qt_api] != gui:
78 print(
79 f'Request for "{gui}" will be ignored because `QT_API` '
80 f'environment variable is set to "{qt_api}"'
81 )
82 else:
83 if gui == "qt5":
84 try:
85 import PyQt5 # noqa
86
87 os.environ["QT_API"] = "pyqt5"
88 except ImportError:
89 try:
90 import PySide2 # noqa
91
92 os.environ["QT_API"] = "pyside2"
93 except ImportError:
94 os.environ["QT_API"] = "pyqt5"
95 elif gui == "qt6":
96 try:
97 import PyQt6 # noqa
98
99 os.environ["QT_API"] = "pyqt6"
100 except ImportError:
101 try:
102 import PySide6 # noqa
103
104 os.environ["QT_API"] = "pyside6"
105 except ImportError:
106 os.environ["QT_API"] = "pyqt6"
107 elif gui == "qt":
108 # Don't set QT_API; let IPython logic choose the version.
109 if "QT_API" in os.environ.keys():
110 del os.environ["QT_API"]
111 else:
112 print(f'Unrecognized Qt version: {gui}. Should be "qt5", "qt6", or "qt".')
113 return
114
115
43 def get_inputhook_name_and_func(gui):
116 def get_inputhook_name_and_func(gui):
44 if gui in registered:
117 if gui in registered:
45 return gui, registered[gui]
118 return gui, registered[gui]
46
119
47 if gui not in backends:
120 if gui not in backends:
48 raise UnknownBackend(gui)
121 raise UnknownBackend(gui)
49
122
50 if gui in aliases:
123 if gui in aliases:
51 return get_inputhook_name_and_func(aliases[gui])
124 return get_inputhook_name_and_func(aliases[gui])
52
125
53 gui_mod = gui
126 gui_mod = gui
54 if gui == "qt5":
127 if gui.startswith("qt"):
55 os.environ["QT_API"] = "pyqt5"
128 set_qt_api(gui)
56 gui_mod = "qt"
57 elif gui == "qt6":
58 os.environ["QT_API"] = "pyqt6"
59 gui_mod = "qt"
129 gui_mod = "qt"
60
130
61 mod = importlib.import_module('IPython.terminal.pt_inputhooks.'+gui_mod)
131 mod = importlib.import_module("IPython.terminal.pt_inputhooks." + gui_mod)
62 return gui, mod.inputhook
132 return gui, mod.inputhook
@@ -1,85 +1,86 b''
1 import sys
1 import sys
2 import os
2 import os
3 from IPython.external.qt_for_kernel import QtCore, QtGui, enum_helper
3 from IPython.external.qt_for_kernel import QtCore, QtGui, enum_helper
4 from IPython import get_ipython
4 from IPython import get_ipython
5
5
6 # If we create a QApplication, keep a reference to it so that it doesn't get
6 # If we create a QApplication, keep a reference to it so that it doesn't get
7 # garbage collected.
7 # garbage collected.
8 _appref = None
8 _appref = None
9 _already_warned = False
9 _already_warned = False
10
10
11
11
12 def _exec(obj):
12 def _exec(obj):
13 # exec on PyQt6, exec_ elsewhere.
13 # exec on PyQt6, exec_ elsewhere.
14 obj.exec() if hasattr(obj, "exec") else obj.exec_()
14 obj.exec() if hasattr(obj, "exec") else obj.exec_()
15
15
16
16
17 def _reclaim_excepthook():
17 def _reclaim_excepthook():
18 shell = get_ipython()
18 shell = get_ipython()
19 if shell is not None:
19 if shell is not None:
20 sys.excepthook = shell.excepthook
20 sys.excepthook = shell.excepthook
21
21
22
22
23 def inputhook(context):
23 def inputhook(context):
24 global _appref
24 global _appref
25 app = QtCore.QCoreApplication.instance()
25 app = QtCore.QCoreApplication.instance()
26 if not app:
26 if not app:
27 if sys.platform == 'linux':
27 if sys.platform == 'linux':
28 if not os.environ.get('DISPLAY') \
28 if not os.environ.get('DISPLAY') \
29 and not os.environ.get('WAYLAND_DISPLAY'):
29 and not os.environ.get('WAYLAND_DISPLAY'):
30 import warnings
30 import warnings
31 global _already_warned
31 global _already_warned
32 if not _already_warned:
32 if not _already_warned:
33 _already_warned = True
33 _already_warned = True
34 warnings.warn(
34 warnings.warn(
35 'The DISPLAY or WAYLAND_DISPLAY environment variable is '
35 'The DISPLAY or WAYLAND_DISPLAY environment variable is '
36 'not set or empty and Qt5 requires this environment '
36 'not set or empty and Qt5 requires this environment '
37 'variable. Deactivate Qt5 code.'
37 'variable. Deactivate Qt5 code.'
38 )
38 )
39 return
39 return
40 try:
40 try:
41 QtCore.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
41 QtCore.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
42 except AttributeError: # Only for Qt>=5.6, <6.
42 except AttributeError: # Only for Qt>=5.6, <6.
43 pass
43 pass
44 try:
44 try:
45 QtCore.QApplication.setHighDpiScaleFactorRoundingPolicy(
45 QtCore.QApplication.setHighDpiScaleFactorRoundingPolicy(
46 QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
46 QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
47 )
47 )
48 except AttributeError: # Only for Qt>=5.14.
48 except AttributeError: # Only for Qt>=5.14.
49 pass
49 pass
50 _appref = app = QtGui.QApplication([" "])
50 _appref = app = QtGui.QApplication([" "])
51
51
52 # "reclaim" IPython sys.excepthook after event loop starts
52 # "reclaim" IPython sys.excepthook after event loop starts
53 # without this, it defaults back to BaseIPythonApplication.excepthook
53 # without this, it defaults back to BaseIPythonApplication.excepthook
54 # and exceptions in the Qt event loop are rendered without traceback
54 # and exceptions in the Qt event loop are rendered without traceback
55 # formatting and look like "bug in IPython".
55 # formatting and look like "bug in IPython".
56 QtCore.QTimer.singleShot(0, _reclaim_excepthook)
56 QtCore.QTimer.singleShot(0, _reclaim_excepthook)
57
57
58 event_loop = QtCore.QEventLoop(app)
58 event_loop = QtCore.QEventLoop(app)
59
59
60 if sys.platform == 'win32':
60 if sys.platform == 'win32':
61 # The QSocketNotifier method doesn't appear to work on Windows.
61 # The QSocketNotifier method doesn't appear to work on Windows.
62 # Use polling instead.
62 # Use polling instead.
63 timer = QtCore.QTimer()
63 timer = QtCore.QTimer()
64 timer.timeout.connect(event_loop.quit)
64 timer.timeout.connect(event_loop.quit)
65 while not context.input_is_ready():
65 while not context.input_is_ready():
66 # NOTE: run the event loop, and after 50 ms, call `quit` to exit it.
66 timer.start(50) # 50 ms
67 timer.start(50) # 50 ms
67 _exec(event_loop)
68 _exec(event_loop)
68 timer.stop()
69 timer.stop()
69 else:
70 else:
70 # On POSIX platforms, we can use a file descriptor to quit the event
71 # On POSIX platforms, we can use a file descriptor to quit the event
71 # loop when there is input ready to read.
72 # loop when there is input ready to read.
72 notifier = QtCore.QSocketNotifier(
73 notifier = QtCore.QSocketNotifier(
73 context.fileno(), enum_helper("QtCore.QSocketNotifier.Type").Read
74 context.fileno(), enum_helper("QtCore.QSocketNotifier.Type").Read
74 )
75 )
75 try:
76 try:
76 # connect the callback we care about before we turn it on
77 # connect the callback we care about before we turn it on
77 # lambda is necessary as PyQT inspect the function signature to know
78 # lambda is necessary as PyQT inspect the function signature to know
78 # what arguments to pass to. See https://github.com/ipython/ipython/pull/12355
79 # what arguments to pass to. See https://github.com/ipython/ipython/pull/12355
79 notifier.activated.connect(lambda: event_loop.exit())
80 notifier.activated.connect(lambda: event_loop.exit())
80 notifier.setEnabled(True)
81 notifier.setEnabled(True)
81 # only start the event loop we are not already flipped
82 # only start the event loop we are not already flipped
82 if not context.input_is_ready():
83 if not context.input_is_ready():
83 _exec(event_loop)
84 _exec(event_loop)
84 finally:
85 finally:
85 notifier.setEnabled(False)
86 notifier.setEnabled(False)
@@ -1,108 +1,108 b''
1 ================================
1 ================================
2 Integrating with GUI event loops
2 Integrating with GUI event loops
3 ================================
3 ================================
4
4
5 When the user types ``%gui qt``, IPython integrates itself with the Qt event
5 When the user types ``%gui qt``, IPython integrates itself with the Qt event
6 loop, so you can use both a GUI and an interactive prompt together. IPython
6 loop, so you can use both a GUI and an interactive prompt together. IPython
7 supports a number of common GUI toolkits, but from IPython 3.0, it is possible
7 supports a number of common GUI toolkits, but from IPython 3.0, it is possible
8 to integrate other event loops without modifying IPython itself.
8 to integrate other event loops without modifying IPython itself.
9
9
10 Supported event loops include ``qt4``, ``qt5``, ``gtk2``, ``gtk3``, ``gtk4``,
10 Supported event loops include ``qt5``, ``qt6``, ``gtk2``, ``gtk3``, ``gtk4``,
11 ``wx``, ``osx`` and ``tk``. Make sure the event loop you specify matches the
11 ``wx``, ``osx`` and ``tk``. Make sure the event loop you specify matches the
12 GUI toolkit used by your own code.
12 GUI toolkit used by your own code.
13
13
14 To make IPython GUI event loop integration occur automatically at every
14 To make IPython GUI event loop integration occur automatically at every
15 startup, set the ``c.InteractiveShellApp.gui`` configuration key in your
15 startup, set the ``c.InteractiveShellApp.gui`` configuration key in your
16 IPython profile (see :ref:`setting_config`).
16 IPython profile (see :ref:`setting_config`).
17
17
18 If the event loop you use is supported by IPython, turning on event loop
18 If the event loop you use is supported by IPython, turning on event loop
19 integration follows the steps just described whether you use Terminal IPython
19 integration follows the steps just described whether you use Terminal IPython
20 or an IPython kernel.
20 or an IPython kernel.
21
21
22 However, the way Terminal IPython handles event loops is very different from
22 However, the way Terminal IPython handles event loops is very different from
23 the way IPython kernel does, so if you need to integrate with a new kind of
23 the way IPython kernel does, so if you need to integrate with a new kind of
24 event loop, different steps are needed to integrate with each.
24 event loop, different steps are needed to integrate with each.
25
25
26 Integrating with a new event loop in the terminal
26 Integrating with a new event loop in the terminal
27 -------------------------------------------------
27 -------------------------------------------------
28
28
29 .. versionchanged:: 5.0
29 .. versionchanged:: 5.0
30
30
31 There is a new API for event loop integration using prompt_toolkit.
31 There is a new API for event loop integration using prompt_toolkit.
32
32
33 In the terminal, IPython uses prompt_toolkit to prompt the user for input.
33 In the terminal, IPython uses prompt_toolkit to prompt the user for input.
34 prompt_toolkit provides hooks to integrate with an external event loop.
34 prompt_toolkit provides hooks to integrate with an external event loop.
35
35
36 To integrate an event loop, define a function which runs the GUI event loop
36 To integrate an event loop, define a function which runs the GUI event loop
37 until there is input waiting for prompt_toolkit to process. There are two ways
37 until there is input waiting for prompt_toolkit to process. There are two ways
38 to detect this condition::
38 to detect this condition::
39
39
40 # Polling for input.
40 # Polling for input.
41 def inputhook(context):
41 def inputhook(context):
42 while not context.input_is_ready():
42 while not context.input_is_ready():
43 # Replace this with the appropriate call for the event loop:
43 # Replace this with the appropriate call for the event loop:
44 iterate_loop_once()
44 iterate_loop_once()
45
45
46 # Using a file descriptor to notify the event loop to stop.
46 # Using a file descriptor to notify the event loop to stop.
47 def inputhook2(context):
47 def inputhook2(context):
48 fd = context.fileno()
48 fd = context.fileno()
49 # Replace the functions below with those for the event loop.
49 # Replace the functions below with those for the event loop.
50 add_file_reader(fd, callback=stop_the_loop)
50 add_file_reader(fd, callback=stop_the_loop)
51 run_the_loop()
51 run_the_loop()
52
52
53 Once you have defined this function, register it with IPython:
53 Once you have defined this function, register it with IPython:
54
54
55 .. currentmodule:: IPython.terminal.pt_inputhooks
55 .. currentmodule:: IPython.terminal.pt_inputhooks
56
56
57 .. function:: register(name, inputhook)
57 .. function:: register(name, inputhook)
58
58
59 Register the function *inputhook* as the event loop integration for the
59 Register the function *inputhook* as the event loop integration for the
60 GUI *name*. If ``name='foo'``, then the user can enable this integration
60 GUI *name*. If ``name='foo'``, then the user can enable this integration
61 by running ``%gui foo``.
61 by running ``%gui foo``.
62
62
63
63
64 Integrating with a new event loop in the kernel
64 Integrating with a new event loop in the kernel
65 -----------------------------------------------
65 -----------------------------------------------
66
66
67 The kernel runs its own event loop, so it's simpler to integrate with others.
67 The kernel runs its own event loop, so it's simpler to integrate with others.
68 IPython allows the other event loop to take control, but it must call
68 IPython allows the other event loop to take control, but it must call
69 :meth:`IPython.kernel.zmq.kernelbase.Kernel.do_one_iteration` periodically.
69 :meth:`IPython.kernel.zmq.kernelbase.Kernel.do_one_iteration` periodically.
70
70
71 To integrate with this, write a function that takes a single argument,
71 To integrate with this, write a function that takes a single argument,
72 the IPython kernel instance, arranges for your event loop to call
72 the IPython kernel instance, arranges for your event loop to call
73 ``kernel.do_one_iteration()`` at least every ``kernel._poll_interval`` seconds,
73 ``kernel.do_one_iteration()`` at least every ``kernel._poll_interval`` seconds,
74 and starts the event loop.
74 and starts the event loop.
75
75
76 Decorate this function with :func:`IPython.kernel.zmq.eventloops.register_integration`,
76 Decorate this function with :func:`IPython.kernel.zmq.eventloops.register_integration`,
77 passing in the names you wish to register it for. Here is a slightly simplified
77 passing in the names you wish to register it for. Here is a slightly simplified
78 version of the Tkinter integration already included in IPython::
78 version of the Tkinter integration already included in IPython::
79
79
80 @register_integration('tk')
80 @register_integration('tk')
81 def loop_tk(kernel):
81 def loop_tk(kernel):
82 """Start a kernel with the Tk event loop."""
82 """Start a kernel with the Tk event loop."""
83 from tkinter import Tk
83 from tkinter import Tk
84
84
85 # Tk uses milliseconds
85 # Tk uses milliseconds
86 poll_interval = int(1000*kernel._poll_interval)
86 poll_interval = int(1000*kernel._poll_interval)
87 # For Tkinter, we create a Tk object and call its withdraw method.
87 # For Tkinter, we create a Tk object and call its withdraw method.
88 class Timer(object):
88 class Timer(object):
89 def __init__(self, func):
89 def __init__(self, func):
90 self.app = Tk()
90 self.app = Tk()
91 self.app.withdraw()
91 self.app.withdraw()
92 self.func = func
92 self.func = func
93
93
94 def on_timer(self):
94 def on_timer(self):
95 self.func()
95 self.func()
96 self.app.after(poll_interval, self.on_timer)
96 self.app.after(poll_interval, self.on_timer)
97
97
98 def start(self):
98 def start(self):
99 self.on_timer() # Call it once to get things going.
99 self.on_timer() # Call it once to get things going.
100 self.app.mainloop()
100 self.app.mainloop()
101
101
102 kernel.timer = Timer(kernel.do_one_iteration)
102 kernel.timer = Timer(kernel.do_one_iteration)
103 kernel.timer.start()
103 kernel.timer.start()
104
104
105 Some event loops can go one better, and integrate checking for messages on the
105 Some event loops can go one better, and integrate checking for messages on the
106 kernel's ZMQ sockets, making the kernel more responsive than plain polling. How
106 kernel's ZMQ sockets, making the kernel more responsive than plain polling. How
107 to do this is outside the scope of this document; if you are interested, look at
107 to do this is outside the scope of this document; if you are interested, look at
108 the integration with Qt in :mod:`IPython.kernel.zmq.eventloops`.
108 the integration with Qt in :mod:`IPython.kernel.zmq.eventloops`.
@@ -1,1044 +1,1037 b''
1 =================
1 =================
2 IPython reference
2 IPython reference
3 =================
3 =================
4
4
5 .. _command_line_options:
5 .. _command_line_options:
6
6
7 Command-line usage
7 Command-line usage
8 ==================
8 ==================
9
9
10 You start IPython with the command::
10 You start IPython with the command::
11
11
12 $ ipython [options] files
12 $ ipython [options] files
13
13
14 If invoked with no options, it executes the file and exits, passing the
14 If invoked with no options, it executes the file and exits, passing the
15 remaining arguments to the script, just as if you had specified the same
15 remaining arguments to the script, just as if you had specified the same
16 command with python. You may need to specify `--` before args to be passed
16 command with python. You may need to specify `--` before args to be passed
17 to the script, to prevent IPython from attempting to parse them.
17 to the script, to prevent IPython from attempting to parse them.
18 If you add the ``-i`` flag, it drops you into the interpreter while still
18 If you add the ``-i`` flag, it drops you into the interpreter while still
19 acknowledging any options you may have set in your ``ipython_config.py``. This
19 acknowledging any options you may have set in your ``ipython_config.py``. This
20 behavior is different from standard Python, which when called as python ``-i``
20 behavior is different from standard Python, which when called as python ``-i``
21 will only execute one file and ignore your configuration setup.
21 will only execute one file and ignore your configuration setup.
22
22
23 Please note that some of the configuration options are not available at the
23 Please note that some of the configuration options are not available at the
24 command line, simply because they are not practical here. Look into your
24 command line, simply because they are not practical here. Look into your
25 configuration files for details on those. There are separate configuration files
25 configuration files for details on those. There are separate configuration files
26 for each profile, and the files look like :file:`ipython_config.py` or
26 for each profile, and the files look like :file:`ipython_config.py` or
27 :file:`ipython_config_{frontendname}.py`. Profile directories look like
27 :file:`ipython_config_{frontendname}.py`. Profile directories look like
28 :file:`profile_{profilename}` and are typically installed in the
28 :file:`profile_{profilename}` and are typically installed in the
29 :envvar:`IPYTHONDIR` directory, which defaults to :file:`$HOME/.ipython`. For
29 :envvar:`IPYTHONDIR` directory, which defaults to :file:`$HOME/.ipython`. For
30 Windows users, :envvar:`HOME` resolves to :file:`C:\\Users\\{YourUserName}` in
30 Windows users, :envvar:`HOME` resolves to :file:`C:\\Users\\{YourUserName}` in
31 most instances.
31 most instances.
32
32
33 Command-line Options
33 Command-line Options
34 --------------------
34 --------------------
35
35
36 To see the options IPython accepts, use ``ipython --help`` (and you probably
36 To see the options IPython accepts, use ``ipython --help`` (and you probably
37 should run the output through a pager such as ``ipython --help | less`` for
37 should run the output through a pager such as ``ipython --help | less`` for
38 more convenient reading). This shows all the options that have a single-word
38 more convenient reading). This shows all the options that have a single-word
39 alias to control them, but IPython lets you configure all of its objects from
39 alias to control them, but IPython lets you configure all of its objects from
40 the command-line by passing the full class name and a corresponding value; type
40 the command-line by passing the full class name and a corresponding value; type
41 ``ipython --help-all`` to see this full list. For example::
41 ``ipython --help-all`` to see this full list. For example::
42
42
43 $ ipython --help-all
43 $ ipython --help-all
44 <...snip...>
44 <...snip...>
45 --matplotlib=<CaselessStrEnum> (InteractiveShellApp.matplotlib)
45 --matplotlib=<CaselessStrEnum> (InteractiveShellApp.matplotlib)
46 Default: None
46 Default: None
47 Choices: ['auto', 'gtk', 'gtk3', 'gtk4', 'inline', 'nbagg', 'notebook', 'osx', 'qt', 'qt4', 'qt5', 'tk', 'wx']
47 Choices: ['auto', 'gtk', 'gtk3', 'gtk4', 'inline', 'nbagg', 'notebook', 'osx', 'qt', 'qt5', 'qt6', 'tk', 'wx']
48 Configure matplotlib for interactive use with the default matplotlib
48 Configure matplotlib for interactive use with the default matplotlib
49 backend.
49 backend.
50 <...snip...>
50 <...snip...>
51
51
52
52
53 Indicate that the following::
53 Indicate that the following::
54
54
55 $ ipython --matplotlib qt
55 $ ipython --matplotlib qt
56
56
57
57
58 is equivalent to::
58 is equivalent to::
59
59
60 $ ipython --InteractiveShellApp.matplotlib='qt'
60 $ ipython --InteractiveShellApp.matplotlib='qt'
61
61
62 Note that in the second form, you *must* use the equal sign, as the expression
62 Note that in the second form, you *must* use the equal sign, as the expression
63 is evaluated as an actual Python assignment. While in the above example the
63 is evaluated as an actual Python assignment. While in the above example the
64 short form is more convenient, only the most common options have a short form,
64 short form is more convenient, only the most common options have a short form,
65 while any configurable variable in IPython can be set at the command-line by
65 while any configurable variable in IPython can be set at the command-line by
66 using the long form. This long form is the same syntax used in the
66 using the long form. This long form is the same syntax used in the
67 configuration files, if you want to set these options permanently.
67 configuration files, if you want to set these options permanently.
68
68
69
69
70 Interactive use
70 Interactive use
71 ===============
71 ===============
72
72
73 IPython is meant to work as a drop-in replacement for the standard interactive
73 IPython is meant to work as a drop-in replacement for the standard interactive
74 interpreter. As such, any code which is valid python should execute normally
74 interpreter. As such, any code which is valid python should execute normally
75 under IPython (cases where this is not true should be reported as bugs). It
75 under IPython (cases where this is not true should be reported as bugs). It
76 does, however, offer many features which are not available at a standard python
76 does, however, offer many features which are not available at a standard python
77 prompt. What follows is a list of these.
77 prompt. What follows is a list of these.
78
78
79
79
80 Caution for Windows users
80 Caution for Windows users
81 -------------------------
81 -------------------------
82
82
83 Windows, unfortunately, uses the ``\`` character as a path separator. This is a
83 Windows, unfortunately, uses the ``\`` character as a path separator. This is a
84 terrible choice, because ``\`` also represents the escape character in most
84 terrible choice, because ``\`` also represents the escape character in most
85 modern programming languages, including Python. For this reason, using '/'
85 modern programming languages, including Python. For this reason, using '/'
86 character is recommended if you have problems with ``\``. However, in Windows
86 character is recommended if you have problems with ``\``. However, in Windows
87 commands '/' flags options, so you can not use it for the root directory. This
87 commands '/' flags options, so you can not use it for the root directory. This
88 means that paths beginning at the root must be typed in a contrived manner
88 means that paths beginning at the root must be typed in a contrived manner
89 like: ``%copy \opt/foo/bar.txt \tmp``
89 like: ``%copy \opt/foo/bar.txt \tmp``
90
90
91 .. _magic:
91 .. _magic:
92
92
93 Magic command system
93 Magic command system
94 --------------------
94 --------------------
95
95
96 IPython will treat any line whose first character is a % as a special
96 IPython will treat any line whose first character is a % as a special
97 call to a 'magic' function. These allow you to control the behavior of
97 call to a 'magic' function. These allow you to control the behavior of
98 IPython itself, plus a lot of system-type features. They are all
98 IPython itself, plus a lot of system-type features. They are all
99 prefixed with a % character, but parameters are given without
99 prefixed with a % character, but parameters are given without
100 parentheses or quotes.
100 parentheses or quotes.
101
101
102 Lines that begin with ``%%`` signal a *cell magic*: they take as arguments not
102 Lines that begin with ``%%`` signal a *cell magic*: they take as arguments not
103 only the rest of the current line, but all lines below them as well, in the
103 only the rest of the current line, but all lines below them as well, in the
104 current execution block. Cell magics can in fact make arbitrary modifications
104 current execution block. Cell magics can in fact make arbitrary modifications
105 to the input they receive, which need not even be valid Python code at all.
105 to the input they receive, which need not even be valid Python code at all.
106 They receive the whole block as a single string.
106 They receive the whole block as a single string.
107
107
108 As a line magic example, the :magic:`cd` magic works just like the OS command of
108 As a line magic example, the :magic:`cd` magic works just like the OS command of
109 the same name::
109 the same name::
110
110
111 In [8]: %cd
111 In [8]: %cd
112 /home/fperez
112 /home/fperez
113
113
114 The following uses the builtin :magic:`timeit` in cell mode::
114 The following uses the builtin :magic:`timeit` in cell mode::
115
115
116 In [10]: %%timeit x = range(10000)
116 In [10]: %%timeit x = range(10000)
117 ...: min(x)
117 ...: min(x)
118 ...: max(x)
118 ...: max(x)
119 ...:
119 ...:
120 1000 loops, best of 3: 438 us per loop
120 1000 loops, best of 3: 438 us per loop
121
121
122 In this case, ``x = range(10000)`` is called as the line argument, and the
122 In this case, ``x = range(10000)`` is called as the line argument, and the
123 block with ``min(x)`` and ``max(x)`` is called as the cell body. The
123 block with ``min(x)`` and ``max(x)`` is called as the cell body. The
124 :magic:`timeit` magic receives both.
124 :magic:`timeit` magic receives both.
125
125
126 If you have 'automagic' enabled (as it is by default), you don't need to type in
126 If you have 'automagic' enabled (as it is by default), you don't need to type in
127 the single ``%`` explicitly for line magics; IPython will scan its internal
127 the single ``%`` explicitly for line magics; IPython will scan its internal
128 list of magic functions and call one if it exists. With automagic on you can
128 list of magic functions and call one if it exists. With automagic on you can
129 then just type ``cd mydir`` to go to directory 'mydir'::
129 then just type ``cd mydir`` to go to directory 'mydir'::
130
130
131 In [9]: cd mydir
131 In [9]: cd mydir
132 /home/fperez/mydir
132 /home/fperez/mydir
133
133
134 Cell magics *always* require an explicit ``%%`` prefix, automagic
134 Cell magics *always* require an explicit ``%%`` prefix, automagic
135 calling only works for line magics.
135 calling only works for line magics.
136
136
137 The automagic system has the lowest possible precedence in name searches, so
137 The automagic system has the lowest possible precedence in name searches, so
138 you can freely use variables with the same names as magic commands. If a magic
138 you can freely use variables with the same names as magic commands. If a magic
139 command is 'shadowed' by a variable, you will need the explicit ``%`` prefix to
139 command is 'shadowed' by a variable, you will need the explicit ``%`` prefix to
140 use it:
140 use it:
141
141
142 .. sourcecode:: ipython
142 .. sourcecode:: ipython
143
143
144 In [1]: cd ipython # %cd is called by automagic
144 In [1]: cd ipython # %cd is called by automagic
145 /home/fperez/ipython
145 /home/fperez/ipython
146
146
147 In [2]: cd=1 # now cd is just a variable
147 In [2]: cd=1 # now cd is just a variable
148
148
149 In [3]: cd .. # and doesn't work as a function anymore
149 In [3]: cd .. # and doesn't work as a function anymore
150 File "<ipython-input-3-9fedb3aff56c>", line 1
150 File "<ipython-input-3-9fedb3aff56c>", line 1
151 cd ..
151 cd ..
152 ^
152 ^
153 SyntaxError: invalid syntax
153 SyntaxError: invalid syntax
154
154
155
155
156 In [4]: %cd .. # but %cd always works
156 In [4]: %cd .. # but %cd always works
157 /home/fperez
157 /home/fperez
158
158
159 In [5]: del cd # if you remove the cd variable, automagic works again
159 In [5]: del cd # if you remove the cd variable, automagic works again
160
160
161 In [6]: cd ipython
161 In [6]: cd ipython
162
162
163 /home/fperez/ipython
163 /home/fperez/ipython
164
164
165 Line magics, if they return a value, can be assigned to a variable using the
165 Line magics, if they return a value, can be assigned to a variable using the
166 syntax ``l = %sx ls`` (which in this particular case returns the result of `ls`
166 syntax ``l = %sx ls`` (which in this particular case returns the result of `ls`
167 as a python list). See :ref:`below <manual_capture>` for more information.
167 as a python list). See :ref:`below <manual_capture>` for more information.
168
168
169 Type ``%magic`` for more information, including a list of all available magic
169 Type ``%magic`` for more information, including a list of all available magic
170 functions at any time and their docstrings. You can also type
170 functions at any time and their docstrings. You can also type
171 ``%magic_function_name?`` (see :ref:`below <dynamic_object_info>` for
171 ``%magic_function_name?`` (see :ref:`below <dynamic_object_info>` for
172 information on the '?' system) to get information about any particular magic
172 information on the '?' system) to get information about any particular magic
173 function you are interested in.
173 function you are interested in.
174
174
175 The API documentation for the :mod:`IPython.core.magic` module contains the full
175 The API documentation for the :mod:`IPython.core.magic` module contains the full
176 docstrings of all currently available magic commands.
176 docstrings of all currently available magic commands.
177
177
178 .. seealso::
178 .. seealso::
179
179
180 :doc:`magics`
180 :doc:`magics`
181 A list of the line and cell magics available in IPython by default
181 A list of the line and cell magics available in IPython by default
182
182
183 :ref:`defining_magics`
183 :ref:`defining_magics`
184 How to define and register additional magic functions
184 How to define and register additional magic functions
185
185
186
186
187 Access to the standard Python help
187 Access to the standard Python help
188 ----------------------------------
188 ----------------------------------
189
189
190 Simply type ``help()`` to access Python's standard help system. You can
190 Simply type ``help()`` to access Python's standard help system. You can
191 also type ``help(object)`` for information about a given object, or
191 also type ``help(object)`` for information about a given object, or
192 ``help('keyword')`` for information on a keyword. You may need to configure your
192 ``help('keyword')`` for information on a keyword. You may need to configure your
193 PYTHONDOCS environment variable for this feature to work correctly.
193 PYTHONDOCS environment variable for this feature to work correctly.
194
194
195 .. _dynamic_object_info:
195 .. _dynamic_object_info:
196
196
197 Dynamic object information
197 Dynamic object information
198 --------------------------
198 --------------------------
199
199
200 Typing ``?word`` or ``word?`` prints detailed information about an object. If
200 Typing ``?word`` or ``word?`` prints detailed information about an object. If
201 certain strings in the object are too long (e.g. function signatures) they get
201 certain strings in the object are too long (e.g. function signatures) they get
202 snipped in the center for brevity. This system gives access variable types and
202 snipped in the center for brevity. This system gives access variable types and
203 values, docstrings, function prototypes and other useful information.
203 values, docstrings, function prototypes and other useful information.
204
204
205 If the information will not fit in the terminal, it is displayed in a pager
205 If the information will not fit in the terminal, it is displayed in a pager
206 (``less`` if available, otherwise a basic internal pager).
206 (``less`` if available, otherwise a basic internal pager).
207
207
208 Typing ``??word`` or ``word??`` gives access to the full information, including
208 Typing ``??word`` or ``word??`` gives access to the full information, including
209 the source code where possible. Long strings are not snipped.
209 the source code where possible. Long strings are not snipped.
210
210
211 The following magic functions are particularly useful for gathering
211 The following magic functions are particularly useful for gathering
212 information about your working environment:
212 information about your working environment:
213
213
214 * :magic:`pdoc` **<object>**: Print (or run through a pager if too long) the
214 * :magic:`pdoc` **<object>**: Print (or run through a pager if too long) the
215 docstring for an object. If the given object is a class, it will
215 docstring for an object. If the given object is a class, it will
216 print both the class and the constructor docstrings.
216 print both the class and the constructor docstrings.
217 * :magic:`pdef` **<object>**: Print the call signature for any callable
217 * :magic:`pdef` **<object>**: Print the call signature for any callable
218 object. If the object is a class, print the constructor information.
218 object. If the object is a class, print the constructor information.
219 * :magic:`psource` **<object>**: Print (or run through a pager if too long)
219 * :magic:`psource` **<object>**: Print (or run through a pager if too long)
220 the source code for an object.
220 the source code for an object.
221 * :magic:`pfile` **<object>**: Show the entire source file where an object was
221 * :magic:`pfile` **<object>**: Show the entire source file where an object was
222 defined via a pager, opening it at the line where the object
222 defined via a pager, opening it at the line where the object
223 definition begins.
223 definition begins.
224 * :magic:`who`/:magic:`whos`: These functions give information about identifiers
224 * :magic:`who`/:magic:`whos`: These functions give information about identifiers
225 you have defined interactively (not things you loaded or defined
225 you have defined interactively (not things you loaded or defined
226 in your configuration files). %who just prints a list of
226 in your configuration files). %who just prints a list of
227 identifiers and %whos prints a table with some basic details about
227 identifiers and %whos prints a table with some basic details about
228 each identifier.
228 each identifier.
229
229
230 The dynamic object information functions (?/??, ``%pdoc``,
230 The dynamic object information functions (?/??, ``%pdoc``,
231 ``%pfile``, ``%pdef``, ``%psource``) work on object attributes, as well as
231 ``%pfile``, ``%pdef``, ``%psource``) work on object attributes, as well as
232 directly on variables. For example, after doing ``import os``, you can use
232 directly on variables. For example, after doing ``import os``, you can use
233 ``os.path.abspath??``.
233 ``os.path.abspath??``.
234
234
235
235
236 Command line completion
236 Command line completion
237 +++++++++++++++++++++++
237 +++++++++++++++++++++++
238
238
239 At any time, hitting TAB will complete any available python commands or
239 At any time, hitting TAB will complete any available python commands or
240 variable names, and show you a list of the possible completions if
240 variable names, and show you a list of the possible completions if
241 there's no unambiguous one. It will also complete filenames in the
241 there's no unambiguous one. It will also complete filenames in the
242 current directory if no python names match what you've typed so far.
242 current directory if no python names match what you've typed so far.
243
243
244
244
245 Search command history
245 Search command history
246 ++++++++++++++++++++++
246 ++++++++++++++++++++++
247
247
248 IPython provides two ways for searching through previous input and thus
248 IPython provides two ways for searching through previous input and thus
249 reduce the need for repetitive typing:
249 reduce the need for repetitive typing:
250
250
251 1. Start typing, and then use the up and down arrow keys (or :kbd:`Ctrl-p`
251 1. Start typing, and then use the up and down arrow keys (or :kbd:`Ctrl-p`
252 and :kbd:`Ctrl-n`) to search through only the history items that match
252 and :kbd:`Ctrl-n`) to search through only the history items that match
253 what you've typed so far.
253 what you've typed so far.
254 2. Hit :kbd:`Ctrl-r`: to open a search prompt. Begin typing and the system
254 2. Hit :kbd:`Ctrl-r`: to open a search prompt. Begin typing and the system
255 searches your history for lines that contain what you've typed so
255 searches your history for lines that contain what you've typed so
256 far, completing as much as it can.
256 far, completing as much as it can.
257
257
258 IPython will save your input history when it leaves and reload it next
258 IPython will save your input history when it leaves and reload it next
259 time you restart it. By default, the history file is named
259 time you restart it. By default, the history file is named
260 :file:`.ipython/profile_{name}/history.sqlite`.
260 :file:`.ipython/profile_{name}/history.sqlite`.
261
261
262 Autoindent
262 Autoindent
263 ++++++++++
263 ++++++++++
264
264
265 Starting with 5.0, IPython uses `prompt_toolkit` in place of ``readline``,
265 Starting with 5.0, IPython uses `prompt_toolkit` in place of ``readline``,
266 it thus can recognize lines ending in ':' and indent the next line,
266 it thus can recognize lines ending in ':' and indent the next line,
267 while also un-indenting automatically after 'raise' or 'return',
267 while also un-indenting automatically after 'raise' or 'return',
268 and support real multi-line editing as well as syntactic coloration
268 and support real multi-line editing as well as syntactic coloration
269 during edition.
269 during edition.
270
270
271 This feature does not use the ``readline`` library anymore, so it will
271 This feature does not use the ``readline`` library anymore, so it will
272 not honor your :file:`~/.inputrc` configuration (or whatever
272 not honor your :file:`~/.inputrc` configuration (or whatever
273 file your :envvar:`INPUTRC` environment variable points to).
273 file your :envvar:`INPUTRC` environment variable points to).
274
274
275 In particular if you want to change the input mode to ``vi``, you will need to
275 In particular if you want to change the input mode to ``vi``, you will need to
276 set the ``TerminalInteractiveShell.editing_mode`` configuration option of IPython.
276 set the ``TerminalInteractiveShell.editing_mode`` configuration option of IPython.
277
277
278 Session logging and restoring
278 Session logging and restoring
279 -----------------------------
279 -----------------------------
280
280
281 You can log all input from a session either by starting IPython with the
281 You can log all input from a session either by starting IPython with the
282 command line switch ``--logfile=foo.py`` (see :ref:`here <command_line_options>`)
282 command line switch ``--logfile=foo.py`` (see :ref:`here <command_line_options>`)
283 or by activating the logging at any moment with the magic function :magic:`logstart`.
283 or by activating the logging at any moment with the magic function :magic:`logstart`.
284
284
285 Log files can later be reloaded by running them as scripts and IPython
285 Log files can later be reloaded by running them as scripts and IPython
286 will attempt to 'replay' the log by executing all the lines in it, thus
286 will attempt to 'replay' the log by executing all the lines in it, thus
287 restoring the state of a previous session. This feature is not quite
287 restoring the state of a previous session. This feature is not quite
288 perfect, but can still be useful in many cases.
288 perfect, but can still be useful in many cases.
289
289
290 The log files can also be used as a way to have a permanent record of
290 The log files can also be used as a way to have a permanent record of
291 any code you wrote while experimenting. Log files are regular text files
291 any code you wrote while experimenting. Log files are regular text files
292 which you can later open in your favorite text editor to extract code or
292 which you can later open in your favorite text editor to extract code or
293 to 'clean them up' before using them to replay a session.
293 to 'clean them up' before using them to replay a session.
294
294
295 The :magic:`logstart` function for activating logging in mid-session is used as
295 The :magic:`logstart` function for activating logging in mid-session is used as
296 follows::
296 follows::
297
297
298 %logstart [log_name [log_mode]]
298 %logstart [log_name [log_mode]]
299
299
300 If no name is given, it defaults to a file named 'ipython_log.py' in your
300 If no name is given, it defaults to a file named 'ipython_log.py' in your
301 current working directory, in 'rotate' mode (see below).
301 current working directory, in 'rotate' mode (see below).
302
302
303 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
303 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
304 history up to that point and then continues logging.
304 history up to that point and then continues logging.
305
305
306 %logstart takes a second optional parameter: logging mode. This can be
306 %logstart takes a second optional parameter: logging mode. This can be
307 one of (note that the modes are given unquoted):
307 one of (note that the modes are given unquoted):
308
308
309 * [over:] overwrite existing log_name.
309 * [over:] overwrite existing log_name.
310 * [backup:] rename (if exists) to log_name~ and start log_name.
310 * [backup:] rename (if exists) to log_name~ and start log_name.
311 * [append:] well, that says it.
311 * [append:] well, that says it.
312 * [rotate:] create rotating logs log_name.1~, log_name.2~, etc.
312 * [rotate:] create rotating logs log_name.1~, log_name.2~, etc.
313
313
314 Adding the '-o' flag to '%logstart' magic (as in '%logstart -o [log_name [log_mode]]')
314 Adding the '-o' flag to '%logstart' magic (as in '%logstart -o [log_name [log_mode]]')
315 will also include output from iPython in the log file.
315 will also include output from iPython in the log file.
316
316
317 The :magic:`logoff` and :magic:`logon` functions allow you to temporarily stop and
317 The :magic:`logoff` and :magic:`logon` functions allow you to temporarily stop and
318 resume logging to a file which had previously been started with
318 resume logging to a file which had previously been started with
319 %logstart. They will fail (with an explanation) if you try to use them
319 %logstart. They will fail (with an explanation) if you try to use them
320 before logging has been started.
320 before logging has been started.
321
321
322 .. _system_shell_access:
322 .. _system_shell_access:
323
323
324 System shell access
324 System shell access
325 -------------------
325 -------------------
326
326
327 Any input line beginning with a ``!`` character is passed verbatim (minus
327 Any input line beginning with a ``!`` character is passed verbatim (minus
328 the ``!``, of course) to the underlying operating system. For example,
328 the ``!``, of course) to the underlying operating system. For example,
329 typing ``!ls`` will run 'ls' in the current directory.
329 typing ``!ls`` will run 'ls' in the current directory.
330
330
331 .. _manual_capture:
331 .. _manual_capture:
332
332
333 Manual capture of command output and magic output
333 Manual capture of command output and magic output
334 -------------------------------------------------
334 -------------------------------------------------
335
335
336 You can assign the result of a system command to a Python variable with the
336 You can assign the result of a system command to a Python variable with the
337 syntax ``myfiles = !ls``. Similarly, the result of a magic (as long as it returns
337 syntax ``myfiles = !ls``. Similarly, the result of a magic (as long as it returns
338 a value) can be assigned to a variable. For example, the syntax ``myfiles = %sx ls``
338 a value) can be assigned to a variable. For example, the syntax ``myfiles = %sx ls``
339 is equivalent to the above system command example (the :magic:`sx` magic runs a shell command
339 is equivalent to the above system command example (the :magic:`sx` magic runs a shell command
340 and captures the output). Each of these gets machine
340 and captures the output). Each of these gets machine
341 readable output from stdout (e.g. without colours), and splits on newlines. To
341 readable output from stdout (e.g. without colours), and splits on newlines. To
342 explicitly get this sort of output without assigning to a variable, use two
342 explicitly get this sort of output without assigning to a variable, use two
343 exclamation marks (``!!ls``) or the :magic:`sx` magic command without an assignment.
343 exclamation marks (``!!ls``) or the :magic:`sx` magic command without an assignment.
344 (However, ``!!`` commands cannot be assigned to a variable.)
344 (However, ``!!`` commands cannot be assigned to a variable.)
345
345
346 The captured list in this example has some convenience features. ``myfiles.n`` or ``myfiles.s``
346 The captured list in this example has some convenience features. ``myfiles.n`` or ``myfiles.s``
347 returns a string delimited by newlines or spaces, respectively. ``myfiles.p``
347 returns a string delimited by newlines or spaces, respectively. ``myfiles.p``
348 produces `path objects <http://pypi.python.org/pypi/path.py>`_ from the list items.
348 produces `path objects <http://pypi.python.org/pypi/path.py>`_ from the list items.
349 See :ref:`string_lists` for details.
349 See :ref:`string_lists` for details.
350
350
351 IPython also allows you to expand the value of python variables when
351 IPython also allows you to expand the value of python variables when
352 making system calls. Wrap variables or expressions in {braces}::
352 making system calls. Wrap variables or expressions in {braces}::
353
353
354 In [1]: pyvar = 'Hello world'
354 In [1]: pyvar = 'Hello world'
355 In [2]: !echo "A python variable: {pyvar}"
355 In [2]: !echo "A python variable: {pyvar}"
356 A python variable: Hello world
356 A python variable: Hello world
357 In [3]: import math
357 In [3]: import math
358 In [4]: x = 8
358 In [4]: x = 8
359 In [5]: !echo {math.factorial(x)}
359 In [5]: !echo {math.factorial(x)}
360 40320
360 40320
361
361
362 For simple cases, you can alternatively prepend $ to a variable name::
362 For simple cases, you can alternatively prepend $ to a variable name::
363
363
364 In [6]: !echo $sys.argv
364 In [6]: !echo $sys.argv
365 [/home/fperez/usr/bin/ipython]
365 [/home/fperez/usr/bin/ipython]
366 In [7]: !echo "A system variable: $$HOME" # Use $$ for literal $
366 In [7]: !echo "A system variable: $$HOME" # Use $$ for literal $
367 A system variable: /home/fperez
367 A system variable: /home/fperez
368
368
369 Note that `$$` is used to represent a literal `$`.
369 Note that `$$` is used to represent a literal `$`.
370
370
371 System command aliases
371 System command aliases
372 ----------------------
372 ----------------------
373
373
374 The :magic:`alias` magic function allows you to define magic functions which are in fact
374 The :magic:`alias` magic function allows you to define magic functions which are in fact
375 system shell commands. These aliases can have parameters.
375 system shell commands. These aliases can have parameters.
376
376
377 ``%alias alias_name cmd`` defines 'alias_name' as an alias for 'cmd'
377 ``%alias alias_name cmd`` defines 'alias_name' as an alias for 'cmd'
378
378
379 Then, typing ``alias_name params`` will execute the system command 'cmd
379 Then, typing ``alias_name params`` will execute the system command 'cmd
380 params' (from your underlying operating system).
380 params' (from your underlying operating system).
381
381
382 You can also define aliases with parameters using ``%s`` specifiers (one per
382 You can also define aliases with parameters using ``%s`` specifiers (one per
383 parameter). The following example defines the parts function as an
383 parameter). The following example defines the parts function as an
384 alias to the command ``echo first %s second %s`` where each ``%s`` will be
384 alias to the command ``echo first %s second %s`` where each ``%s`` will be
385 replaced by a positional parameter to the call to %parts::
385 replaced by a positional parameter to the call to %parts::
386
386
387 In [1]: %alias parts echo first %s second %s
387 In [1]: %alias parts echo first %s second %s
388 In [2]: parts A B
388 In [2]: parts A B
389 first A second B
389 first A second B
390 In [3]: parts A
390 In [3]: parts A
391 ERROR: Alias <parts> requires 2 arguments, 1 given.
391 ERROR: Alias <parts> requires 2 arguments, 1 given.
392
392
393 If called with no parameters, :magic:`alias` prints the table of currently
393 If called with no parameters, :magic:`alias` prints the table of currently
394 defined aliases.
394 defined aliases.
395
395
396 The :magic:`rehashx` magic allows you to load your entire $PATH as
396 The :magic:`rehashx` magic allows you to load your entire $PATH as
397 ipython aliases. See its docstring for further details.
397 ipython aliases. See its docstring for further details.
398
398
399
399
400 .. _dreload:
400 .. _dreload:
401
401
402 Recursive reload
402 Recursive reload
403 ----------------
403 ----------------
404
404
405 The :mod:`IPython.lib.deepreload` module allows you to recursively reload a
405 The :mod:`IPython.lib.deepreload` module allows you to recursively reload a
406 module: changes made to any of its dependencies will be reloaded without
406 module: changes made to any of its dependencies will be reloaded without
407 having to exit. To start using it, do::
407 having to exit. To start using it, do::
408
408
409 from IPython.lib.deepreload import reload as dreload
409 from IPython.lib.deepreload import reload as dreload
410
410
411
411
412 Verbose and colored exception traceback printouts
412 Verbose and colored exception traceback printouts
413 -------------------------------------------------
413 -------------------------------------------------
414
414
415 IPython provides the option to see very detailed exception tracebacks,
415 IPython provides the option to see very detailed exception tracebacks,
416 which can be especially useful when debugging large programs. You can
416 which can be especially useful when debugging large programs. You can
417 run any Python file with the %run function to benefit from these
417 run any Python file with the %run function to benefit from these
418 detailed tracebacks. Furthermore, both normal and verbose tracebacks can
418 detailed tracebacks. Furthermore, both normal and verbose tracebacks can
419 be colored (if your terminal supports it) which makes them much easier
419 be colored (if your terminal supports it) which makes them much easier
420 to parse visually.
420 to parse visually.
421
421
422 See the magic :magic:`xmode` and :magic:`colors` functions for details.
422 See the magic :magic:`xmode` and :magic:`colors` functions for details.
423
423
424 These features are basically a terminal version of Ka-Ping Yee's cgitb
424 These features are basically a terminal version of Ka-Ping Yee's cgitb
425 module, now part of the standard Python library.
425 module, now part of the standard Python library.
426
426
427
427
428 .. _input_caching:
428 .. _input_caching:
429
429
430 Input caching system
430 Input caching system
431 --------------------
431 --------------------
432
432
433 IPython offers numbered prompts (In/Out) with input and output caching
433 IPython offers numbered prompts (In/Out) with input and output caching
434 (also referred to as 'input history'). All input is saved and can be
434 (also referred to as 'input history'). All input is saved and can be
435 retrieved as variables (besides the usual arrow key recall), in
435 retrieved as variables (besides the usual arrow key recall), in
436 addition to the :magic:`rep` magic command that brings a history entry
436 addition to the :magic:`rep` magic command that brings a history entry
437 up for editing on the next command line.
437 up for editing on the next command line.
438
438
439 The following variables always exist:
439 The following variables always exist:
440
440
441 * ``_i``, ``_ii``, ``_iii``: store previous, next previous and next-next
441 * ``_i``, ``_ii``, ``_iii``: store previous, next previous and next-next
442 previous inputs.
442 previous inputs.
443
443
444 * ``In``, ``_ih`` : a list of all inputs; ``_ih[n]`` is the input from line
444 * ``In``, ``_ih`` : a list of all inputs; ``_ih[n]`` is the input from line
445 ``n``. If you overwrite In with a variable of your own, you can remake the
445 ``n``. If you overwrite In with a variable of your own, you can remake the
446 assignment to the internal list with a simple ``In=_ih``.
446 assignment to the internal list with a simple ``In=_ih``.
447
447
448 Additionally, global variables named ``_i<n>`` are dynamically created (``<n>``
448 Additionally, global variables named ``_i<n>`` are dynamically created (``<n>``
449 being the prompt counter), so ``_i<n> == _ih[<n>] == In[<n>]``.
449 being the prompt counter), so ``_i<n> == _ih[<n>] == In[<n>]``.
450
450
451 For example, what you typed at prompt 14 is available as ``_i14``, ``_ih[14]``
451 For example, what you typed at prompt 14 is available as ``_i14``, ``_ih[14]``
452 and ``In[14]``.
452 and ``In[14]``.
453
453
454 This allows you to easily cut and paste multi line interactive prompts
454 This allows you to easily cut and paste multi line interactive prompts
455 by printing them out: they print like a clean string, without prompt
455 by printing them out: they print like a clean string, without prompt
456 characters. You can also manipulate them like regular variables (they
456 characters. You can also manipulate them like regular variables (they
457 are strings), modify or exec them.
457 are strings), modify or exec them.
458
458
459 You can also re-execute multiple lines of input easily by using the magic
459 You can also re-execute multiple lines of input easily by using the magic
460 :magic:`rerun` or :magic:`macro` functions. The macro system also allows you to
460 :magic:`rerun` or :magic:`macro` functions. The macro system also allows you to
461 re-execute previous lines which include magic function calls (which require
461 re-execute previous lines which include magic function calls (which require
462 special processing). Type %macro? for more details on the macro system.
462 special processing). Type %macro? for more details on the macro system.
463
463
464 A history function :magic:`history` allows you to see any part of your input
464 A history function :magic:`history` allows you to see any part of your input
465 history by printing a range of the _i variables.
465 history by printing a range of the _i variables.
466
466
467 You can also search ('grep') through your history by typing
467 You can also search ('grep') through your history by typing
468 ``%hist -g somestring``. This is handy for searching for URLs, IP addresses,
468 ``%hist -g somestring``. This is handy for searching for URLs, IP addresses,
469 etc. You can bring history entries listed by '%hist -g' up for editing
469 etc. You can bring history entries listed by '%hist -g' up for editing
470 with the %recall command, or run them immediately with :magic:`rerun`.
470 with the %recall command, or run them immediately with :magic:`rerun`.
471
471
472 .. _output_caching:
472 .. _output_caching:
473
473
474 Output caching system
474 Output caching system
475 ---------------------
475 ---------------------
476
476
477 For output that is returned from actions, a system similar to the input
477 For output that is returned from actions, a system similar to the input
478 cache exists but using _ instead of _i. Only actions that produce a
478 cache exists but using _ instead of _i. Only actions that produce a
479 result (NOT assignments, for example) are cached. If you are familiar
479 result (NOT assignments, for example) are cached. If you are familiar
480 with Mathematica, IPython's _ variables behave exactly like
480 with Mathematica, IPython's _ variables behave exactly like
481 Mathematica's % variables.
481 Mathematica's % variables.
482
482
483 The following variables always exist:
483 The following variables always exist:
484
484
485 * [_] (a single underscore): stores previous output, like Python's
485 * [_] (a single underscore): stores previous output, like Python's
486 default interpreter.
486 default interpreter.
487 * [__] (two underscores): next previous.
487 * [__] (two underscores): next previous.
488 * [___] (three underscores): next-next previous.
488 * [___] (three underscores): next-next previous.
489
489
490 Additionally, global variables named _<n> are dynamically created (<n>
490 Additionally, global variables named _<n> are dynamically created (<n>
491 being the prompt counter), such that the result of output <n> is always
491 being the prompt counter), such that the result of output <n> is always
492 available as _<n> (don't use the angle brackets, just the number, e.g.
492 available as _<n> (don't use the angle brackets, just the number, e.g.
493 ``_21``).
493 ``_21``).
494
494
495 These variables are also stored in a global dictionary (not a
495 These variables are also stored in a global dictionary (not a
496 list, since it only has entries for lines which returned a result)
496 list, since it only has entries for lines which returned a result)
497 available under the names _oh and Out (similar to _ih and In). So the
497 available under the names _oh and Out (similar to _ih and In). So the
498 output from line 12 can be obtained as ``_12``, ``Out[12]`` or ``_oh[12]``. If you
498 output from line 12 can be obtained as ``_12``, ``Out[12]`` or ``_oh[12]``. If you
499 accidentally overwrite the Out variable you can recover it by typing
499 accidentally overwrite the Out variable you can recover it by typing
500 ``Out=_oh`` at the prompt.
500 ``Out=_oh`` at the prompt.
501
501
502 This system obviously can potentially put heavy memory demands on your
502 This system obviously can potentially put heavy memory demands on your
503 system, since it prevents Python's garbage collector from removing any
503 system, since it prevents Python's garbage collector from removing any
504 previously computed results. You can control how many results are kept
504 previously computed results. You can control how many results are kept
505 in memory with the configuration option ``InteractiveShell.cache_size``.
505 in memory with the configuration option ``InteractiveShell.cache_size``.
506 If you set it to 0, output caching is disabled. You can also use the :magic:`reset`
506 If you set it to 0, output caching is disabled. You can also use the :magic:`reset`
507 and :magic:`xdel` magics to clear large items from memory.
507 and :magic:`xdel` magics to clear large items from memory.
508
508
509 Directory history
509 Directory history
510 -----------------
510 -----------------
511
511
512 Your history of visited directories is kept in the global list _dh, and
512 Your history of visited directories is kept in the global list _dh, and
513 the magic :magic:`cd` command can be used to go to any entry in that list. The
513 the magic :magic:`cd` command can be used to go to any entry in that list. The
514 :magic:`dhist` command allows you to view this history. Do ``cd -<TAB>`` to
514 :magic:`dhist` command allows you to view this history. Do ``cd -<TAB>`` to
515 conveniently view the directory history.
515 conveniently view the directory history.
516
516
517
517
518 Automatic parentheses and quotes
518 Automatic parentheses and quotes
519 --------------------------------
519 --------------------------------
520
520
521 These features were adapted from Nathan Gray's LazyPython. They are
521 These features were adapted from Nathan Gray's LazyPython. They are
522 meant to allow less typing for common situations.
522 meant to allow less typing for common situations.
523
523
524 Callable objects (i.e. functions, methods, etc) can be invoked like this
524 Callable objects (i.e. functions, methods, etc) can be invoked like this
525 (notice the commas between the arguments)::
525 (notice the commas between the arguments)::
526
526
527 In [1]: callable_ob arg1, arg2, arg3
527 In [1]: callable_ob arg1, arg2, arg3
528 ------> callable_ob(arg1, arg2, arg3)
528 ------> callable_ob(arg1, arg2, arg3)
529
529
530 .. note::
530 .. note::
531 This feature is disabled by default. To enable it, use the ``%autocall``
531 This feature is disabled by default. To enable it, use the ``%autocall``
532 magic command. The commands below with special prefixes will always work,
532 magic command. The commands below with special prefixes will always work,
533 however.
533 however.
534
534
535 You can force automatic parentheses by using '/' as the first character
535 You can force automatic parentheses by using '/' as the first character
536 of a line. For example::
536 of a line. For example::
537
537
538 In [2]: /globals # becomes 'globals()'
538 In [2]: /globals # becomes 'globals()'
539
539
540 Note that the '/' MUST be the first character on the line! This won't work::
540 Note that the '/' MUST be the first character on the line! This won't work::
541
541
542 In [3]: print /globals # syntax error
542 In [3]: print /globals # syntax error
543
543
544 In most cases the automatic algorithm should work, so you should rarely
544 In most cases the automatic algorithm should work, so you should rarely
545 need to explicitly invoke /. One notable exception is if you are trying
545 need to explicitly invoke /. One notable exception is if you are trying
546 to call a function with a list of tuples as arguments (the parenthesis
546 to call a function with a list of tuples as arguments (the parenthesis
547 will confuse IPython)::
547 will confuse IPython)::
548
548
549 In [4]: zip (1,2,3),(4,5,6) # won't work
549 In [4]: zip (1,2,3),(4,5,6) # won't work
550
550
551 but this will work::
551 but this will work::
552
552
553 In [5]: /zip (1,2,3),(4,5,6)
553 In [5]: /zip (1,2,3),(4,5,6)
554 ------> zip ((1,2,3),(4,5,6))
554 ------> zip ((1,2,3),(4,5,6))
555 Out[5]: [(1, 4), (2, 5), (3, 6)]
555 Out[5]: [(1, 4), (2, 5), (3, 6)]
556
556
557 IPython tells you that it has altered your command line by displaying
557 IPython tells you that it has altered your command line by displaying
558 the new command line preceded by ``--->``.
558 the new command line preceded by ``--->``.
559
559
560 You can force automatic quoting of a function's arguments by using ``,``
560 You can force automatic quoting of a function's arguments by using ``,``
561 or ``;`` as the first character of a line. For example::
561 or ``;`` as the first character of a line. For example::
562
562
563 In [1]: ,my_function /home/me # becomes my_function("/home/me")
563 In [1]: ,my_function /home/me # becomes my_function("/home/me")
564
564
565 If you use ';' the whole argument is quoted as a single string, while ',' splits
565 If you use ';' the whole argument is quoted as a single string, while ',' splits
566 on whitespace::
566 on whitespace::
567
567
568 In [2]: ,my_function a b c # becomes my_function("a","b","c")
568 In [2]: ,my_function a b c # becomes my_function("a","b","c")
569
569
570 In [3]: ;my_function a b c # becomes my_function("a b c")
570 In [3]: ;my_function a b c # becomes my_function("a b c")
571
571
572 Note that the ',' or ';' MUST be the first character on the line! This
572 Note that the ',' or ';' MUST be the first character on the line! This
573 won't work::
573 won't work::
574
574
575 In [4]: x = ,my_function /home/me # syntax error
575 In [4]: x = ,my_function /home/me # syntax error
576
576
577 IPython as your default Python environment
577 IPython as your default Python environment
578 ==========================================
578 ==========================================
579
579
580 Python honors the environment variable :envvar:`PYTHONSTARTUP` and will
580 Python honors the environment variable :envvar:`PYTHONSTARTUP` and will
581 execute at startup the file referenced by this variable. If you put the
581 execute at startup the file referenced by this variable. If you put the
582 following code at the end of that file, then IPython will be your working
582 following code at the end of that file, then IPython will be your working
583 environment anytime you start Python::
583 environment anytime you start Python::
584
584
585 import os, IPython
585 import os, IPython
586 os.environ['PYTHONSTARTUP'] = '' # Prevent running this again
586 os.environ['PYTHONSTARTUP'] = '' # Prevent running this again
587 IPython.start_ipython()
587 IPython.start_ipython()
588 raise SystemExit
588 raise SystemExit
589
589
590 The ``raise SystemExit`` is needed to exit Python when
590 The ``raise SystemExit`` is needed to exit Python when
591 it finishes, otherwise you'll be back at the normal Python ``>>>``
591 it finishes, otherwise you'll be back at the normal Python ``>>>``
592 prompt.
592 prompt.
593
593
594 This is probably useful to developers who manage multiple Python
594 This is probably useful to developers who manage multiple Python
595 versions and don't want to have correspondingly multiple IPython
595 versions and don't want to have correspondingly multiple IPython
596 versions. Note that in this mode, there is no way to pass IPython any
596 versions. Note that in this mode, there is no way to pass IPython any
597 command-line options, as those are trapped first by Python itself.
597 command-line options, as those are trapped first by Python itself.
598
598
599 .. _Embedding:
599 .. _Embedding:
600
600
601 Embedding IPython
601 Embedding IPython
602 =================
602 =================
603
603
604 You can start a regular IPython session with
604 You can start a regular IPython session with
605
605
606 .. sourcecode:: python
606 .. sourcecode:: python
607
607
608 import IPython
608 import IPython
609 IPython.start_ipython(argv=[])
609 IPython.start_ipython(argv=[])
610
610
611 at any point in your program. This will load IPython configuration,
611 at any point in your program. This will load IPython configuration,
612 startup files, and everything, just as if it were a normal IPython session.
612 startup files, and everything, just as if it were a normal IPython session.
613 For information on setting configuration options when running IPython from
613 For information on setting configuration options when running IPython from
614 python, see :ref:`configure_start_ipython`.
614 python, see :ref:`configure_start_ipython`.
615
615
616 It is also possible to embed an IPython shell in a namespace in your Python
616 It is also possible to embed an IPython shell in a namespace in your Python
617 code. This allows you to evaluate dynamically the state of your code, operate
617 code. This allows you to evaluate dynamically the state of your code, operate
618 with your variables, analyze them, etc. For example, if you run the following
618 with your variables, analyze them, etc. For example, if you run the following
619 code snippet::
619 code snippet::
620
620
621 import IPython
621 import IPython
622
622
623 a = 42
623 a = 42
624 IPython.embed()
624 IPython.embed()
625
625
626 and within the IPython shell, you reassign `a` to `23` to do further testing of
626 and within the IPython shell, you reassign `a` to `23` to do further testing of
627 some sort, you can then exit::
627 some sort, you can then exit::
628
628
629 >>> IPython.embed()
629 >>> IPython.embed()
630 Python 3.6.2 (default, Jul 17 2017, 16:44:45)
630 Python 3.6.2 (default, Jul 17 2017, 16:44:45)
631 Type 'copyright', 'credits' or 'license' for more information
631 Type 'copyright', 'credits' or 'license' for more information
632 IPython 6.2.0.dev -- An enhanced Interactive Python. Type '?' for help.
632 IPython 6.2.0.dev -- An enhanced Interactive Python. Type '?' for help.
633
633
634 In [1]: a = 23
634 In [1]: a = 23
635
635
636 In [2]: exit()
636 In [2]: exit()
637
637
638 Once you exit and print `a`, the value 23 will be shown::
638 Once you exit and print `a`, the value 23 will be shown::
639
639
640
640
641 In: print(a)
641 In: print(a)
642 23
642 23
643
643
644 It's important to note that the code run in the embedded IPython shell will
644 It's important to note that the code run in the embedded IPython shell will
645 *not* change the state of your code and variables, **unless** the shell is
645 *not* change the state of your code and variables, **unless** the shell is
646 contained within the global namespace. In the above example, `a` is changed
646 contained within the global namespace. In the above example, `a` is changed
647 because this is true.
647 because this is true.
648
648
649 To further exemplify this, consider the following example::
649 To further exemplify this, consider the following example::
650
650
651 import IPython
651 import IPython
652 def do():
652 def do():
653 a = 42
653 a = 42
654 print(a)
654 print(a)
655 IPython.embed()
655 IPython.embed()
656 print(a)
656 print(a)
657
657
658 Now if call the function and complete the state changes as we did above, the
658 Now if call the function and complete the state changes as we did above, the
659 value `42` will be printed. Again, this is because it's not in the global
659 value `42` will be printed. Again, this is because it's not in the global
660 namespace::
660 namespace::
661
661
662 do()
662 do()
663
663
664 Running a file with the above code can lead to the following session::
664 Running a file with the above code can lead to the following session::
665
665
666 >>> do()
666 >>> do()
667 42
667 42
668 Python 3.6.2 (default, Jul 17 2017, 16:44:45)
668 Python 3.6.2 (default, Jul 17 2017, 16:44:45)
669 Type 'copyright', 'credits' or 'license' for more information
669 Type 'copyright', 'credits' or 'license' for more information
670 IPython 6.2.0.dev -- An enhanced Interactive Python. Type '?' for help.
670 IPython 6.2.0.dev -- An enhanced Interactive Python. Type '?' for help.
671
671
672 In [1]: a = 23
672 In [1]: a = 23
673
673
674 In [2]: exit()
674 In [2]: exit()
675 42
675 42
676
676
677 .. note::
677 .. note::
678
678
679 At present, embedding IPython cannot be done from inside IPython.
679 At present, embedding IPython cannot be done from inside IPython.
680 Run the code samples below outside IPython.
680 Run the code samples below outside IPython.
681
681
682 This feature allows you to easily have a fully functional python
682 This feature allows you to easily have a fully functional python
683 environment for doing object introspection anywhere in your code with a
683 environment for doing object introspection anywhere in your code with a
684 simple function call. In some cases a simple print statement is enough,
684 simple function call. In some cases a simple print statement is enough,
685 but if you need to do more detailed analysis of a code fragment this
685 but if you need to do more detailed analysis of a code fragment this
686 feature can be very valuable.
686 feature can be very valuable.
687
687
688 It can also be useful in scientific computing situations where it is
688 It can also be useful in scientific computing situations where it is
689 common to need to do some automatic, computationally intensive part and
689 common to need to do some automatic, computationally intensive part and
690 then stop to look at data, plots, etc.
690 then stop to look at data, plots, etc.
691 Opening an IPython instance will give you full access to your data and
691 Opening an IPython instance will give you full access to your data and
692 functions, and you can resume program execution once you are done with
692 functions, and you can resume program execution once you are done with
693 the interactive part (perhaps to stop again later, as many times as
693 the interactive part (perhaps to stop again later, as many times as
694 needed).
694 needed).
695
695
696 The following code snippet is the bare minimum you need to include in
696 The following code snippet is the bare minimum you need to include in
697 your Python programs for this to work (detailed examples follow later)::
697 your Python programs for this to work (detailed examples follow later)::
698
698
699 from IPython import embed
699 from IPython import embed
700
700
701 embed() # this call anywhere in your program will start IPython
701 embed() # this call anywhere in your program will start IPython
702
702
703 You can also embed an IPython *kernel*, for use with qtconsole, etc. via
703 You can also embed an IPython *kernel*, for use with qtconsole, etc. via
704 ``IPython.embed_kernel()``. This should work the same way, but you can
704 ``IPython.embed_kernel()``. This should work the same way, but you can
705 connect an external frontend (``ipython qtconsole`` or ``ipython console``),
705 connect an external frontend (``ipython qtconsole`` or ``ipython console``),
706 rather than interacting with it in the terminal.
706 rather than interacting with it in the terminal.
707
707
708 You can run embedded instances even in code which is itself being run at
708 You can run embedded instances even in code which is itself being run at
709 the IPython interactive prompt with '%run <filename>'. Since it's easy
709 the IPython interactive prompt with '%run <filename>'. Since it's easy
710 to get lost as to where you are (in your top-level IPython or in your
710 to get lost as to where you are (in your top-level IPython or in your
711 embedded one), it's a good idea in such cases to set the in/out prompts
711 embedded one), it's a good idea in such cases to set the in/out prompts
712 to something different for the embedded instances. The code examples
712 to something different for the embedded instances. The code examples
713 below illustrate this.
713 below illustrate this.
714
714
715 You can also have multiple IPython instances in your program and open
715 You can also have multiple IPython instances in your program and open
716 them separately, for example with different options for data
716 them separately, for example with different options for data
717 presentation. If you close and open the same instance multiple times,
717 presentation. If you close and open the same instance multiple times,
718 its prompt counters simply continue from each execution to the next.
718 its prompt counters simply continue from each execution to the next.
719
719
720 Please look at the docstrings in the :mod:`~IPython.frontend.terminal.embed`
720 Please look at the docstrings in the :mod:`~IPython.frontend.terminal.embed`
721 module for more details on the use of this system.
721 module for more details on the use of this system.
722
722
723 The following sample file illustrating how to use the embedding
723 The following sample file illustrating how to use the embedding
724 functionality is provided in the examples directory as embed_class_long.py.
724 functionality is provided in the examples directory as embed_class_long.py.
725 It should be fairly self-explanatory:
725 It should be fairly self-explanatory:
726
726
727 .. literalinclude:: ../../../examples/Embedding/embed_class_long.py
727 .. literalinclude:: ../../../examples/Embedding/embed_class_long.py
728 :language: python
728 :language: python
729
729
730 Once you understand how the system functions, you can use the following
730 Once you understand how the system functions, you can use the following
731 code fragments in your programs which are ready for cut and paste:
731 code fragments in your programs which are ready for cut and paste:
732
732
733 .. literalinclude:: ../../../examples/Embedding/embed_class_short.py
733 .. literalinclude:: ../../../examples/Embedding/embed_class_short.py
734 :language: python
734 :language: python
735
735
736 Using the Python debugger (pdb)
736 Using the Python debugger (pdb)
737 ===============================
737 ===============================
738
738
739 Running entire programs via pdb
739 Running entire programs via pdb
740 -------------------------------
740 -------------------------------
741
741
742 pdb, the Python debugger, is a powerful interactive debugger which
742 pdb, the Python debugger, is a powerful interactive debugger which
743 allows you to step through code, set breakpoints, watch variables,
743 allows you to step through code, set breakpoints, watch variables,
744 etc. IPython makes it very easy to start any script under the control
744 etc. IPython makes it very easy to start any script under the control
745 of pdb, regardless of whether you have wrapped it into a 'main()'
745 of pdb, regardless of whether you have wrapped it into a 'main()'
746 function or not. For this, simply type ``%run -d myscript`` at an
746 function or not. For this, simply type ``%run -d myscript`` at an
747 IPython prompt. See the :magic:`run` command's documentation for more details, including
747 IPython prompt. See the :magic:`run` command's documentation for more details, including
748 how to control where pdb will stop execution first.
748 how to control where pdb will stop execution first.
749
749
750 For more information on the use of the pdb debugger, see :ref:`debugger-commands`
750 For more information on the use of the pdb debugger, see :ref:`debugger-commands`
751 in the Python documentation.
751 in the Python documentation.
752
752
753 IPython extends the debugger with a few useful additions, like coloring of
753 IPython extends the debugger with a few useful additions, like coloring of
754 tracebacks. The debugger will adopt the color scheme selected for IPython.
754 tracebacks. The debugger will adopt the color scheme selected for IPython.
755
755
756 The ``where`` command has also been extended to take as argument the number of
756 The ``where`` command has also been extended to take as argument the number of
757 context line to show. This allows to a many line of context on shallow stack trace:
757 context line to show. This allows to a many line of context on shallow stack trace:
758
758
759 .. code::
759 .. code::
760
760
761 In [5]: def foo(x):
761 In [5]: def foo(x):
762 ...: 1
762 ...: 1
763 ...: 2
763 ...: 2
764 ...: 3
764 ...: 3
765 ...: return 1/x+foo(x-1)
765 ...: return 1/x+foo(x-1)
766 ...: 5
766 ...: 5
767 ...: 6
767 ...: 6
768 ...: 7
768 ...: 7
769 ...:
769 ...:
770
770
771 In[6]: foo(1)
771 In[6]: foo(1)
772 # ...
772 # ...
773 ipdb> where 8
773 ipdb> where 8
774 <ipython-input-6-9e45007b2b59>(1)<module>
774 <ipython-input-6-9e45007b2b59>(1)<module>
775 ----> 1 foo(1)
775 ----> 1 foo(1)
776
776
777 <ipython-input-5-7baadc3d1465>(5)foo()
777 <ipython-input-5-7baadc3d1465>(5)foo()
778 1 def foo(x):
778 1 def foo(x):
779 2 1
779 2 1
780 3 2
780 3 2
781 4 3
781 4 3
782 ----> 5 return 1/x+foo(x-1)
782 ----> 5 return 1/x+foo(x-1)
783 6 5
783 6 5
784 7 6
784 7 6
785 8 7
785 8 7
786
786
787 > <ipython-input-5-7baadc3d1465>(5)foo()
787 > <ipython-input-5-7baadc3d1465>(5)foo()
788 1 def foo(x):
788 1 def foo(x):
789 2 1
789 2 1
790 3 2
790 3 2
791 4 3
791 4 3
792 ----> 5 return 1/x+foo(x-1)
792 ----> 5 return 1/x+foo(x-1)
793 6 5
793 6 5
794 7 6
794 7 6
795 8 7
795 8 7
796
796
797
797
798 And less context on shallower Stack Trace:
798 And less context on shallower Stack Trace:
799
799
800 .. code::
800 .. code::
801
801
802 ipdb> where 1
802 ipdb> where 1
803 <ipython-input-13-afa180a57233>(1)<module>
803 <ipython-input-13-afa180a57233>(1)<module>
804 ----> 1 foo(7)
804 ----> 1 foo(7)
805
805
806 <ipython-input-5-7baadc3d1465>(5)foo()
806 <ipython-input-5-7baadc3d1465>(5)foo()
807 ----> 5 return 1/x+foo(x-1)
807 ----> 5 return 1/x+foo(x-1)
808
808
809 <ipython-input-5-7baadc3d1465>(5)foo()
809 <ipython-input-5-7baadc3d1465>(5)foo()
810 ----> 5 return 1/x+foo(x-1)
810 ----> 5 return 1/x+foo(x-1)
811
811
812 <ipython-input-5-7baadc3d1465>(5)foo()
812 <ipython-input-5-7baadc3d1465>(5)foo()
813 ----> 5 return 1/x+foo(x-1)
813 ----> 5 return 1/x+foo(x-1)
814
814
815 <ipython-input-5-7baadc3d1465>(5)foo()
815 <ipython-input-5-7baadc3d1465>(5)foo()
816 ----> 5 return 1/x+foo(x-1)
816 ----> 5 return 1/x+foo(x-1)
817
817
818
818
819 Post-mortem debugging
819 Post-mortem debugging
820 ---------------------
820 ---------------------
821
821
822 Going into a debugger when an exception occurs can be
822 Going into a debugger when an exception occurs can be
823 extremely useful in order to find the origin of subtle bugs, because pdb
823 extremely useful in order to find the origin of subtle bugs, because pdb
824 opens up at the point in your code which triggered the exception, and
824 opens up at the point in your code which triggered the exception, and
825 while your program is at this point 'dead', all the data is still
825 while your program is at this point 'dead', all the data is still
826 available and you can walk up and down the stack frame and understand
826 available and you can walk up and down the stack frame and understand
827 the origin of the problem.
827 the origin of the problem.
828
828
829 You can use the :magic:`debug` magic after an exception has occurred to start
829 You can use the :magic:`debug` magic after an exception has occurred to start
830 post-mortem debugging. IPython can also call debugger every time your code
830 post-mortem debugging. IPython can also call debugger every time your code
831 triggers an uncaught exception. This feature can be toggled with the :magic:`pdb` magic
831 triggers an uncaught exception. This feature can be toggled with the :magic:`pdb` magic
832 command, or you can start IPython with the ``--pdb`` option.
832 command, or you can start IPython with the ``--pdb`` option.
833
833
834 For a post-mortem debugger in your programs outside IPython,
834 For a post-mortem debugger in your programs outside IPython,
835 put the following lines toward the top of your 'main' routine::
835 put the following lines toward the top of your 'main' routine::
836
836
837 import sys
837 import sys
838 from IPython.core import ultratb
838 from IPython.core import ultratb
839 sys.excepthook = ultratb.FormattedTB(mode='Verbose',
839 sys.excepthook = ultratb.FormattedTB(mode='Verbose',
840 color_scheme='Linux', call_pdb=1)
840 color_scheme='Linux', call_pdb=1)
841
841
842 The mode keyword can be either 'Verbose' or 'Plain', giving either very
842 The mode keyword can be either 'Verbose' or 'Plain', giving either very
843 detailed or normal tracebacks respectively. The color_scheme keyword can
843 detailed or normal tracebacks respectively. The color_scheme keyword can
844 be one of 'NoColor', 'Linux' (default) or 'LightBG'. These are the same
844 be one of 'NoColor', 'Linux' (default) or 'LightBG'. These are the same
845 options which can be set in IPython with ``--colors`` and ``--xmode``.
845 options which can be set in IPython with ``--colors`` and ``--xmode``.
846
846
847 This will give any of your programs detailed, colored tracebacks with
847 This will give any of your programs detailed, colored tracebacks with
848 automatic invocation of pdb.
848 automatic invocation of pdb.
849
849
850 .. _pasting_with_prompts:
850 .. _pasting_with_prompts:
851
851
852 Pasting of code starting with Python or IPython prompts
852 Pasting of code starting with Python or IPython prompts
853 =======================================================
853 =======================================================
854
854
855 IPython is smart enough to filter out input prompts, be they plain Python ones
855 IPython is smart enough to filter out input prompts, be they plain Python ones
856 (``>>>`` and ``...``) or IPython ones (``In [N]:`` and ``...:``). You can
856 (``>>>`` and ``...``) or IPython ones (``In [N]:`` and ``...:``). You can
857 therefore copy and paste from existing interactive sessions without worry.
857 therefore copy and paste from existing interactive sessions without worry.
858
858
859 The following is a 'screenshot' of how things work, copying an example from the
859 The following is a 'screenshot' of how things work, copying an example from the
860 standard Python tutorial::
860 standard Python tutorial::
861
861
862 In [1]: >>> # Fibonacci series:
862 In [1]: >>> # Fibonacci series:
863
863
864 In [2]: ... # the sum of two elements defines the next
864 In [2]: ... # the sum of two elements defines the next
865
865
866 In [3]: ... a, b = 0, 1
866 In [3]: ... a, b = 0, 1
867
867
868 In [4]: >>> while b < 10:
868 In [4]: >>> while b < 10:
869 ...: ... print(b)
869 ...: ... print(b)
870 ...: ... a, b = b, a+b
870 ...: ... a, b = b, a+b
871 ...:
871 ...:
872 1
872 1
873 1
873 1
874 2
874 2
875 3
875 3
876 5
876 5
877 8
877 8
878
878
879 And pasting from IPython sessions works equally well::
879 And pasting from IPython sessions works equally well::
880
880
881 In [1]: In [5]: def f(x):
881 In [1]: In [5]: def f(x):
882 ...: ...: "A simple function"
882 ...: ...: "A simple function"
883 ...: ...: return x**2
883 ...: ...: return x**2
884 ...: ...:
884 ...: ...:
885
885
886 In [2]: f(3)
886 In [2]: f(3)
887 Out[2]: 9
887 Out[2]: 9
888
888
889 .. _gui_support:
889 .. _gui_support:
890
890
891 GUI event loop support
891 GUI event loop support
892 ======================
892 ======================
893
893
894 IPython has excellent support for working interactively with Graphical User
894 IPython has excellent support for working interactively with Graphical User
895 Interface (GUI) toolkits, such as wxPython, PyQt4/PySide, PyGTK and Tk. This is
895 Interface (GUI) toolkits, such as wxPython, PyQt/PySide, PyGTK and Tk. This is
896 implemented by running the toolkit's event loop while IPython is waiting for
896 implemented by running the toolkit's event loop while IPython is waiting for
897 input.
897 input.
898
898
899 For users, enabling GUI event loop integration is simple. You simple use the
899 For users, enabling GUI event loop integration is simple. You simple use the
900 :magic:`gui` magic as follows::
900 :magic:`gui` magic as follows::
901
901
902 %gui [GUINAME]
902 %gui [GUINAME]
903
903
904 With no arguments, ``%gui`` removes all GUI support. Valid ``GUINAME``
904 With no arguments, ``%gui`` removes all GUI support. Valid ``GUINAME``
905 arguments include ``wx``, ``qt``, ``qt5``, ``gtk``, ``gtk3`` ``gtk4``, and
905 arguments include ``wx``, ``qt``, ``qt5``, ``qt6``, ``gtk``, ``gtk3`` ``gtk4``, and
906 ``tk``.
906 ``tk``.
907
907
908 Thus, to use wxPython interactively and create a running :class:`wx.App`
908 Thus, to use wxPython interactively and create a running :class:`wx.App`
909 object, do::
909 object, do::
910
910
911 %gui wx
911 %gui wx
912
912
913 You can also start IPython with an event loop set up using the `--gui`
913 You can also start IPython with an event loop set up using the `--gui`
914 flag::
914 flag::
915
915
916 $ ipython --gui=qt
916 $ ipython --gui=qt
917
917
918 For information on IPython's matplotlib_ integration (and the ``matplotlib``
918 For information on IPython's matplotlib_ integration (and the ``matplotlib``
919 mode) see :ref:`this section <matplotlib_support>`.
919 mode) see :ref:`this section <matplotlib_support>`.
920
920
921 For developers that want to integrate additional event loops with IPython, see
921 For developers that want to integrate additional event loops with IPython, see
922 :doc:`/config/eventloops`.
922 :doc:`/config/eventloops`.
923
923
924 When running inside IPython with an integrated event loop, a GUI application
924 When running inside IPython with an integrated event loop, a GUI application
925 should *not* start its own event loop. This means that applications that are
925 should *not* start its own event loop. This means that applications that are
926 meant to be used both
926 meant to be used both
927 in IPython and as standalone apps need to have special code to detects how the
927 in IPython and as standalone apps need to have special code to detects how the
928 application is being run. We highly recommend using IPython's support for this.
928 application is being run. We highly recommend using IPython's support for this.
929 Since the details vary slightly between toolkits, we point you to the various
929 Since the details vary slightly between toolkits, we point you to the various
930 examples in our source directory :file:`examples/IPython Kernel/gui/` that
930 examples in our source directory :file:`examples/IPython Kernel/gui/` that
931 demonstrate these capabilities.
931 demonstrate these capabilities.
932
932
933 PyQt and PySide
933 PyQt and PySide
934 ---------------
934 ---------------
935
935
936 .. attempt at explanation of the complete mess that is Qt support
936 .. attempt at explanation of the complete mess that is Qt support
937
937
938 When you use ``--gui=qt`` or ``--matplotlib=qt``, IPython can work with either
938 When you use ``--gui=qt`` or ``--matplotlib=qt``, IPython can work with either
939 PyQt4 or PySide. There are three options for configuration here, because
939 PyQt or PySide. ``qt`` implies "use the latest version available", and it favors
940 PyQt4 has two APIs for QString and QVariant: v1, which is the default on
940 PyQt over PySide. To request a specific version, use ``qt5`` or ``qt6``. Note that
941 Python 2, and the more natural v2, which is the only API supported by PySide.
941 Qt4 is not supported with the ``--gui`` switch (and has not been for some time now).
942 v2 is also the default for PyQt4 on Python 3. IPython's code for the QtConsole
943 uses v2, but you can still use any interface in your code, since the
944 Qt frontend is in a different process.
945
946 The default will be to import PyQt4 without configuration of the APIs, thus
947 matching what most applications would expect. It will fall back to PySide if
948 PyQt4 is unavailable.
949
942
950 If specified, IPython will respect the environment variable ``QT_API`` used
943 If specified, IPython will respect the environment variable ``QT_API`` used
951 by ETS. ETS 4.0 also works with both PyQt4 and PySide, but it requires
944 by ETS. ETS 4.0 also works with both PyQt4 and PySide, but it requires
952 PyQt4 to use its v2 API. So if ``QT_API=pyside`` PySide will be used,
945 PyQt4 to use its v2 API. So if ``QT_API=pyside`` PySide will be used,
953 and if ``QT_API=pyqt`` then PyQt4 will be used *with the v2 API* for
946 and if ``QT_API=pyqt`` then PyQt4 will be used *with the v2 API* for
954 QString and QVariant, so ETS codes like MayaVi will also work with IPython.
947 QString and QVariant, so ETS codes like MayaVi will also work with IPython.
955
948
956 If you launch IPython in matplotlib mode with ``ipython --matplotlib=qt``,
949 If you launch IPython in matplotlib mode with ``ipython --matplotlib=qt``,
957 then IPython will ask matplotlib which Qt library to use (only if QT_API is
950 then IPython will ask matplotlib which Qt library to use (only if QT_API is
958 *not set*), via the 'backend.qt4' rcParam. If matplotlib is version 1.0.1 or
951 *not set*), via the 'backend.qt4' rcParam. If matplotlib is version 1.0.1 or
959 older, then IPython will always use PyQt4 without setting the v2 APIs, since
952 older, then IPython will always use PyQt4 without setting the v2 APIs, since
960 neither v2 PyQt nor PySide work.
953 neither v2 PyQt nor PySide work.
961
954
962 .. warning::
955 .. warning::
963
956
964 Note that this means for ETS 4 to work with PyQt4, ``QT_API`` *must* be set
957 Note that this means for ETS 4 to work with PyQt4, ``QT_API`` *must* be set
965 to work with IPython's qt integration, because otherwise PyQt4 will be
958 to work with IPython's qt integration, because otherwise PyQt4 will be
966 loaded in an incompatible mode.
959 loaded in an incompatible mode.
967
960
968 It also means that you must *not* have ``QT_API`` set if you want to
961 It also means that you must *not* have ``QT_API`` set if you want to
969 use ``--gui=qt`` with code that requires PyQt4 API v1.
962 use ``--gui=qt`` with code that requires PyQt4 API v1.
970
963
971
964
972 .. _matplotlib_support:
965 .. _matplotlib_support:
973
966
974 Plotting with matplotlib
967 Plotting with matplotlib
975 ========================
968 ========================
976
969
977 matplotlib_ provides high quality 2D and 3D plotting for Python. matplotlib_
970 matplotlib_ provides high quality 2D and 3D plotting for Python. matplotlib_
978 can produce plots on screen using a variety of GUI toolkits, including Tk,
971 can produce plots on screen using a variety of GUI toolkits, including Tk,
979 PyGTK, PyQt4 and wxPython. It also provides a number of commands useful for
972 PyGTK, PyQt4 and wxPython. It also provides a number of commands useful for
980 scientific computing, all with a syntax compatible with that of the popular
973 scientific computing, all with a syntax compatible with that of the popular
981 Matlab program.
974 Matlab program.
982
975
983 To start IPython with matplotlib support, use the ``--matplotlib`` switch. If
976 To start IPython with matplotlib support, use the ``--matplotlib`` switch. If
984 IPython is already running, you can run the :magic:`matplotlib` magic. If no
977 IPython is already running, you can run the :magic:`matplotlib` magic. If no
985 arguments are given, IPython will automatically detect your choice of
978 arguments are given, IPython will automatically detect your choice of
986 matplotlib backend. You can also request a specific backend with
979 matplotlib backend. You can also request a specific backend with
987 ``%matplotlib backend``, where ``backend`` must be one of: 'tk', 'qt', 'wx',
980 ``%matplotlib backend``, where ``backend`` must be one of: 'tk', 'qt', 'wx',
988 'gtk', 'osx'. In the web notebook and Qt console, 'inline' is also a valid
981 'gtk', 'osx'. In the web notebook and Qt console, 'inline' is also a valid
989 backend value, which produces static figures inlined inside the application
982 backend value, which produces static figures inlined inside the application
990 window instead of matplotlib's interactive figures that live in separate
983 window instead of matplotlib's interactive figures that live in separate
991 windows.
984 windows.
992
985
993 .. _interactive_demos:
986 .. _interactive_demos:
994
987
995 Interactive demos with IPython
988 Interactive demos with IPython
996 ==============================
989 ==============================
997
990
998 IPython ships with a basic system for running scripts interactively in
991 IPython ships with a basic system for running scripts interactively in
999 sections, useful when presenting code to audiences. A few tags embedded
992 sections, useful when presenting code to audiences. A few tags embedded
1000 in comments (so that the script remains valid Python code) divide a file
993 in comments (so that the script remains valid Python code) divide a file
1001 into separate blocks, and the demo can be run one block at a time, with
994 into separate blocks, and the demo can be run one block at a time, with
1002 IPython printing (with syntax highlighting) the block before executing
995 IPython printing (with syntax highlighting) the block before executing
1003 it, and returning to the interactive prompt after each block. The
996 it, and returning to the interactive prompt after each block. The
1004 interactive namespace is updated after each block is run with the
997 interactive namespace is updated after each block is run with the
1005 contents of the demo's namespace.
998 contents of the demo's namespace.
1006
999
1007 This allows you to show a piece of code, run it and then execute
1000 This allows you to show a piece of code, run it and then execute
1008 interactively commands based on the variables just created. Once you
1001 interactively commands based on the variables just created. Once you
1009 want to continue, you simply execute the next block of the demo. The
1002 want to continue, you simply execute the next block of the demo. The
1010 following listing shows the markup necessary for dividing a script into
1003 following listing shows the markup necessary for dividing a script into
1011 sections for execution as a demo:
1004 sections for execution as a demo:
1012
1005
1013 .. literalinclude:: ../../../examples/IPython Kernel/example-demo.py
1006 .. literalinclude:: ../../../examples/IPython Kernel/example-demo.py
1014 :language: python
1007 :language: python
1015
1008
1016 In order to run a file as a demo, you must first make a Demo object out
1009 In order to run a file as a demo, you must first make a Demo object out
1017 of it. If the file is named myscript.py, the following code will make a
1010 of it. If the file is named myscript.py, the following code will make a
1018 demo::
1011 demo::
1019
1012
1020 from IPython.lib.demo import Demo
1013 from IPython.lib.demo import Demo
1021
1014
1022 mydemo = Demo('myscript.py')
1015 mydemo = Demo('myscript.py')
1023
1016
1024 This creates the mydemo object, whose blocks you run one at a time by
1017 This creates the mydemo object, whose blocks you run one at a time by
1025 simply calling the object with no arguments. Then call it to run each step
1018 simply calling the object with no arguments. Then call it to run each step
1026 of the demo::
1019 of the demo::
1027
1020
1028 mydemo()
1021 mydemo()
1029
1022
1030 Demo objects can be
1023 Demo objects can be
1031 restarted, you can move forward or back skipping blocks, re-execute the
1024 restarted, you can move forward or back skipping blocks, re-execute the
1032 last block, etc. See the :mod:`IPython.lib.demo` module and the
1025 last block, etc. See the :mod:`IPython.lib.demo` module and the
1033 :class:`~IPython.lib.demo.Demo` class for details.
1026 :class:`~IPython.lib.demo.Demo` class for details.
1034
1027
1035 Limitations: These demos are limited to
1028 Limitations: These demos are limited to
1036 fairly simple uses. In particular, you cannot break up sections within
1029 fairly simple uses. In particular, you cannot break up sections within
1037 indented code (loops, if statements, function definitions, etc.)
1030 indented code (loops, if statements, function definitions, etc.)
1038 Supporting something like this would basically require tracking the
1031 Supporting something like this would basically require tracking the
1039 internal execution state of the Python interpreter, so only top-level
1032 internal execution state of the Python interpreter, so only top-level
1040 divisions are allowed. If you want to be able to open an IPython
1033 divisions are allowed. If you want to be able to open an IPython
1041 instance at an arbitrary point in a program, you can use IPython's
1034 instance at an arbitrary point in a program, you can use IPython's
1042 :ref:`embedding facilities <Embedding>`.
1035 :ref:`embedding facilities <Embedding>`.
1043
1036
1044 .. include:: ../links.txt
1037 .. include:: ../links.txt
General Comments 0
You need to be logged in to leave comments. Login now