##// END OF EJS Templates
Some minimal typing and removal of allow-none
Matthias Bussonnier -
Show More
@@ -1,3346 +1,3346 b''
1 """Completion for IPython.
1 """Completion for IPython.
2
2
3 This module started as fork of the rlcompleter module in the Python standard
3 This module started as fork of the rlcompleter module in the Python standard
4 library. The original enhancements made to rlcompleter have been sent
4 library. The original enhancements made to rlcompleter have been sent
5 upstream and were accepted as of Python 2.3,
5 upstream and were accepted as of Python 2.3,
6
6
7 This module now support a wide variety of completion mechanism both available
7 This module now support a wide variety of completion mechanism both available
8 for normal classic Python code, as well as completer for IPython specific
8 for normal classic Python code, as well as completer for IPython specific
9 Syntax like magics.
9 Syntax like magics.
10
10
11 Latex and Unicode completion
11 Latex and Unicode completion
12 ============================
12 ============================
13
13
14 IPython and compatible frontends not only can complete your code, but can help
14 IPython and compatible frontends not only can complete your code, but can help
15 you to input a wide range of characters. In particular we allow you to insert
15 you to input a wide range of characters. In particular we allow you to insert
16 a unicode character using the tab completion mechanism.
16 a unicode character using the tab completion mechanism.
17
17
18 Forward latex/unicode completion
18 Forward latex/unicode completion
19 --------------------------------
19 --------------------------------
20
20
21 Forward completion allows you to easily type a unicode character using its latex
21 Forward completion allows you to easily type a unicode character using its latex
22 name, or unicode long description. To do so type a backslash follow by the
22 name, or unicode long description. To do so type a backslash follow by the
23 relevant name and press tab:
23 relevant name and press tab:
24
24
25
25
26 Using latex completion:
26 Using latex completion:
27
27
28 .. code::
28 .. code::
29
29
30 \\alpha<tab>
30 \\alpha<tab>
31 Ξ±
31 Ξ±
32
32
33 or using unicode completion:
33 or using unicode completion:
34
34
35
35
36 .. code::
36 .. code::
37
37
38 \\GREEK SMALL LETTER ALPHA<tab>
38 \\GREEK SMALL LETTER ALPHA<tab>
39 Ξ±
39 Ξ±
40
40
41
41
42 Only valid Python identifiers will complete. Combining characters (like arrow or
42 Only valid Python identifiers will complete. Combining characters (like arrow or
43 dots) are also available, unlike latex they need to be put after the their
43 dots) are also available, unlike latex they need to be put after the their
44 counterpart that is to say, ``F\\\\vec<tab>`` is correct, not ``\\\\vec<tab>F``.
44 counterpart that is to say, ``F\\\\vec<tab>`` is correct, not ``\\\\vec<tab>F``.
45
45
46 Some browsers are known to display combining characters incorrectly.
46 Some browsers are known to display combining characters incorrectly.
47
47
48 Backward latex completion
48 Backward latex completion
49 -------------------------
49 -------------------------
50
50
51 It is sometime challenging to know how to type a character, if you are using
51 It is sometime challenging to know how to type a character, if you are using
52 IPython, or any compatible frontend you can prepend backslash to the character
52 IPython, or any compatible frontend you can prepend backslash to the character
53 and press :kbd:`Tab` to expand it to its latex form.
53 and press :kbd:`Tab` to expand it to its latex form.
54
54
55 .. code::
55 .. code::
56
56
57 \\Ξ±<tab>
57 \\Ξ±<tab>
58 \\alpha
58 \\alpha
59
59
60
60
61 Both forward and backward completions can be deactivated by setting the
61 Both forward and backward completions can be deactivated by setting the
62 :std:configtrait:`Completer.backslash_combining_completions` option to
62 :std:configtrait:`Completer.backslash_combining_completions` option to
63 ``False``.
63 ``False``.
64
64
65
65
66 Experimental
66 Experimental
67 ============
67 ============
68
68
69 Starting with IPython 6.0, this module can make use of the Jedi library to
69 Starting with IPython 6.0, this module can make use of the Jedi library to
70 generate completions both using static analysis of the code, and dynamically
70 generate completions both using static analysis of the code, and dynamically
71 inspecting multiple namespaces. Jedi is an autocompletion and static analysis
71 inspecting multiple namespaces. Jedi is an autocompletion and static analysis
72 for Python. The APIs attached to this new mechanism is unstable and will
72 for Python. The APIs attached to this new mechanism is unstable and will
73 raise unless use in an :any:`provisionalcompleter` context manager.
73 raise unless use in an :any:`provisionalcompleter` context manager.
74
74
75 You will find that the following are experimental:
75 You will find that the following are experimental:
76
76
77 - :any:`provisionalcompleter`
77 - :any:`provisionalcompleter`
78 - :any:`IPCompleter.completions`
78 - :any:`IPCompleter.completions`
79 - :any:`Completion`
79 - :any:`Completion`
80 - :any:`rectify_completions`
80 - :any:`rectify_completions`
81
81
82 .. note::
82 .. note::
83
83
84 better name for :any:`rectify_completions` ?
84 better name for :any:`rectify_completions` ?
85
85
86 We welcome any feedback on these new API, and we also encourage you to try this
86 We welcome any feedback on these new API, and we also encourage you to try this
87 module in debug mode (start IPython with ``--Completer.debug=True``) in order
87 module in debug mode (start IPython with ``--Completer.debug=True``) in order
88 to have extra logging information if :any:`jedi` is crashing, or if current
88 to have extra logging information if :any:`jedi` is crashing, or if current
89 IPython completer pending deprecations are returning results not yet handled
89 IPython completer pending deprecations are returning results not yet handled
90 by :any:`jedi`
90 by :any:`jedi`
91
91
92 Using Jedi for tab completion allow snippets like the following to work without
92 Using Jedi for tab completion allow snippets like the following to work without
93 having to execute any code:
93 having to execute any code:
94
94
95 >>> myvar = ['hello', 42]
95 >>> myvar = ['hello', 42]
96 ... myvar[1].bi<tab>
96 ... myvar[1].bi<tab>
97
97
98 Tab completion will be able to infer that ``myvar[1]`` is a real number without
98 Tab completion will be able to infer that ``myvar[1]`` is a real number without
99 executing almost any code unlike the deprecated :any:`IPCompleter.greedy`
99 executing almost any code unlike the deprecated :any:`IPCompleter.greedy`
100 option.
100 option.
101
101
102 Be sure to update :any:`jedi` to the latest stable version or to try the
102 Be sure to update :any:`jedi` to the latest stable version or to try the
103 current development version to get better completions.
103 current development version to get better completions.
104
104
105 Matchers
105 Matchers
106 ========
106 ========
107
107
108 All completions routines are implemented using unified *Matchers* API.
108 All completions routines are implemented using unified *Matchers* API.
109 The matchers API is provisional and subject to change without notice.
109 The matchers API is provisional and subject to change without notice.
110
110
111 The built-in matchers include:
111 The built-in matchers include:
112
112
113 - :any:`IPCompleter.dict_key_matcher`: dictionary key completions,
113 - :any:`IPCompleter.dict_key_matcher`: dictionary key completions,
114 - :any:`IPCompleter.magic_matcher`: completions for magics,
114 - :any:`IPCompleter.magic_matcher`: completions for magics,
115 - :any:`IPCompleter.unicode_name_matcher`,
115 - :any:`IPCompleter.unicode_name_matcher`,
116 :any:`IPCompleter.fwd_unicode_matcher`
116 :any:`IPCompleter.fwd_unicode_matcher`
117 and :any:`IPCompleter.latex_name_matcher`: see `Forward latex/unicode completion`_,
117 and :any:`IPCompleter.latex_name_matcher`: see `Forward latex/unicode completion`_,
118 - :any:`back_unicode_name_matcher` and :any:`back_latex_name_matcher`: see `Backward latex completion`_,
118 - :any:`back_unicode_name_matcher` and :any:`back_latex_name_matcher`: see `Backward latex completion`_,
119 - :any:`IPCompleter.file_matcher`: paths to files and directories,
119 - :any:`IPCompleter.file_matcher`: paths to files and directories,
120 - :any:`IPCompleter.python_func_kw_matcher` - function keywords,
120 - :any:`IPCompleter.python_func_kw_matcher` - function keywords,
121 - :any:`IPCompleter.python_matches` - globals and attributes (v1 API),
121 - :any:`IPCompleter.python_matches` - globals and attributes (v1 API),
122 - ``IPCompleter.jedi_matcher`` - static analysis with Jedi,
122 - ``IPCompleter.jedi_matcher`` - static analysis with Jedi,
123 - :any:`IPCompleter.custom_completer_matcher` - pluggable completer with a default
123 - :any:`IPCompleter.custom_completer_matcher` - pluggable completer with a default
124 implementation in :any:`InteractiveShell` which uses IPython hooks system
124 implementation in :any:`InteractiveShell` which uses IPython hooks system
125 (`complete_command`) with string dispatch (including regular expressions).
125 (`complete_command`) with string dispatch (including regular expressions).
126 Differently to other matchers, ``custom_completer_matcher`` will not suppress
126 Differently to other matchers, ``custom_completer_matcher`` will not suppress
127 Jedi results to match behaviour in earlier IPython versions.
127 Jedi results to match behaviour in earlier IPython versions.
128
128
129 Custom matchers can be added by appending to ``IPCompleter.custom_matchers`` list.
129 Custom matchers can be added by appending to ``IPCompleter.custom_matchers`` list.
130
130
131 Matcher API
131 Matcher API
132 -----------
132 -----------
133
133
134 Simplifying some details, the ``Matcher`` interface can described as
134 Simplifying some details, the ``Matcher`` interface can described as
135
135
136 .. code-block::
136 .. code-block::
137
137
138 MatcherAPIv1 = Callable[[str], list[str]]
138 MatcherAPIv1 = Callable[[str], list[str]]
139 MatcherAPIv2 = Callable[[CompletionContext], SimpleMatcherResult]
139 MatcherAPIv2 = Callable[[CompletionContext], SimpleMatcherResult]
140
140
141 Matcher = MatcherAPIv1 | MatcherAPIv2
141 Matcher = MatcherAPIv1 | MatcherAPIv2
142
142
143 The ``MatcherAPIv1`` reflects the matcher API as available prior to IPython 8.6.0
143 The ``MatcherAPIv1`` reflects the matcher API as available prior to IPython 8.6.0
144 and remains supported as a simplest way for generating completions. This is also
144 and remains supported as a simplest way for generating completions. This is also
145 currently the only API supported by the IPython hooks system `complete_command`.
145 currently the only API supported by the IPython hooks system `complete_command`.
146
146
147 To distinguish between matcher versions ``matcher_api_version`` attribute is used.
147 To distinguish between matcher versions ``matcher_api_version`` attribute is used.
148 More precisely, the API allows to omit ``matcher_api_version`` for v1 Matchers,
148 More precisely, the API allows to omit ``matcher_api_version`` for v1 Matchers,
149 and requires a literal ``2`` for v2 Matchers.
149 and requires a literal ``2`` for v2 Matchers.
150
150
151 Once the API stabilises future versions may relax the requirement for specifying
151 Once the API stabilises future versions may relax the requirement for specifying
152 ``matcher_api_version`` by switching to :any:`functools.singledispatch`, therefore
152 ``matcher_api_version`` by switching to :any:`functools.singledispatch`, therefore
153 please do not rely on the presence of ``matcher_api_version`` for any purposes.
153 please do not rely on the presence of ``matcher_api_version`` for any purposes.
154
154
155 Suppression of competing matchers
155 Suppression of competing matchers
156 ---------------------------------
156 ---------------------------------
157
157
158 By default results from all matchers are combined, in the order determined by
158 By default results from all matchers are combined, in the order determined by
159 their priority. Matchers can request to suppress results from subsequent
159 their priority. Matchers can request to suppress results from subsequent
160 matchers by setting ``suppress`` to ``True`` in the ``MatcherResult``.
160 matchers by setting ``suppress`` to ``True`` in the ``MatcherResult``.
161
161
162 When multiple matchers simultaneously request surpression, the results from of
162 When multiple matchers simultaneously request surpression, the results from of
163 the matcher with higher priority will be returned.
163 the matcher with higher priority will be returned.
164
164
165 Sometimes it is desirable to suppress most but not all other matchers;
165 Sometimes it is desirable to suppress most but not all other matchers;
166 this can be achieved by adding a set of identifiers of matchers which
166 this can be achieved by adding a set of identifiers of matchers which
167 should not be suppressed to ``MatcherResult`` under ``do_not_suppress`` key.
167 should not be suppressed to ``MatcherResult`` under ``do_not_suppress`` key.
168
168
169 The suppression behaviour can is user-configurable via
169 The suppression behaviour can is user-configurable via
170 :std:configtrait:`IPCompleter.suppress_competing_matchers`.
170 :std:configtrait:`IPCompleter.suppress_competing_matchers`.
171 """
171 """
172
172
173
173
174 # Copyright (c) IPython Development Team.
174 # Copyright (c) IPython Development Team.
175 # Distributed under the terms of the Modified BSD License.
175 # Distributed under the terms of the Modified BSD License.
176 #
176 #
177 # Some of this code originated from rlcompleter in the Python standard library
177 # Some of this code originated from rlcompleter in the Python standard library
178 # Copyright (C) 2001 Python Software Foundation, www.python.org
178 # Copyright (C) 2001 Python Software Foundation, www.python.org
179
179
180 from __future__ import annotations
180 from __future__ import annotations
181 import builtins as builtin_mod
181 import builtins as builtin_mod
182 import enum
182 import enum
183 import glob
183 import glob
184 import inspect
184 import inspect
185 import itertools
185 import itertools
186 import keyword
186 import keyword
187 import os
187 import os
188 import re
188 import re
189 import string
189 import string
190 import sys
190 import sys
191 import tokenize
191 import tokenize
192 import time
192 import time
193 import unicodedata
193 import unicodedata
194 import uuid
194 import uuid
195 import warnings
195 import warnings
196 from ast import literal_eval
196 from ast import literal_eval
197 from collections import defaultdict
197 from collections import defaultdict
198 from contextlib import contextmanager
198 from contextlib import contextmanager
199 from dataclasses import dataclass
199 from dataclasses import dataclass
200 from functools import cached_property, partial
200 from functools import cached_property, partial
201 from types import SimpleNamespace
201 from types import SimpleNamespace
202 from typing import (
202 from typing import (
203 Iterable,
203 Iterable,
204 Iterator,
204 Iterator,
205 List,
205 List,
206 Tuple,
206 Tuple,
207 Union,
207 Union,
208 Any,
208 Any,
209 Sequence,
209 Sequence,
210 Dict,
210 Dict,
211 Optional,
211 Optional,
212 TYPE_CHECKING,
212 TYPE_CHECKING,
213 Set,
213 Set,
214 Sized,
214 Sized,
215 TypeVar,
215 TypeVar,
216 Literal,
216 Literal,
217 )
217 )
218
218
219 from IPython.core.guarded_eval import guarded_eval, EvaluationContext
219 from IPython.core.guarded_eval import guarded_eval, EvaluationContext
220 from IPython.core.error import TryNext
220 from IPython.core.error import TryNext
221 from IPython.core.inputtransformer2 import ESC_MAGIC
221 from IPython.core.inputtransformer2 import ESC_MAGIC
222 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
222 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
223 from IPython.core.oinspect import InspectColors
223 from IPython.core.oinspect import InspectColors
224 from IPython.testing.skipdoctest import skip_doctest
224 from IPython.testing.skipdoctest import skip_doctest
225 from IPython.utils import generics
225 from IPython.utils import generics
226 from IPython.utils.decorators import sphinx_options
226 from IPython.utils.decorators import sphinx_options
227 from IPython.utils.dir2 import dir2, get_real_method
227 from IPython.utils.dir2 import dir2, get_real_method
228 from IPython.utils.docs import GENERATING_DOCUMENTATION
228 from IPython.utils.docs import GENERATING_DOCUMENTATION
229 from IPython.utils.path import ensure_dir_exists
229 from IPython.utils.path import ensure_dir_exists
230 from IPython.utils.process import arg_split
230 from IPython.utils.process import arg_split
231 from traitlets import (
231 from traitlets import (
232 Bool,
232 Bool,
233 Enum,
233 Enum,
234 Int,
234 Int,
235 List as ListTrait,
235 List as ListTrait,
236 Unicode,
236 Unicode,
237 Dict as DictTrait,
237 Dict as DictTrait,
238 Union as UnionTrait,
238 Union as UnionTrait,
239 observe,
239 observe,
240 )
240 )
241 from traitlets.config.configurable import Configurable
241 from traitlets.config.configurable import Configurable
242
242
243 import __main__
243 import __main__
244
244
245 # skip module docstests
245 # skip module docstests
246 __skip_doctest__ = True
246 __skip_doctest__ = True
247
247
248
248
249 try:
249 try:
250 import jedi
250 import jedi
251 jedi.settings.case_insensitive_completion = False
251 jedi.settings.case_insensitive_completion = False
252 import jedi.api.helpers
252 import jedi.api.helpers
253 import jedi.api.classes
253 import jedi.api.classes
254 JEDI_INSTALLED = True
254 JEDI_INSTALLED = True
255 except ImportError:
255 except ImportError:
256 JEDI_INSTALLED = False
256 JEDI_INSTALLED = False
257
257
258
258
259 if TYPE_CHECKING or GENERATING_DOCUMENTATION and sys.version_info >= (3, 11):
259 if TYPE_CHECKING or GENERATING_DOCUMENTATION and sys.version_info >= (3, 11):
260 from typing import cast
260 from typing import cast
261 from typing_extensions import TypedDict, NotRequired, Protocol, TypeAlias, TypeGuard
261 from typing_extensions import TypedDict, NotRequired, Protocol, TypeAlias, TypeGuard
262 else:
262 else:
263 from typing import Generic
263 from typing import Generic
264
264
265 def cast(type_, obj):
265 def cast(type_, obj):
266 """Workaround for `TypeError: MatcherAPIv2() takes no arguments`"""
266 """Workaround for `TypeError: MatcherAPIv2() takes no arguments`"""
267 return obj
267 return obj
268
268
269 # do not require on runtime
269 # do not require on runtime
270 NotRequired = Tuple # requires Python >=3.11
270 NotRequired = Tuple # requires Python >=3.11
271 TypedDict = Dict # by extension of `NotRequired` requires 3.11 too
271 TypedDict = Dict # by extension of `NotRequired` requires 3.11 too
272 Protocol = object # requires Python >=3.8
272 Protocol = object # requires Python >=3.8
273 TypeAlias = Any # requires Python >=3.10
273 TypeAlias = Any # requires Python >=3.10
274 TypeGuard = Generic # requires Python >=3.10
274 TypeGuard = Generic # requires Python >=3.10
275 if GENERATING_DOCUMENTATION:
275 if GENERATING_DOCUMENTATION:
276 from typing import TypedDict
276 from typing import TypedDict
277
277
278 # -----------------------------------------------------------------------------
278 # -----------------------------------------------------------------------------
279 # Globals
279 # Globals
280 #-----------------------------------------------------------------------------
280 #-----------------------------------------------------------------------------
281
281
282 # ranges where we have most of the valid unicode names. We could be more finer
282 # ranges where we have most of the valid unicode names. We could be more finer
283 # grained but is it worth it for performance While unicode have character in the
283 # grained but is it worth it for performance While unicode have character in the
284 # range 0, 0x110000, we seem to have name for about 10% of those. (131808 as I
284 # range 0, 0x110000, we seem to have name for about 10% of those. (131808 as I
285 # write this). With below range we cover them all, with a density of ~67%
285 # write this). With below range we cover them all, with a density of ~67%
286 # biggest next gap we consider only adds up about 1% density and there are 600
286 # biggest next gap we consider only adds up about 1% density and there are 600
287 # gaps that would need hard coding.
287 # gaps that would need hard coding.
288 _UNICODE_RANGES = [(32, 0x323B0), (0xE0001, 0xE01F0)]
288 _UNICODE_RANGES = [(32, 0x323B0), (0xE0001, 0xE01F0)]
289
289
290 # Public API
290 # Public API
291 __all__ = ["Completer", "IPCompleter"]
291 __all__ = ["Completer", "IPCompleter"]
292
292
293 if sys.platform == 'win32':
293 if sys.platform == 'win32':
294 PROTECTABLES = ' '
294 PROTECTABLES = ' '
295 else:
295 else:
296 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
296 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
297
297
298 # Protect against returning an enormous number of completions which the frontend
298 # Protect against returning an enormous number of completions which the frontend
299 # may have trouble processing.
299 # may have trouble processing.
300 MATCHES_LIMIT = 500
300 MATCHES_LIMIT = 500
301
301
302 # Completion type reported when no type can be inferred.
302 # Completion type reported when no type can be inferred.
303 _UNKNOWN_TYPE = "<unknown>"
303 _UNKNOWN_TYPE = "<unknown>"
304
304
305 # sentinel value to signal lack of a match
305 # sentinel value to signal lack of a match
306 not_found = object()
306 not_found = object()
307
307
308 class ProvisionalCompleterWarning(FutureWarning):
308 class ProvisionalCompleterWarning(FutureWarning):
309 """
309 """
310 Exception raise by an experimental feature in this module.
310 Exception raise by an experimental feature in this module.
311
311
312 Wrap code in :any:`provisionalcompleter` context manager if you
312 Wrap code in :any:`provisionalcompleter` context manager if you
313 are certain you want to use an unstable feature.
313 are certain you want to use an unstable feature.
314 """
314 """
315 pass
315 pass
316
316
317 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
317 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
318
318
319
319
320 @skip_doctest
320 @skip_doctest
321 @contextmanager
321 @contextmanager
322 def provisionalcompleter(action='ignore'):
322 def provisionalcompleter(action='ignore'):
323 """
323 """
324 This context manager has to be used in any place where unstable completer
324 This context manager has to be used in any place where unstable completer
325 behavior and API may be called.
325 behavior and API may be called.
326
326
327 >>> with provisionalcompleter():
327 >>> with provisionalcompleter():
328 ... completer.do_experimental_things() # works
328 ... completer.do_experimental_things() # works
329
329
330 >>> completer.do_experimental_things() # raises.
330 >>> completer.do_experimental_things() # raises.
331
331
332 .. note::
332 .. note::
333
333
334 Unstable
334 Unstable
335
335
336 By using this context manager you agree that the API in use may change
336 By using this context manager you agree that the API in use may change
337 without warning, and that you won't complain if they do so.
337 without warning, and that you won't complain if they do so.
338
338
339 You also understand that, if the API is not to your liking, you should report
339 You also understand that, if the API is not to your liking, you should report
340 a bug to explain your use case upstream.
340 a bug to explain your use case upstream.
341
341
342 We'll be happy to get your feedback, feature requests, and improvements on
342 We'll be happy to get your feedback, feature requests, and improvements on
343 any of the unstable APIs!
343 any of the unstable APIs!
344 """
344 """
345 with warnings.catch_warnings():
345 with warnings.catch_warnings():
346 warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
346 warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
347 yield
347 yield
348
348
349
349
350 def has_open_quotes(s):
350 def has_open_quotes(s):
351 """Return whether a string has open quotes.
351 """Return whether a string has open quotes.
352
352
353 This simply counts whether the number of quote characters of either type in
353 This simply counts whether the number of quote characters of either type in
354 the string is odd.
354 the string is odd.
355
355
356 Returns
356 Returns
357 -------
357 -------
358 If there is an open quote, the quote character is returned. Else, return
358 If there is an open quote, the quote character is returned. Else, return
359 False.
359 False.
360 """
360 """
361 # We check " first, then ', so complex cases with nested quotes will get
361 # We check " first, then ', so complex cases with nested quotes will get
362 # the " to take precedence.
362 # the " to take precedence.
363 if s.count('"') % 2:
363 if s.count('"') % 2:
364 return '"'
364 return '"'
365 elif s.count("'") % 2:
365 elif s.count("'") % 2:
366 return "'"
366 return "'"
367 else:
367 else:
368 return False
368 return False
369
369
370
370
371 def protect_filename(s, protectables=PROTECTABLES):
371 def protect_filename(s, protectables=PROTECTABLES):
372 """Escape a string to protect certain characters."""
372 """Escape a string to protect certain characters."""
373 if set(s) & set(protectables):
373 if set(s) & set(protectables):
374 if sys.platform == "win32":
374 if sys.platform == "win32":
375 return '"' + s + '"'
375 return '"' + s + '"'
376 else:
376 else:
377 return "".join(("\\" + c if c in protectables else c) for c in s)
377 return "".join(("\\" + c if c in protectables else c) for c in s)
378 else:
378 else:
379 return s
379 return s
380
380
381
381
382 def expand_user(path:str) -> Tuple[str, bool, str]:
382 def expand_user(path:str) -> Tuple[str, bool, str]:
383 """Expand ``~``-style usernames in strings.
383 """Expand ``~``-style usernames in strings.
384
384
385 This is similar to :func:`os.path.expanduser`, but it computes and returns
385 This is similar to :func:`os.path.expanduser`, but it computes and returns
386 extra information that will be useful if the input was being used in
386 extra information that will be useful if the input was being used in
387 computing completions, and you wish to return the completions with the
387 computing completions, and you wish to return the completions with the
388 original '~' instead of its expanded value.
388 original '~' instead of its expanded value.
389
389
390 Parameters
390 Parameters
391 ----------
391 ----------
392 path : str
392 path : str
393 String to be expanded. If no ~ is present, the output is the same as the
393 String to be expanded. If no ~ is present, the output is the same as the
394 input.
394 input.
395
395
396 Returns
396 Returns
397 -------
397 -------
398 newpath : str
398 newpath : str
399 Result of ~ expansion in the input path.
399 Result of ~ expansion in the input path.
400 tilde_expand : bool
400 tilde_expand : bool
401 Whether any expansion was performed or not.
401 Whether any expansion was performed or not.
402 tilde_val : str
402 tilde_val : str
403 The value that ~ was replaced with.
403 The value that ~ was replaced with.
404 """
404 """
405 # Default values
405 # Default values
406 tilde_expand = False
406 tilde_expand = False
407 tilde_val = ''
407 tilde_val = ''
408 newpath = path
408 newpath = path
409
409
410 if path.startswith('~'):
410 if path.startswith('~'):
411 tilde_expand = True
411 tilde_expand = True
412 rest = len(path)-1
412 rest = len(path)-1
413 newpath = os.path.expanduser(path)
413 newpath = os.path.expanduser(path)
414 if rest:
414 if rest:
415 tilde_val = newpath[:-rest]
415 tilde_val = newpath[:-rest]
416 else:
416 else:
417 tilde_val = newpath
417 tilde_val = newpath
418
418
419 return newpath, tilde_expand, tilde_val
419 return newpath, tilde_expand, tilde_val
420
420
421
421
422 def compress_user(path:str, tilde_expand:bool, tilde_val:str) -> str:
422 def compress_user(path:str, tilde_expand:bool, tilde_val:str) -> str:
423 """Does the opposite of expand_user, with its outputs.
423 """Does the opposite of expand_user, with its outputs.
424 """
424 """
425 if tilde_expand:
425 if tilde_expand:
426 return path.replace(tilde_val, '~')
426 return path.replace(tilde_val, '~')
427 else:
427 else:
428 return path
428 return path
429
429
430
430
431 def completions_sorting_key(word):
431 def completions_sorting_key(word):
432 """key for sorting completions
432 """key for sorting completions
433
433
434 This does several things:
434 This does several things:
435
435
436 - Demote any completions starting with underscores to the end
436 - Demote any completions starting with underscores to the end
437 - Insert any %magic and %%cellmagic completions in the alphabetical order
437 - Insert any %magic and %%cellmagic completions in the alphabetical order
438 by their name
438 by their name
439 """
439 """
440 prio1, prio2 = 0, 0
440 prio1, prio2 = 0, 0
441
441
442 if word.startswith('__'):
442 if word.startswith('__'):
443 prio1 = 2
443 prio1 = 2
444 elif word.startswith('_'):
444 elif word.startswith('_'):
445 prio1 = 1
445 prio1 = 1
446
446
447 if word.endswith('='):
447 if word.endswith('='):
448 prio1 = -1
448 prio1 = -1
449
449
450 if word.startswith('%%'):
450 if word.startswith('%%'):
451 # If there's another % in there, this is something else, so leave it alone
451 # If there's another % in there, this is something else, so leave it alone
452 if not "%" in word[2:]:
452 if not "%" in word[2:]:
453 word = word[2:]
453 word = word[2:]
454 prio2 = 2
454 prio2 = 2
455 elif word.startswith('%'):
455 elif word.startswith('%'):
456 if not "%" in word[1:]:
456 if not "%" in word[1:]:
457 word = word[1:]
457 word = word[1:]
458 prio2 = 1
458 prio2 = 1
459
459
460 return prio1, word, prio2
460 return prio1, word, prio2
461
461
462
462
463 class _FakeJediCompletion:
463 class _FakeJediCompletion:
464 """
464 """
465 This is a workaround to communicate to the UI that Jedi has crashed and to
465 This is a workaround to communicate to the UI that Jedi has crashed and to
466 report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
466 report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
467
467
468 Added in IPython 6.0 so should likely be removed for 7.0
468 Added in IPython 6.0 so should likely be removed for 7.0
469
469
470 """
470 """
471
471
472 def __init__(self, name):
472 def __init__(self, name):
473
473
474 self.name = name
474 self.name = name
475 self.complete = name
475 self.complete = name
476 self.type = 'crashed'
476 self.type = 'crashed'
477 self.name_with_symbols = name
477 self.name_with_symbols = name
478 self.signature = ""
478 self.signature = ""
479 self._origin = "fake"
479 self._origin = "fake"
480 self.text = "crashed"
480 self.text = "crashed"
481
481
482 def __repr__(self):
482 def __repr__(self):
483 return '<Fake completion object jedi has crashed>'
483 return '<Fake completion object jedi has crashed>'
484
484
485
485
486 _JediCompletionLike = Union["jedi.api.Completion", _FakeJediCompletion]
486 _JediCompletionLike = Union["jedi.api.Completion", _FakeJediCompletion]
487
487
488
488
489 class Completion:
489 class Completion:
490 """
490 """
491 Completion object used and returned by IPython completers.
491 Completion object used and returned by IPython completers.
492
492
493 .. warning::
493 .. warning::
494
494
495 Unstable
495 Unstable
496
496
497 This function is unstable, API may change without warning.
497 This function is unstable, API may change without warning.
498 It will also raise unless use in proper context manager.
498 It will also raise unless use in proper context manager.
499
499
500 This act as a middle ground :any:`Completion` object between the
500 This act as a middle ground :any:`Completion` object between the
501 :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
501 :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
502 object. While Jedi need a lot of information about evaluator and how the
502 object. While Jedi need a lot of information about evaluator and how the
503 code should be ran/inspected, PromptToolkit (and other frontend) mostly
503 code should be ran/inspected, PromptToolkit (and other frontend) mostly
504 need user facing information.
504 need user facing information.
505
505
506 - Which range should be replaced replaced by what.
506 - Which range should be replaced replaced by what.
507 - Some metadata (like completion type), or meta information to displayed to
507 - Some metadata (like completion type), or meta information to displayed to
508 the use user.
508 the use user.
509
509
510 For debugging purpose we can also store the origin of the completion (``jedi``,
510 For debugging purpose we can also store the origin of the completion (``jedi``,
511 ``IPython.python_matches``, ``IPython.magics_matches``...).
511 ``IPython.python_matches``, ``IPython.magics_matches``...).
512 """
512 """
513
513
514 __slots__ = ['start', 'end', 'text', 'type', 'signature', '_origin']
514 __slots__ = ['start', 'end', 'text', 'type', 'signature', '_origin']
515
515
516 def __init__(
516 def __init__(
517 self,
517 self,
518 start: int,
518 start: int,
519 end: int,
519 end: int,
520 text: str,
520 text: str,
521 *,
521 *,
522 type: Optional[str] = None,
522 type: Optional[str] = None,
523 _origin="",
523 _origin="",
524 signature="",
524 signature="",
525 ) -> None:
525 ) -> None:
526 warnings.warn(
526 warnings.warn(
527 "``Completion`` is a provisional API (as of IPython 6.0). "
527 "``Completion`` is a provisional API (as of IPython 6.0). "
528 "It may change without warnings. "
528 "It may change without warnings. "
529 "Use in corresponding context manager.",
529 "Use in corresponding context manager.",
530 category=ProvisionalCompleterWarning,
530 category=ProvisionalCompleterWarning,
531 stacklevel=2,
531 stacklevel=2,
532 )
532 )
533
533
534 self.start = start
534 self.start = start
535 self.end = end
535 self.end = end
536 self.text = text
536 self.text = text
537 self.type = type
537 self.type = type
538 self.signature = signature
538 self.signature = signature
539 self._origin = _origin
539 self._origin = _origin
540
540
541 def __repr__(self):
541 def __repr__(self):
542 return '<Completion start=%s end=%s text=%r type=%r, signature=%r,>' % \
542 return '<Completion start=%s end=%s text=%r type=%r, signature=%r,>' % \
543 (self.start, self.end, self.text, self.type or '?', self.signature or '?')
543 (self.start, self.end, self.text, self.type or '?', self.signature or '?')
544
544
545 def __eq__(self, other) -> bool:
545 def __eq__(self, other) -> bool:
546 """
546 """
547 Equality and hash do not hash the type (as some completer may not be
547 Equality and hash do not hash the type (as some completer may not be
548 able to infer the type), but are use to (partially) de-duplicate
548 able to infer the type), but are use to (partially) de-duplicate
549 completion.
549 completion.
550
550
551 Completely de-duplicating completion is a bit tricker that just
551 Completely de-duplicating completion is a bit tricker that just
552 comparing as it depends on surrounding text, which Completions are not
552 comparing as it depends on surrounding text, which Completions are not
553 aware of.
553 aware of.
554 """
554 """
555 return self.start == other.start and \
555 return self.start == other.start and \
556 self.end == other.end and \
556 self.end == other.end and \
557 self.text == other.text
557 self.text == other.text
558
558
559 def __hash__(self):
559 def __hash__(self):
560 return hash((self.start, self.end, self.text))
560 return hash((self.start, self.end, self.text))
561
561
562
562
563 class SimpleCompletion:
563 class SimpleCompletion:
564 """Completion item to be included in the dictionary returned by new-style Matcher (API v2).
564 """Completion item to be included in the dictionary returned by new-style Matcher (API v2).
565
565
566 .. warning::
566 .. warning::
567
567
568 Provisional
568 Provisional
569
569
570 This class is used to describe the currently supported attributes of
570 This class is used to describe the currently supported attributes of
571 simple completion items, and any additional implementation details
571 simple completion items, and any additional implementation details
572 should not be relied on. Additional attributes may be included in
572 should not be relied on. Additional attributes may be included in
573 future versions, and meaning of text disambiguated from the current
573 future versions, and meaning of text disambiguated from the current
574 dual meaning of "text to insert" and "text to used as a label".
574 dual meaning of "text to insert" and "text to used as a label".
575 """
575 """
576
576
577 __slots__ = ["text", "type"]
577 __slots__ = ["text", "type"]
578
578
579 def __init__(self, text: str, *, type: Optional[str] = None):
579 def __init__(self, text: str, *, type: Optional[str] = None):
580 self.text = text
580 self.text = text
581 self.type = type
581 self.type = type
582
582
583 def __repr__(self):
583 def __repr__(self):
584 return f"<SimpleCompletion text={self.text!r} type={self.type!r}>"
584 return f"<SimpleCompletion text={self.text!r} type={self.type!r}>"
585
585
586
586
587 class _MatcherResultBase(TypedDict):
587 class _MatcherResultBase(TypedDict):
588 """Definition of dictionary to be returned by new-style Matcher (API v2)."""
588 """Definition of dictionary to be returned by new-style Matcher (API v2)."""
589
589
590 #: Suffix of the provided ``CompletionContext.token``, if not given defaults to full token.
590 #: Suffix of the provided ``CompletionContext.token``, if not given defaults to full token.
591 matched_fragment: NotRequired[str]
591 matched_fragment: NotRequired[str]
592
592
593 #: Whether to suppress results from all other matchers (True), some
593 #: Whether to suppress results from all other matchers (True), some
594 #: matchers (set of identifiers) or none (False); default is False.
594 #: matchers (set of identifiers) or none (False); default is False.
595 suppress: NotRequired[Union[bool, Set[str]]]
595 suppress: NotRequired[Union[bool, Set[str]]]
596
596
597 #: Identifiers of matchers which should NOT be suppressed when this matcher
597 #: Identifiers of matchers which should NOT be suppressed when this matcher
598 #: requests to suppress all other matchers; defaults to an empty set.
598 #: requests to suppress all other matchers; defaults to an empty set.
599 do_not_suppress: NotRequired[Set[str]]
599 do_not_suppress: NotRequired[Set[str]]
600
600
601 #: Are completions already ordered and should be left as-is? default is False.
601 #: Are completions already ordered and should be left as-is? default is False.
602 ordered: NotRequired[bool]
602 ordered: NotRequired[bool]
603
603
604
604
605 @sphinx_options(show_inherited_members=True, exclude_inherited_from=["dict"])
605 @sphinx_options(show_inherited_members=True, exclude_inherited_from=["dict"])
606 class SimpleMatcherResult(_MatcherResultBase, TypedDict):
606 class SimpleMatcherResult(_MatcherResultBase, TypedDict):
607 """Result of new-style completion matcher."""
607 """Result of new-style completion matcher."""
608
608
609 # note: TypedDict is added again to the inheritance chain
609 # note: TypedDict is added again to the inheritance chain
610 # in order to get __orig_bases__ for documentation
610 # in order to get __orig_bases__ for documentation
611
611
612 #: List of candidate completions
612 #: List of candidate completions
613 completions: Sequence[SimpleCompletion] | Iterator[SimpleCompletion]
613 completions: Sequence[SimpleCompletion] | Iterator[SimpleCompletion]
614
614
615
615
616 class _JediMatcherResult(_MatcherResultBase):
616 class _JediMatcherResult(_MatcherResultBase):
617 """Matching result returned by Jedi (will be processed differently)"""
617 """Matching result returned by Jedi (will be processed differently)"""
618
618
619 #: list of candidate completions
619 #: list of candidate completions
620 completions: Iterator[_JediCompletionLike]
620 completions: Iterator[_JediCompletionLike]
621
621
622
622
623 AnyMatcherCompletion = Union[_JediCompletionLike, SimpleCompletion]
623 AnyMatcherCompletion = Union[_JediCompletionLike, SimpleCompletion]
624 AnyCompletion = TypeVar("AnyCompletion", AnyMatcherCompletion, Completion)
624 AnyCompletion = TypeVar("AnyCompletion", AnyMatcherCompletion, Completion)
625
625
626
626
627 @dataclass
627 @dataclass
628 class CompletionContext:
628 class CompletionContext:
629 """Completion context provided as an argument to matchers in the Matcher API v2."""
629 """Completion context provided as an argument to matchers in the Matcher API v2."""
630
630
631 # rationale: many legacy matchers relied on completer state (`self.text_until_cursor`)
631 # rationale: many legacy matchers relied on completer state (`self.text_until_cursor`)
632 # which was not explicitly visible as an argument of the matcher, making any refactor
632 # which was not explicitly visible as an argument of the matcher, making any refactor
633 # prone to errors; by explicitly passing `cursor_position` we can decouple the matchers
633 # prone to errors; by explicitly passing `cursor_position` we can decouple the matchers
634 # from the completer, and make substituting them in sub-classes easier.
634 # from the completer, and make substituting them in sub-classes easier.
635
635
636 #: Relevant fragment of code directly preceding the cursor.
636 #: Relevant fragment of code directly preceding the cursor.
637 #: The extraction of token is implemented via splitter heuristic
637 #: The extraction of token is implemented via splitter heuristic
638 #: (following readline behaviour for legacy reasons), which is user configurable
638 #: (following readline behaviour for legacy reasons), which is user configurable
639 #: (by switching the greedy mode).
639 #: (by switching the greedy mode).
640 token: str
640 token: str
641
641
642 #: The full available content of the editor or buffer
642 #: The full available content of the editor or buffer
643 full_text: str
643 full_text: str
644
644
645 #: Cursor position in the line (the same for ``full_text`` and ``text``).
645 #: Cursor position in the line (the same for ``full_text`` and ``text``).
646 cursor_position: int
646 cursor_position: int
647
647
648 #: Cursor line in ``full_text``.
648 #: Cursor line in ``full_text``.
649 cursor_line: int
649 cursor_line: int
650
650
651 #: The maximum number of completions that will be used downstream.
651 #: The maximum number of completions that will be used downstream.
652 #: Matchers can use this information to abort early.
652 #: Matchers can use this information to abort early.
653 #: The built-in Jedi matcher is currently excepted from this limit.
653 #: The built-in Jedi matcher is currently excepted from this limit.
654 # If not given, return all possible completions.
654 # If not given, return all possible completions.
655 limit: Optional[int]
655 limit: Optional[int]
656
656
657 @cached_property
657 @cached_property
658 def text_until_cursor(self) -> str:
658 def text_until_cursor(self) -> str:
659 return self.line_with_cursor[: self.cursor_position]
659 return self.line_with_cursor[: self.cursor_position]
660
660
661 @cached_property
661 @cached_property
662 def line_with_cursor(self) -> str:
662 def line_with_cursor(self) -> str:
663 return self.full_text.split("\n")[self.cursor_line]
663 return self.full_text.split("\n")[self.cursor_line]
664
664
665
665
666 #: Matcher results for API v2.
666 #: Matcher results for API v2.
667 MatcherResult = Union[SimpleMatcherResult, _JediMatcherResult]
667 MatcherResult = Union[SimpleMatcherResult, _JediMatcherResult]
668
668
669
669
670 class _MatcherAPIv1Base(Protocol):
670 class _MatcherAPIv1Base(Protocol):
671 def __call__(self, text: str) -> List[str]:
671 def __call__(self, text: str) -> List[str]:
672 """Call signature."""
672 """Call signature."""
673 ...
673 ...
674
674
675 #: Used to construct the default matcher identifier
675 #: Used to construct the default matcher identifier
676 __qualname__: str
676 __qualname__: str
677
677
678
678
679 class _MatcherAPIv1Total(_MatcherAPIv1Base, Protocol):
679 class _MatcherAPIv1Total(_MatcherAPIv1Base, Protocol):
680 #: API version
680 #: API version
681 matcher_api_version: Optional[Literal[1]]
681 matcher_api_version: Optional[Literal[1]]
682
682
683 def __call__(self, text: str) -> List[str]:
683 def __call__(self, text: str) -> List[str]:
684 """Call signature."""
684 """Call signature."""
685 ...
685 ...
686
686
687
687
688 #: Protocol describing Matcher API v1.
688 #: Protocol describing Matcher API v1.
689 MatcherAPIv1: TypeAlias = Union[_MatcherAPIv1Base, _MatcherAPIv1Total]
689 MatcherAPIv1: TypeAlias = Union[_MatcherAPIv1Base, _MatcherAPIv1Total]
690
690
691
691
692 class MatcherAPIv2(Protocol):
692 class MatcherAPIv2(Protocol):
693 """Protocol describing Matcher API v2."""
693 """Protocol describing Matcher API v2."""
694
694
695 #: API version
695 #: API version
696 matcher_api_version: Literal[2] = 2
696 matcher_api_version: Literal[2] = 2
697
697
698 def __call__(self, context: CompletionContext) -> MatcherResult:
698 def __call__(self, context: CompletionContext) -> MatcherResult:
699 """Call signature."""
699 """Call signature."""
700 ...
700 ...
701
701
702 #: Used to construct the default matcher identifier
702 #: Used to construct the default matcher identifier
703 __qualname__: str
703 __qualname__: str
704
704
705
705
706 Matcher: TypeAlias = Union[MatcherAPIv1, MatcherAPIv2]
706 Matcher: TypeAlias = Union[MatcherAPIv1, MatcherAPIv2]
707
707
708
708
709 def _is_matcher_v1(matcher: Matcher) -> TypeGuard[MatcherAPIv1]:
709 def _is_matcher_v1(matcher: Matcher) -> TypeGuard[MatcherAPIv1]:
710 api_version = _get_matcher_api_version(matcher)
710 api_version = _get_matcher_api_version(matcher)
711 return api_version == 1
711 return api_version == 1
712
712
713
713
714 def _is_matcher_v2(matcher: Matcher) -> TypeGuard[MatcherAPIv2]:
714 def _is_matcher_v2(matcher: Matcher) -> TypeGuard[MatcherAPIv2]:
715 api_version = _get_matcher_api_version(matcher)
715 api_version = _get_matcher_api_version(matcher)
716 return api_version == 2
716 return api_version == 2
717
717
718
718
719 def _is_sizable(value: Any) -> TypeGuard[Sized]:
719 def _is_sizable(value: Any) -> TypeGuard[Sized]:
720 """Determines whether objects is sizable"""
720 """Determines whether objects is sizable"""
721 return hasattr(value, "__len__")
721 return hasattr(value, "__len__")
722
722
723
723
724 def _is_iterator(value: Any) -> TypeGuard[Iterator]:
724 def _is_iterator(value: Any) -> TypeGuard[Iterator]:
725 """Determines whether objects is sizable"""
725 """Determines whether objects is sizable"""
726 return hasattr(value, "__next__")
726 return hasattr(value, "__next__")
727
727
728
728
729 def has_any_completions(result: MatcherResult) -> bool:
729 def has_any_completions(result: MatcherResult) -> bool:
730 """Check if any result includes any completions."""
730 """Check if any result includes any completions."""
731 completions = result["completions"]
731 completions = result["completions"]
732 if _is_sizable(completions):
732 if _is_sizable(completions):
733 return len(completions) != 0
733 return len(completions) != 0
734 if _is_iterator(completions):
734 if _is_iterator(completions):
735 try:
735 try:
736 old_iterator = completions
736 old_iterator = completions
737 first = next(old_iterator)
737 first = next(old_iterator)
738 result["completions"] = cast(
738 result["completions"] = cast(
739 Iterator[SimpleCompletion],
739 Iterator[SimpleCompletion],
740 itertools.chain([first], old_iterator),
740 itertools.chain([first], old_iterator),
741 )
741 )
742 return True
742 return True
743 except StopIteration:
743 except StopIteration:
744 return False
744 return False
745 raise ValueError(
745 raise ValueError(
746 "Completions returned by matcher need to be an Iterator or a Sizable"
746 "Completions returned by matcher need to be an Iterator or a Sizable"
747 )
747 )
748
748
749
749
750 def completion_matcher(
750 def completion_matcher(
751 *,
751 *,
752 priority: Optional[float] = None,
752 priority: Optional[float] = None,
753 identifier: Optional[str] = None,
753 identifier: Optional[str] = None,
754 api_version: int = 1,
754 api_version: int = 1,
755 ):
755 ):
756 """Adds attributes describing the matcher.
756 """Adds attributes describing the matcher.
757
757
758 Parameters
758 Parameters
759 ----------
759 ----------
760 priority : Optional[float]
760 priority : Optional[float]
761 The priority of the matcher, determines the order of execution of matchers.
761 The priority of the matcher, determines the order of execution of matchers.
762 Higher priority means that the matcher will be executed first. Defaults to 0.
762 Higher priority means that the matcher will be executed first. Defaults to 0.
763 identifier : Optional[str]
763 identifier : Optional[str]
764 identifier of the matcher allowing users to modify the behaviour via traitlets,
764 identifier of the matcher allowing users to modify the behaviour via traitlets,
765 and also used to for debugging (will be passed as ``origin`` with the completions).
765 and also used to for debugging (will be passed as ``origin`` with the completions).
766
766
767 Defaults to matcher function's ``__qualname__`` (for example,
767 Defaults to matcher function's ``__qualname__`` (for example,
768 ``IPCompleter.file_matcher`` for the built-in matched defined
768 ``IPCompleter.file_matcher`` for the built-in matched defined
769 as a ``file_matcher`` method of the ``IPCompleter`` class).
769 as a ``file_matcher`` method of the ``IPCompleter`` class).
770 api_version: Optional[int]
770 api_version: Optional[int]
771 version of the Matcher API used by this matcher.
771 version of the Matcher API used by this matcher.
772 Currently supported values are 1 and 2.
772 Currently supported values are 1 and 2.
773 Defaults to 1.
773 Defaults to 1.
774 """
774 """
775
775
776 def wrapper(func: Matcher):
776 def wrapper(func: Matcher):
777 func.matcher_priority = priority or 0 # type: ignore
777 func.matcher_priority = priority or 0 # type: ignore
778 func.matcher_identifier = identifier or func.__qualname__ # type: ignore
778 func.matcher_identifier = identifier or func.__qualname__ # type: ignore
779 func.matcher_api_version = api_version # type: ignore
779 func.matcher_api_version = api_version # type: ignore
780 if TYPE_CHECKING:
780 if TYPE_CHECKING:
781 if api_version == 1:
781 if api_version == 1:
782 func = cast(MatcherAPIv1, func)
782 func = cast(MatcherAPIv1, func)
783 elif api_version == 2:
783 elif api_version == 2:
784 func = cast(MatcherAPIv2, func)
784 func = cast(MatcherAPIv2, func)
785 return func
785 return func
786
786
787 return wrapper
787 return wrapper
788
788
789
789
790 def _get_matcher_priority(matcher: Matcher):
790 def _get_matcher_priority(matcher: Matcher):
791 return getattr(matcher, "matcher_priority", 0)
791 return getattr(matcher, "matcher_priority", 0)
792
792
793
793
794 def _get_matcher_id(matcher: Matcher):
794 def _get_matcher_id(matcher: Matcher):
795 return getattr(matcher, "matcher_identifier", matcher.__qualname__)
795 return getattr(matcher, "matcher_identifier", matcher.__qualname__)
796
796
797
797
798 def _get_matcher_api_version(matcher):
798 def _get_matcher_api_version(matcher):
799 return getattr(matcher, "matcher_api_version", 1)
799 return getattr(matcher, "matcher_api_version", 1)
800
800
801
801
802 context_matcher = partial(completion_matcher, api_version=2)
802 context_matcher = partial(completion_matcher, api_version=2)
803
803
804
804
805 _IC = Iterable[Completion]
805 _IC = Iterable[Completion]
806
806
807
807
808 def _deduplicate_completions(text: str, completions: _IC)-> _IC:
808 def _deduplicate_completions(text: str, completions: _IC)-> _IC:
809 """
809 """
810 Deduplicate a set of completions.
810 Deduplicate a set of completions.
811
811
812 .. warning::
812 .. warning::
813
813
814 Unstable
814 Unstable
815
815
816 This function is unstable, API may change without warning.
816 This function is unstable, API may change without warning.
817
817
818 Parameters
818 Parameters
819 ----------
819 ----------
820 text : str
820 text : str
821 text that should be completed.
821 text that should be completed.
822 completions : Iterator[Completion]
822 completions : Iterator[Completion]
823 iterator over the completions to deduplicate
823 iterator over the completions to deduplicate
824
824
825 Yields
825 Yields
826 ------
826 ------
827 `Completions` objects
827 `Completions` objects
828 Completions coming from multiple sources, may be different but end up having
828 Completions coming from multiple sources, may be different but end up having
829 the same effect when applied to ``text``. If this is the case, this will
829 the same effect when applied to ``text``. If this is the case, this will
830 consider completions as equal and only emit the first encountered.
830 consider completions as equal and only emit the first encountered.
831 Not folded in `completions()` yet for debugging purpose, and to detect when
831 Not folded in `completions()` yet for debugging purpose, and to detect when
832 the IPython completer does return things that Jedi does not, but should be
832 the IPython completer does return things that Jedi does not, but should be
833 at some point.
833 at some point.
834 """
834 """
835 completions = list(completions)
835 completions = list(completions)
836 if not completions:
836 if not completions:
837 return
837 return
838
838
839 new_start = min(c.start for c in completions)
839 new_start = min(c.start for c in completions)
840 new_end = max(c.end for c in completions)
840 new_end = max(c.end for c in completions)
841
841
842 seen = set()
842 seen = set()
843 for c in completions:
843 for c in completions:
844 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
844 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
845 if new_text not in seen:
845 if new_text not in seen:
846 yield c
846 yield c
847 seen.add(new_text)
847 seen.add(new_text)
848
848
849
849
850 def rectify_completions(text: str, completions: _IC, *, _debug: bool = False) -> _IC:
850 def rectify_completions(text: str, completions: _IC, *, _debug: bool = False) -> _IC:
851 """
851 """
852 Rectify a set of completions to all have the same ``start`` and ``end``
852 Rectify a set of completions to all have the same ``start`` and ``end``
853
853
854 .. warning::
854 .. warning::
855
855
856 Unstable
856 Unstable
857
857
858 This function is unstable, API may change without warning.
858 This function is unstable, API may change without warning.
859 It will also raise unless use in proper context manager.
859 It will also raise unless use in proper context manager.
860
860
861 Parameters
861 Parameters
862 ----------
862 ----------
863 text : str
863 text : str
864 text that should be completed.
864 text that should be completed.
865 completions : Iterator[Completion]
865 completions : Iterator[Completion]
866 iterator over the completions to rectify
866 iterator over the completions to rectify
867 _debug : bool
867 _debug : bool
868 Log failed completion
868 Log failed completion
869
869
870 Notes
870 Notes
871 -----
871 -----
872 :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
872 :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
873 the Jupyter Protocol requires them to behave like so. This will readjust
873 the Jupyter Protocol requires them to behave like so. This will readjust
874 the completion to have the same ``start`` and ``end`` by padding both
874 the completion to have the same ``start`` and ``end`` by padding both
875 extremities with surrounding text.
875 extremities with surrounding text.
876
876
877 During stabilisation should support a ``_debug`` option to log which
877 During stabilisation should support a ``_debug`` option to log which
878 completion are return by the IPython completer and not found in Jedi in
878 completion are return by the IPython completer and not found in Jedi in
879 order to make upstream bug report.
879 order to make upstream bug report.
880 """
880 """
881 warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
881 warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
882 "It may change without warnings. "
882 "It may change without warnings. "
883 "Use in corresponding context manager.",
883 "Use in corresponding context manager.",
884 category=ProvisionalCompleterWarning, stacklevel=2)
884 category=ProvisionalCompleterWarning, stacklevel=2)
885
885
886 completions = list(completions)
886 completions = list(completions)
887 if not completions:
887 if not completions:
888 return
888 return
889 starts = (c.start for c in completions)
889 starts = (c.start for c in completions)
890 ends = (c.end for c in completions)
890 ends = (c.end for c in completions)
891
891
892 new_start = min(starts)
892 new_start = min(starts)
893 new_end = max(ends)
893 new_end = max(ends)
894
894
895 seen_jedi = set()
895 seen_jedi = set()
896 seen_python_matches = set()
896 seen_python_matches = set()
897 for c in completions:
897 for c in completions:
898 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
898 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
899 if c._origin == 'jedi':
899 if c._origin == 'jedi':
900 seen_jedi.add(new_text)
900 seen_jedi.add(new_text)
901 elif c._origin == 'IPCompleter.python_matches':
901 elif c._origin == 'IPCompleter.python_matches':
902 seen_python_matches.add(new_text)
902 seen_python_matches.add(new_text)
903 yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin, signature=c.signature)
903 yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin, signature=c.signature)
904 diff = seen_python_matches.difference(seen_jedi)
904 diff = seen_python_matches.difference(seen_jedi)
905 if diff and _debug:
905 if diff and _debug:
906 print('IPython.python matches have extras:', diff)
906 print('IPython.python matches have extras:', diff)
907
907
908
908
909 if sys.platform == 'win32':
909 if sys.platform == 'win32':
910 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
910 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
911 else:
911 else:
912 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
912 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
913
913
914 GREEDY_DELIMS = ' =\r\n'
914 GREEDY_DELIMS = ' =\r\n'
915
915
916
916
917 class CompletionSplitter(object):
917 class CompletionSplitter(object):
918 """An object to split an input line in a manner similar to readline.
918 """An object to split an input line in a manner similar to readline.
919
919
920 By having our own implementation, we can expose readline-like completion in
920 By having our own implementation, we can expose readline-like completion in
921 a uniform manner to all frontends. This object only needs to be given the
921 a uniform manner to all frontends. This object only needs to be given the
922 line of text to be split and the cursor position on said line, and it
922 line of text to be split and the cursor position on said line, and it
923 returns the 'word' to be completed on at the cursor after splitting the
923 returns the 'word' to be completed on at the cursor after splitting the
924 entire line.
924 entire line.
925
925
926 What characters are used as splitting delimiters can be controlled by
926 What characters are used as splitting delimiters can be controlled by
927 setting the ``delims`` attribute (this is a property that internally
927 setting the ``delims`` attribute (this is a property that internally
928 automatically builds the necessary regular expression)"""
928 automatically builds the necessary regular expression)"""
929
929
930 # Private interface
930 # Private interface
931
931
932 # A string of delimiter characters. The default value makes sense for
932 # A string of delimiter characters. The default value makes sense for
933 # IPython's most typical usage patterns.
933 # IPython's most typical usage patterns.
934 _delims = DELIMS
934 _delims = DELIMS
935
935
936 # The expression (a normal string) to be compiled into a regular expression
936 # The expression (a normal string) to be compiled into a regular expression
937 # for actual splitting. We store it as an attribute mostly for ease of
937 # for actual splitting. We store it as an attribute mostly for ease of
938 # debugging, since this type of code can be so tricky to debug.
938 # debugging, since this type of code can be so tricky to debug.
939 _delim_expr = None
939 _delim_expr = None
940
940
941 # The regular expression that does the actual splitting
941 # The regular expression that does the actual splitting
942 _delim_re = None
942 _delim_re = None
943
943
944 def __init__(self, delims=None):
944 def __init__(self, delims=None):
945 delims = CompletionSplitter._delims if delims is None else delims
945 delims = CompletionSplitter._delims if delims is None else delims
946 self.delims = delims
946 self.delims = delims
947
947
948 @property
948 @property
949 def delims(self):
949 def delims(self):
950 """Return the string of delimiter characters."""
950 """Return the string of delimiter characters."""
951 return self._delims
951 return self._delims
952
952
953 @delims.setter
953 @delims.setter
954 def delims(self, delims):
954 def delims(self, delims):
955 """Set the delimiters for line splitting."""
955 """Set the delimiters for line splitting."""
956 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
956 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
957 self._delim_re = re.compile(expr)
957 self._delim_re = re.compile(expr)
958 self._delims = delims
958 self._delims = delims
959 self._delim_expr = expr
959 self._delim_expr = expr
960
960
961 def split_line(self, line, cursor_pos=None):
961 def split_line(self, line, cursor_pos=None):
962 """Split a line of text with a cursor at the given position.
962 """Split a line of text with a cursor at the given position.
963 """
963 """
964 l = line if cursor_pos is None else line[:cursor_pos]
964 l = line if cursor_pos is None else line[:cursor_pos]
965 return self._delim_re.split(l)[-1]
965 return self._delim_re.split(l)[-1]
966
966
967
967
968
968
969 class Completer(Configurable):
969 class Completer(Configurable):
970
970
971 greedy = Bool(
971 greedy = Bool(
972 False,
972 False,
973 help="""Activate greedy completion.
973 help="""Activate greedy completion.
974
974
975 .. deprecated:: 8.8
975 .. deprecated:: 8.8
976 Use :std:configtrait:`Completer.evaluation` and :std:configtrait:`Completer.auto_close_dict_keys` instead.
976 Use :std:configtrait:`Completer.evaluation` and :std:configtrait:`Completer.auto_close_dict_keys` instead.
977
977
978 When enabled in IPython 8.8 or newer, changes configuration as follows:
978 When enabled in IPython 8.8 or newer, changes configuration as follows:
979
979
980 - ``Completer.evaluation = 'unsafe'``
980 - ``Completer.evaluation = 'unsafe'``
981 - ``Completer.auto_close_dict_keys = True``
981 - ``Completer.auto_close_dict_keys = True``
982 """,
982 """,
983 ).tag(config=True)
983 ).tag(config=True)
984
984
985 evaluation = Enum(
985 evaluation = Enum(
986 ("forbidden", "minimal", "limited", "unsafe", "dangerous"),
986 ("forbidden", "minimal", "limited", "unsafe", "dangerous"),
987 default_value="limited",
987 default_value="limited",
988 help="""Policy for code evaluation under completion.
988 help="""Policy for code evaluation under completion.
989
989
990 Successive options allow to enable more eager evaluation for better
990 Successive options allow to enable more eager evaluation for better
991 completion suggestions, including for nested dictionaries, nested lists,
991 completion suggestions, including for nested dictionaries, nested lists,
992 or even results of function calls.
992 or even results of function calls.
993 Setting ``unsafe`` or higher can lead to evaluation of arbitrary user
993 Setting ``unsafe`` or higher can lead to evaluation of arbitrary user
994 code on :kbd:`Tab` with potentially unwanted or dangerous side effects.
994 code on :kbd:`Tab` with potentially unwanted or dangerous side effects.
995
995
996 Allowed values are:
996 Allowed values are:
997
997
998 - ``forbidden``: no evaluation of code is permitted,
998 - ``forbidden``: no evaluation of code is permitted,
999 - ``minimal``: evaluation of literals and access to built-in namespace;
999 - ``minimal``: evaluation of literals and access to built-in namespace;
1000 no item/attribute evaluationm no access to locals/globals,
1000 no item/attribute evaluationm no access to locals/globals,
1001 no evaluation of any operations or comparisons.
1001 no evaluation of any operations or comparisons.
1002 - ``limited``: access to all namespaces, evaluation of hard-coded methods
1002 - ``limited``: access to all namespaces, evaluation of hard-coded methods
1003 (for example: :any:`dict.keys`, :any:`object.__getattr__`,
1003 (for example: :any:`dict.keys`, :any:`object.__getattr__`,
1004 :any:`object.__getitem__`) on allow-listed objects (for example:
1004 :any:`object.__getitem__`) on allow-listed objects (for example:
1005 :any:`dict`, :any:`list`, :any:`tuple`, ``pandas.Series``),
1005 :any:`dict`, :any:`list`, :any:`tuple`, ``pandas.Series``),
1006 - ``unsafe``: evaluation of all methods and function calls but not of
1006 - ``unsafe``: evaluation of all methods and function calls but not of
1007 syntax with side-effects like `del x`,
1007 syntax with side-effects like `del x`,
1008 - ``dangerous``: completely arbitrary evaluation.
1008 - ``dangerous``: completely arbitrary evaluation.
1009 """,
1009 """,
1010 ).tag(config=True)
1010 ).tag(config=True)
1011
1011
1012 use_jedi = Bool(default_value=JEDI_INSTALLED,
1012 use_jedi = Bool(default_value=JEDI_INSTALLED,
1013 help="Experimental: Use Jedi to generate autocompletions. "
1013 help="Experimental: Use Jedi to generate autocompletions. "
1014 "Default to True if jedi is installed.").tag(config=True)
1014 "Default to True if jedi is installed.").tag(config=True)
1015
1015
1016 jedi_compute_type_timeout = Int(default_value=400,
1016 jedi_compute_type_timeout = Int(default_value=400,
1017 help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types.
1017 help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types.
1018 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
1018 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
1019 performance by preventing jedi to build its cache.
1019 performance by preventing jedi to build its cache.
1020 """).tag(config=True)
1020 """).tag(config=True)
1021
1021
1022 debug = Bool(default_value=False,
1022 debug = Bool(default_value=False,
1023 help='Enable debug for the Completer. Mostly print extra '
1023 help='Enable debug for the Completer. Mostly print extra '
1024 'information for experimental jedi integration.')\
1024 'information for experimental jedi integration.')\
1025 .tag(config=True)
1025 .tag(config=True)
1026
1026
1027 backslash_combining_completions = Bool(True,
1027 backslash_combining_completions = Bool(True,
1028 help="Enable unicode completions, e.g. \\alpha<tab> . "
1028 help="Enable unicode completions, e.g. \\alpha<tab> . "
1029 "Includes completion of latex commands, unicode names, and expanding "
1029 "Includes completion of latex commands, unicode names, and expanding "
1030 "unicode characters back to latex commands.").tag(config=True)
1030 "unicode characters back to latex commands.").tag(config=True)
1031
1031
1032 auto_close_dict_keys = Bool(
1032 auto_close_dict_keys = Bool(
1033 False,
1033 False,
1034 help="""
1034 help="""
1035 Enable auto-closing dictionary keys.
1035 Enable auto-closing dictionary keys.
1036
1036
1037 When enabled string keys will be suffixed with a final quote
1037 When enabled string keys will be suffixed with a final quote
1038 (matching the opening quote), tuple keys will also receive a
1038 (matching the opening quote), tuple keys will also receive a
1039 separating comma if needed, and keys which are final will
1039 separating comma if needed, and keys which are final will
1040 receive a closing bracket (``]``).
1040 receive a closing bracket (``]``).
1041 """,
1041 """,
1042 ).tag(config=True)
1042 ).tag(config=True)
1043
1043
1044 def __init__(self, namespace=None, global_namespace=None, **kwargs):
1044 def __init__(self, namespace=None, global_namespace=None, **kwargs):
1045 """Create a new completer for the command line.
1045 """Create a new completer for the command line.
1046
1046
1047 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
1047 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
1048
1048
1049 If unspecified, the default namespace where completions are performed
1049 If unspecified, the default namespace where completions are performed
1050 is __main__ (technically, __main__.__dict__). Namespaces should be
1050 is __main__ (technically, __main__.__dict__). Namespaces should be
1051 given as dictionaries.
1051 given as dictionaries.
1052
1052
1053 An optional second namespace can be given. This allows the completer
1053 An optional second namespace can be given. This allows the completer
1054 to handle cases where both the local and global scopes need to be
1054 to handle cases where both the local and global scopes need to be
1055 distinguished.
1055 distinguished.
1056 """
1056 """
1057
1057
1058 # Don't bind to namespace quite yet, but flag whether the user wants a
1058 # Don't bind to namespace quite yet, but flag whether the user wants a
1059 # specific namespace or to use __main__.__dict__. This will allow us
1059 # specific namespace or to use __main__.__dict__. This will allow us
1060 # to bind to __main__.__dict__ at completion time, not now.
1060 # to bind to __main__.__dict__ at completion time, not now.
1061 if namespace is None:
1061 if namespace is None:
1062 self.use_main_ns = True
1062 self.use_main_ns = True
1063 else:
1063 else:
1064 self.use_main_ns = False
1064 self.use_main_ns = False
1065 self.namespace = namespace
1065 self.namespace = namespace
1066
1066
1067 # The global namespace, if given, can be bound directly
1067 # The global namespace, if given, can be bound directly
1068 if global_namespace is None:
1068 if global_namespace is None:
1069 self.global_namespace = {}
1069 self.global_namespace = {}
1070 else:
1070 else:
1071 self.global_namespace = global_namespace
1071 self.global_namespace = global_namespace
1072
1072
1073 self.custom_matchers = []
1073 self.custom_matchers = []
1074
1074
1075 super(Completer, self).__init__(**kwargs)
1075 super(Completer, self).__init__(**kwargs)
1076
1076
1077 def complete(self, text, state):
1077 def complete(self, text, state):
1078 """Return the next possible completion for 'text'.
1078 """Return the next possible completion for 'text'.
1079
1079
1080 This is called successively with state == 0, 1, 2, ... until it
1080 This is called successively with state == 0, 1, 2, ... until it
1081 returns None. The completion should begin with 'text'.
1081 returns None. The completion should begin with 'text'.
1082
1082
1083 """
1083 """
1084 if self.use_main_ns:
1084 if self.use_main_ns:
1085 self.namespace = __main__.__dict__
1085 self.namespace = __main__.__dict__
1086
1086
1087 if state == 0:
1087 if state == 0:
1088 if "." in text:
1088 if "." in text:
1089 self.matches = self.attr_matches(text)
1089 self.matches = self.attr_matches(text)
1090 else:
1090 else:
1091 self.matches = self.global_matches(text)
1091 self.matches = self.global_matches(text)
1092 try:
1092 try:
1093 return self.matches[state]
1093 return self.matches[state]
1094 except IndexError:
1094 except IndexError:
1095 return None
1095 return None
1096
1096
1097 def global_matches(self, text):
1097 def global_matches(self, text):
1098 """Compute matches when text is a simple name.
1098 """Compute matches when text is a simple name.
1099
1099
1100 Return a list of all keywords, built-in functions and names currently
1100 Return a list of all keywords, built-in functions and names currently
1101 defined in self.namespace or self.global_namespace that match.
1101 defined in self.namespace or self.global_namespace that match.
1102
1102
1103 """
1103 """
1104 matches = []
1104 matches = []
1105 match_append = matches.append
1105 match_append = matches.append
1106 n = len(text)
1106 n = len(text)
1107 for lst in [
1107 for lst in [
1108 keyword.kwlist,
1108 keyword.kwlist,
1109 builtin_mod.__dict__.keys(),
1109 builtin_mod.__dict__.keys(),
1110 list(self.namespace.keys()),
1110 list(self.namespace.keys()),
1111 list(self.global_namespace.keys()),
1111 list(self.global_namespace.keys()),
1112 ]:
1112 ]:
1113 for word in lst:
1113 for word in lst:
1114 if word[:n] == text and word != "__builtins__":
1114 if word[:n] == text and word != "__builtins__":
1115 match_append(word)
1115 match_append(word)
1116
1116
1117 snake_case_re = re.compile(r"[^_]+(_[^_]+)+?\Z")
1117 snake_case_re = re.compile(r"[^_]+(_[^_]+)+?\Z")
1118 for lst in [list(self.namespace.keys()), list(self.global_namespace.keys())]:
1118 for lst in [list(self.namespace.keys()), list(self.global_namespace.keys())]:
1119 shortened = {
1119 shortened = {
1120 "_".join([sub[0] for sub in word.split("_")]): word
1120 "_".join([sub[0] for sub in word.split("_")]): word
1121 for word in lst
1121 for word in lst
1122 if snake_case_re.match(word)
1122 if snake_case_re.match(word)
1123 }
1123 }
1124 for word in shortened.keys():
1124 for word in shortened.keys():
1125 if word[:n] == text and word != "__builtins__":
1125 if word[:n] == text and word != "__builtins__":
1126 match_append(shortened[word])
1126 match_append(shortened[word])
1127 return matches
1127 return matches
1128
1128
1129 def attr_matches(self, text):
1129 def attr_matches(self, text):
1130 """Compute matches when text contains a dot.
1130 """Compute matches when text contains a dot.
1131
1131
1132 Assuming the text is of the form NAME.NAME....[NAME], and is
1132 Assuming the text is of the form NAME.NAME....[NAME], and is
1133 evaluatable in self.namespace or self.global_namespace, it will be
1133 evaluatable in self.namespace or self.global_namespace, it will be
1134 evaluated and its attributes (as revealed by dir()) are used as
1134 evaluated and its attributes (as revealed by dir()) are used as
1135 possible completions. (For class instances, class members are
1135 possible completions. (For class instances, class members are
1136 also considered.)
1136 also considered.)
1137
1137
1138 WARNING: this can still invoke arbitrary C code, if an object
1138 WARNING: this can still invoke arbitrary C code, if an object
1139 with a __getattr__ hook is evaluated.
1139 with a __getattr__ hook is evaluated.
1140
1140
1141 """
1141 """
1142 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
1142 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
1143 if not m2:
1143 if not m2:
1144 return []
1144 return []
1145 expr, attr = m2.group(1, 2)
1145 expr, attr = m2.group(1, 2)
1146
1146
1147 obj = self._evaluate_expr(expr)
1147 obj = self._evaluate_expr(expr)
1148
1148
1149 if obj is not_found:
1149 if obj is not_found:
1150 return []
1150 return []
1151
1151
1152 if self.limit_to__all__ and hasattr(obj, '__all__'):
1152 if self.limit_to__all__ and hasattr(obj, '__all__'):
1153 words = get__all__entries(obj)
1153 words = get__all__entries(obj)
1154 else:
1154 else:
1155 words = dir2(obj)
1155 words = dir2(obj)
1156
1156
1157 try:
1157 try:
1158 words = generics.complete_object(obj, words)
1158 words = generics.complete_object(obj, words)
1159 except TryNext:
1159 except TryNext:
1160 pass
1160 pass
1161 except AssertionError:
1161 except AssertionError:
1162 raise
1162 raise
1163 except Exception:
1163 except Exception:
1164 # Silence errors from completion function
1164 # Silence errors from completion function
1165 pass
1165 pass
1166 # Build match list to return
1166 # Build match list to return
1167 n = len(attr)
1167 n = len(attr)
1168
1168
1169 # Note: ideally we would just return words here and the prefix
1169 # Note: ideally we would just return words here and the prefix
1170 # reconciliator would know that we intend to append to rather than
1170 # reconciliator would know that we intend to append to rather than
1171 # replace the input text; this requires refactoring to return range
1171 # replace the input text; this requires refactoring to return range
1172 # which ought to be replaced (as does jedi).
1172 # which ought to be replaced (as does jedi).
1173 tokens = _parse_tokens(expr)
1173 tokens = _parse_tokens(expr)
1174 rev_tokens = reversed(tokens)
1174 rev_tokens = reversed(tokens)
1175 skip_over = {tokenize.ENDMARKER, tokenize.NEWLINE}
1175 skip_over = {tokenize.ENDMARKER, tokenize.NEWLINE}
1176 name_turn = True
1176 name_turn = True
1177
1177
1178 parts = []
1178 parts = []
1179 for token in rev_tokens:
1179 for token in rev_tokens:
1180 if token.type in skip_over:
1180 if token.type in skip_over:
1181 continue
1181 continue
1182 if token.type == tokenize.NAME and name_turn:
1182 if token.type == tokenize.NAME and name_turn:
1183 parts.append(token.string)
1183 parts.append(token.string)
1184 name_turn = False
1184 name_turn = False
1185 elif token.type == tokenize.OP and token.string == "." and not name_turn:
1185 elif token.type == tokenize.OP and token.string == "." and not name_turn:
1186 parts.append(token.string)
1186 parts.append(token.string)
1187 name_turn = True
1187 name_turn = True
1188 else:
1188 else:
1189 # short-circuit if not empty nor name token
1189 # short-circuit if not empty nor name token
1190 break
1190 break
1191
1191
1192 prefix_after_space = "".join(reversed(parts))
1192 prefix_after_space = "".join(reversed(parts))
1193
1193
1194 return ["%s.%s" % (prefix_after_space, w) for w in words if w[:n] == attr]
1194 return ["%s.%s" % (prefix_after_space, w) for w in words if w[:n] == attr]
1195
1195
1196 def _evaluate_expr(self, expr):
1196 def _evaluate_expr(self, expr):
1197 obj = not_found
1197 obj = not_found
1198 done = False
1198 done = False
1199 while not done and expr:
1199 while not done and expr:
1200 try:
1200 try:
1201 obj = guarded_eval(
1201 obj = guarded_eval(
1202 expr,
1202 expr,
1203 EvaluationContext(
1203 EvaluationContext(
1204 globals=self.global_namespace,
1204 globals=self.global_namespace,
1205 locals=self.namespace,
1205 locals=self.namespace,
1206 evaluation=self.evaluation,
1206 evaluation=self.evaluation,
1207 ),
1207 ),
1208 )
1208 )
1209 done = True
1209 done = True
1210 except Exception as e:
1210 except Exception as e:
1211 if self.debug:
1211 if self.debug:
1212 print("Evaluation exception", e)
1212 print("Evaluation exception", e)
1213 # trim the expression to remove any invalid prefix
1213 # trim the expression to remove any invalid prefix
1214 # e.g. user starts `(d[`, so we get `expr = '(d'`,
1214 # e.g. user starts `(d[`, so we get `expr = '(d'`,
1215 # where parenthesis is not closed.
1215 # where parenthesis is not closed.
1216 # TODO: make this faster by reusing parts of the computation?
1216 # TODO: make this faster by reusing parts of the computation?
1217 expr = expr[1:]
1217 expr = expr[1:]
1218 return obj
1218 return obj
1219
1219
1220 def get__all__entries(obj):
1220 def get__all__entries(obj):
1221 """returns the strings in the __all__ attribute"""
1221 """returns the strings in the __all__ attribute"""
1222 try:
1222 try:
1223 words = getattr(obj, '__all__')
1223 words = getattr(obj, '__all__')
1224 except:
1224 except:
1225 return []
1225 return []
1226
1226
1227 return [w for w in words if isinstance(w, str)]
1227 return [w for w in words if isinstance(w, str)]
1228
1228
1229
1229
1230 class _DictKeyState(enum.Flag):
1230 class _DictKeyState(enum.Flag):
1231 """Represent state of the key match in context of other possible matches.
1231 """Represent state of the key match in context of other possible matches.
1232
1232
1233 - given `d1 = {'a': 1}` completion on `d1['<tab>` will yield `{'a': END_OF_ITEM}` as there is no tuple.
1233 - given `d1 = {'a': 1}` completion on `d1['<tab>` will yield `{'a': END_OF_ITEM}` as there is no tuple.
1234 - given `d2 = {('a', 'b'): 1}`: `d2['a', '<tab>` will yield `{'b': END_OF_TUPLE}` as there is no tuple members to add beyond `'b'`.
1234 - given `d2 = {('a', 'b'): 1}`: `d2['a', '<tab>` will yield `{'b': END_OF_TUPLE}` as there is no tuple members to add beyond `'b'`.
1235 - given `d3 = {('a', 'b'): 1}`: `d3['<tab>` will yield `{'a': IN_TUPLE}` as `'a'` can be added.
1235 - given `d3 = {('a', 'b'): 1}`: `d3['<tab>` will yield `{'a': IN_TUPLE}` as `'a'` can be added.
1236 - given `d4 = {'a': 1, ('a', 'b'): 2}`: `d4['<tab>` will yield `{'a': END_OF_ITEM & END_OF_TUPLE}`
1236 - given `d4 = {'a': 1, ('a', 'b'): 2}`: `d4['<tab>` will yield `{'a': END_OF_ITEM & END_OF_TUPLE}`
1237 """
1237 """
1238
1238
1239 BASELINE = 0
1239 BASELINE = 0
1240 END_OF_ITEM = enum.auto()
1240 END_OF_ITEM = enum.auto()
1241 END_OF_TUPLE = enum.auto()
1241 END_OF_TUPLE = enum.auto()
1242 IN_TUPLE = enum.auto()
1242 IN_TUPLE = enum.auto()
1243
1243
1244
1244
1245 def _parse_tokens(c):
1245 def _parse_tokens(c):
1246 """Parse tokens even if there is an error."""
1246 """Parse tokens even if there is an error."""
1247 tokens = []
1247 tokens = []
1248 token_generator = tokenize.generate_tokens(iter(c.splitlines()).__next__)
1248 token_generator = tokenize.generate_tokens(iter(c.splitlines()).__next__)
1249 while True:
1249 while True:
1250 try:
1250 try:
1251 tokens.append(next(token_generator))
1251 tokens.append(next(token_generator))
1252 except tokenize.TokenError:
1252 except tokenize.TokenError:
1253 return tokens
1253 return tokens
1254 except StopIteration:
1254 except StopIteration:
1255 return tokens
1255 return tokens
1256
1256
1257
1257
1258 def _match_number_in_dict_key_prefix(prefix: str) -> Union[str, None]:
1258 def _match_number_in_dict_key_prefix(prefix: str) -> Union[str, None]:
1259 """Match any valid Python numeric literal in a prefix of dictionary keys.
1259 """Match any valid Python numeric literal in a prefix of dictionary keys.
1260
1260
1261 References:
1261 References:
1262 - https://docs.python.org/3/reference/lexical_analysis.html#numeric-literals
1262 - https://docs.python.org/3/reference/lexical_analysis.html#numeric-literals
1263 - https://docs.python.org/3/library/tokenize.html
1263 - https://docs.python.org/3/library/tokenize.html
1264 """
1264 """
1265 if prefix[-1].isspace():
1265 if prefix[-1].isspace():
1266 # if user typed a space we do not have anything to complete
1266 # if user typed a space we do not have anything to complete
1267 # even if there was a valid number token before
1267 # even if there was a valid number token before
1268 return None
1268 return None
1269 tokens = _parse_tokens(prefix)
1269 tokens = _parse_tokens(prefix)
1270 rev_tokens = reversed(tokens)
1270 rev_tokens = reversed(tokens)
1271 skip_over = {tokenize.ENDMARKER, tokenize.NEWLINE}
1271 skip_over = {tokenize.ENDMARKER, tokenize.NEWLINE}
1272 number = None
1272 number = None
1273 for token in rev_tokens:
1273 for token in rev_tokens:
1274 if token.type in skip_over:
1274 if token.type in skip_over:
1275 continue
1275 continue
1276 if number is None:
1276 if number is None:
1277 if token.type == tokenize.NUMBER:
1277 if token.type == tokenize.NUMBER:
1278 number = token.string
1278 number = token.string
1279 continue
1279 continue
1280 else:
1280 else:
1281 # we did not match a number
1281 # we did not match a number
1282 return None
1282 return None
1283 if token.type == tokenize.OP:
1283 if token.type == tokenize.OP:
1284 if token.string == ",":
1284 if token.string == ",":
1285 break
1285 break
1286 if token.string in {"+", "-"}:
1286 if token.string in {"+", "-"}:
1287 number = token.string + number
1287 number = token.string + number
1288 else:
1288 else:
1289 return None
1289 return None
1290 return number
1290 return number
1291
1291
1292
1292
1293 _INT_FORMATS = {
1293 _INT_FORMATS = {
1294 "0b": bin,
1294 "0b": bin,
1295 "0o": oct,
1295 "0o": oct,
1296 "0x": hex,
1296 "0x": hex,
1297 }
1297 }
1298
1298
1299
1299
1300 def match_dict_keys(
1300 def match_dict_keys(
1301 keys: List[Union[str, bytes, Tuple[Union[str, bytes], ...]]],
1301 keys: List[Union[str, bytes, Tuple[Union[str, bytes], ...]]],
1302 prefix: str,
1302 prefix: str,
1303 delims: str,
1303 delims: str,
1304 extra_prefix: Optional[Tuple[Union[str, bytes], ...]] = None,
1304 extra_prefix: Optional[Tuple[Union[str, bytes], ...]] = None,
1305 ) -> Tuple[str, int, Dict[str, _DictKeyState]]:
1305 ) -> Tuple[str, int, Dict[str, _DictKeyState]]:
1306 """Used by dict_key_matches, matching the prefix to a list of keys
1306 """Used by dict_key_matches, matching the prefix to a list of keys
1307
1307
1308 Parameters
1308 Parameters
1309 ----------
1309 ----------
1310 keys
1310 keys
1311 list of keys in dictionary currently being completed.
1311 list of keys in dictionary currently being completed.
1312 prefix
1312 prefix
1313 Part of the text already typed by the user. E.g. `mydict[b'fo`
1313 Part of the text already typed by the user. E.g. `mydict[b'fo`
1314 delims
1314 delims
1315 String of delimiters to consider when finding the current key.
1315 String of delimiters to consider when finding the current key.
1316 extra_prefix : optional
1316 extra_prefix : optional
1317 Part of the text already typed in multi-key index cases. E.g. for
1317 Part of the text already typed in multi-key index cases. E.g. for
1318 `mydict['foo', "bar", 'b`, this would be `('foo', 'bar')`.
1318 `mydict['foo', "bar", 'b`, this would be `('foo', 'bar')`.
1319
1319
1320 Returns
1320 Returns
1321 -------
1321 -------
1322 A tuple of three elements: ``quote``, ``token_start``, ``matched``, with
1322 A tuple of three elements: ``quote``, ``token_start``, ``matched``, with
1323 ``quote`` being the quote that need to be used to close current string.
1323 ``quote`` being the quote that need to be used to close current string.
1324 ``token_start`` the position where the replacement should start occurring,
1324 ``token_start`` the position where the replacement should start occurring,
1325 ``matches`` a dictionary of replacement/completion keys on keys and values
1325 ``matches`` a dictionary of replacement/completion keys on keys and values
1326 indicating whether the state.
1326 indicating whether the state.
1327 """
1327 """
1328 prefix_tuple = extra_prefix if extra_prefix else ()
1328 prefix_tuple = extra_prefix if extra_prefix else ()
1329
1329
1330 prefix_tuple_size = sum(
1330 prefix_tuple_size = sum(
1331 [
1331 [
1332 # for pandas, do not count slices as taking space
1332 # for pandas, do not count slices as taking space
1333 not isinstance(k, slice)
1333 not isinstance(k, slice)
1334 for k in prefix_tuple
1334 for k in prefix_tuple
1335 ]
1335 ]
1336 )
1336 )
1337 text_serializable_types = (str, bytes, int, float, slice)
1337 text_serializable_types = (str, bytes, int, float, slice)
1338
1338
1339 def filter_prefix_tuple(key):
1339 def filter_prefix_tuple(key):
1340 # Reject too short keys
1340 # Reject too short keys
1341 if len(key) <= prefix_tuple_size:
1341 if len(key) <= prefix_tuple_size:
1342 return False
1342 return False
1343 # Reject keys which cannot be serialised to text
1343 # Reject keys which cannot be serialised to text
1344 for k in key:
1344 for k in key:
1345 if not isinstance(k, text_serializable_types):
1345 if not isinstance(k, text_serializable_types):
1346 return False
1346 return False
1347 # Reject keys that do not match the prefix
1347 # Reject keys that do not match the prefix
1348 for k, pt in zip(key, prefix_tuple):
1348 for k, pt in zip(key, prefix_tuple):
1349 if k != pt and not isinstance(pt, slice):
1349 if k != pt and not isinstance(pt, slice):
1350 return False
1350 return False
1351 # All checks passed!
1351 # All checks passed!
1352 return True
1352 return True
1353
1353
1354 filtered_key_is_final: Dict[
1354 filtered_key_is_final: Dict[
1355 Union[str, bytes, int, float], _DictKeyState
1355 Union[str, bytes, int, float], _DictKeyState
1356 ] = defaultdict(lambda: _DictKeyState.BASELINE)
1356 ] = defaultdict(lambda: _DictKeyState.BASELINE)
1357
1357
1358 for k in keys:
1358 for k in keys:
1359 # If at least one of the matches is not final, mark as undetermined.
1359 # If at least one of the matches is not final, mark as undetermined.
1360 # This can happen with `d = {111: 'b', (111, 222): 'a'}` where
1360 # This can happen with `d = {111: 'b', (111, 222): 'a'}` where
1361 # `111` appears final on first match but is not final on the second.
1361 # `111` appears final on first match but is not final on the second.
1362
1362
1363 if isinstance(k, tuple):
1363 if isinstance(k, tuple):
1364 if filter_prefix_tuple(k):
1364 if filter_prefix_tuple(k):
1365 key_fragment = k[prefix_tuple_size]
1365 key_fragment = k[prefix_tuple_size]
1366 filtered_key_is_final[key_fragment] |= (
1366 filtered_key_is_final[key_fragment] |= (
1367 _DictKeyState.END_OF_TUPLE
1367 _DictKeyState.END_OF_TUPLE
1368 if len(k) == prefix_tuple_size + 1
1368 if len(k) == prefix_tuple_size + 1
1369 else _DictKeyState.IN_TUPLE
1369 else _DictKeyState.IN_TUPLE
1370 )
1370 )
1371 elif prefix_tuple_size > 0:
1371 elif prefix_tuple_size > 0:
1372 # we are completing a tuple but this key is not a tuple,
1372 # we are completing a tuple but this key is not a tuple,
1373 # so we should ignore it
1373 # so we should ignore it
1374 pass
1374 pass
1375 else:
1375 else:
1376 if isinstance(k, text_serializable_types):
1376 if isinstance(k, text_serializable_types):
1377 filtered_key_is_final[k] |= _DictKeyState.END_OF_ITEM
1377 filtered_key_is_final[k] |= _DictKeyState.END_OF_ITEM
1378
1378
1379 filtered_keys = filtered_key_is_final.keys()
1379 filtered_keys = filtered_key_is_final.keys()
1380
1380
1381 if not prefix:
1381 if not prefix:
1382 return "", 0, {repr(k): v for k, v in filtered_key_is_final.items()}
1382 return "", 0, {repr(k): v for k, v in filtered_key_is_final.items()}
1383
1383
1384 quote_match = re.search("(?:\"|')", prefix)
1384 quote_match = re.search("(?:\"|')", prefix)
1385 is_user_prefix_numeric = False
1385 is_user_prefix_numeric = False
1386
1386
1387 if quote_match:
1387 if quote_match:
1388 quote = quote_match.group()
1388 quote = quote_match.group()
1389 valid_prefix = prefix + quote
1389 valid_prefix = prefix + quote
1390 try:
1390 try:
1391 prefix_str = literal_eval(valid_prefix)
1391 prefix_str = literal_eval(valid_prefix)
1392 except Exception:
1392 except Exception:
1393 return "", 0, {}
1393 return "", 0, {}
1394 else:
1394 else:
1395 # If it does not look like a string, let's assume
1395 # If it does not look like a string, let's assume
1396 # we are dealing with a number or variable.
1396 # we are dealing with a number or variable.
1397 number_match = _match_number_in_dict_key_prefix(prefix)
1397 number_match = _match_number_in_dict_key_prefix(prefix)
1398
1398
1399 # We do not want the key matcher to suggest variable names so we yield:
1399 # We do not want the key matcher to suggest variable names so we yield:
1400 if number_match is None:
1400 if number_match is None:
1401 # The alternative would be to assume that user forgort the quote
1401 # The alternative would be to assume that user forgort the quote
1402 # and if the substring matches, suggest adding it at the start.
1402 # and if the substring matches, suggest adding it at the start.
1403 return "", 0, {}
1403 return "", 0, {}
1404
1404
1405 prefix_str = number_match
1405 prefix_str = number_match
1406 is_user_prefix_numeric = True
1406 is_user_prefix_numeric = True
1407 quote = ""
1407 quote = ""
1408
1408
1409 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
1409 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
1410 token_match = re.search(pattern, prefix, re.UNICODE)
1410 token_match = re.search(pattern, prefix, re.UNICODE)
1411 assert token_match is not None # silence mypy
1411 assert token_match is not None # silence mypy
1412 token_start = token_match.start()
1412 token_start = token_match.start()
1413 token_prefix = token_match.group()
1413 token_prefix = token_match.group()
1414
1414
1415 matched: Dict[str, _DictKeyState] = {}
1415 matched: Dict[str, _DictKeyState] = {}
1416
1416
1417 str_key: Union[str, bytes]
1417 str_key: Union[str, bytes]
1418
1418
1419 for key in filtered_keys:
1419 for key in filtered_keys:
1420 if isinstance(key, (int, float)):
1420 if isinstance(key, (int, float)):
1421 # User typed a number but this key is not a number.
1421 # User typed a number but this key is not a number.
1422 if not is_user_prefix_numeric:
1422 if not is_user_prefix_numeric:
1423 continue
1423 continue
1424 str_key = str(key)
1424 str_key = str(key)
1425 if isinstance(key, int):
1425 if isinstance(key, int):
1426 int_base = prefix_str[:2].lower()
1426 int_base = prefix_str[:2].lower()
1427 # if user typed integer using binary/oct/hex notation:
1427 # if user typed integer using binary/oct/hex notation:
1428 if int_base in _INT_FORMATS:
1428 if int_base in _INT_FORMATS:
1429 int_format = _INT_FORMATS[int_base]
1429 int_format = _INT_FORMATS[int_base]
1430 str_key = int_format(key)
1430 str_key = int_format(key)
1431 else:
1431 else:
1432 # User typed a string but this key is a number.
1432 # User typed a string but this key is a number.
1433 if is_user_prefix_numeric:
1433 if is_user_prefix_numeric:
1434 continue
1434 continue
1435 str_key = key
1435 str_key = key
1436 try:
1436 try:
1437 if not str_key.startswith(prefix_str):
1437 if not str_key.startswith(prefix_str):
1438 continue
1438 continue
1439 except (AttributeError, TypeError, UnicodeError) as e:
1439 except (AttributeError, TypeError, UnicodeError) as e:
1440 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
1440 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
1441 continue
1441 continue
1442
1442
1443 # reformat remainder of key to begin with prefix
1443 # reformat remainder of key to begin with prefix
1444 rem = str_key[len(prefix_str) :]
1444 rem = str_key[len(prefix_str) :]
1445 # force repr wrapped in '
1445 # force repr wrapped in '
1446 rem_repr = repr(rem + '"') if isinstance(rem, str) else repr(rem + b'"')
1446 rem_repr = repr(rem + '"') if isinstance(rem, str) else repr(rem + b'"')
1447 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
1447 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
1448 if quote == '"':
1448 if quote == '"':
1449 # The entered prefix is quoted with ",
1449 # The entered prefix is quoted with ",
1450 # but the match is quoted with '.
1450 # but the match is quoted with '.
1451 # A contained " hence needs escaping for comparison:
1451 # A contained " hence needs escaping for comparison:
1452 rem_repr = rem_repr.replace('"', '\\"')
1452 rem_repr = rem_repr.replace('"', '\\"')
1453
1453
1454 # then reinsert prefix from start of token
1454 # then reinsert prefix from start of token
1455 match = "%s%s" % (token_prefix, rem_repr)
1455 match = "%s%s" % (token_prefix, rem_repr)
1456
1456
1457 matched[match] = filtered_key_is_final[key]
1457 matched[match] = filtered_key_is_final[key]
1458 return quote, token_start, matched
1458 return quote, token_start, matched
1459
1459
1460
1460
1461 def cursor_to_position(text:str, line:int, column:int)->int:
1461 def cursor_to_position(text:str, line:int, column:int)->int:
1462 """
1462 """
1463 Convert the (line,column) position of the cursor in text to an offset in a
1463 Convert the (line,column) position of the cursor in text to an offset in a
1464 string.
1464 string.
1465
1465
1466 Parameters
1466 Parameters
1467 ----------
1467 ----------
1468 text : str
1468 text : str
1469 The text in which to calculate the cursor offset
1469 The text in which to calculate the cursor offset
1470 line : int
1470 line : int
1471 Line of the cursor; 0-indexed
1471 Line of the cursor; 0-indexed
1472 column : int
1472 column : int
1473 Column of the cursor 0-indexed
1473 Column of the cursor 0-indexed
1474
1474
1475 Returns
1475 Returns
1476 -------
1476 -------
1477 Position of the cursor in ``text``, 0-indexed.
1477 Position of the cursor in ``text``, 0-indexed.
1478
1478
1479 See Also
1479 See Also
1480 --------
1480 --------
1481 position_to_cursor : reciprocal of this function
1481 position_to_cursor : reciprocal of this function
1482
1482
1483 """
1483 """
1484 lines = text.split('\n')
1484 lines = text.split('\n')
1485 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
1485 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
1486
1486
1487 return sum(len(l) + 1 for l in lines[:line]) + column
1487 return sum(len(l) + 1 for l in lines[:line]) + column
1488
1488
1489 def position_to_cursor(text:str, offset:int)->Tuple[int, int]:
1489 def position_to_cursor(text:str, offset:int)->Tuple[int, int]:
1490 """
1490 """
1491 Convert the position of the cursor in text (0 indexed) to a line
1491 Convert the position of the cursor in text (0 indexed) to a line
1492 number(0-indexed) and a column number (0-indexed) pair
1492 number(0-indexed) and a column number (0-indexed) pair
1493
1493
1494 Position should be a valid position in ``text``.
1494 Position should be a valid position in ``text``.
1495
1495
1496 Parameters
1496 Parameters
1497 ----------
1497 ----------
1498 text : str
1498 text : str
1499 The text in which to calculate the cursor offset
1499 The text in which to calculate the cursor offset
1500 offset : int
1500 offset : int
1501 Position of the cursor in ``text``, 0-indexed.
1501 Position of the cursor in ``text``, 0-indexed.
1502
1502
1503 Returns
1503 Returns
1504 -------
1504 -------
1505 (line, column) : (int, int)
1505 (line, column) : (int, int)
1506 Line of the cursor; 0-indexed, column of the cursor 0-indexed
1506 Line of the cursor; 0-indexed, column of the cursor 0-indexed
1507
1507
1508 See Also
1508 See Also
1509 --------
1509 --------
1510 cursor_to_position : reciprocal of this function
1510 cursor_to_position : reciprocal of this function
1511
1511
1512 """
1512 """
1513
1513
1514 assert 0 <= offset <= len(text) , "0 <= %s <= %s" % (offset , len(text))
1514 assert 0 <= offset <= len(text) , "0 <= %s <= %s" % (offset , len(text))
1515
1515
1516 before = text[:offset]
1516 before = text[:offset]
1517 blines = before.split('\n') # ! splitnes trim trailing \n
1517 blines = before.split('\n') # ! splitnes trim trailing \n
1518 line = before.count('\n')
1518 line = before.count('\n')
1519 col = len(blines[-1])
1519 col = len(blines[-1])
1520 return line, col
1520 return line, col
1521
1521
1522
1522
1523 def _safe_isinstance(obj, module, class_name, *attrs):
1523 def _safe_isinstance(obj, module, class_name, *attrs):
1524 """Checks if obj is an instance of module.class_name if loaded
1524 """Checks if obj is an instance of module.class_name if loaded
1525 """
1525 """
1526 if module in sys.modules:
1526 if module in sys.modules:
1527 m = sys.modules[module]
1527 m = sys.modules[module]
1528 for attr in [class_name, *attrs]:
1528 for attr in [class_name, *attrs]:
1529 m = getattr(m, attr)
1529 m = getattr(m, attr)
1530 return isinstance(obj, m)
1530 return isinstance(obj, m)
1531
1531
1532
1532
1533 @context_matcher()
1533 @context_matcher()
1534 def back_unicode_name_matcher(context: CompletionContext):
1534 def back_unicode_name_matcher(context: CompletionContext):
1535 """Match Unicode characters back to Unicode name
1535 """Match Unicode characters back to Unicode name
1536
1536
1537 Same as :any:`back_unicode_name_matches`, but adopted to new Matcher API.
1537 Same as :any:`back_unicode_name_matches`, but adopted to new Matcher API.
1538 """
1538 """
1539 fragment, matches = back_unicode_name_matches(context.text_until_cursor)
1539 fragment, matches = back_unicode_name_matches(context.text_until_cursor)
1540 return _convert_matcher_v1_result_to_v2(
1540 return _convert_matcher_v1_result_to_v2(
1541 matches, type="unicode", fragment=fragment, suppress_if_matches=True
1541 matches, type="unicode", fragment=fragment, suppress_if_matches=True
1542 )
1542 )
1543
1543
1544
1544
1545 def back_unicode_name_matches(text: str) -> Tuple[str, Sequence[str]]:
1545 def back_unicode_name_matches(text: str) -> Tuple[str, Sequence[str]]:
1546 """Match Unicode characters back to Unicode name
1546 """Match Unicode characters back to Unicode name
1547
1547
1548 This does ``β˜ƒ`` -> ``\\snowman``
1548 This does ``β˜ƒ`` -> ``\\snowman``
1549
1549
1550 Note that snowman is not a valid python3 combining character but will be expanded.
1550 Note that snowman is not a valid python3 combining character but will be expanded.
1551 Though it will not recombine back to the snowman character by the completion machinery.
1551 Though it will not recombine back to the snowman character by the completion machinery.
1552
1552
1553 This will not either back-complete standard sequences like \\n, \\b ...
1553 This will not either back-complete standard sequences like \\n, \\b ...
1554
1554
1555 .. deprecated:: 8.6
1555 .. deprecated:: 8.6
1556 You can use :meth:`back_unicode_name_matcher` instead.
1556 You can use :meth:`back_unicode_name_matcher` instead.
1557
1557
1558 Returns
1558 Returns
1559 =======
1559 =======
1560
1560
1561 Return a tuple with two elements:
1561 Return a tuple with two elements:
1562
1562
1563 - The Unicode character that was matched (preceded with a backslash), or
1563 - The Unicode character that was matched (preceded with a backslash), or
1564 empty string,
1564 empty string,
1565 - a sequence (of 1), name for the match Unicode character, preceded by
1565 - a sequence (of 1), name for the match Unicode character, preceded by
1566 backslash, or empty if no match.
1566 backslash, or empty if no match.
1567 """
1567 """
1568 if len(text)<2:
1568 if len(text)<2:
1569 return '', ()
1569 return '', ()
1570 maybe_slash = text[-2]
1570 maybe_slash = text[-2]
1571 if maybe_slash != '\\':
1571 if maybe_slash != '\\':
1572 return '', ()
1572 return '', ()
1573
1573
1574 char = text[-1]
1574 char = text[-1]
1575 # no expand on quote for completion in strings.
1575 # no expand on quote for completion in strings.
1576 # nor backcomplete standard ascii keys
1576 # nor backcomplete standard ascii keys
1577 if char in string.ascii_letters or char in ('"',"'"):
1577 if char in string.ascii_letters or char in ('"',"'"):
1578 return '', ()
1578 return '', ()
1579 try :
1579 try :
1580 unic = unicodedata.name(char)
1580 unic = unicodedata.name(char)
1581 return '\\'+char,('\\'+unic,)
1581 return '\\'+char,('\\'+unic,)
1582 except KeyError:
1582 except KeyError:
1583 pass
1583 pass
1584 return '', ()
1584 return '', ()
1585
1585
1586
1586
1587 @context_matcher()
1587 @context_matcher()
1588 def back_latex_name_matcher(context: CompletionContext):
1588 def back_latex_name_matcher(context: CompletionContext):
1589 """Match latex characters back to unicode name
1589 """Match latex characters back to unicode name
1590
1590
1591 Same as :any:`back_latex_name_matches`, but adopted to new Matcher API.
1591 Same as :any:`back_latex_name_matches`, but adopted to new Matcher API.
1592 """
1592 """
1593 fragment, matches = back_latex_name_matches(context.text_until_cursor)
1593 fragment, matches = back_latex_name_matches(context.text_until_cursor)
1594 return _convert_matcher_v1_result_to_v2(
1594 return _convert_matcher_v1_result_to_v2(
1595 matches, type="latex", fragment=fragment, suppress_if_matches=True
1595 matches, type="latex", fragment=fragment, suppress_if_matches=True
1596 )
1596 )
1597
1597
1598
1598
1599 def back_latex_name_matches(text: str) -> Tuple[str, Sequence[str]]:
1599 def back_latex_name_matches(text: str) -> Tuple[str, Sequence[str]]:
1600 """Match latex characters back to unicode name
1600 """Match latex characters back to unicode name
1601
1601
1602 This does ``\\β„΅`` -> ``\\aleph``
1602 This does ``\\β„΅`` -> ``\\aleph``
1603
1603
1604 .. deprecated:: 8.6
1604 .. deprecated:: 8.6
1605 You can use :meth:`back_latex_name_matcher` instead.
1605 You can use :meth:`back_latex_name_matcher` instead.
1606 """
1606 """
1607 if len(text)<2:
1607 if len(text)<2:
1608 return '', ()
1608 return '', ()
1609 maybe_slash = text[-2]
1609 maybe_slash = text[-2]
1610 if maybe_slash != '\\':
1610 if maybe_slash != '\\':
1611 return '', ()
1611 return '', ()
1612
1612
1613
1613
1614 char = text[-1]
1614 char = text[-1]
1615 # no expand on quote for completion in strings.
1615 # no expand on quote for completion in strings.
1616 # nor backcomplete standard ascii keys
1616 # nor backcomplete standard ascii keys
1617 if char in string.ascii_letters or char in ('"',"'"):
1617 if char in string.ascii_letters or char in ('"',"'"):
1618 return '', ()
1618 return '', ()
1619 try :
1619 try :
1620 latex = reverse_latex_symbol[char]
1620 latex = reverse_latex_symbol[char]
1621 # '\\' replace the \ as well
1621 # '\\' replace the \ as well
1622 return '\\'+char,[latex]
1622 return '\\'+char,[latex]
1623 except KeyError:
1623 except KeyError:
1624 pass
1624 pass
1625 return '', ()
1625 return '', ()
1626
1626
1627
1627
1628 def _formatparamchildren(parameter) -> str:
1628 def _formatparamchildren(parameter) -> str:
1629 """
1629 """
1630 Get parameter name and value from Jedi Private API
1630 Get parameter name and value from Jedi Private API
1631
1631
1632 Jedi does not expose a simple way to get `param=value` from its API.
1632 Jedi does not expose a simple way to get `param=value` from its API.
1633
1633
1634 Parameters
1634 Parameters
1635 ----------
1635 ----------
1636 parameter
1636 parameter
1637 Jedi's function `Param`
1637 Jedi's function `Param`
1638
1638
1639 Returns
1639 Returns
1640 -------
1640 -------
1641 A string like 'a', 'b=1', '*args', '**kwargs'
1641 A string like 'a', 'b=1', '*args', '**kwargs'
1642
1642
1643 """
1643 """
1644 description = parameter.description
1644 description = parameter.description
1645 if not description.startswith('param '):
1645 if not description.startswith('param '):
1646 raise ValueError('Jedi function parameter description have change format.'
1646 raise ValueError('Jedi function parameter description have change format.'
1647 'Expected "param ...", found %r".' % description)
1647 'Expected "param ...", found %r".' % description)
1648 return description[6:]
1648 return description[6:]
1649
1649
1650 def _make_signature(completion)-> str:
1650 def _make_signature(completion)-> str:
1651 """
1651 """
1652 Make the signature from a jedi completion
1652 Make the signature from a jedi completion
1653
1653
1654 Parameters
1654 Parameters
1655 ----------
1655 ----------
1656 completion : jedi.Completion
1656 completion : jedi.Completion
1657 object does not complete a function type
1657 object does not complete a function type
1658
1658
1659 Returns
1659 Returns
1660 -------
1660 -------
1661 a string consisting of the function signature, with the parenthesis but
1661 a string consisting of the function signature, with the parenthesis but
1662 without the function name. example:
1662 without the function name. example:
1663 `(a, *args, b=1, **kwargs)`
1663 `(a, *args, b=1, **kwargs)`
1664
1664
1665 """
1665 """
1666
1666
1667 # it looks like this might work on jedi 0.17
1667 # it looks like this might work on jedi 0.17
1668 if hasattr(completion, 'get_signatures'):
1668 if hasattr(completion, 'get_signatures'):
1669 signatures = completion.get_signatures()
1669 signatures = completion.get_signatures()
1670 if not signatures:
1670 if not signatures:
1671 return '(?)'
1671 return '(?)'
1672
1672
1673 c0 = completion.get_signatures()[0]
1673 c0 = completion.get_signatures()[0]
1674 return '('+c0.to_string().split('(', maxsplit=1)[1]
1674 return '('+c0.to_string().split('(', maxsplit=1)[1]
1675
1675
1676 return '(%s)'% ', '.join([f for f in (_formatparamchildren(p) for signature in completion.get_signatures()
1676 return '(%s)'% ', '.join([f for f in (_formatparamchildren(p) for signature in completion.get_signatures()
1677 for p in signature.defined_names()) if f])
1677 for p in signature.defined_names()) if f])
1678
1678
1679
1679
1680 _CompleteResult = Dict[str, MatcherResult]
1680 _CompleteResult = Dict[str, MatcherResult]
1681
1681
1682
1682
1683 DICT_MATCHER_REGEX = re.compile(
1683 DICT_MATCHER_REGEX = re.compile(
1684 r"""(?x)
1684 r"""(?x)
1685 ( # match dict-referring - or any get item object - expression
1685 ( # match dict-referring - or any get item object - expression
1686 .+
1686 .+
1687 )
1687 )
1688 \[ # open bracket
1688 \[ # open bracket
1689 \s* # and optional whitespace
1689 \s* # and optional whitespace
1690 # Capture any number of serializable objects (e.g. "a", "b", 'c')
1690 # Capture any number of serializable objects (e.g. "a", "b", 'c')
1691 # and slices
1691 # and slices
1692 ((?:(?:
1692 ((?:(?:
1693 (?: # closed string
1693 (?: # closed string
1694 [uUbB]? # string prefix (r not handled)
1694 [uUbB]? # string prefix (r not handled)
1695 (?:
1695 (?:
1696 '(?:[^']|(?<!\\)\\')*'
1696 '(?:[^']|(?<!\\)\\')*'
1697 |
1697 |
1698 "(?:[^"]|(?<!\\)\\")*"
1698 "(?:[^"]|(?<!\\)\\")*"
1699 )
1699 )
1700 )
1700 )
1701 |
1701 |
1702 # capture integers and slices
1702 # capture integers and slices
1703 (?:[-+]?\d+)?(?::(?:[-+]?\d+)?){0,2}
1703 (?:[-+]?\d+)?(?::(?:[-+]?\d+)?){0,2}
1704 |
1704 |
1705 # integer in bin/hex/oct notation
1705 # integer in bin/hex/oct notation
1706 0[bBxXoO]_?(?:\w|\d)+
1706 0[bBxXoO]_?(?:\w|\d)+
1707 )
1707 )
1708 \s*,\s*
1708 \s*,\s*
1709 )*)
1709 )*)
1710 ((?:
1710 ((?:
1711 (?: # unclosed string
1711 (?: # unclosed string
1712 [uUbB]? # string prefix (r not handled)
1712 [uUbB]? # string prefix (r not handled)
1713 (?:
1713 (?:
1714 '(?:[^']|(?<!\\)\\')*
1714 '(?:[^']|(?<!\\)\\')*
1715 |
1715 |
1716 "(?:[^"]|(?<!\\)\\")*
1716 "(?:[^"]|(?<!\\)\\")*
1717 )
1717 )
1718 )
1718 )
1719 |
1719 |
1720 # unfinished integer
1720 # unfinished integer
1721 (?:[-+]?\d+)
1721 (?:[-+]?\d+)
1722 |
1722 |
1723 # integer in bin/hex/oct notation
1723 # integer in bin/hex/oct notation
1724 0[bBxXoO]_?(?:\w|\d)+
1724 0[bBxXoO]_?(?:\w|\d)+
1725 )
1725 )
1726 )?
1726 )?
1727 $
1727 $
1728 """
1728 """
1729 )
1729 )
1730
1730
1731
1731
1732 def _convert_matcher_v1_result_to_v2(
1732 def _convert_matcher_v1_result_to_v2(
1733 matches: Sequence[str],
1733 matches: Sequence[str],
1734 type: str,
1734 type: str,
1735 fragment: Optional[str] = None,
1735 fragment: Optional[str] = None,
1736 suppress_if_matches: bool = False,
1736 suppress_if_matches: bool = False,
1737 ) -> SimpleMatcherResult:
1737 ) -> SimpleMatcherResult:
1738 """Utility to help with transition"""
1738 """Utility to help with transition"""
1739 result = {
1739 result = {
1740 "completions": [SimpleCompletion(text=match, type=type) for match in matches],
1740 "completions": [SimpleCompletion(text=match, type=type) for match in matches],
1741 "suppress": (True if matches else False) if suppress_if_matches else False,
1741 "suppress": (True if matches else False) if suppress_if_matches else False,
1742 }
1742 }
1743 if fragment is not None:
1743 if fragment is not None:
1744 result["matched_fragment"] = fragment
1744 result["matched_fragment"] = fragment
1745 return cast(SimpleMatcherResult, result)
1745 return cast(SimpleMatcherResult, result)
1746
1746
1747
1747
1748 class IPCompleter(Completer):
1748 class IPCompleter(Completer):
1749 """Extension of the completer class with IPython-specific features"""
1749 """Extension of the completer class with IPython-specific features"""
1750
1750
1751 @observe('greedy')
1751 @observe('greedy')
1752 def _greedy_changed(self, change):
1752 def _greedy_changed(self, change):
1753 """update the splitter and readline delims when greedy is changed"""
1753 """update the splitter and readline delims when greedy is changed"""
1754 if change["new"]:
1754 if change["new"]:
1755 self.evaluation = "unsafe"
1755 self.evaluation = "unsafe"
1756 self.auto_close_dict_keys = True
1756 self.auto_close_dict_keys = True
1757 self.splitter.delims = GREEDY_DELIMS
1757 self.splitter.delims = GREEDY_DELIMS
1758 else:
1758 else:
1759 self.evaluation = "limited"
1759 self.evaluation = "limited"
1760 self.auto_close_dict_keys = False
1760 self.auto_close_dict_keys = False
1761 self.splitter.delims = DELIMS
1761 self.splitter.delims = DELIMS
1762
1762
1763 dict_keys_only = Bool(
1763 dict_keys_only = Bool(
1764 False,
1764 False,
1765 help="""
1765 help="""
1766 Whether to show dict key matches only.
1766 Whether to show dict key matches only.
1767
1767
1768 (disables all matchers except for `IPCompleter.dict_key_matcher`).
1768 (disables all matchers except for `IPCompleter.dict_key_matcher`).
1769 """,
1769 """,
1770 )
1770 )
1771
1771
1772 suppress_competing_matchers = UnionTrait(
1772 suppress_competing_matchers = UnionTrait(
1773 [Bool(allow_none=True), DictTrait(Bool(None, allow_none=True))],
1773 [Bool(allow_none=True), DictTrait(Bool(None, allow_none=True))],
1774 default_value=None,
1774 default_value=None,
1775 help="""
1775 help="""
1776 Whether to suppress completions from other *Matchers*.
1776 Whether to suppress completions from other *Matchers*.
1777
1777
1778 When set to ``None`` (default) the matchers will attempt to auto-detect
1778 When set to ``None`` (default) the matchers will attempt to auto-detect
1779 whether suppression of other matchers is desirable. For example, at
1779 whether suppression of other matchers is desirable. For example, at
1780 the beginning of a line followed by `%` we expect a magic completion
1780 the beginning of a line followed by `%` we expect a magic completion
1781 to be the only applicable option, and after ``my_dict['`` we usually
1781 to be the only applicable option, and after ``my_dict['`` we usually
1782 expect a completion with an existing dictionary key.
1782 expect a completion with an existing dictionary key.
1783
1783
1784 If you want to disable this heuristic and see completions from all matchers,
1784 If you want to disable this heuristic and see completions from all matchers,
1785 set ``IPCompleter.suppress_competing_matchers = False``.
1785 set ``IPCompleter.suppress_competing_matchers = False``.
1786 To disable the heuristic for specific matchers provide a dictionary mapping:
1786 To disable the heuristic for specific matchers provide a dictionary mapping:
1787 ``IPCompleter.suppress_competing_matchers = {'IPCompleter.dict_key_matcher': False}``.
1787 ``IPCompleter.suppress_competing_matchers = {'IPCompleter.dict_key_matcher': False}``.
1788
1788
1789 Set ``IPCompleter.suppress_competing_matchers = True`` to limit
1789 Set ``IPCompleter.suppress_competing_matchers = True`` to limit
1790 completions to the set of matchers with the highest priority;
1790 completions to the set of matchers with the highest priority;
1791 this is equivalent to ``IPCompleter.merge_completions`` and
1791 this is equivalent to ``IPCompleter.merge_completions`` and
1792 can be beneficial for performance, but will sometimes omit relevant
1792 can be beneficial for performance, but will sometimes omit relevant
1793 candidates from matchers further down the priority list.
1793 candidates from matchers further down the priority list.
1794 """,
1794 """,
1795 ).tag(config=True)
1795 ).tag(config=True)
1796
1796
1797 merge_completions = Bool(
1797 merge_completions = Bool(
1798 True,
1798 True,
1799 help="""Whether to merge completion results into a single list
1799 help="""Whether to merge completion results into a single list
1800
1800
1801 If False, only the completion results from the first non-empty
1801 If False, only the completion results from the first non-empty
1802 completer will be returned.
1802 completer will be returned.
1803
1803
1804 As of version 8.6.0, setting the value to ``False`` is an alias for:
1804 As of version 8.6.0, setting the value to ``False`` is an alias for:
1805 ``IPCompleter.suppress_competing_matchers = True.``.
1805 ``IPCompleter.suppress_competing_matchers = True.``.
1806 """,
1806 """,
1807 ).tag(config=True)
1807 ).tag(config=True)
1808
1808
1809 disable_matchers = ListTrait(
1809 disable_matchers = ListTrait(
1810 Unicode(),
1810 Unicode(),
1811 help="""List of matchers to disable.
1811 help="""List of matchers to disable.
1812
1812
1813 The list should contain matcher identifiers (see :any:`completion_matcher`).
1813 The list should contain matcher identifiers (see :any:`completion_matcher`).
1814 """,
1814 """,
1815 ).tag(config=True)
1815 ).tag(config=True)
1816
1816
1817 omit__names = Enum(
1817 omit__names = Enum(
1818 (0, 1, 2),
1818 (0, 1, 2),
1819 default_value=2,
1819 default_value=2,
1820 help="""Instruct the completer to omit private method names
1820 help="""Instruct the completer to omit private method names
1821
1821
1822 Specifically, when completing on ``object.<tab>``.
1822 Specifically, when completing on ``object.<tab>``.
1823
1823
1824 When 2 [default]: all names that start with '_' will be excluded.
1824 When 2 [default]: all names that start with '_' will be excluded.
1825
1825
1826 When 1: all 'magic' names (``__foo__``) will be excluded.
1826 When 1: all 'magic' names (``__foo__``) will be excluded.
1827
1827
1828 When 0: nothing will be excluded.
1828 When 0: nothing will be excluded.
1829 """
1829 """
1830 ).tag(config=True)
1830 ).tag(config=True)
1831 limit_to__all__ = Bool(False,
1831 limit_to__all__ = Bool(False,
1832 help="""
1832 help="""
1833 DEPRECATED as of version 5.0.
1833 DEPRECATED as of version 5.0.
1834
1834
1835 Instruct the completer to use __all__ for the completion
1835 Instruct the completer to use __all__ for the completion
1836
1836
1837 Specifically, when completing on ``object.<tab>``.
1837 Specifically, when completing on ``object.<tab>``.
1838
1838
1839 When True: only those names in obj.__all__ will be included.
1839 When True: only those names in obj.__all__ will be included.
1840
1840
1841 When False [default]: the __all__ attribute is ignored
1841 When False [default]: the __all__ attribute is ignored
1842 """,
1842 """,
1843 ).tag(config=True)
1843 ).tag(config=True)
1844
1844
1845 profile_completions = Bool(
1845 profile_completions = Bool(
1846 default_value=False,
1846 default_value=False,
1847 help="If True, emit profiling data for completion subsystem using cProfile."
1847 help="If True, emit profiling data for completion subsystem using cProfile."
1848 ).tag(config=True)
1848 ).tag(config=True)
1849
1849
1850 profiler_output_dir = Unicode(
1850 profiler_output_dir = Unicode(
1851 default_value=".completion_profiles",
1851 default_value=".completion_profiles",
1852 help="Template for path at which to output profile data for completions."
1852 help="Template for path at which to output profile data for completions."
1853 ).tag(config=True)
1853 ).tag(config=True)
1854
1854
1855 @observe('limit_to__all__')
1855 @observe('limit_to__all__')
1856 def _limit_to_all_changed(self, change):
1856 def _limit_to_all_changed(self, change):
1857 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
1857 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
1858 'value has been deprecated since IPython 5.0, will be made to have '
1858 'value has been deprecated since IPython 5.0, will be made to have '
1859 'no effects and then removed in future version of IPython.',
1859 'no effects and then removed in future version of IPython.',
1860 UserWarning)
1860 UserWarning)
1861
1861
1862 def __init__(
1862 def __init__(
1863 self, shell=None, namespace=None, global_namespace=None, config=None, **kwargs
1863 self, shell=None, namespace=None, global_namespace=None, config=None, **kwargs
1864 ):
1864 ):
1865 """IPCompleter() -> completer
1865 """IPCompleter() -> completer
1866
1866
1867 Return a completer object.
1867 Return a completer object.
1868
1868
1869 Parameters
1869 Parameters
1870 ----------
1870 ----------
1871 shell
1871 shell
1872 a pointer to the ipython shell itself. This is needed
1872 a pointer to the ipython shell itself. This is needed
1873 because this completer knows about magic functions, and those can
1873 because this completer knows about magic functions, and those can
1874 only be accessed via the ipython instance.
1874 only be accessed via the ipython instance.
1875 namespace : dict, optional
1875 namespace : dict, optional
1876 an optional dict where completions are performed.
1876 an optional dict where completions are performed.
1877 global_namespace : dict, optional
1877 global_namespace : dict, optional
1878 secondary optional dict for completions, to
1878 secondary optional dict for completions, to
1879 handle cases (such as IPython embedded inside functions) where
1879 handle cases (such as IPython embedded inside functions) where
1880 both Python scopes are visible.
1880 both Python scopes are visible.
1881 config : Config
1881 config : Config
1882 traitlet's config object
1882 traitlet's config object
1883 **kwargs
1883 **kwargs
1884 passed to super class unmodified.
1884 passed to super class unmodified.
1885 """
1885 """
1886
1886
1887 self.magic_escape = ESC_MAGIC
1887 self.magic_escape = ESC_MAGIC
1888 self.splitter = CompletionSplitter()
1888 self.splitter = CompletionSplitter()
1889
1889
1890 # _greedy_changed() depends on splitter and readline being defined:
1890 # _greedy_changed() depends on splitter and readline being defined:
1891 super().__init__(
1891 super().__init__(
1892 namespace=namespace,
1892 namespace=namespace,
1893 global_namespace=global_namespace,
1893 global_namespace=global_namespace,
1894 config=config,
1894 config=config,
1895 **kwargs,
1895 **kwargs,
1896 )
1896 )
1897
1897
1898 # List where completion matches will be stored
1898 # List where completion matches will be stored
1899 self.matches = []
1899 self.matches = []
1900 self.shell = shell
1900 self.shell = shell
1901 # Regexp to split filenames with spaces in them
1901 # Regexp to split filenames with spaces in them
1902 self.space_name_re = re.compile(r'([^\\] )')
1902 self.space_name_re = re.compile(r'([^\\] )')
1903 # Hold a local ref. to glob.glob for speed
1903 # Hold a local ref. to glob.glob for speed
1904 self.glob = glob.glob
1904 self.glob = glob.glob
1905
1905
1906 # Determine if we are running on 'dumb' terminals, like (X)Emacs
1906 # Determine if we are running on 'dumb' terminals, like (X)Emacs
1907 # buffers, to avoid completion problems.
1907 # buffers, to avoid completion problems.
1908 term = os.environ.get('TERM','xterm')
1908 term = os.environ.get('TERM','xterm')
1909 self.dumb_terminal = term in ['dumb','emacs']
1909 self.dumb_terminal = term in ['dumb','emacs']
1910
1910
1911 # Special handling of backslashes needed in win32 platforms
1911 # Special handling of backslashes needed in win32 platforms
1912 if sys.platform == "win32":
1912 if sys.platform == "win32":
1913 self.clean_glob = self._clean_glob_win32
1913 self.clean_glob = self._clean_glob_win32
1914 else:
1914 else:
1915 self.clean_glob = self._clean_glob
1915 self.clean_glob = self._clean_glob
1916
1916
1917 #regexp to parse docstring for function signature
1917 #regexp to parse docstring for function signature
1918 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1918 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1919 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1919 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1920 #use this if positional argument name is also needed
1920 #use this if positional argument name is also needed
1921 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
1921 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
1922
1922
1923 self.magic_arg_matchers = [
1923 self.magic_arg_matchers = [
1924 self.magic_config_matcher,
1924 self.magic_config_matcher,
1925 self.magic_color_matcher,
1925 self.magic_color_matcher,
1926 ]
1926 ]
1927
1927
1928 # This is set externally by InteractiveShell
1928 # This is set externally by InteractiveShell
1929 self.custom_completers = None
1929 self.custom_completers = None
1930
1930
1931 # This is a list of names of unicode characters that can be completed
1931 # This is a list of names of unicode characters that can be completed
1932 # into their corresponding unicode value. The list is large, so we
1932 # into their corresponding unicode value. The list is large, so we
1933 # lazily initialize it on first use. Consuming code should access this
1933 # lazily initialize it on first use. Consuming code should access this
1934 # attribute through the `@unicode_names` property.
1934 # attribute through the `@unicode_names` property.
1935 self._unicode_names = None
1935 self._unicode_names = None
1936
1936
1937 self._backslash_combining_matchers = [
1937 self._backslash_combining_matchers = [
1938 self.latex_name_matcher,
1938 self.latex_name_matcher,
1939 self.unicode_name_matcher,
1939 self.unicode_name_matcher,
1940 back_latex_name_matcher,
1940 back_latex_name_matcher,
1941 back_unicode_name_matcher,
1941 back_unicode_name_matcher,
1942 self.fwd_unicode_matcher,
1942 self.fwd_unicode_matcher,
1943 ]
1943 ]
1944
1944
1945 if not self.backslash_combining_completions:
1945 if not self.backslash_combining_completions:
1946 for matcher in self._backslash_combining_matchers:
1946 for matcher in self._backslash_combining_matchers:
1947 self.disable_matchers.append(_get_matcher_id(matcher))
1947 self.disable_matchers.append(_get_matcher_id(matcher))
1948
1948
1949 if not self.merge_completions:
1949 if not self.merge_completions:
1950 self.suppress_competing_matchers = True
1950 self.suppress_competing_matchers = True
1951
1951
1952 @property
1952 @property
1953 def matchers(self) -> List[Matcher]:
1953 def matchers(self) -> List[Matcher]:
1954 """All active matcher routines for completion"""
1954 """All active matcher routines for completion"""
1955 if self.dict_keys_only:
1955 if self.dict_keys_only:
1956 return [self.dict_key_matcher]
1956 return [self.dict_key_matcher]
1957
1957
1958 if self.use_jedi:
1958 if self.use_jedi:
1959 return [
1959 return [
1960 *self.custom_matchers,
1960 *self.custom_matchers,
1961 *self._backslash_combining_matchers,
1961 *self._backslash_combining_matchers,
1962 *self.magic_arg_matchers,
1962 *self.magic_arg_matchers,
1963 self.custom_completer_matcher,
1963 self.custom_completer_matcher,
1964 self.magic_matcher,
1964 self.magic_matcher,
1965 self._jedi_matcher,
1965 self._jedi_matcher,
1966 self.dict_key_matcher,
1966 self.dict_key_matcher,
1967 self.file_matcher,
1967 self.file_matcher,
1968 ]
1968 ]
1969 else:
1969 else:
1970 return [
1970 return [
1971 *self.custom_matchers,
1971 *self.custom_matchers,
1972 *self._backslash_combining_matchers,
1972 *self._backslash_combining_matchers,
1973 *self.magic_arg_matchers,
1973 *self.magic_arg_matchers,
1974 self.custom_completer_matcher,
1974 self.custom_completer_matcher,
1975 self.dict_key_matcher,
1975 self.dict_key_matcher,
1976 # TODO: convert python_matches to v2 API
1976 # TODO: convert python_matches to v2 API
1977 self.magic_matcher,
1977 self.magic_matcher,
1978 self.python_matches,
1978 self.python_matches,
1979 self.file_matcher,
1979 self.file_matcher,
1980 self.python_func_kw_matcher,
1980 self.python_func_kw_matcher,
1981 ]
1981 ]
1982
1982
1983 def all_completions(self, text:str) -> List[str]:
1983 def all_completions(self, text:str) -> List[str]:
1984 """
1984 """
1985 Wrapper around the completion methods for the benefit of emacs.
1985 Wrapper around the completion methods for the benefit of emacs.
1986 """
1986 """
1987 prefix = text.rpartition('.')[0]
1987 prefix = text.rpartition('.')[0]
1988 with provisionalcompleter():
1988 with provisionalcompleter():
1989 return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text
1989 return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text
1990 for c in self.completions(text, len(text))]
1990 for c in self.completions(text, len(text))]
1991
1991
1992 return self.complete(text)[1]
1992 return self.complete(text)[1]
1993
1993
1994 def _clean_glob(self, text:str):
1994 def _clean_glob(self, text:str):
1995 return self.glob("%s*" % text)
1995 return self.glob("%s*" % text)
1996
1996
1997 def _clean_glob_win32(self, text:str):
1997 def _clean_glob_win32(self, text:str):
1998 return [f.replace("\\","/")
1998 return [f.replace("\\","/")
1999 for f in self.glob("%s*" % text)]
1999 for f in self.glob("%s*" % text)]
2000
2000
2001 @context_matcher()
2001 @context_matcher()
2002 def file_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2002 def file_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2003 """Same as :any:`file_matches`, but adopted to new Matcher API."""
2003 """Same as :any:`file_matches`, but adopted to new Matcher API."""
2004 matches = self.file_matches(context.token)
2004 matches = self.file_matches(context.token)
2005 # TODO: add a heuristic for suppressing (e.g. if it has OS-specific delimiter,
2005 # TODO: add a heuristic for suppressing (e.g. if it has OS-specific delimiter,
2006 # starts with `/home/`, `C:\`, etc)
2006 # starts with `/home/`, `C:\`, etc)
2007 return _convert_matcher_v1_result_to_v2(matches, type="path")
2007 return _convert_matcher_v1_result_to_v2(matches, type="path")
2008
2008
2009 def file_matches(self, text: str) -> List[str]:
2009 def file_matches(self, text: str) -> List[str]:
2010 """Match filenames, expanding ~USER type strings.
2010 """Match filenames, expanding ~USER type strings.
2011
2011
2012 Most of the seemingly convoluted logic in this completer is an
2012 Most of the seemingly convoluted logic in this completer is an
2013 attempt to handle filenames with spaces in them. And yet it's not
2013 attempt to handle filenames with spaces in them. And yet it's not
2014 quite perfect, because Python's readline doesn't expose all of the
2014 quite perfect, because Python's readline doesn't expose all of the
2015 GNU readline details needed for this to be done correctly.
2015 GNU readline details needed for this to be done correctly.
2016
2016
2017 For a filename with a space in it, the printed completions will be
2017 For a filename with a space in it, the printed completions will be
2018 only the parts after what's already been typed (instead of the
2018 only the parts after what's already been typed (instead of the
2019 full completions, as is normally done). I don't think with the
2019 full completions, as is normally done). I don't think with the
2020 current (as of Python 2.3) Python readline it's possible to do
2020 current (as of Python 2.3) Python readline it's possible to do
2021 better.
2021 better.
2022
2022
2023 .. deprecated:: 8.6
2023 .. deprecated:: 8.6
2024 You can use :meth:`file_matcher` instead.
2024 You can use :meth:`file_matcher` instead.
2025 """
2025 """
2026
2026
2027 # chars that require escaping with backslash - i.e. chars
2027 # chars that require escaping with backslash - i.e. chars
2028 # that readline treats incorrectly as delimiters, but we
2028 # that readline treats incorrectly as delimiters, but we
2029 # don't want to treat as delimiters in filename matching
2029 # don't want to treat as delimiters in filename matching
2030 # when escaped with backslash
2030 # when escaped with backslash
2031 if text.startswith('!'):
2031 if text.startswith('!'):
2032 text = text[1:]
2032 text = text[1:]
2033 text_prefix = u'!'
2033 text_prefix = u'!'
2034 else:
2034 else:
2035 text_prefix = u''
2035 text_prefix = u''
2036
2036
2037 text_until_cursor = self.text_until_cursor
2037 text_until_cursor = self.text_until_cursor
2038 # track strings with open quotes
2038 # track strings with open quotes
2039 open_quotes = has_open_quotes(text_until_cursor)
2039 open_quotes = has_open_quotes(text_until_cursor)
2040
2040
2041 if '(' in text_until_cursor or '[' in text_until_cursor:
2041 if '(' in text_until_cursor or '[' in text_until_cursor:
2042 lsplit = text
2042 lsplit = text
2043 else:
2043 else:
2044 try:
2044 try:
2045 # arg_split ~ shlex.split, but with unicode bugs fixed by us
2045 # arg_split ~ shlex.split, but with unicode bugs fixed by us
2046 lsplit = arg_split(text_until_cursor)[-1]
2046 lsplit = arg_split(text_until_cursor)[-1]
2047 except ValueError:
2047 except ValueError:
2048 # typically an unmatched ", or backslash without escaped char.
2048 # typically an unmatched ", or backslash without escaped char.
2049 if open_quotes:
2049 if open_quotes:
2050 lsplit = text_until_cursor.split(open_quotes)[-1]
2050 lsplit = text_until_cursor.split(open_quotes)[-1]
2051 else:
2051 else:
2052 return []
2052 return []
2053 except IndexError:
2053 except IndexError:
2054 # tab pressed on empty line
2054 # tab pressed on empty line
2055 lsplit = ""
2055 lsplit = ""
2056
2056
2057 if not open_quotes and lsplit != protect_filename(lsplit):
2057 if not open_quotes and lsplit != protect_filename(lsplit):
2058 # if protectables are found, do matching on the whole escaped name
2058 # if protectables are found, do matching on the whole escaped name
2059 has_protectables = True
2059 has_protectables = True
2060 text0,text = text,lsplit
2060 text0,text = text,lsplit
2061 else:
2061 else:
2062 has_protectables = False
2062 has_protectables = False
2063 text = os.path.expanduser(text)
2063 text = os.path.expanduser(text)
2064
2064
2065 if text == "":
2065 if text == "":
2066 return [text_prefix + protect_filename(f) for f in self.glob("*")]
2066 return [text_prefix + protect_filename(f) for f in self.glob("*")]
2067
2067
2068 # Compute the matches from the filesystem
2068 # Compute the matches from the filesystem
2069 if sys.platform == 'win32':
2069 if sys.platform == 'win32':
2070 m0 = self.clean_glob(text)
2070 m0 = self.clean_glob(text)
2071 else:
2071 else:
2072 m0 = self.clean_glob(text.replace('\\', ''))
2072 m0 = self.clean_glob(text.replace('\\', ''))
2073
2073
2074 if has_protectables:
2074 if has_protectables:
2075 # If we had protectables, we need to revert our changes to the
2075 # If we had protectables, we need to revert our changes to the
2076 # beginning of filename so that we don't double-write the part
2076 # beginning of filename so that we don't double-write the part
2077 # of the filename we have so far
2077 # of the filename we have so far
2078 len_lsplit = len(lsplit)
2078 len_lsplit = len(lsplit)
2079 matches = [text_prefix + text0 +
2079 matches = [text_prefix + text0 +
2080 protect_filename(f[len_lsplit:]) for f in m0]
2080 protect_filename(f[len_lsplit:]) for f in m0]
2081 else:
2081 else:
2082 if open_quotes:
2082 if open_quotes:
2083 # if we have a string with an open quote, we don't need to
2083 # if we have a string with an open quote, we don't need to
2084 # protect the names beyond the quote (and we _shouldn't_, as
2084 # protect the names beyond the quote (and we _shouldn't_, as
2085 # it would cause bugs when the filesystem call is made).
2085 # it would cause bugs when the filesystem call is made).
2086 matches = m0 if sys.platform == "win32" else\
2086 matches = m0 if sys.platform == "win32" else\
2087 [protect_filename(f, open_quotes) for f in m0]
2087 [protect_filename(f, open_quotes) for f in m0]
2088 else:
2088 else:
2089 matches = [text_prefix +
2089 matches = [text_prefix +
2090 protect_filename(f) for f in m0]
2090 protect_filename(f) for f in m0]
2091
2091
2092 # Mark directories in input list by appending '/' to their names.
2092 # Mark directories in input list by appending '/' to their names.
2093 return [x+'/' if os.path.isdir(x) else x for x in matches]
2093 return [x+'/' if os.path.isdir(x) else x for x in matches]
2094
2094
2095 @context_matcher()
2095 @context_matcher()
2096 def magic_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2096 def magic_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2097 """Match magics."""
2097 """Match magics."""
2098 text = context.token
2098 text = context.token
2099 matches = self.magic_matches(text)
2099 matches = self.magic_matches(text)
2100 result = _convert_matcher_v1_result_to_v2(matches, type="magic")
2100 result = _convert_matcher_v1_result_to_v2(matches, type="magic")
2101 is_magic_prefix = len(text) > 0 and text[0] == "%"
2101 is_magic_prefix = len(text) > 0 and text[0] == "%"
2102 result["suppress"] = is_magic_prefix and bool(result["completions"])
2102 result["suppress"] = is_magic_prefix and bool(result["completions"])
2103 return result
2103 return result
2104
2104
2105 def magic_matches(self, text: str):
2105 def magic_matches(self, text: str):
2106 """Match magics.
2106 """Match magics.
2107
2107
2108 .. deprecated:: 8.6
2108 .. deprecated:: 8.6
2109 You can use :meth:`magic_matcher` instead.
2109 You can use :meth:`magic_matcher` instead.
2110 """
2110 """
2111 # Get all shell magics now rather than statically, so magics loaded at
2111 # Get all shell magics now rather than statically, so magics loaded at
2112 # runtime show up too.
2112 # runtime show up too.
2113 lsm = self.shell.magics_manager.lsmagic()
2113 lsm = self.shell.magics_manager.lsmagic()
2114 line_magics = lsm['line']
2114 line_magics = lsm['line']
2115 cell_magics = lsm['cell']
2115 cell_magics = lsm['cell']
2116 pre = self.magic_escape
2116 pre = self.magic_escape
2117 pre2 = pre+pre
2117 pre2 = pre+pre
2118
2118
2119 explicit_magic = text.startswith(pre)
2119 explicit_magic = text.startswith(pre)
2120
2120
2121 # Completion logic:
2121 # Completion logic:
2122 # - user gives %%: only do cell magics
2122 # - user gives %%: only do cell magics
2123 # - user gives %: do both line and cell magics
2123 # - user gives %: do both line and cell magics
2124 # - no prefix: do both
2124 # - no prefix: do both
2125 # In other words, line magics are skipped if the user gives %% explicitly
2125 # In other words, line magics are skipped if the user gives %% explicitly
2126 #
2126 #
2127 # We also exclude magics that match any currently visible names:
2127 # We also exclude magics that match any currently visible names:
2128 # https://github.com/ipython/ipython/issues/4877, unless the user has
2128 # https://github.com/ipython/ipython/issues/4877, unless the user has
2129 # typed a %:
2129 # typed a %:
2130 # https://github.com/ipython/ipython/issues/10754
2130 # https://github.com/ipython/ipython/issues/10754
2131 bare_text = text.lstrip(pre)
2131 bare_text = text.lstrip(pre)
2132 global_matches = self.global_matches(bare_text)
2132 global_matches = self.global_matches(bare_text)
2133 if not explicit_magic:
2133 if not explicit_magic:
2134 def matches(magic):
2134 def matches(magic):
2135 """
2135 """
2136 Filter magics, in particular remove magics that match
2136 Filter magics, in particular remove magics that match
2137 a name present in global namespace.
2137 a name present in global namespace.
2138 """
2138 """
2139 return ( magic.startswith(bare_text) and
2139 return ( magic.startswith(bare_text) and
2140 magic not in global_matches )
2140 magic not in global_matches )
2141 else:
2141 else:
2142 def matches(magic):
2142 def matches(magic):
2143 return magic.startswith(bare_text)
2143 return magic.startswith(bare_text)
2144
2144
2145 comp = [ pre2+m for m in cell_magics if matches(m)]
2145 comp = [ pre2+m for m in cell_magics if matches(m)]
2146 if not text.startswith(pre2):
2146 if not text.startswith(pre2):
2147 comp += [ pre+m for m in line_magics if matches(m)]
2147 comp += [ pre+m for m in line_magics if matches(m)]
2148
2148
2149 return comp
2149 return comp
2150
2150
2151 @context_matcher()
2151 @context_matcher()
2152 def magic_config_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2152 def magic_config_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2153 """Match class names and attributes for %config magic."""
2153 """Match class names and attributes for %config magic."""
2154 # NOTE: uses `line_buffer` equivalent for compatibility
2154 # NOTE: uses `line_buffer` equivalent for compatibility
2155 matches = self.magic_config_matches(context.line_with_cursor)
2155 matches = self.magic_config_matches(context.line_with_cursor)
2156 return _convert_matcher_v1_result_to_v2(matches, type="param")
2156 return _convert_matcher_v1_result_to_v2(matches, type="param")
2157
2157
2158 def magic_config_matches(self, text: str) -> List[str]:
2158 def magic_config_matches(self, text: str) -> List[str]:
2159 """Match class names and attributes for %config magic.
2159 """Match class names and attributes for %config magic.
2160
2160
2161 .. deprecated:: 8.6
2161 .. deprecated:: 8.6
2162 You can use :meth:`magic_config_matcher` instead.
2162 You can use :meth:`magic_config_matcher` instead.
2163 """
2163 """
2164 texts = text.strip().split()
2164 texts = text.strip().split()
2165
2165
2166 if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'):
2166 if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'):
2167 # get all configuration classes
2167 # get all configuration classes
2168 classes = sorted(set([ c for c in self.shell.configurables
2168 classes = sorted(set([ c for c in self.shell.configurables
2169 if c.__class__.class_traits(config=True)
2169 if c.__class__.class_traits(config=True)
2170 ]), key=lambda x: x.__class__.__name__)
2170 ]), key=lambda x: x.__class__.__name__)
2171 classnames = [ c.__class__.__name__ for c in classes ]
2171 classnames = [ c.__class__.__name__ for c in classes ]
2172
2172
2173 # return all classnames if config or %config is given
2173 # return all classnames if config or %config is given
2174 if len(texts) == 1:
2174 if len(texts) == 1:
2175 return classnames
2175 return classnames
2176
2176
2177 # match classname
2177 # match classname
2178 classname_texts = texts[1].split('.')
2178 classname_texts = texts[1].split('.')
2179 classname = classname_texts[0]
2179 classname = classname_texts[0]
2180 classname_matches = [ c for c in classnames
2180 classname_matches = [ c for c in classnames
2181 if c.startswith(classname) ]
2181 if c.startswith(classname) ]
2182
2182
2183 # return matched classes or the matched class with attributes
2183 # return matched classes or the matched class with attributes
2184 if texts[1].find('.') < 0:
2184 if texts[1].find('.') < 0:
2185 return classname_matches
2185 return classname_matches
2186 elif len(classname_matches) == 1 and \
2186 elif len(classname_matches) == 1 and \
2187 classname_matches[0] == classname:
2187 classname_matches[0] == classname:
2188 cls = classes[classnames.index(classname)].__class__
2188 cls = classes[classnames.index(classname)].__class__
2189 help = cls.class_get_help()
2189 help = cls.class_get_help()
2190 # strip leading '--' from cl-args:
2190 # strip leading '--' from cl-args:
2191 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
2191 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
2192 return [ attr.split('=')[0]
2192 return [ attr.split('=')[0]
2193 for attr in help.strip().splitlines()
2193 for attr in help.strip().splitlines()
2194 if attr.startswith(texts[1]) ]
2194 if attr.startswith(texts[1]) ]
2195 return []
2195 return []
2196
2196
2197 @context_matcher()
2197 @context_matcher()
2198 def magic_color_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2198 def magic_color_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2199 """Match color schemes for %colors magic."""
2199 """Match color schemes for %colors magic."""
2200 # NOTE: uses `line_buffer` equivalent for compatibility
2200 # NOTE: uses `line_buffer` equivalent for compatibility
2201 matches = self.magic_color_matches(context.line_with_cursor)
2201 matches = self.magic_color_matches(context.line_with_cursor)
2202 return _convert_matcher_v1_result_to_v2(matches, type="param")
2202 return _convert_matcher_v1_result_to_v2(matches, type="param")
2203
2203
2204 def magic_color_matches(self, text: str) -> List[str]:
2204 def magic_color_matches(self, text: str) -> List[str]:
2205 """Match color schemes for %colors magic.
2205 """Match color schemes for %colors magic.
2206
2206
2207 .. deprecated:: 8.6
2207 .. deprecated:: 8.6
2208 You can use :meth:`magic_color_matcher` instead.
2208 You can use :meth:`magic_color_matcher` instead.
2209 """
2209 """
2210 texts = text.split()
2210 texts = text.split()
2211 if text.endswith(' '):
2211 if text.endswith(' '):
2212 # .split() strips off the trailing whitespace. Add '' back
2212 # .split() strips off the trailing whitespace. Add '' back
2213 # so that: '%colors ' -> ['%colors', '']
2213 # so that: '%colors ' -> ['%colors', '']
2214 texts.append('')
2214 texts.append('')
2215
2215
2216 if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'):
2216 if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'):
2217 prefix = texts[1]
2217 prefix = texts[1]
2218 return [ color for color in InspectColors.keys()
2218 return [ color for color in InspectColors.keys()
2219 if color.startswith(prefix) ]
2219 if color.startswith(prefix) ]
2220 return []
2220 return []
2221
2221
2222 @context_matcher(identifier="IPCompleter.jedi_matcher")
2222 @context_matcher(identifier="IPCompleter.jedi_matcher")
2223 def _jedi_matcher(self, context: CompletionContext) -> _JediMatcherResult:
2223 def _jedi_matcher(self, context: CompletionContext) -> _JediMatcherResult:
2224 matches = self._jedi_matches(
2224 matches = self._jedi_matches(
2225 cursor_column=context.cursor_position,
2225 cursor_column=context.cursor_position,
2226 cursor_line=context.cursor_line,
2226 cursor_line=context.cursor_line,
2227 text=context.full_text,
2227 text=context.full_text,
2228 )
2228 )
2229 return {
2229 return {
2230 "completions": matches,
2230 "completions": matches,
2231 # static analysis should not suppress other matchers
2231 # static analysis should not suppress other matchers
2232 "suppress": False,
2232 "suppress": False,
2233 }
2233 }
2234
2234
2235 def _jedi_matches(
2235 def _jedi_matches(
2236 self, cursor_column: int, cursor_line: int, text: str
2236 self, cursor_column: int, cursor_line: int, text: str
2237 ) -> Iterator[_JediCompletionLike]:
2237 ) -> Iterator[_JediCompletionLike]:
2238 """
2238 """
2239 Return a list of :any:`jedi.api.Completion`\\s object from a ``text`` and
2239 Return a list of :any:`jedi.api.Completion`\\s object from a ``text`` and
2240 cursor position.
2240 cursor position.
2241
2241
2242 Parameters
2242 Parameters
2243 ----------
2243 ----------
2244 cursor_column : int
2244 cursor_column : int
2245 column position of the cursor in ``text``, 0-indexed.
2245 column position of the cursor in ``text``, 0-indexed.
2246 cursor_line : int
2246 cursor_line : int
2247 line position of the cursor in ``text``, 0-indexed
2247 line position of the cursor in ``text``, 0-indexed
2248 text : str
2248 text : str
2249 text to complete
2249 text to complete
2250
2250
2251 Notes
2251 Notes
2252 -----
2252 -----
2253 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
2253 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
2254 object containing a string with the Jedi debug information attached.
2254 object containing a string with the Jedi debug information attached.
2255
2255
2256 .. deprecated:: 8.6
2256 .. deprecated:: 8.6
2257 You can use :meth:`_jedi_matcher` instead.
2257 You can use :meth:`_jedi_matcher` instead.
2258 """
2258 """
2259 namespaces = [self.namespace]
2259 namespaces = [self.namespace]
2260 if self.global_namespace is not None:
2260 if self.global_namespace is not None:
2261 namespaces.append(self.global_namespace)
2261 namespaces.append(self.global_namespace)
2262
2262
2263 completion_filter = lambda x:x
2263 completion_filter = lambda x:x
2264 offset = cursor_to_position(text, cursor_line, cursor_column)
2264 offset = cursor_to_position(text, cursor_line, cursor_column)
2265 # filter output if we are completing for object members
2265 # filter output if we are completing for object members
2266 if offset:
2266 if offset:
2267 pre = text[offset-1]
2267 pre = text[offset-1]
2268 if pre == '.':
2268 if pre == '.':
2269 if self.omit__names == 2:
2269 if self.omit__names == 2:
2270 completion_filter = lambda c:not c.name.startswith('_')
2270 completion_filter = lambda c:not c.name.startswith('_')
2271 elif self.omit__names == 1:
2271 elif self.omit__names == 1:
2272 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
2272 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
2273 elif self.omit__names == 0:
2273 elif self.omit__names == 0:
2274 completion_filter = lambda x:x
2274 completion_filter = lambda x:x
2275 else:
2275 else:
2276 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
2276 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
2277
2277
2278 interpreter = jedi.Interpreter(text[:offset], namespaces)
2278 interpreter = jedi.Interpreter(text[:offset], namespaces)
2279 try_jedi = True
2279 try_jedi = True
2280
2280
2281 try:
2281 try:
2282 # find the first token in the current tree -- if it is a ' or " then we are in a string
2282 # find the first token in the current tree -- if it is a ' or " then we are in a string
2283 completing_string = False
2283 completing_string = False
2284 try:
2284 try:
2285 first_child = next(c for c in interpreter._get_module().tree_node.children if hasattr(c, 'value'))
2285 first_child = next(c for c in interpreter._get_module().tree_node.children if hasattr(c, 'value'))
2286 except StopIteration:
2286 except StopIteration:
2287 pass
2287 pass
2288 else:
2288 else:
2289 # note the value may be ', ", or it may also be ''' or """, or
2289 # note the value may be ', ", or it may also be ''' or """, or
2290 # in some cases, """what/you/typed..., but all of these are
2290 # in some cases, """what/you/typed..., but all of these are
2291 # strings.
2291 # strings.
2292 completing_string = len(first_child.value) > 0 and first_child.value[0] in {"'", '"'}
2292 completing_string = len(first_child.value) > 0 and first_child.value[0] in {"'", '"'}
2293
2293
2294 # if we are in a string jedi is likely not the right candidate for
2294 # if we are in a string jedi is likely not the right candidate for
2295 # now. Skip it.
2295 # now. Skip it.
2296 try_jedi = not completing_string
2296 try_jedi = not completing_string
2297 except Exception as e:
2297 except Exception as e:
2298 # many of things can go wrong, we are using private API just don't crash.
2298 # many of things can go wrong, we are using private API just don't crash.
2299 if self.debug:
2299 if self.debug:
2300 print("Error detecting if completing a non-finished string :", e, '|')
2300 print("Error detecting if completing a non-finished string :", e, '|')
2301
2301
2302 if not try_jedi:
2302 if not try_jedi:
2303 return iter([])
2303 return iter([])
2304 try:
2304 try:
2305 return filter(completion_filter, interpreter.complete(column=cursor_column, line=cursor_line + 1))
2305 return filter(completion_filter, interpreter.complete(column=cursor_column, line=cursor_line + 1))
2306 except Exception as e:
2306 except Exception as e:
2307 if self.debug:
2307 if self.debug:
2308 return iter(
2308 return iter(
2309 [
2309 [
2310 _FakeJediCompletion(
2310 _FakeJediCompletion(
2311 'Oops Jedi has crashed, please report a bug with the following:\n"""\n%s\ns"""'
2311 'Oops Jedi has crashed, please report a bug with the following:\n"""\n%s\ns"""'
2312 % (e)
2312 % (e)
2313 )
2313 )
2314 ]
2314 ]
2315 )
2315 )
2316 else:
2316 else:
2317 return iter([])
2317 return iter([])
2318
2318
2319 @completion_matcher(api_version=1)
2319 @completion_matcher(api_version=1)
2320 def python_matches(self, text: str) -> Iterable[str]:
2320 def python_matches(self, text: str) -> Iterable[str]:
2321 """Match attributes or global python names"""
2321 """Match attributes or global python names"""
2322 if "." in text:
2322 if "." in text:
2323 try:
2323 try:
2324 matches = self.attr_matches(text)
2324 matches = self.attr_matches(text)
2325 if text.endswith('.') and self.omit__names:
2325 if text.endswith('.') and self.omit__names:
2326 if self.omit__names == 1:
2326 if self.omit__names == 1:
2327 # true if txt is _not_ a __ name, false otherwise:
2327 # true if txt is _not_ a __ name, false otherwise:
2328 no__name = (lambda txt:
2328 no__name = (lambda txt:
2329 re.match(r'.*\.__.*?__',txt) is None)
2329 re.match(r'.*\.__.*?__',txt) is None)
2330 else:
2330 else:
2331 # true if txt is _not_ a _ name, false otherwise:
2331 # true if txt is _not_ a _ name, false otherwise:
2332 no__name = (lambda txt:
2332 no__name = (lambda txt:
2333 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
2333 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
2334 matches = filter(no__name, matches)
2334 matches = filter(no__name, matches)
2335 except NameError:
2335 except NameError:
2336 # catches <undefined attributes>.<tab>
2336 # catches <undefined attributes>.<tab>
2337 matches = []
2337 matches = []
2338 else:
2338 else:
2339 matches = self.global_matches(text)
2339 matches = self.global_matches(text)
2340 return matches
2340 return matches
2341
2341
2342 def _default_arguments_from_docstring(self, doc):
2342 def _default_arguments_from_docstring(self, doc):
2343 """Parse the first line of docstring for call signature.
2343 """Parse the first line of docstring for call signature.
2344
2344
2345 Docstring should be of the form 'min(iterable[, key=func])\n'.
2345 Docstring should be of the form 'min(iterable[, key=func])\n'.
2346 It can also parse cython docstring of the form
2346 It can also parse cython docstring of the form
2347 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
2347 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
2348 """
2348 """
2349 if doc is None:
2349 if doc is None:
2350 return []
2350 return []
2351
2351
2352 #care only the firstline
2352 #care only the firstline
2353 line = doc.lstrip().splitlines()[0]
2353 line = doc.lstrip().splitlines()[0]
2354
2354
2355 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
2355 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
2356 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
2356 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
2357 sig = self.docstring_sig_re.search(line)
2357 sig = self.docstring_sig_re.search(line)
2358 if sig is None:
2358 if sig is None:
2359 return []
2359 return []
2360 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
2360 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
2361 sig = sig.groups()[0].split(',')
2361 sig = sig.groups()[0].split(',')
2362 ret = []
2362 ret = []
2363 for s in sig:
2363 for s in sig:
2364 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
2364 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
2365 ret += self.docstring_kwd_re.findall(s)
2365 ret += self.docstring_kwd_re.findall(s)
2366 return ret
2366 return ret
2367
2367
2368 def _default_arguments(self, obj):
2368 def _default_arguments(self, obj):
2369 """Return the list of default arguments of obj if it is callable,
2369 """Return the list of default arguments of obj if it is callable,
2370 or empty list otherwise."""
2370 or empty list otherwise."""
2371 call_obj = obj
2371 call_obj = obj
2372 ret = []
2372 ret = []
2373 if inspect.isbuiltin(obj):
2373 if inspect.isbuiltin(obj):
2374 pass
2374 pass
2375 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
2375 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
2376 if inspect.isclass(obj):
2376 if inspect.isclass(obj):
2377 #for cython embedsignature=True the constructor docstring
2377 #for cython embedsignature=True the constructor docstring
2378 #belongs to the object itself not __init__
2378 #belongs to the object itself not __init__
2379 ret += self._default_arguments_from_docstring(
2379 ret += self._default_arguments_from_docstring(
2380 getattr(obj, '__doc__', ''))
2380 getattr(obj, '__doc__', ''))
2381 # for classes, check for __init__,__new__
2381 # for classes, check for __init__,__new__
2382 call_obj = (getattr(obj, '__init__', None) or
2382 call_obj = (getattr(obj, '__init__', None) or
2383 getattr(obj, '__new__', None))
2383 getattr(obj, '__new__', None))
2384 # for all others, check if they are __call__able
2384 # for all others, check if they are __call__able
2385 elif hasattr(obj, '__call__'):
2385 elif hasattr(obj, '__call__'):
2386 call_obj = obj.__call__
2386 call_obj = obj.__call__
2387 ret += self._default_arguments_from_docstring(
2387 ret += self._default_arguments_from_docstring(
2388 getattr(call_obj, '__doc__', ''))
2388 getattr(call_obj, '__doc__', ''))
2389
2389
2390 _keeps = (inspect.Parameter.KEYWORD_ONLY,
2390 _keeps = (inspect.Parameter.KEYWORD_ONLY,
2391 inspect.Parameter.POSITIONAL_OR_KEYWORD)
2391 inspect.Parameter.POSITIONAL_OR_KEYWORD)
2392
2392
2393 try:
2393 try:
2394 sig = inspect.signature(obj)
2394 sig = inspect.signature(obj)
2395 ret.extend(k for k, v in sig.parameters.items() if
2395 ret.extend(k for k, v in sig.parameters.items() if
2396 v.kind in _keeps)
2396 v.kind in _keeps)
2397 except ValueError:
2397 except ValueError:
2398 pass
2398 pass
2399
2399
2400 return list(set(ret))
2400 return list(set(ret))
2401
2401
2402 @context_matcher()
2402 @context_matcher()
2403 def python_func_kw_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2403 def python_func_kw_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2404 """Match named parameters (kwargs) of the last open function."""
2404 """Match named parameters (kwargs) of the last open function."""
2405 matches = self.python_func_kw_matches(context.token)
2405 matches = self.python_func_kw_matches(context.token)
2406 return _convert_matcher_v1_result_to_v2(matches, type="param")
2406 return _convert_matcher_v1_result_to_v2(matches, type="param")
2407
2407
2408 def python_func_kw_matches(self, text):
2408 def python_func_kw_matches(self, text):
2409 """Match named parameters (kwargs) of the last open function.
2409 """Match named parameters (kwargs) of the last open function.
2410
2410
2411 .. deprecated:: 8.6
2411 .. deprecated:: 8.6
2412 You can use :meth:`python_func_kw_matcher` instead.
2412 You can use :meth:`python_func_kw_matcher` instead.
2413 """
2413 """
2414
2414
2415 if "." in text: # a parameter cannot be dotted
2415 if "." in text: # a parameter cannot be dotted
2416 return []
2416 return []
2417 try: regexp = self.__funcParamsRegex
2417 try: regexp = self.__funcParamsRegex
2418 except AttributeError:
2418 except AttributeError:
2419 regexp = self.__funcParamsRegex = re.compile(r'''
2419 regexp = self.__funcParamsRegex = re.compile(r'''
2420 '.*?(?<!\\)' | # single quoted strings or
2420 '.*?(?<!\\)' | # single quoted strings or
2421 ".*?(?<!\\)" | # double quoted strings or
2421 ".*?(?<!\\)" | # double quoted strings or
2422 \w+ | # identifier
2422 \w+ | # identifier
2423 \S # other characters
2423 \S # other characters
2424 ''', re.VERBOSE | re.DOTALL)
2424 ''', re.VERBOSE | re.DOTALL)
2425 # 1. find the nearest identifier that comes before an unclosed
2425 # 1. find the nearest identifier that comes before an unclosed
2426 # parenthesis before the cursor
2426 # parenthesis before the cursor
2427 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
2427 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
2428 tokens = regexp.findall(self.text_until_cursor)
2428 tokens = regexp.findall(self.text_until_cursor)
2429 iterTokens = reversed(tokens); openPar = 0
2429 iterTokens = reversed(tokens); openPar = 0
2430
2430
2431 for token in iterTokens:
2431 for token in iterTokens:
2432 if token == ')':
2432 if token == ')':
2433 openPar -= 1
2433 openPar -= 1
2434 elif token == '(':
2434 elif token == '(':
2435 openPar += 1
2435 openPar += 1
2436 if openPar > 0:
2436 if openPar > 0:
2437 # found the last unclosed parenthesis
2437 # found the last unclosed parenthesis
2438 break
2438 break
2439 else:
2439 else:
2440 return []
2440 return []
2441 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
2441 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
2442 ids = []
2442 ids = []
2443 isId = re.compile(r'\w+$').match
2443 isId = re.compile(r'\w+$').match
2444
2444
2445 while True:
2445 while True:
2446 try:
2446 try:
2447 ids.append(next(iterTokens))
2447 ids.append(next(iterTokens))
2448 if not isId(ids[-1]):
2448 if not isId(ids[-1]):
2449 ids.pop(); break
2449 ids.pop(); break
2450 if not next(iterTokens) == '.':
2450 if not next(iterTokens) == '.':
2451 break
2451 break
2452 except StopIteration:
2452 except StopIteration:
2453 break
2453 break
2454
2454
2455 # Find all named arguments already assigned to, as to avoid suggesting
2455 # Find all named arguments already assigned to, as to avoid suggesting
2456 # them again
2456 # them again
2457 usedNamedArgs = set()
2457 usedNamedArgs = set()
2458 par_level = -1
2458 par_level = -1
2459 for token, next_token in zip(tokens, tokens[1:]):
2459 for token, next_token in zip(tokens, tokens[1:]):
2460 if token == '(':
2460 if token == '(':
2461 par_level += 1
2461 par_level += 1
2462 elif token == ')':
2462 elif token == ')':
2463 par_level -= 1
2463 par_level -= 1
2464
2464
2465 if par_level != 0:
2465 if par_level != 0:
2466 continue
2466 continue
2467
2467
2468 if next_token != '=':
2468 if next_token != '=':
2469 continue
2469 continue
2470
2470
2471 usedNamedArgs.add(token)
2471 usedNamedArgs.add(token)
2472
2472
2473 argMatches = []
2473 argMatches = []
2474 try:
2474 try:
2475 callableObj = '.'.join(ids[::-1])
2475 callableObj = '.'.join(ids[::-1])
2476 namedArgs = self._default_arguments(eval(callableObj,
2476 namedArgs = self._default_arguments(eval(callableObj,
2477 self.namespace))
2477 self.namespace))
2478
2478
2479 # Remove used named arguments from the list, no need to show twice
2479 # Remove used named arguments from the list, no need to show twice
2480 for namedArg in set(namedArgs) - usedNamedArgs:
2480 for namedArg in set(namedArgs) - usedNamedArgs:
2481 if namedArg.startswith(text):
2481 if namedArg.startswith(text):
2482 argMatches.append("%s=" %namedArg)
2482 argMatches.append("%s=" %namedArg)
2483 except:
2483 except:
2484 pass
2484 pass
2485
2485
2486 return argMatches
2486 return argMatches
2487
2487
2488 @staticmethod
2488 @staticmethod
2489 def _get_keys(obj: Any) -> List[Any]:
2489 def _get_keys(obj: Any) -> List[Any]:
2490 # Objects can define their own completions by defining an
2490 # Objects can define their own completions by defining an
2491 # _ipy_key_completions_() method.
2491 # _ipy_key_completions_() method.
2492 method = get_real_method(obj, '_ipython_key_completions_')
2492 method = get_real_method(obj, '_ipython_key_completions_')
2493 if method is not None:
2493 if method is not None:
2494 return method()
2494 return method()
2495
2495
2496 # Special case some common in-memory dict-like types
2496 # Special case some common in-memory dict-like types
2497 if isinstance(obj, dict) or _safe_isinstance(obj, "pandas", "DataFrame"):
2497 if isinstance(obj, dict) or _safe_isinstance(obj, "pandas", "DataFrame"):
2498 try:
2498 try:
2499 return list(obj.keys())
2499 return list(obj.keys())
2500 except Exception:
2500 except Exception:
2501 return []
2501 return []
2502 elif _safe_isinstance(obj, "pandas", "core", "indexing", "_LocIndexer"):
2502 elif _safe_isinstance(obj, "pandas", "core", "indexing", "_LocIndexer"):
2503 try:
2503 try:
2504 return list(obj.obj.keys())
2504 return list(obj.obj.keys())
2505 except Exception:
2505 except Exception:
2506 return []
2506 return []
2507 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
2507 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
2508 _safe_isinstance(obj, 'numpy', 'void'):
2508 _safe_isinstance(obj, 'numpy', 'void'):
2509 return obj.dtype.names or []
2509 return obj.dtype.names or []
2510 return []
2510 return []
2511
2511
2512 @context_matcher()
2512 @context_matcher()
2513 def dict_key_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2513 def dict_key_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
2514 """Match string keys in a dictionary, after e.g. ``foo[``."""
2514 """Match string keys in a dictionary, after e.g. ``foo[``."""
2515 matches = self.dict_key_matches(context.token)
2515 matches = self.dict_key_matches(context.token)
2516 return _convert_matcher_v1_result_to_v2(
2516 return _convert_matcher_v1_result_to_v2(
2517 matches, type="dict key", suppress_if_matches=True
2517 matches, type="dict key", suppress_if_matches=True
2518 )
2518 )
2519
2519
2520 def dict_key_matches(self, text: str) -> List[str]:
2520 def dict_key_matches(self, text: str) -> List[str]:
2521 """Match string keys in a dictionary, after e.g. ``foo[``.
2521 """Match string keys in a dictionary, after e.g. ``foo[``.
2522
2522
2523 .. deprecated:: 8.6
2523 .. deprecated:: 8.6
2524 You can use :meth:`dict_key_matcher` instead.
2524 You can use :meth:`dict_key_matcher` instead.
2525 """
2525 """
2526
2526
2527 # Short-circuit on closed dictionary (regular expression would
2527 # Short-circuit on closed dictionary (regular expression would
2528 # not match anyway, but would take quite a while).
2528 # not match anyway, but would take quite a while).
2529 if self.text_until_cursor.strip().endswith("]"):
2529 if self.text_until_cursor.strip().endswith("]"):
2530 return []
2530 return []
2531
2531
2532 match = DICT_MATCHER_REGEX.search(self.text_until_cursor)
2532 match = DICT_MATCHER_REGEX.search(self.text_until_cursor)
2533
2533
2534 if match is None:
2534 if match is None:
2535 return []
2535 return []
2536
2536
2537 expr, prior_tuple_keys, key_prefix = match.groups()
2537 expr, prior_tuple_keys, key_prefix = match.groups()
2538
2538
2539 obj = self._evaluate_expr(expr)
2539 obj = self._evaluate_expr(expr)
2540
2540
2541 if obj is not_found:
2541 if obj is not_found:
2542 return []
2542 return []
2543
2543
2544 keys = self._get_keys(obj)
2544 keys = self._get_keys(obj)
2545 if not keys:
2545 if not keys:
2546 return keys
2546 return keys
2547
2547
2548 tuple_prefix = guarded_eval(
2548 tuple_prefix = guarded_eval(
2549 prior_tuple_keys,
2549 prior_tuple_keys,
2550 EvaluationContext(
2550 EvaluationContext(
2551 globals=self.global_namespace,
2551 globals=self.global_namespace,
2552 locals=self.namespace,
2552 locals=self.namespace,
2553 evaluation=self.evaluation,
2553 evaluation=self.evaluation, # type: ignore
2554 in_subscript=True,
2554 in_subscript=True,
2555 ),
2555 ),
2556 )
2556 )
2557
2557
2558 closing_quote, token_offset, matches = match_dict_keys(
2558 closing_quote, token_offset, matches = match_dict_keys(
2559 keys, key_prefix, self.splitter.delims, extra_prefix=tuple_prefix
2559 keys, key_prefix, self.splitter.delims, extra_prefix=tuple_prefix
2560 )
2560 )
2561 if not matches:
2561 if not matches:
2562 return []
2562 return []
2563
2563
2564 # get the cursor position of
2564 # get the cursor position of
2565 # - the text being completed
2565 # - the text being completed
2566 # - the start of the key text
2566 # - the start of the key text
2567 # - the start of the completion
2567 # - the start of the completion
2568 text_start = len(self.text_until_cursor) - len(text)
2568 text_start = len(self.text_until_cursor) - len(text)
2569 if key_prefix:
2569 if key_prefix:
2570 key_start = match.start(3)
2570 key_start = match.start(3)
2571 completion_start = key_start + token_offset
2571 completion_start = key_start + token_offset
2572 else:
2572 else:
2573 key_start = completion_start = match.end()
2573 key_start = completion_start = match.end()
2574
2574
2575 # grab the leading prefix, to make sure all completions start with `text`
2575 # grab the leading prefix, to make sure all completions start with `text`
2576 if text_start > key_start:
2576 if text_start > key_start:
2577 leading = ''
2577 leading = ''
2578 else:
2578 else:
2579 leading = text[text_start:completion_start]
2579 leading = text[text_start:completion_start]
2580
2580
2581 # append closing quote and bracket as appropriate
2581 # append closing quote and bracket as appropriate
2582 # this is *not* appropriate if the opening quote or bracket is outside
2582 # this is *not* appropriate if the opening quote or bracket is outside
2583 # the text given to this method, e.g. `d["""a\nt
2583 # the text given to this method, e.g. `d["""a\nt
2584 can_close_quote = False
2584 can_close_quote = False
2585 can_close_bracket = False
2585 can_close_bracket = False
2586
2586
2587 continuation = self.line_buffer[len(self.text_until_cursor) :].strip()
2587 continuation = self.line_buffer[len(self.text_until_cursor) :].strip()
2588
2588
2589 if continuation.startswith(closing_quote):
2589 if continuation.startswith(closing_quote):
2590 # do not close if already closed, e.g. `d['a<tab>'`
2590 # do not close if already closed, e.g. `d['a<tab>'`
2591 continuation = continuation[len(closing_quote) :]
2591 continuation = continuation[len(closing_quote) :]
2592 else:
2592 else:
2593 can_close_quote = True
2593 can_close_quote = True
2594
2594
2595 continuation = continuation.strip()
2595 continuation = continuation.strip()
2596
2596
2597 # e.g. `pandas.DataFrame` has different tuple indexer behaviour,
2597 # e.g. `pandas.DataFrame` has different tuple indexer behaviour,
2598 # handling it is out of scope, so let's avoid appending suffixes.
2598 # handling it is out of scope, so let's avoid appending suffixes.
2599 has_known_tuple_handling = isinstance(obj, dict)
2599 has_known_tuple_handling = isinstance(obj, dict)
2600
2600
2601 can_close_bracket = (
2601 can_close_bracket = (
2602 not continuation.startswith("]") and self.auto_close_dict_keys
2602 not continuation.startswith("]") and self.auto_close_dict_keys
2603 )
2603 )
2604 can_close_tuple_item = (
2604 can_close_tuple_item = (
2605 not continuation.startswith(",")
2605 not continuation.startswith(",")
2606 and has_known_tuple_handling
2606 and has_known_tuple_handling
2607 and self.auto_close_dict_keys
2607 and self.auto_close_dict_keys
2608 )
2608 )
2609 can_close_quote = can_close_quote and self.auto_close_dict_keys
2609 can_close_quote = can_close_quote and self.auto_close_dict_keys
2610
2610
2611 # fast path if closing qoute should be appended but not suffix is allowed
2611 # fast path if closing qoute should be appended but not suffix is allowed
2612 if not can_close_quote and not can_close_bracket and closing_quote:
2612 if not can_close_quote and not can_close_bracket and closing_quote:
2613 return [leading + k for k in matches]
2613 return [leading + k for k in matches]
2614
2614
2615 results = []
2615 results = []
2616
2616
2617 end_of_tuple_or_item = _DictKeyState.END_OF_TUPLE | _DictKeyState.END_OF_ITEM
2617 end_of_tuple_or_item = _DictKeyState.END_OF_TUPLE | _DictKeyState.END_OF_ITEM
2618
2618
2619 for k, state_flag in matches.items():
2619 for k, state_flag in matches.items():
2620 result = leading + k
2620 result = leading + k
2621 if can_close_quote and closing_quote:
2621 if can_close_quote and closing_quote:
2622 result += closing_quote
2622 result += closing_quote
2623
2623
2624 if state_flag == end_of_tuple_or_item:
2624 if state_flag == end_of_tuple_or_item:
2625 # We do not know which suffix to add,
2625 # We do not know which suffix to add,
2626 # e.g. both tuple item and string
2626 # e.g. both tuple item and string
2627 # match this item.
2627 # match this item.
2628 pass
2628 pass
2629
2629
2630 if state_flag in end_of_tuple_or_item and can_close_bracket:
2630 if state_flag in end_of_tuple_or_item and can_close_bracket:
2631 result += "]"
2631 result += "]"
2632 if state_flag == _DictKeyState.IN_TUPLE and can_close_tuple_item:
2632 if state_flag == _DictKeyState.IN_TUPLE and can_close_tuple_item:
2633 result += ", "
2633 result += ", "
2634 results.append(result)
2634 results.append(result)
2635 return results
2635 return results
2636
2636
2637 @context_matcher()
2637 @context_matcher()
2638 def unicode_name_matcher(self, context: CompletionContext):
2638 def unicode_name_matcher(self, context: CompletionContext):
2639 """Same as :any:`unicode_name_matches`, but adopted to new Matcher API."""
2639 """Same as :any:`unicode_name_matches`, but adopted to new Matcher API."""
2640 fragment, matches = self.unicode_name_matches(context.text_until_cursor)
2640 fragment, matches = self.unicode_name_matches(context.text_until_cursor)
2641 return _convert_matcher_v1_result_to_v2(
2641 return _convert_matcher_v1_result_to_v2(
2642 matches, type="unicode", fragment=fragment, suppress_if_matches=True
2642 matches, type="unicode", fragment=fragment, suppress_if_matches=True
2643 )
2643 )
2644
2644
2645 @staticmethod
2645 @staticmethod
2646 def unicode_name_matches(text: str) -> Tuple[str, List[str]]:
2646 def unicode_name_matches(text: str) -> Tuple[str, List[str]]:
2647 """Match Latex-like syntax for unicode characters base
2647 """Match Latex-like syntax for unicode characters base
2648 on the name of the character.
2648 on the name of the character.
2649
2649
2650 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
2650 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
2651
2651
2652 Works only on valid python 3 identifier, or on combining characters that
2652 Works only on valid python 3 identifier, or on combining characters that
2653 will combine to form a valid identifier.
2653 will combine to form a valid identifier.
2654 """
2654 """
2655 slashpos = text.rfind('\\')
2655 slashpos = text.rfind('\\')
2656 if slashpos > -1:
2656 if slashpos > -1:
2657 s = text[slashpos+1:]
2657 s = text[slashpos+1:]
2658 try :
2658 try :
2659 unic = unicodedata.lookup(s)
2659 unic = unicodedata.lookup(s)
2660 # allow combining chars
2660 # allow combining chars
2661 if ('a'+unic).isidentifier():
2661 if ('a'+unic).isidentifier():
2662 return '\\'+s,[unic]
2662 return '\\'+s,[unic]
2663 except KeyError:
2663 except KeyError:
2664 pass
2664 pass
2665 return '', []
2665 return '', []
2666
2666
2667 @context_matcher()
2667 @context_matcher()
2668 def latex_name_matcher(self, context: CompletionContext):
2668 def latex_name_matcher(self, context: CompletionContext):
2669 """Match Latex syntax for unicode characters.
2669 """Match Latex syntax for unicode characters.
2670
2670
2671 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
2671 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
2672 """
2672 """
2673 fragment, matches = self.latex_matches(context.text_until_cursor)
2673 fragment, matches = self.latex_matches(context.text_until_cursor)
2674 return _convert_matcher_v1_result_to_v2(
2674 return _convert_matcher_v1_result_to_v2(
2675 matches, type="latex", fragment=fragment, suppress_if_matches=True
2675 matches, type="latex", fragment=fragment, suppress_if_matches=True
2676 )
2676 )
2677
2677
2678 def latex_matches(self, text: str) -> Tuple[str, Sequence[str]]:
2678 def latex_matches(self, text: str) -> Tuple[str, Sequence[str]]:
2679 """Match Latex syntax for unicode characters.
2679 """Match Latex syntax for unicode characters.
2680
2680
2681 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
2681 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
2682
2682
2683 .. deprecated:: 8.6
2683 .. deprecated:: 8.6
2684 You can use :meth:`latex_name_matcher` instead.
2684 You can use :meth:`latex_name_matcher` instead.
2685 """
2685 """
2686 slashpos = text.rfind('\\')
2686 slashpos = text.rfind('\\')
2687 if slashpos > -1:
2687 if slashpos > -1:
2688 s = text[slashpos:]
2688 s = text[slashpos:]
2689 if s in latex_symbols:
2689 if s in latex_symbols:
2690 # Try to complete a full latex symbol to unicode
2690 # Try to complete a full latex symbol to unicode
2691 # \\alpha -> Ξ±
2691 # \\alpha -> Ξ±
2692 return s, [latex_symbols[s]]
2692 return s, [latex_symbols[s]]
2693 else:
2693 else:
2694 # If a user has partially typed a latex symbol, give them
2694 # If a user has partially typed a latex symbol, give them
2695 # a full list of options \al -> [\aleph, \alpha]
2695 # a full list of options \al -> [\aleph, \alpha]
2696 matches = [k for k in latex_symbols if k.startswith(s)]
2696 matches = [k for k in latex_symbols if k.startswith(s)]
2697 if matches:
2697 if matches:
2698 return s, matches
2698 return s, matches
2699 return '', ()
2699 return '', ()
2700
2700
2701 @context_matcher()
2701 @context_matcher()
2702 def custom_completer_matcher(self, context):
2702 def custom_completer_matcher(self, context):
2703 """Dispatch custom completer.
2703 """Dispatch custom completer.
2704
2704
2705 If a match is found, suppresses all other matchers except for Jedi.
2705 If a match is found, suppresses all other matchers except for Jedi.
2706 """
2706 """
2707 matches = self.dispatch_custom_completer(context.token) or []
2707 matches = self.dispatch_custom_completer(context.token) or []
2708 result = _convert_matcher_v1_result_to_v2(
2708 result = _convert_matcher_v1_result_to_v2(
2709 matches, type=_UNKNOWN_TYPE, suppress_if_matches=True
2709 matches, type=_UNKNOWN_TYPE, suppress_if_matches=True
2710 )
2710 )
2711 result["ordered"] = True
2711 result["ordered"] = True
2712 result["do_not_suppress"] = {_get_matcher_id(self._jedi_matcher)}
2712 result["do_not_suppress"] = {_get_matcher_id(self._jedi_matcher)}
2713 return result
2713 return result
2714
2714
2715 def dispatch_custom_completer(self, text):
2715 def dispatch_custom_completer(self, text):
2716 """
2716 """
2717 .. deprecated:: 8.6
2717 .. deprecated:: 8.6
2718 You can use :meth:`custom_completer_matcher` instead.
2718 You can use :meth:`custom_completer_matcher` instead.
2719 """
2719 """
2720 if not self.custom_completers:
2720 if not self.custom_completers:
2721 return
2721 return
2722
2722
2723 line = self.line_buffer
2723 line = self.line_buffer
2724 if not line.strip():
2724 if not line.strip():
2725 return None
2725 return None
2726
2726
2727 # Create a little structure to pass all the relevant information about
2727 # Create a little structure to pass all the relevant information about
2728 # the current completion to any custom completer.
2728 # the current completion to any custom completer.
2729 event = SimpleNamespace()
2729 event = SimpleNamespace()
2730 event.line = line
2730 event.line = line
2731 event.symbol = text
2731 event.symbol = text
2732 cmd = line.split(None,1)[0]
2732 cmd = line.split(None,1)[0]
2733 event.command = cmd
2733 event.command = cmd
2734 event.text_until_cursor = self.text_until_cursor
2734 event.text_until_cursor = self.text_until_cursor
2735
2735
2736 # for foo etc, try also to find completer for %foo
2736 # for foo etc, try also to find completer for %foo
2737 if not cmd.startswith(self.magic_escape):
2737 if not cmd.startswith(self.magic_escape):
2738 try_magic = self.custom_completers.s_matches(
2738 try_magic = self.custom_completers.s_matches(
2739 self.magic_escape + cmd)
2739 self.magic_escape + cmd)
2740 else:
2740 else:
2741 try_magic = []
2741 try_magic = []
2742
2742
2743 for c in itertools.chain(self.custom_completers.s_matches(cmd),
2743 for c in itertools.chain(self.custom_completers.s_matches(cmd),
2744 try_magic,
2744 try_magic,
2745 self.custom_completers.flat_matches(self.text_until_cursor)):
2745 self.custom_completers.flat_matches(self.text_until_cursor)):
2746 try:
2746 try:
2747 res = c(event)
2747 res = c(event)
2748 if res:
2748 if res:
2749 # first, try case sensitive match
2749 # first, try case sensitive match
2750 withcase = [r for r in res if r.startswith(text)]
2750 withcase = [r for r in res if r.startswith(text)]
2751 if withcase:
2751 if withcase:
2752 return withcase
2752 return withcase
2753 # if none, then case insensitive ones are ok too
2753 # if none, then case insensitive ones are ok too
2754 text_low = text.lower()
2754 text_low = text.lower()
2755 return [r for r in res if r.lower().startswith(text_low)]
2755 return [r for r in res if r.lower().startswith(text_low)]
2756 except TryNext:
2756 except TryNext:
2757 pass
2757 pass
2758 except KeyboardInterrupt:
2758 except KeyboardInterrupt:
2759 """
2759 """
2760 If custom completer take too long,
2760 If custom completer take too long,
2761 let keyboard interrupt abort and return nothing.
2761 let keyboard interrupt abort and return nothing.
2762 """
2762 """
2763 break
2763 break
2764
2764
2765 return None
2765 return None
2766
2766
2767 def completions(self, text: str, offset: int)->Iterator[Completion]:
2767 def completions(self, text: str, offset: int)->Iterator[Completion]:
2768 """
2768 """
2769 Returns an iterator over the possible completions
2769 Returns an iterator over the possible completions
2770
2770
2771 .. warning::
2771 .. warning::
2772
2772
2773 Unstable
2773 Unstable
2774
2774
2775 This function is unstable, API may change without warning.
2775 This function is unstable, API may change without warning.
2776 It will also raise unless use in proper context manager.
2776 It will also raise unless use in proper context manager.
2777
2777
2778 Parameters
2778 Parameters
2779 ----------
2779 ----------
2780 text : str
2780 text : str
2781 Full text of the current input, multi line string.
2781 Full text of the current input, multi line string.
2782 offset : int
2782 offset : int
2783 Integer representing the position of the cursor in ``text``. Offset
2783 Integer representing the position of the cursor in ``text``. Offset
2784 is 0-based indexed.
2784 is 0-based indexed.
2785
2785
2786 Yields
2786 Yields
2787 ------
2787 ------
2788 Completion
2788 Completion
2789
2789
2790 Notes
2790 Notes
2791 -----
2791 -----
2792 The cursor on a text can either be seen as being "in between"
2792 The cursor on a text can either be seen as being "in between"
2793 characters or "On" a character depending on the interface visible to
2793 characters or "On" a character depending on the interface visible to
2794 the user. For consistency the cursor being on "in between" characters X
2794 the user. For consistency the cursor being on "in between" characters X
2795 and Y is equivalent to the cursor being "on" character Y, that is to say
2795 and Y is equivalent to the cursor being "on" character Y, that is to say
2796 the character the cursor is on is considered as being after the cursor.
2796 the character the cursor is on is considered as being after the cursor.
2797
2797
2798 Combining characters may span more that one position in the
2798 Combining characters may span more that one position in the
2799 text.
2799 text.
2800
2800
2801 .. note::
2801 .. note::
2802
2802
2803 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
2803 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
2804 fake Completion token to distinguish completion returned by Jedi
2804 fake Completion token to distinguish completion returned by Jedi
2805 and usual IPython completion.
2805 and usual IPython completion.
2806
2806
2807 .. note::
2807 .. note::
2808
2808
2809 Completions are not completely deduplicated yet. If identical
2809 Completions are not completely deduplicated yet. If identical
2810 completions are coming from different sources this function does not
2810 completions are coming from different sources this function does not
2811 ensure that each completion object will only be present once.
2811 ensure that each completion object will only be present once.
2812 """
2812 """
2813 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
2813 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
2814 "It may change without warnings. "
2814 "It may change without warnings. "
2815 "Use in corresponding context manager.",
2815 "Use in corresponding context manager.",
2816 category=ProvisionalCompleterWarning, stacklevel=2)
2816 category=ProvisionalCompleterWarning, stacklevel=2)
2817
2817
2818 seen = set()
2818 seen = set()
2819 profiler:Optional[cProfile.Profile]
2819 profiler:Optional[cProfile.Profile]
2820 try:
2820 try:
2821 if self.profile_completions:
2821 if self.profile_completions:
2822 import cProfile
2822 import cProfile
2823 profiler = cProfile.Profile()
2823 profiler = cProfile.Profile()
2824 profiler.enable()
2824 profiler.enable()
2825 else:
2825 else:
2826 profiler = None
2826 profiler = None
2827
2827
2828 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
2828 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
2829 if c and (c in seen):
2829 if c and (c in seen):
2830 continue
2830 continue
2831 yield c
2831 yield c
2832 seen.add(c)
2832 seen.add(c)
2833 except KeyboardInterrupt:
2833 except KeyboardInterrupt:
2834 """if completions take too long and users send keyboard interrupt,
2834 """if completions take too long and users send keyboard interrupt,
2835 do not crash and return ASAP. """
2835 do not crash and return ASAP. """
2836 pass
2836 pass
2837 finally:
2837 finally:
2838 if profiler is not None:
2838 if profiler is not None:
2839 profiler.disable()
2839 profiler.disable()
2840 ensure_dir_exists(self.profiler_output_dir)
2840 ensure_dir_exists(self.profiler_output_dir)
2841 output_path = os.path.join(self.profiler_output_dir, str(uuid.uuid4()))
2841 output_path = os.path.join(self.profiler_output_dir, str(uuid.uuid4()))
2842 print("Writing profiler output to", output_path)
2842 print("Writing profiler output to", output_path)
2843 profiler.dump_stats(output_path)
2843 profiler.dump_stats(output_path)
2844
2844
2845 def _completions(self, full_text: str, offset: int, *, _timeout) -> Iterator[Completion]:
2845 def _completions(self, full_text: str, offset: int, *, _timeout) -> Iterator[Completion]:
2846 """
2846 """
2847 Core completion module.Same signature as :any:`completions`, with the
2847 Core completion module.Same signature as :any:`completions`, with the
2848 extra `timeout` parameter (in seconds).
2848 extra `timeout` parameter (in seconds).
2849
2849
2850 Computing jedi's completion ``.type`` can be quite expensive (it is a
2850 Computing jedi's completion ``.type`` can be quite expensive (it is a
2851 lazy property) and can require some warm-up, more warm up than just
2851 lazy property) and can require some warm-up, more warm up than just
2852 computing the ``name`` of a completion. The warm-up can be :
2852 computing the ``name`` of a completion. The warm-up can be :
2853
2853
2854 - Long warm-up the first time a module is encountered after
2854 - Long warm-up the first time a module is encountered after
2855 install/update: actually build parse/inference tree.
2855 install/update: actually build parse/inference tree.
2856
2856
2857 - first time the module is encountered in a session: load tree from
2857 - first time the module is encountered in a session: load tree from
2858 disk.
2858 disk.
2859
2859
2860 We don't want to block completions for tens of seconds so we give the
2860 We don't want to block completions for tens of seconds so we give the
2861 completer a "budget" of ``_timeout`` seconds per invocation to compute
2861 completer a "budget" of ``_timeout`` seconds per invocation to compute
2862 completions types, the completions that have not yet been computed will
2862 completions types, the completions that have not yet been computed will
2863 be marked as "unknown" an will have a chance to be computed next round
2863 be marked as "unknown" an will have a chance to be computed next round
2864 are things get cached.
2864 are things get cached.
2865
2865
2866 Keep in mind that Jedi is not the only thing treating the completion so
2866 Keep in mind that Jedi is not the only thing treating the completion so
2867 keep the timeout short-ish as if we take more than 0.3 second we still
2867 keep the timeout short-ish as if we take more than 0.3 second we still
2868 have lots of processing to do.
2868 have lots of processing to do.
2869
2869
2870 """
2870 """
2871 deadline = time.monotonic() + _timeout
2871 deadline = time.monotonic() + _timeout
2872
2872
2873 before = full_text[:offset]
2873 before = full_text[:offset]
2874 cursor_line, cursor_column = position_to_cursor(full_text, offset)
2874 cursor_line, cursor_column = position_to_cursor(full_text, offset)
2875
2875
2876 jedi_matcher_id = _get_matcher_id(self._jedi_matcher)
2876 jedi_matcher_id = _get_matcher_id(self._jedi_matcher)
2877
2877
2878 def is_non_jedi_result(
2878 def is_non_jedi_result(
2879 result: MatcherResult, identifier: str
2879 result: MatcherResult, identifier: str
2880 ) -> TypeGuard[SimpleMatcherResult]:
2880 ) -> TypeGuard[SimpleMatcherResult]:
2881 return identifier != jedi_matcher_id
2881 return identifier != jedi_matcher_id
2882
2882
2883 results = self._complete(
2883 results = self._complete(
2884 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column
2884 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column
2885 )
2885 )
2886
2886
2887 non_jedi_results: Dict[str, SimpleMatcherResult] = {
2887 non_jedi_results: Dict[str, SimpleMatcherResult] = {
2888 identifier: result
2888 identifier: result
2889 for identifier, result in results.items()
2889 for identifier, result in results.items()
2890 if is_non_jedi_result(result, identifier)
2890 if is_non_jedi_result(result, identifier)
2891 }
2891 }
2892
2892
2893 jedi_matches = (
2893 jedi_matches = (
2894 cast(_JediMatcherResult, results[jedi_matcher_id])["completions"]
2894 cast(_JediMatcherResult, results[jedi_matcher_id])["completions"]
2895 if jedi_matcher_id in results
2895 if jedi_matcher_id in results
2896 else ()
2896 else ()
2897 )
2897 )
2898
2898
2899 iter_jm = iter(jedi_matches)
2899 iter_jm = iter(jedi_matches)
2900 if _timeout:
2900 if _timeout:
2901 for jm in iter_jm:
2901 for jm in iter_jm:
2902 try:
2902 try:
2903 type_ = jm.type
2903 type_ = jm.type
2904 except Exception:
2904 except Exception:
2905 if self.debug:
2905 if self.debug:
2906 print("Error in Jedi getting type of ", jm)
2906 print("Error in Jedi getting type of ", jm)
2907 type_ = None
2907 type_ = None
2908 delta = len(jm.name_with_symbols) - len(jm.complete)
2908 delta = len(jm.name_with_symbols) - len(jm.complete)
2909 if type_ == 'function':
2909 if type_ == 'function':
2910 signature = _make_signature(jm)
2910 signature = _make_signature(jm)
2911 else:
2911 else:
2912 signature = ''
2912 signature = ''
2913 yield Completion(start=offset - delta,
2913 yield Completion(start=offset - delta,
2914 end=offset,
2914 end=offset,
2915 text=jm.name_with_symbols,
2915 text=jm.name_with_symbols,
2916 type=type_,
2916 type=type_,
2917 signature=signature,
2917 signature=signature,
2918 _origin='jedi')
2918 _origin='jedi')
2919
2919
2920 if time.monotonic() > deadline:
2920 if time.monotonic() > deadline:
2921 break
2921 break
2922
2922
2923 for jm in iter_jm:
2923 for jm in iter_jm:
2924 delta = len(jm.name_with_symbols) - len(jm.complete)
2924 delta = len(jm.name_with_symbols) - len(jm.complete)
2925 yield Completion(
2925 yield Completion(
2926 start=offset - delta,
2926 start=offset - delta,
2927 end=offset,
2927 end=offset,
2928 text=jm.name_with_symbols,
2928 text=jm.name_with_symbols,
2929 type=_UNKNOWN_TYPE, # don't compute type for speed
2929 type=_UNKNOWN_TYPE, # don't compute type for speed
2930 _origin="jedi",
2930 _origin="jedi",
2931 signature="",
2931 signature="",
2932 )
2932 )
2933
2933
2934 # TODO:
2934 # TODO:
2935 # Suppress this, right now just for debug.
2935 # Suppress this, right now just for debug.
2936 if jedi_matches and non_jedi_results and self.debug:
2936 if jedi_matches and non_jedi_results and self.debug:
2937 some_start_offset = before.rfind(
2937 some_start_offset = before.rfind(
2938 next(iter(non_jedi_results.values()))["matched_fragment"]
2938 next(iter(non_jedi_results.values()))["matched_fragment"]
2939 )
2939 )
2940 yield Completion(
2940 yield Completion(
2941 start=some_start_offset,
2941 start=some_start_offset,
2942 end=offset,
2942 end=offset,
2943 text="--jedi/ipython--",
2943 text="--jedi/ipython--",
2944 _origin="debug",
2944 _origin="debug",
2945 type="none",
2945 type="none",
2946 signature="",
2946 signature="",
2947 )
2947 )
2948
2948
2949 ordered: List[Completion] = []
2949 ordered: List[Completion] = []
2950 sortable: List[Completion] = []
2950 sortable: List[Completion] = []
2951
2951
2952 for origin, result in non_jedi_results.items():
2952 for origin, result in non_jedi_results.items():
2953 matched_text = result["matched_fragment"]
2953 matched_text = result["matched_fragment"]
2954 start_offset = before.rfind(matched_text)
2954 start_offset = before.rfind(matched_text)
2955 is_ordered = result.get("ordered", False)
2955 is_ordered = result.get("ordered", False)
2956 container = ordered if is_ordered else sortable
2956 container = ordered if is_ordered else sortable
2957
2957
2958 # I'm unsure if this is always true, so let's assert and see if it
2958 # I'm unsure if this is always true, so let's assert and see if it
2959 # crash
2959 # crash
2960 assert before.endswith(matched_text)
2960 assert before.endswith(matched_text)
2961
2961
2962 for simple_completion in result["completions"]:
2962 for simple_completion in result["completions"]:
2963 completion = Completion(
2963 completion = Completion(
2964 start=start_offset,
2964 start=start_offset,
2965 end=offset,
2965 end=offset,
2966 text=simple_completion.text,
2966 text=simple_completion.text,
2967 _origin=origin,
2967 _origin=origin,
2968 signature="",
2968 signature="",
2969 type=simple_completion.type or _UNKNOWN_TYPE,
2969 type=simple_completion.type or _UNKNOWN_TYPE,
2970 )
2970 )
2971 container.append(completion)
2971 container.append(completion)
2972
2972
2973 yield from list(self._deduplicate(ordered + self._sort(sortable)))[
2973 yield from list(self._deduplicate(ordered + self._sort(sortable)))[
2974 :MATCHES_LIMIT
2974 :MATCHES_LIMIT
2975 ]
2975 ]
2976
2976
2977 def complete(self, text=None, line_buffer=None, cursor_pos=None) -> Tuple[str, Sequence[str]]:
2977 def complete(self, text=None, line_buffer=None, cursor_pos=None) -> Tuple[str, Sequence[str]]:
2978 """Find completions for the given text and line context.
2978 """Find completions for the given text and line context.
2979
2979
2980 Note that both the text and the line_buffer are optional, but at least
2980 Note that both the text and the line_buffer are optional, but at least
2981 one of them must be given.
2981 one of them must be given.
2982
2982
2983 Parameters
2983 Parameters
2984 ----------
2984 ----------
2985 text : string, optional
2985 text : string, optional
2986 Text to perform the completion on. If not given, the line buffer
2986 Text to perform the completion on. If not given, the line buffer
2987 is split using the instance's CompletionSplitter object.
2987 is split using the instance's CompletionSplitter object.
2988 line_buffer : string, optional
2988 line_buffer : string, optional
2989 If not given, the completer attempts to obtain the current line
2989 If not given, the completer attempts to obtain the current line
2990 buffer via readline. This keyword allows clients which are
2990 buffer via readline. This keyword allows clients which are
2991 requesting for text completions in non-readline contexts to inform
2991 requesting for text completions in non-readline contexts to inform
2992 the completer of the entire text.
2992 the completer of the entire text.
2993 cursor_pos : int, optional
2993 cursor_pos : int, optional
2994 Index of the cursor in the full line buffer. Should be provided by
2994 Index of the cursor in the full line buffer. Should be provided by
2995 remote frontends where kernel has no access to frontend state.
2995 remote frontends where kernel has no access to frontend state.
2996
2996
2997 Returns
2997 Returns
2998 -------
2998 -------
2999 Tuple of two items:
2999 Tuple of two items:
3000 text : str
3000 text : str
3001 Text that was actually used in the completion.
3001 Text that was actually used in the completion.
3002 matches : list
3002 matches : list
3003 A list of completion matches.
3003 A list of completion matches.
3004
3004
3005 Notes
3005 Notes
3006 -----
3006 -----
3007 This API is likely to be deprecated and replaced by
3007 This API is likely to be deprecated and replaced by
3008 :any:`IPCompleter.completions` in the future.
3008 :any:`IPCompleter.completions` in the future.
3009
3009
3010 """
3010 """
3011 warnings.warn('`Completer.complete` is pending deprecation since '
3011 warnings.warn('`Completer.complete` is pending deprecation since '
3012 'IPython 6.0 and will be replaced by `Completer.completions`.',
3012 'IPython 6.0 and will be replaced by `Completer.completions`.',
3013 PendingDeprecationWarning)
3013 PendingDeprecationWarning)
3014 # potential todo, FOLD the 3rd throw away argument of _complete
3014 # potential todo, FOLD the 3rd throw away argument of _complete
3015 # into the first 2 one.
3015 # into the first 2 one.
3016 # TODO: Q: does the above refer to jedi completions (i.e. 0-indexed?)
3016 # TODO: Q: does the above refer to jedi completions (i.e. 0-indexed?)
3017 # TODO: should we deprecate now, or does it stay?
3017 # TODO: should we deprecate now, or does it stay?
3018
3018
3019 results = self._complete(
3019 results = self._complete(
3020 line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0
3020 line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0
3021 )
3021 )
3022
3022
3023 jedi_matcher_id = _get_matcher_id(self._jedi_matcher)
3023 jedi_matcher_id = _get_matcher_id(self._jedi_matcher)
3024
3024
3025 return self._arrange_and_extract(
3025 return self._arrange_and_extract(
3026 results,
3026 results,
3027 # TODO: can we confirm that excluding Jedi here was a deliberate choice in previous version?
3027 # TODO: can we confirm that excluding Jedi here was a deliberate choice in previous version?
3028 skip_matchers={jedi_matcher_id},
3028 skip_matchers={jedi_matcher_id},
3029 # this API does not support different start/end positions (fragments of token).
3029 # this API does not support different start/end positions (fragments of token).
3030 abort_if_offset_changes=True,
3030 abort_if_offset_changes=True,
3031 )
3031 )
3032
3032
3033 def _arrange_and_extract(
3033 def _arrange_and_extract(
3034 self,
3034 self,
3035 results: Dict[str, MatcherResult],
3035 results: Dict[str, MatcherResult],
3036 skip_matchers: Set[str],
3036 skip_matchers: Set[str],
3037 abort_if_offset_changes: bool,
3037 abort_if_offset_changes: bool,
3038 ):
3038 ):
3039 sortable: List[AnyMatcherCompletion] = []
3039 sortable: List[AnyMatcherCompletion] = []
3040 ordered: List[AnyMatcherCompletion] = []
3040 ordered: List[AnyMatcherCompletion] = []
3041 most_recent_fragment = None
3041 most_recent_fragment = None
3042 for identifier, result in results.items():
3042 for identifier, result in results.items():
3043 if identifier in skip_matchers:
3043 if identifier in skip_matchers:
3044 continue
3044 continue
3045 if not result["completions"]:
3045 if not result["completions"]:
3046 continue
3046 continue
3047 if not most_recent_fragment:
3047 if not most_recent_fragment:
3048 most_recent_fragment = result["matched_fragment"]
3048 most_recent_fragment = result["matched_fragment"]
3049 if (
3049 if (
3050 abort_if_offset_changes
3050 abort_if_offset_changes
3051 and result["matched_fragment"] != most_recent_fragment
3051 and result["matched_fragment"] != most_recent_fragment
3052 ):
3052 ):
3053 break
3053 break
3054 if result.get("ordered", False):
3054 if result.get("ordered", False):
3055 ordered.extend(result["completions"])
3055 ordered.extend(result["completions"])
3056 else:
3056 else:
3057 sortable.extend(result["completions"])
3057 sortable.extend(result["completions"])
3058
3058
3059 if not most_recent_fragment:
3059 if not most_recent_fragment:
3060 most_recent_fragment = "" # to satisfy typechecker (and just in case)
3060 most_recent_fragment = "" # to satisfy typechecker (and just in case)
3061
3061
3062 return most_recent_fragment, [
3062 return most_recent_fragment, [
3063 m.text for m in self._deduplicate(ordered + self._sort(sortable))
3063 m.text for m in self._deduplicate(ordered + self._sort(sortable))
3064 ]
3064 ]
3065
3065
3066 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
3066 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
3067 full_text=None) -> _CompleteResult:
3067 full_text=None) -> _CompleteResult:
3068 """
3068 """
3069 Like complete but can also returns raw jedi completions as well as the
3069 Like complete but can also returns raw jedi completions as well as the
3070 origin of the completion text. This could (and should) be made much
3070 origin of the completion text. This could (and should) be made much
3071 cleaner but that will be simpler once we drop the old (and stateful)
3071 cleaner but that will be simpler once we drop the old (and stateful)
3072 :any:`complete` API.
3072 :any:`complete` API.
3073
3073
3074 With current provisional API, cursor_pos act both (depending on the
3074 With current provisional API, cursor_pos act both (depending on the
3075 caller) as the offset in the ``text`` or ``line_buffer``, or as the
3075 caller) as the offset in the ``text`` or ``line_buffer``, or as the
3076 ``column`` when passing multiline strings this could/should be renamed
3076 ``column`` when passing multiline strings this could/should be renamed
3077 but would add extra noise.
3077 but would add extra noise.
3078
3078
3079 Parameters
3079 Parameters
3080 ----------
3080 ----------
3081 cursor_line
3081 cursor_line
3082 Index of the line the cursor is on. 0 indexed.
3082 Index of the line the cursor is on. 0 indexed.
3083 cursor_pos
3083 cursor_pos
3084 Position of the cursor in the current line/line_buffer/text. 0
3084 Position of the cursor in the current line/line_buffer/text. 0
3085 indexed.
3085 indexed.
3086 line_buffer : optional, str
3086 line_buffer : optional, str
3087 The current line the cursor is in, this is mostly due to legacy
3087 The current line the cursor is in, this is mostly due to legacy
3088 reason that readline could only give a us the single current line.
3088 reason that readline could only give a us the single current line.
3089 Prefer `full_text`.
3089 Prefer `full_text`.
3090 text : str
3090 text : str
3091 The current "token" the cursor is in, mostly also for historical
3091 The current "token" the cursor is in, mostly also for historical
3092 reasons. as the completer would trigger only after the current line
3092 reasons. as the completer would trigger only after the current line
3093 was parsed.
3093 was parsed.
3094 full_text : str
3094 full_text : str
3095 Full text of the current cell.
3095 Full text of the current cell.
3096
3096
3097 Returns
3097 Returns
3098 -------
3098 -------
3099 An ordered dictionary where keys are identifiers of completion
3099 An ordered dictionary where keys are identifiers of completion
3100 matchers and values are ``MatcherResult``s.
3100 matchers and values are ``MatcherResult``s.
3101 """
3101 """
3102
3102
3103 # if the cursor position isn't given, the only sane assumption we can
3103 # if the cursor position isn't given, the only sane assumption we can
3104 # make is that it's at the end of the line (the common case)
3104 # make is that it's at the end of the line (the common case)
3105 if cursor_pos is None:
3105 if cursor_pos is None:
3106 cursor_pos = len(line_buffer) if text is None else len(text)
3106 cursor_pos = len(line_buffer) if text is None else len(text)
3107
3107
3108 if self.use_main_ns:
3108 if self.use_main_ns:
3109 self.namespace = __main__.__dict__
3109 self.namespace = __main__.__dict__
3110
3110
3111 # if text is either None or an empty string, rely on the line buffer
3111 # if text is either None or an empty string, rely on the line buffer
3112 if (not line_buffer) and full_text:
3112 if (not line_buffer) and full_text:
3113 line_buffer = full_text.split('\n')[cursor_line]
3113 line_buffer = full_text.split('\n')[cursor_line]
3114 if not text: # issue #11508: check line_buffer before calling split_line
3114 if not text: # issue #11508: check line_buffer before calling split_line
3115 text = (
3115 text = (
3116 self.splitter.split_line(line_buffer, cursor_pos) if line_buffer else ""
3116 self.splitter.split_line(line_buffer, cursor_pos) if line_buffer else ""
3117 )
3117 )
3118
3118
3119 # If no line buffer is given, assume the input text is all there was
3119 # If no line buffer is given, assume the input text is all there was
3120 if line_buffer is None:
3120 if line_buffer is None:
3121 line_buffer = text
3121 line_buffer = text
3122
3122
3123 # deprecated - do not use `line_buffer` in new code.
3123 # deprecated - do not use `line_buffer` in new code.
3124 self.line_buffer = line_buffer
3124 self.line_buffer = line_buffer
3125 self.text_until_cursor = self.line_buffer[:cursor_pos]
3125 self.text_until_cursor = self.line_buffer[:cursor_pos]
3126
3126
3127 if not full_text:
3127 if not full_text:
3128 full_text = line_buffer
3128 full_text = line_buffer
3129
3129
3130 context = CompletionContext(
3130 context = CompletionContext(
3131 full_text=full_text,
3131 full_text=full_text,
3132 cursor_position=cursor_pos,
3132 cursor_position=cursor_pos,
3133 cursor_line=cursor_line,
3133 cursor_line=cursor_line,
3134 token=text,
3134 token=text,
3135 limit=MATCHES_LIMIT,
3135 limit=MATCHES_LIMIT,
3136 )
3136 )
3137
3137
3138 # Start with a clean slate of completions
3138 # Start with a clean slate of completions
3139 results: Dict[str, MatcherResult] = {}
3139 results: Dict[str, MatcherResult] = {}
3140
3140
3141 jedi_matcher_id = _get_matcher_id(self._jedi_matcher)
3141 jedi_matcher_id = _get_matcher_id(self._jedi_matcher)
3142
3142
3143 suppressed_matchers: Set[str] = set()
3143 suppressed_matchers: Set[str] = set()
3144
3144
3145 matchers = {
3145 matchers = {
3146 _get_matcher_id(matcher): matcher
3146 _get_matcher_id(matcher): matcher
3147 for matcher in sorted(
3147 for matcher in sorted(
3148 self.matchers, key=_get_matcher_priority, reverse=True
3148 self.matchers, key=_get_matcher_priority, reverse=True
3149 )
3149 )
3150 }
3150 }
3151
3151
3152 for matcher_id, matcher in matchers.items():
3152 for matcher_id, matcher in matchers.items():
3153 matcher_id = _get_matcher_id(matcher)
3153 matcher_id = _get_matcher_id(matcher)
3154
3154
3155 if matcher_id in self.disable_matchers:
3155 if matcher_id in self.disable_matchers:
3156 continue
3156 continue
3157
3157
3158 if matcher_id in results:
3158 if matcher_id in results:
3159 warnings.warn(f"Duplicate matcher ID: {matcher_id}.")
3159 warnings.warn(f"Duplicate matcher ID: {matcher_id}.")
3160
3160
3161 if matcher_id in suppressed_matchers:
3161 if matcher_id in suppressed_matchers:
3162 continue
3162 continue
3163
3163
3164 result: MatcherResult
3164 result: MatcherResult
3165 try:
3165 try:
3166 if _is_matcher_v1(matcher):
3166 if _is_matcher_v1(matcher):
3167 result = _convert_matcher_v1_result_to_v2(
3167 result = _convert_matcher_v1_result_to_v2(
3168 matcher(text), type=_UNKNOWN_TYPE
3168 matcher(text), type=_UNKNOWN_TYPE
3169 )
3169 )
3170 elif _is_matcher_v2(matcher):
3170 elif _is_matcher_v2(matcher):
3171 result = matcher(context)
3171 result = matcher(context)
3172 else:
3172 else:
3173 api_version = _get_matcher_api_version(matcher)
3173 api_version = _get_matcher_api_version(matcher)
3174 raise ValueError(f"Unsupported API version {api_version}")
3174 raise ValueError(f"Unsupported API version {api_version}")
3175 except:
3175 except:
3176 # Show the ugly traceback if the matcher causes an
3176 # Show the ugly traceback if the matcher causes an
3177 # exception, but do NOT crash the kernel!
3177 # exception, but do NOT crash the kernel!
3178 sys.excepthook(*sys.exc_info())
3178 sys.excepthook(*sys.exc_info())
3179 continue
3179 continue
3180
3180
3181 # set default value for matched fragment if suffix was not selected.
3181 # set default value for matched fragment if suffix was not selected.
3182 result["matched_fragment"] = result.get("matched_fragment", context.token)
3182 result["matched_fragment"] = result.get("matched_fragment", context.token)
3183
3183
3184 if not suppressed_matchers:
3184 if not suppressed_matchers:
3185 suppression_recommended: Union[bool, Set[str]] = result.get(
3185 suppression_recommended: Union[bool, Set[str]] = result.get(
3186 "suppress", False
3186 "suppress", False
3187 )
3187 )
3188
3188
3189 suppression_config = (
3189 suppression_config = (
3190 self.suppress_competing_matchers.get(matcher_id, None)
3190 self.suppress_competing_matchers.get(matcher_id, None)
3191 if isinstance(self.suppress_competing_matchers, dict)
3191 if isinstance(self.suppress_competing_matchers, dict)
3192 else self.suppress_competing_matchers
3192 else self.suppress_competing_matchers
3193 )
3193 )
3194 should_suppress = (
3194 should_suppress = (
3195 (suppression_config is True)
3195 (suppression_config is True)
3196 or (suppression_recommended and (suppression_config is not False))
3196 or (suppression_recommended and (suppression_config is not False))
3197 ) and has_any_completions(result)
3197 ) and has_any_completions(result)
3198
3198
3199 if should_suppress:
3199 if should_suppress:
3200 suppression_exceptions: Set[str] = result.get(
3200 suppression_exceptions: Set[str] = result.get(
3201 "do_not_suppress", set()
3201 "do_not_suppress", set()
3202 )
3202 )
3203 if isinstance(suppression_recommended, Iterable):
3203 if isinstance(suppression_recommended, Iterable):
3204 to_suppress = set(suppression_recommended)
3204 to_suppress = set(suppression_recommended)
3205 else:
3205 else:
3206 to_suppress = set(matchers)
3206 to_suppress = set(matchers)
3207 suppressed_matchers = to_suppress - suppression_exceptions
3207 suppressed_matchers = to_suppress - suppression_exceptions
3208
3208
3209 new_results = {}
3209 new_results = {}
3210 for previous_matcher_id, previous_result in results.items():
3210 for previous_matcher_id, previous_result in results.items():
3211 if previous_matcher_id not in suppressed_matchers:
3211 if previous_matcher_id not in suppressed_matchers:
3212 new_results[previous_matcher_id] = previous_result
3212 new_results[previous_matcher_id] = previous_result
3213 results = new_results
3213 results = new_results
3214
3214
3215 results[matcher_id] = result
3215 results[matcher_id] = result
3216
3216
3217 _, matches = self._arrange_and_extract(
3217 _, matches = self._arrange_and_extract(
3218 results,
3218 results,
3219 # TODO Jedi completions non included in legacy stateful API; was this deliberate or omission?
3219 # TODO Jedi completions non included in legacy stateful API; was this deliberate or omission?
3220 # if it was omission, we can remove the filtering step, otherwise remove this comment.
3220 # if it was omission, we can remove the filtering step, otherwise remove this comment.
3221 skip_matchers={jedi_matcher_id},
3221 skip_matchers={jedi_matcher_id},
3222 abort_if_offset_changes=False,
3222 abort_if_offset_changes=False,
3223 )
3223 )
3224
3224
3225 # populate legacy stateful API
3225 # populate legacy stateful API
3226 self.matches = matches
3226 self.matches = matches
3227
3227
3228 return results
3228 return results
3229
3229
3230 @staticmethod
3230 @staticmethod
3231 def _deduplicate(
3231 def _deduplicate(
3232 matches: Sequence[AnyCompletion],
3232 matches: Sequence[AnyCompletion],
3233 ) -> Iterable[AnyCompletion]:
3233 ) -> Iterable[AnyCompletion]:
3234 filtered_matches: Dict[str, AnyCompletion] = {}
3234 filtered_matches: Dict[str, AnyCompletion] = {}
3235 for match in matches:
3235 for match in matches:
3236 text = match.text
3236 text = match.text
3237 if (
3237 if (
3238 text not in filtered_matches
3238 text not in filtered_matches
3239 or filtered_matches[text].type == _UNKNOWN_TYPE
3239 or filtered_matches[text].type == _UNKNOWN_TYPE
3240 ):
3240 ):
3241 filtered_matches[text] = match
3241 filtered_matches[text] = match
3242
3242
3243 return filtered_matches.values()
3243 return filtered_matches.values()
3244
3244
3245 @staticmethod
3245 @staticmethod
3246 def _sort(matches: Sequence[AnyCompletion]):
3246 def _sort(matches: Sequence[AnyCompletion]):
3247 return sorted(matches, key=lambda x: completions_sorting_key(x.text))
3247 return sorted(matches, key=lambda x: completions_sorting_key(x.text))
3248
3248
3249 @context_matcher()
3249 @context_matcher()
3250 def fwd_unicode_matcher(self, context: CompletionContext):
3250 def fwd_unicode_matcher(self, context: CompletionContext):
3251 """Same as :any:`fwd_unicode_match`, but adopted to new Matcher API."""
3251 """Same as :any:`fwd_unicode_match`, but adopted to new Matcher API."""
3252 # TODO: use `context.limit` to terminate early once we matched the maximum
3252 # TODO: use `context.limit` to terminate early once we matched the maximum
3253 # number that will be used downstream; can be added as an optional to
3253 # number that will be used downstream; can be added as an optional to
3254 # `fwd_unicode_match(text: str, limit: int = None)` or we could re-implement here.
3254 # `fwd_unicode_match(text: str, limit: int = None)` or we could re-implement here.
3255 fragment, matches = self.fwd_unicode_match(context.text_until_cursor)
3255 fragment, matches = self.fwd_unicode_match(context.text_until_cursor)
3256 return _convert_matcher_v1_result_to_v2(
3256 return _convert_matcher_v1_result_to_v2(
3257 matches, type="unicode", fragment=fragment, suppress_if_matches=True
3257 matches, type="unicode", fragment=fragment, suppress_if_matches=True
3258 )
3258 )
3259
3259
3260 def fwd_unicode_match(self, text: str) -> Tuple[str, Sequence[str]]:
3260 def fwd_unicode_match(self, text: str) -> Tuple[str, Sequence[str]]:
3261 """
3261 """
3262 Forward match a string starting with a backslash with a list of
3262 Forward match a string starting with a backslash with a list of
3263 potential Unicode completions.
3263 potential Unicode completions.
3264
3264
3265 Will compute list of Unicode character names on first call and cache it.
3265 Will compute list of Unicode character names on first call and cache it.
3266
3266
3267 .. deprecated:: 8.6
3267 .. deprecated:: 8.6
3268 You can use :meth:`fwd_unicode_matcher` instead.
3268 You can use :meth:`fwd_unicode_matcher` instead.
3269
3269
3270 Returns
3270 Returns
3271 -------
3271 -------
3272 At tuple with:
3272 At tuple with:
3273 - matched text (empty if no matches)
3273 - matched text (empty if no matches)
3274 - list of potential completions, empty tuple otherwise)
3274 - list of potential completions, empty tuple otherwise)
3275 """
3275 """
3276 # TODO: self.unicode_names is here a list we traverse each time with ~100k elements.
3276 # TODO: self.unicode_names is here a list we traverse each time with ~100k elements.
3277 # We could do a faster match using a Trie.
3277 # We could do a faster match using a Trie.
3278
3278
3279 # Using pygtrie the following seem to work:
3279 # Using pygtrie the following seem to work:
3280
3280
3281 # s = PrefixSet()
3281 # s = PrefixSet()
3282
3282
3283 # for c in range(0,0x10FFFF + 1):
3283 # for c in range(0,0x10FFFF + 1):
3284 # try:
3284 # try:
3285 # s.add(unicodedata.name(chr(c)))
3285 # s.add(unicodedata.name(chr(c)))
3286 # except ValueError:
3286 # except ValueError:
3287 # pass
3287 # pass
3288 # [''.join(k) for k in s.iter(prefix)]
3288 # [''.join(k) for k in s.iter(prefix)]
3289
3289
3290 # But need to be timed and adds an extra dependency.
3290 # But need to be timed and adds an extra dependency.
3291
3291
3292 slashpos = text.rfind('\\')
3292 slashpos = text.rfind('\\')
3293 # if text starts with slash
3293 # if text starts with slash
3294 if slashpos > -1:
3294 if slashpos > -1:
3295 # PERF: It's important that we don't access self._unicode_names
3295 # PERF: It's important that we don't access self._unicode_names
3296 # until we're inside this if-block. _unicode_names is lazily
3296 # until we're inside this if-block. _unicode_names is lazily
3297 # initialized, and it takes a user-noticeable amount of time to
3297 # initialized, and it takes a user-noticeable amount of time to
3298 # initialize it, so we don't want to initialize it unless we're
3298 # initialize it, so we don't want to initialize it unless we're
3299 # actually going to use it.
3299 # actually going to use it.
3300 s = text[slashpos + 1 :]
3300 s = text[slashpos + 1 :]
3301 sup = s.upper()
3301 sup = s.upper()
3302 candidates = [x for x in self.unicode_names if x.startswith(sup)]
3302 candidates = [x for x in self.unicode_names if x.startswith(sup)]
3303 if candidates:
3303 if candidates:
3304 return s, candidates
3304 return s, candidates
3305 candidates = [x for x in self.unicode_names if sup in x]
3305 candidates = [x for x in self.unicode_names if sup in x]
3306 if candidates:
3306 if candidates:
3307 return s, candidates
3307 return s, candidates
3308 splitsup = sup.split(" ")
3308 splitsup = sup.split(" ")
3309 candidates = [
3309 candidates = [
3310 x for x in self.unicode_names if all(u in x for u in splitsup)
3310 x for x in self.unicode_names if all(u in x for u in splitsup)
3311 ]
3311 ]
3312 if candidates:
3312 if candidates:
3313 return s, candidates
3313 return s, candidates
3314
3314
3315 return "", ()
3315 return "", ()
3316
3316
3317 # if text does not start with slash
3317 # if text does not start with slash
3318 else:
3318 else:
3319 return '', ()
3319 return '', ()
3320
3320
3321 @property
3321 @property
3322 def unicode_names(self) -> List[str]:
3322 def unicode_names(self) -> List[str]:
3323 """List of names of unicode code points that can be completed.
3323 """List of names of unicode code points that can be completed.
3324
3324
3325 The list is lazily initialized on first access.
3325 The list is lazily initialized on first access.
3326 """
3326 """
3327 if self._unicode_names is None:
3327 if self._unicode_names is None:
3328 names = []
3328 names = []
3329 for c in range(0,0x10FFFF + 1):
3329 for c in range(0,0x10FFFF + 1):
3330 try:
3330 try:
3331 names.append(unicodedata.name(chr(c)))
3331 names.append(unicodedata.name(chr(c)))
3332 except ValueError:
3332 except ValueError:
3333 pass
3333 pass
3334 self._unicode_names = _unicode_name_compute(_UNICODE_RANGES)
3334 self._unicode_names = _unicode_name_compute(_UNICODE_RANGES)
3335
3335
3336 return self._unicode_names
3336 return self._unicode_names
3337
3337
3338 def _unicode_name_compute(ranges:List[Tuple[int,int]]) -> List[str]:
3338 def _unicode_name_compute(ranges:List[Tuple[int,int]]) -> List[str]:
3339 names = []
3339 names = []
3340 for start,stop in ranges:
3340 for start,stop in ranges:
3341 for c in range(start, stop) :
3341 for c in range(start, stop) :
3342 try:
3342 try:
3343 names.append(unicodedata.name(chr(c)))
3343 names.append(unicodedata.name(chr(c)))
3344 except ValueError:
3344 except ValueError:
3345 pass
3345 pass
3346 return names
3346 return names
@@ -1,1031 +1,1031 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Display formatters.
2 """Display formatters.
3
3
4 Inheritance diagram:
4 Inheritance diagram:
5
5
6 .. inheritance-diagram:: IPython.core.formatters
6 .. inheritance-diagram:: IPython.core.formatters
7 :parts: 3
7 :parts: 3
8 """
8 """
9
9
10 # Copyright (c) IPython Development Team.
10 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
11 # Distributed under the terms of the Modified BSD License.
12
12
13 import abc
13 import abc
14 import sys
14 import sys
15 import traceback
15 import traceback
16 import warnings
16 import warnings
17 from io import StringIO
17 from io import StringIO
18
18
19 from decorator import decorator
19 from decorator import decorator
20
20
21 from traitlets.config.configurable import Configurable
21 from traitlets.config.configurable import Configurable
22 from .getipython import get_ipython
22 from .getipython import get_ipython
23 from ..utils.sentinel import Sentinel
23 from ..utils.sentinel import Sentinel
24 from ..utils.dir2 import get_real_method
24 from ..utils.dir2 import get_real_method
25 from ..lib import pretty
25 from ..lib import pretty
26 from traitlets import (
26 from traitlets import (
27 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
27 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
28 ForwardDeclaredInstance,
28 ForwardDeclaredInstance,
29 default, observe,
29 default, observe,
30 )
30 )
31
31
32 from typing import Any
32 from typing import Any
33
33
34
34
35 class DisplayFormatter(Configurable):
35 class DisplayFormatter(Configurable):
36
36
37 active_types = List(Unicode(),
37 active_types = List(Unicode(),
38 help="""List of currently active mime-types to display.
38 help="""List of currently active mime-types to display.
39 You can use this to set a white-list for formats to display.
39 You can use this to set a white-list for formats to display.
40
40
41 Most users will not need to change this value.
41 Most users will not need to change this value.
42 """).tag(config=True)
42 """).tag(config=True)
43
43
44 @default('active_types')
44 @default('active_types')
45 def _active_types_default(self):
45 def _active_types_default(self):
46 return self.format_types
46 return self.format_types
47
47
48 @observe('active_types')
48 @observe('active_types')
49 def _active_types_changed(self, change):
49 def _active_types_changed(self, change):
50 for key, formatter in self.formatters.items():
50 for key, formatter in self.formatters.items():
51 if key in change['new']:
51 if key in change['new']:
52 formatter.enabled = True
52 formatter.enabled = True
53 else:
53 else:
54 formatter.enabled = False
54 formatter.enabled = False
55
55
56 ipython_display_formatter = ForwardDeclaredInstance("FormatterABC")
56 ipython_display_formatter = ForwardDeclaredInstance("FormatterABC") # type: ignore
57
57
58 @default("ipython_display_formatter")
58 @default("ipython_display_formatter")
59 def _default_formatter(self):
59 def _default_formatter(self):
60 return IPythonDisplayFormatter(parent=self)
60 return IPythonDisplayFormatter(parent=self)
61
61
62 mimebundle_formatter = ForwardDeclaredInstance("FormatterABC")
62 mimebundle_formatter = ForwardDeclaredInstance("FormatterABC") # type: ignore
63
63
64 @default("mimebundle_formatter")
64 @default("mimebundle_formatter")
65 def _default_mime_formatter(self):
65 def _default_mime_formatter(self):
66 return MimeBundleFormatter(parent=self)
66 return MimeBundleFormatter(parent=self)
67
67
68 # A dict of formatter whose keys are format types (MIME types) and whose
68 # A dict of formatter whose keys are format types (MIME types) and whose
69 # values are subclasses of BaseFormatter.
69 # values are subclasses of BaseFormatter.
70 formatters = Dict()
70 formatters = Dict()
71
71
72 @default("formatters")
72 @default("formatters")
73 def _formatters_default(self):
73 def _formatters_default(self):
74 """Activate the default formatters."""
74 """Activate the default formatters."""
75 formatter_classes = [
75 formatter_classes = [
76 PlainTextFormatter,
76 PlainTextFormatter,
77 HTMLFormatter,
77 HTMLFormatter,
78 MarkdownFormatter,
78 MarkdownFormatter,
79 SVGFormatter,
79 SVGFormatter,
80 PNGFormatter,
80 PNGFormatter,
81 PDFFormatter,
81 PDFFormatter,
82 JPEGFormatter,
82 JPEGFormatter,
83 LatexFormatter,
83 LatexFormatter,
84 JSONFormatter,
84 JSONFormatter,
85 JavascriptFormatter
85 JavascriptFormatter
86 ]
86 ]
87 d = {}
87 d = {}
88 for cls in formatter_classes:
88 for cls in formatter_classes:
89 f = cls(parent=self)
89 f = cls(parent=self)
90 d[f.format_type] = f
90 d[f.format_type] = f
91 return d
91 return d
92
92
93 def format(self, obj, include=None, exclude=None):
93 def format(self, obj, include=None, exclude=None):
94 """Return a format data dict for an object.
94 """Return a format data dict for an object.
95
95
96 By default all format types will be computed.
96 By default all format types will be computed.
97
97
98 The following MIME types are usually implemented:
98 The following MIME types are usually implemented:
99
99
100 * text/plain
100 * text/plain
101 * text/html
101 * text/html
102 * text/markdown
102 * text/markdown
103 * text/latex
103 * text/latex
104 * application/json
104 * application/json
105 * application/javascript
105 * application/javascript
106 * application/pdf
106 * application/pdf
107 * image/png
107 * image/png
108 * image/jpeg
108 * image/jpeg
109 * image/svg+xml
109 * image/svg+xml
110
110
111 Parameters
111 Parameters
112 ----------
112 ----------
113 obj : object
113 obj : object
114 The Python object whose format data will be computed.
114 The Python object whose format data will be computed.
115 include : list, tuple or set; optional
115 include : list, tuple or set; optional
116 A list of format type strings (MIME types) to include in the
116 A list of format type strings (MIME types) to include in the
117 format data dict. If this is set *only* the format types included
117 format data dict. If this is set *only* the format types included
118 in this list will be computed.
118 in this list will be computed.
119 exclude : list, tuple or set; optional
119 exclude : list, tuple or set; optional
120 A list of format type string (MIME types) to exclude in the format
120 A list of format type string (MIME types) to exclude in the format
121 data dict. If this is set all format types will be computed,
121 data dict. If this is set all format types will be computed,
122 except for those included in this argument.
122 except for those included in this argument.
123 Mimetypes present in exclude will take precedence over the ones in include
123 Mimetypes present in exclude will take precedence over the ones in include
124
124
125 Returns
125 Returns
126 -------
126 -------
127 (format_dict, metadata_dict) : tuple of two dicts
127 (format_dict, metadata_dict) : tuple of two dicts
128 format_dict is a dictionary of key/value pairs, one of each format that was
128 format_dict is a dictionary of key/value pairs, one of each format that was
129 generated for the object. The keys are the format types, which
129 generated for the object. The keys are the format types, which
130 will usually be MIME type strings and the values and JSON'able
130 will usually be MIME type strings and the values and JSON'able
131 data structure containing the raw data for the representation in
131 data structure containing the raw data for the representation in
132 that format.
132 that format.
133
133
134 metadata_dict is a dictionary of metadata about each mime-type output.
134 metadata_dict is a dictionary of metadata about each mime-type output.
135 Its keys will be a strict subset of the keys in format_dict.
135 Its keys will be a strict subset of the keys in format_dict.
136
136
137 Notes
137 Notes
138 -----
138 -----
139 If an object implement `_repr_mimebundle_` as well as various
139 If an object implement `_repr_mimebundle_` as well as various
140 `_repr_*_`, the data returned by `_repr_mimebundle_` will take
140 `_repr_*_`, the data returned by `_repr_mimebundle_` will take
141 precedence and the corresponding `_repr_*_` for this mimetype will
141 precedence and the corresponding `_repr_*_` for this mimetype will
142 not be called.
142 not be called.
143
143
144 """
144 """
145 format_dict = {}
145 format_dict = {}
146 md_dict = {}
146 md_dict = {}
147
147
148 if self.ipython_display_formatter(obj):
148 if self.ipython_display_formatter(obj):
149 # object handled itself, don't proceed
149 # object handled itself, don't proceed
150 return {}, {}
150 return {}, {}
151
151
152 format_dict, md_dict = self.mimebundle_formatter(obj, include=include, exclude=exclude)
152 format_dict, md_dict = self.mimebundle_formatter(obj, include=include, exclude=exclude)
153
153
154 if format_dict or md_dict:
154 if format_dict or md_dict:
155 if include:
155 if include:
156 format_dict = {k:v for k,v in format_dict.items() if k in include}
156 format_dict = {k:v for k,v in format_dict.items() if k in include}
157 md_dict = {k:v for k,v in md_dict.items() if k in include}
157 md_dict = {k:v for k,v in md_dict.items() if k in include}
158 if exclude:
158 if exclude:
159 format_dict = {k:v for k,v in format_dict.items() if k not in exclude}
159 format_dict = {k:v for k,v in format_dict.items() if k not in exclude}
160 md_dict = {k:v for k,v in md_dict.items() if k not in exclude}
160 md_dict = {k:v for k,v in md_dict.items() if k not in exclude}
161
161
162 for format_type, formatter in self.formatters.items():
162 for format_type, formatter in self.formatters.items():
163 if format_type in format_dict:
163 if format_type in format_dict:
164 # already got it from mimebundle, maybe don't render again.
164 # already got it from mimebundle, maybe don't render again.
165 # exception: manually registered per-mime renderer
165 # exception: manually registered per-mime renderer
166 # check priority:
166 # check priority:
167 # 1. user-registered per-mime formatter
167 # 1. user-registered per-mime formatter
168 # 2. mime-bundle (user-registered or repr method)
168 # 2. mime-bundle (user-registered or repr method)
169 # 3. default per-mime formatter (e.g. repr method)
169 # 3. default per-mime formatter (e.g. repr method)
170 try:
170 try:
171 formatter.lookup(obj)
171 formatter.lookup(obj)
172 except KeyError:
172 except KeyError:
173 # no special formatter, use mime-bundle-provided value
173 # no special formatter, use mime-bundle-provided value
174 continue
174 continue
175 if include and format_type not in include:
175 if include and format_type not in include:
176 continue
176 continue
177 if exclude and format_type in exclude:
177 if exclude and format_type in exclude:
178 continue
178 continue
179
179
180 md = None
180 md = None
181 try:
181 try:
182 data = formatter(obj)
182 data = formatter(obj)
183 except:
183 except:
184 # FIXME: log the exception
184 # FIXME: log the exception
185 raise
185 raise
186
186
187 # formatters can return raw data or (data, metadata)
187 # formatters can return raw data or (data, metadata)
188 if isinstance(data, tuple) and len(data) == 2:
188 if isinstance(data, tuple) and len(data) == 2:
189 data, md = data
189 data, md = data
190
190
191 if data is not None:
191 if data is not None:
192 format_dict[format_type] = data
192 format_dict[format_type] = data
193 if md is not None:
193 if md is not None:
194 md_dict[format_type] = md
194 md_dict[format_type] = md
195 return format_dict, md_dict
195 return format_dict, md_dict
196
196
197 @property
197 @property
198 def format_types(self):
198 def format_types(self):
199 """Return the format types (MIME types) of the active formatters."""
199 """Return the format types (MIME types) of the active formatters."""
200 return list(self.formatters.keys())
200 return list(self.formatters.keys())
201
201
202
202
203 #-----------------------------------------------------------------------------
203 #-----------------------------------------------------------------------------
204 # Formatters for specific format types (text, html, svg, etc.)
204 # Formatters for specific format types (text, html, svg, etc.)
205 #-----------------------------------------------------------------------------
205 #-----------------------------------------------------------------------------
206
206
207
207
208 def _safe_repr(obj):
208 def _safe_repr(obj):
209 """Try to return a repr of an object
209 """Try to return a repr of an object
210
210
211 always returns a string, at least.
211 always returns a string, at least.
212 """
212 """
213 try:
213 try:
214 return repr(obj)
214 return repr(obj)
215 except Exception as e:
215 except Exception as e:
216 return "un-repr-able object (%r)" % e
216 return "un-repr-able object (%r)" % e
217
217
218
218
219 class FormatterWarning(UserWarning):
219 class FormatterWarning(UserWarning):
220 """Warning class for errors in formatters"""
220 """Warning class for errors in formatters"""
221
221
222 @decorator
222 @decorator
223 def catch_format_error(method, self, *args, **kwargs):
223 def catch_format_error(method, self, *args, **kwargs):
224 """show traceback on failed format call"""
224 """show traceback on failed format call"""
225 try:
225 try:
226 r = method(self, *args, **kwargs)
226 r = method(self, *args, **kwargs)
227 except NotImplementedError:
227 except NotImplementedError:
228 # don't warn on NotImplementedErrors
228 # don't warn on NotImplementedErrors
229 return self._check_return(None, args[0])
229 return self._check_return(None, args[0])
230 except Exception:
230 except Exception:
231 exc_info = sys.exc_info()
231 exc_info = sys.exc_info()
232 ip = get_ipython()
232 ip = get_ipython()
233 if ip is not None:
233 if ip is not None:
234 ip.showtraceback(exc_info)
234 ip.showtraceback(exc_info)
235 else:
235 else:
236 traceback.print_exception(*exc_info)
236 traceback.print_exception(*exc_info)
237 return self._check_return(None, args[0])
237 return self._check_return(None, args[0])
238 return self._check_return(r, args[0])
238 return self._check_return(r, args[0])
239
239
240
240
241 class FormatterABC(metaclass=abc.ABCMeta):
241 class FormatterABC(metaclass=abc.ABCMeta):
242 """ Abstract base class for Formatters.
242 """ Abstract base class for Formatters.
243
243
244 A formatter is a callable class that is responsible for computing the
244 A formatter is a callable class that is responsible for computing the
245 raw format data for a particular format type (MIME type). For example,
245 raw format data for a particular format type (MIME type). For example,
246 an HTML formatter would have a format type of `text/html` and would return
246 an HTML formatter would have a format type of `text/html` and would return
247 the HTML representation of the object when called.
247 the HTML representation of the object when called.
248 """
248 """
249
249
250 # The format type of the data returned, usually a MIME type.
250 # The format type of the data returned, usually a MIME type.
251 format_type = 'text/plain'
251 format_type = 'text/plain'
252
252
253 # Is the formatter enabled...
253 # Is the formatter enabled...
254 enabled = True
254 enabled = True
255
255
256 @abc.abstractmethod
256 @abc.abstractmethod
257 def __call__(self, obj):
257 def __call__(self, obj):
258 """Return a JSON'able representation of the object.
258 """Return a JSON'able representation of the object.
259
259
260 If the object cannot be formatted by this formatter,
260 If the object cannot be formatted by this formatter,
261 warn and return None.
261 warn and return None.
262 """
262 """
263 return repr(obj)
263 return repr(obj)
264
264
265
265
266 def _mod_name_key(typ):
266 def _mod_name_key(typ):
267 """Return a (__module__, __name__) tuple for a type.
267 """Return a (__module__, __name__) tuple for a type.
268
268
269 Used as key in Formatter.deferred_printers.
269 Used as key in Formatter.deferred_printers.
270 """
270 """
271 module = getattr(typ, '__module__', None)
271 module = getattr(typ, '__module__', None)
272 name = getattr(typ, '__name__', None)
272 name = getattr(typ, '__name__', None)
273 return (module, name)
273 return (module, name)
274
274
275
275
276 def _get_type(obj):
276 def _get_type(obj):
277 """Return the type of an instance (old and new-style)"""
277 """Return the type of an instance (old and new-style)"""
278 return getattr(obj, '__class__', None) or type(obj)
278 return getattr(obj, '__class__', None) or type(obj)
279
279
280
280
281 _raise_key_error = Sentinel('_raise_key_error', __name__,
281 _raise_key_error = Sentinel('_raise_key_error', __name__,
282 """
282 """
283 Special value to raise a KeyError
283 Special value to raise a KeyError
284
284
285 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
285 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
286 """)
286 """)
287
287
288
288
289 class BaseFormatter(Configurable):
289 class BaseFormatter(Configurable):
290 """A base formatter class that is configurable.
290 """A base formatter class that is configurable.
291
291
292 This formatter should usually be used as the base class of all formatters.
292 This formatter should usually be used as the base class of all formatters.
293 It is a traited :class:`Configurable` class and includes an extensible
293 It is a traited :class:`Configurable` class and includes an extensible
294 API for users to determine how their objects are formatted. The following
294 API for users to determine how their objects are formatted. The following
295 logic is used to find a function to format an given object.
295 logic is used to find a function to format an given object.
296
296
297 1. The object is introspected to see if it has a method with the name
297 1. The object is introspected to see if it has a method with the name
298 :attr:`print_method`. If is does, that object is passed to that method
298 :attr:`print_method`. If is does, that object is passed to that method
299 for formatting.
299 for formatting.
300 2. If no print method is found, three internal dictionaries are consulted
300 2. If no print method is found, three internal dictionaries are consulted
301 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
301 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
302 and :attr:`deferred_printers`.
302 and :attr:`deferred_printers`.
303
303
304 Users should use these dictionaries to register functions that will be
304 Users should use these dictionaries to register functions that will be
305 used to compute the format data for their objects (if those objects don't
305 used to compute the format data for their objects (if those objects don't
306 have the special print methods). The easiest way of using these
306 have the special print methods). The easiest way of using these
307 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
307 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
308 methods.
308 methods.
309
309
310 If no function/callable is found to compute the format data, ``None`` is
310 If no function/callable is found to compute the format data, ``None`` is
311 returned and this format type is not used.
311 returned and this format type is not used.
312 """
312 """
313
313
314 format_type = Unicode("text/plain")
314 format_type = Unicode("text/plain")
315 _return_type: Any = str
315 _return_type: Any = str
316
316
317 enabled = Bool(True).tag(config=True)
317 enabled = Bool(True).tag(config=True)
318
318
319 print_method = ObjectName('__repr__')
319 print_method = ObjectName('__repr__')
320
320
321 # The singleton printers.
321 # The singleton printers.
322 # Maps the IDs of the builtin singleton objects to the format functions.
322 # Maps the IDs of the builtin singleton objects to the format functions.
323 singleton_printers = Dict().tag(config=True)
323 singleton_printers = Dict().tag(config=True)
324
324
325 # The type-specific printers.
325 # The type-specific printers.
326 # Map type objects to the format functions.
326 # Map type objects to the format functions.
327 type_printers = Dict().tag(config=True)
327 type_printers = Dict().tag(config=True)
328
328
329 # The deferred-import type-specific printers.
329 # The deferred-import type-specific printers.
330 # Map (modulename, classname) pairs to the format functions.
330 # Map (modulename, classname) pairs to the format functions.
331 deferred_printers = Dict().tag(config=True)
331 deferred_printers = Dict().tag(config=True)
332
332
333 @catch_format_error
333 @catch_format_error
334 def __call__(self, obj):
334 def __call__(self, obj):
335 """Compute the format for an object."""
335 """Compute the format for an object."""
336 if self.enabled:
336 if self.enabled:
337 # lookup registered printer
337 # lookup registered printer
338 try:
338 try:
339 printer = self.lookup(obj)
339 printer = self.lookup(obj)
340 except KeyError:
340 except KeyError:
341 pass
341 pass
342 else:
342 else:
343 return printer(obj)
343 return printer(obj)
344 # Finally look for special method names
344 # Finally look for special method names
345 method = get_real_method(obj, self.print_method)
345 method = get_real_method(obj, self.print_method)
346 if method is not None:
346 if method is not None:
347 return method()
347 return method()
348 return None
348 return None
349 else:
349 else:
350 return None
350 return None
351
351
352 def __contains__(self, typ):
352 def __contains__(self, typ):
353 """map in to lookup_by_type"""
353 """map in to lookup_by_type"""
354 try:
354 try:
355 self.lookup_by_type(typ)
355 self.lookup_by_type(typ)
356 except KeyError:
356 except KeyError:
357 return False
357 return False
358 else:
358 else:
359 return True
359 return True
360
360
361 def _check_return(self, r, obj):
361 def _check_return(self, r, obj):
362 """Check that a return value is appropriate
362 """Check that a return value is appropriate
363
363
364 Return the value if so, None otherwise, warning if invalid.
364 Return the value if so, None otherwise, warning if invalid.
365 """
365 """
366 if r is None or isinstance(r, self._return_type) or \
366 if r is None or isinstance(r, self._return_type) or \
367 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
367 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
368 return r
368 return r
369 else:
369 else:
370 warnings.warn(
370 warnings.warn(
371 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
371 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
372 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
372 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
373 FormatterWarning
373 FormatterWarning
374 )
374 )
375
375
376 def lookup(self, obj):
376 def lookup(self, obj):
377 """Look up the formatter for a given instance.
377 """Look up the formatter for a given instance.
378
378
379 Parameters
379 Parameters
380 ----------
380 ----------
381 obj : object instance
381 obj : object instance
382
382
383 Returns
383 Returns
384 -------
384 -------
385 f : callable
385 f : callable
386 The registered formatting callable for the type.
386 The registered formatting callable for the type.
387
387
388 Raises
388 Raises
389 ------
389 ------
390 KeyError if the type has not been registered.
390 KeyError if the type has not been registered.
391 """
391 """
392 # look for singleton first
392 # look for singleton first
393 obj_id = id(obj)
393 obj_id = id(obj)
394 if obj_id in self.singleton_printers:
394 if obj_id in self.singleton_printers:
395 return self.singleton_printers[obj_id]
395 return self.singleton_printers[obj_id]
396 # then lookup by type
396 # then lookup by type
397 return self.lookup_by_type(_get_type(obj))
397 return self.lookup_by_type(_get_type(obj))
398
398
399 def lookup_by_type(self, typ):
399 def lookup_by_type(self, typ):
400 """Look up the registered formatter for a type.
400 """Look up the registered formatter for a type.
401
401
402 Parameters
402 Parameters
403 ----------
403 ----------
404 typ : type or '__module__.__name__' string for a type
404 typ : type or '__module__.__name__' string for a type
405
405
406 Returns
406 Returns
407 -------
407 -------
408 f : callable
408 f : callable
409 The registered formatting callable for the type.
409 The registered formatting callable for the type.
410
410
411 Raises
411 Raises
412 ------
412 ------
413 KeyError if the type has not been registered.
413 KeyError if the type has not been registered.
414 """
414 """
415 if isinstance(typ, str):
415 if isinstance(typ, str):
416 typ_key = tuple(typ.rsplit('.',1))
416 typ_key = tuple(typ.rsplit('.',1))
417 if typ_key not in self.deferred_printers:
417 if typ_key not in self.deferred_printers:
418 # We may have it cached in the type map. We will have to
418 # We may have it cached in the type map. We will have to
419 # iterate over all of the types to check.
419 # iterate over all of the types to check.
420 for cls in self.type_printers:
420 for cls in self.type_printers:
421 if _mod_name_key(cls) == typ_key:
421 if _mod_name_key(cls) == typ_key:
422 return self.type_printers[cls]
422 return self.type_printers[cls]
423 else:
423 else:
424 return self.deferred_printers[typ_key]
424 return self.deferred_printers[typ_key]
425 else:
425 else:
426 for cls in pretty._get_mro(typ):
426 for cls in pretty._get_mro(typ):
427 if cls in self.type_printers or self._in_deferred_types(cls):
427 if cls in self.type_printers or self._in_deferred_types(cls):
428 return self.type_printers[cls]
428 return self.type_printers[cls]
429
429
430 # If we have reached here, the lookup failed.
430 # If we have reached here, the lookup failed.
431 raise KeyError("No registered printer for {0!r}".format(typ))
431 raise KeyError("No registered printer for {0!r}".format(typ))
432
432
433 def for_type(self, typ, func=None):
433 def for_type(self, typ, func=None):
434 """Add a format function for a given type.
434 """Add a format function for a given type.
435
435
436 Parameters
436 Parameters
437 ----------
437 ----------
438 typ : type or '__module__.__name__' string for a type
438 typ : type or '__module__.__name__' string for a type
439 The class of the object that will be formatted using `func`.
439 The class of the object that will be formatted using `func`.
440
440
441 func : callable
441 func : callable
442 A callable for computing the format data.
442 A callable for computing the format data.
443 `func` will be called with the object to be formatted,
443 `func` will be called with the object to be formatted,
444 and will return the raw data in this formatter's format.
444 and will return the raw data in this formatter's format.
445 Subclasses may use a different call signature for the
445 Subclasses may use a different call signature for the
446 `func` argument.
446 `func` argument.
447
447
448 If `func` is None or not specified, there will be no change,
448 If `func` is None or not specified, there will be no change,
449 only returning the current value.
449 only returning the current value.
450
450
451 Returns
451 Returns
452 -------
452 -------
453 oldfunc : callable
453 oldfunc : callable
454 The currently registered callable.
454 The currently registered callable.
455 If you are registering a new formatter,
455 If you are registering a new formatter,
456 this will be the previous value (to enable restoring later).
456 this will be the previous value (to enable restoring later).
457 """
457 """
458 # if string given, interpret as 'pkg.module.class_name'
458 # if string given, interpret as 'pkg.module.class_name'
459 if isinstance(typ, str):
459 if isinstance(typ, str):
460 type_module, type_name = typ.rsplit('.', 1)
460 type_module, type_name = typ.rsplit('.', 1)
461 return self.for_type_by_name(type_module, type_name, func)
461 return self.for_type_by_name(type_module, type_name, func)
462
462
463 try:
463 try:
464 oldfunc = self.lookup_by_type(typ)
464 oldfunc = self.lookup_by_type(typ)
465 except KeyError:
465 except KeyError:
466 oldfunc = None
466 oldfunc = None
467
467
468 if func is not None:
468 if func is not None:
469 self.type_printers[typ] = func
469 self.type_printers[typ] = func
470
470
471 return oldfunc
471 return oldfunc
472
472
473 def for_type_by_name(self, type_module, type_name, func=None):
473 def for_type_by_name(self, type_module, type_name, func=None):
474 """Add a format function for a type specified by the full dotted
474 """Add a format function for a type specified by the full dotted
475 module and name of the type, rather than the type of the object.
475 module and name of the type, rather than the type of the object.
476
476
477 Parameters
477 Parameters
478 ----------
478 ----------
479 type_module : str
479 type_module : str
480 The full dotted name of the module the type is defined in, like
480 The full dotted name of the module the type is defined in, like
481 ``numpy``.
481 ``numpy``.
482
482
483 type_name : str
483 type_name : str
484 The name of the type (the class name), like ``dtype``
484 The name of the type (the class name), like ``dtype``
485
485
486 func : callable
486 func : callable
487 A callable for computing the format data.
487 A callable for computing the format data.
488 `func` will be called with the object to be formatted,
488 `func` will be called with the object to be formatted,
489 and will return the raw data in this formatter's format.
489 and will return the raw data in this formatter's format.
490 Subclasses may use a different call signature for the
490 Subclasses may use a different call signature for the
491 `func` argument.
491 `func` argument.
492
492
493 If `func` is None or unspecified, there will be no change,
493 If `func` is None or unspecified, there will be no change,
494 only returning the current value.
494 only returning the current value.
495
495
496 Returns
496 Returns
497 -------
497 -------
498 oldfunc : callable
498 oldfunc : callable
499 The currently registered callable.
499 The currently registered callable.
500 If you are registering a new formatter,
500 If you are registering a new formatter,
501 this will be the previous value (to enable restoring later).
501 this will be the previous value (to enable restoring later).
502 """
502 """
503 key = (type_module, type_name)
503 key = (type_module, type_name)
504
504
505 try:
505 try:
506 oldfunc = self.lookup_by_type("%s.%s" % key)
506 oldfunc = self.lookup_by_type("%s.%s" % key)
507 except KeyError:
507 except KeyError:
508 oldfunc = None
508 oldfunc = None
509
509
510 if func is not None:
510 if func is not None:
511 self.deferred_printers[key] = func
511 self.deferred_printers[key] = func
512 return oldfunc
512 return oldfunc
513
513
514 def pop(self, typ, default=_raise_key_error):
514 def pop(self, typ, default=_raise_key_error):
515 """Pop a formatter for the given type.
515 """Pop a formatter for the given type.
516
516
517 Parameters
517 Parameters
518 ----------
518 ----------
519 typ : type or '__module__.__name__' string for a type
519 typ : type or '__module__.__name__' string for a type
520 default : object
520 default : object
521 value to be returned if no formatter is registered for typ.
521 value to be returned if no formatter is registered for typ.
522
522
523 Returns
523 Returns
524 -------
524 -------
525 obj : object
525 obj : object
526 The last registered object for the type.
526 The last registered object for the type.
527
527
528 Raises
528 Raises
529 ------
529 ------
530 KeyError if the type is not registered and default is not specified.
530 KeyError if the type is not registered and default is not specified.
531 """
531 """
532
532
533 if isinstance(typ, str):
533 if isinstance(typ, str):
534 typ_key = tuple(typ.rsplit('.',1))
534 typ_key = tuple(typ.rsplit('.',1))
535 if typ_key not in self.deferred_printers:
535 if typ_key not in self.deferred_printers:
536 # We may have it cached in the type map. We will have to
536 # We may have it cached in the type map. We will have to
537 # iterate over all of the types to check.
537 # iterate over all of the types to check.
538 for cls in self.type_printers:
538 for cls in self.type_printers:
539 if _mod_name_key(cls) == typ_key:
539 if _mod_name_key(cls) == typ_key:
540 old = self.type_printers.pop(cls)
540 old = self.type_printers.pop(cls)
541 break
541 break
542 else:
542 else:
543 old = default
543 old = default
544 else:
544 else:
545 old = self.deferred_printers.pop(typ_key)
545 old = self.deferred_printers.pop(typ_key)
546 else:
546 else:
547 if typ in self.type_printers:
547 if typ in self.type_printers:
548 old = self.type_printers.pop(typ)
548 old = self.type_printers.pop(typ)
549 else:
549 else:
550 old = self.deferred_printers.pop(_mod_name_key(typ), default)
550 old = self.deferred_printers.pop(_mod_name_key(typ), default)
551 if old is _raise_key_error:
551 if old is _raise_key_error:
552 raise KeyError("No registered value for {0!r}".format(typ))
552 raise KeyError("No registered value for {0!r}".format(typ))
553 return old
553 return old
554
554
555 def _in_deferred_types(self, cls):
555 def _in_deferred_types(self, cls):
556 """
556 """
557 Check if the given class is specified in the deferred type registry.
557 Check if the given class is specified in the deferred type registry.
558
558
559 Successful matches will be moved to the regular type registry for future use.
559 Successful matches will be moved to the regular type registry for future use.
560 """
560 """
561 mod = getattr(cls, '__module__', None)
561 mod = getattr(cls, '__module__', None)
562 name = getattr(cls, '__name__', None)
562 name = getattr(cls, '__name__', None)
563 key = (mod, name)
563 key = (mod, name)
564 if key in self.deferred_printers:
564 if key in self.deferred_printers:
565 # Move the printer over to the regular registry.
565 # Move the printer over to the regular registry.
566 printer = self.deferred_printers.pop(key)
566 printer = self.deferred_printers.pop(key)
567 self.type_printers[cls] = printer
567 self.type_printers[cls] = printer
568 return True
568 return True
569 return False
569 return False
570
570
571
571
572 class PlainTextFormatter(BaseFormatter):
572 class PlainTextFormatter(BaseFormatter):
573 """The default pretty-printer.
573 """The default pretty-printer.
574
574
575 This uses :mod:`IPython.lib.pretty` to compute the format data of
575 This uses :mod:`IPython.lib.pretty` to compute the format data of
576 the object. If the object cannot be pretty printed, :func:`repr` is used.
576 the object. If the object cannot be pretty printed, :func:`repr` is used.
577 See the documentation of :mod:`IPython.lib.pretty` for details on
577 See the documentation of :mod:`IPython.lib.pretty` for details on
578 how to write pretty printers. Here is a simple example::
578 how to write pretty printers. Here is a simple example::
579
579
580 def dtype_pprinter(obj, p, cycle):
580 def dtype_pprinter(obj, p, cycle):
581 if cycle:
581 if cycle:
582 return p.text('dtype(...)')
582 return p.text('dtype(...)')
583 if hasattr(obj, 'fields'):
583 if hasattr(obj, 'fields'):
584 if obj.fields is None:
584 if obj.fields is None:
585 p.text(repr(obj))
585 p.text(repr(obj))
586 else:
586 else:
587 p.begin_group(7, 'dtype([')
587 p.begin_group(7, 'dtype([')
588 for i, field in enumerate(obj.descr):
588 for i, field in enumerate(obj.descr):
589 if i > 0:
589 if i > 0:
590 p.text(',')
590 p.text(',')
591 p.breakable()
591 p.breakable()
592 p.pretty(field)
592 p.pretty(field)
593 p.end_group(7, '])')
593 p.end_group(7, '])')
594 """
594 """
595
595
596 # The format type of data returned.
596 # The format type of data returned.
597 format_type = Unicode('text/plain')
597 format_type = Unicode('text/plain')
598
598
599 # This subclass ignores this attribute as it always need to return
599 # This subclass ignores this attribute as it always need to return
600 # something.
600 # something.
601 enabled = Bool(True).tag(config=False)
601 enabled = Bool(True).tag(config=False)
602
602
603 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH,
603 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH,
604 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
604 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
605
605
606 Set to 0 to disable truncation.
606 Set to 0 to disable truncation.
607 """
607 """
608 ).tag(config=True)
608 ).tag(config=True)
609
609
610 # Look for a _repr_pretty_ methods to use for pretty printing.
610 # Look for a _repr_pretty_ methods to use for pretty printing.
611 print_method = ObjectName('_repr_pretty_')
611 print_method = ObjectName('_repr_pretty_')
612
612
613 # Whether to pretty-print or not.
613 # Whether to pretty-print or not.
614 pprint = Bool(True).tag(config=True)
614 pprint = Bool(True).tag(config=True)
615
615
616 # Whether to be verbose or not.
616 # Whether to be verbose or not.
617 verbose = Bool(False).tag(config=True)
617 verbose = Bool(False).tag(config=True)
618
618
619 # The maximum width.
619 # The maximum width.
620 max_width = Integer(79).tag(config=True)
620 max_width = Integer(79).tag(config=True)
621
621
622 # The newline character.
622 # The newline character.
623 newline = Unicode('\n').tag(config=True)
623 newline = Unicode('\n').tag(config=True)
624
624
625 # format-string for pprinting floats
625 # format-string for pprinting floats
626 float_format = Unicode('%r')
626 float_format = Unicode('%r')
627 # setter for float precision, either int or direct format-string
627 # setter for float precision, either int or direct format-string
628 float_precision = CUnicode('').tag(config=True)
628 float_precision = CUnicode('').tag(config=True)
629
629
630 @observe('float_precision')
630 @observe('float_precision')
631 def _float_precision_changed(self, change):
631 def _float_precision_changed(self, change):
632 """float_precision changed, set float_format accordingly.
632 """float_precision changed, set float_format accordingly.
633
633
634 float_precision can be set by int or str.
634 float_precision can be set by int or str.
635 This will set float_format, after interpreting input.
635 This will set float_format, after interpreting input.
636 If numpy has been imported, numpy print precision will also be set.
636 If numpy has been imported, numpy print precision will also be set.
637
637
638 integer `n` sets format to '%.nf', otherwise, format set directly.
638 integer `n` sets format to '%.nf', otherwise, format set directly.
639
639
640 An empty string returns to defaults (repr for float, 8 for numpy).
640 An empty string returns to defaults (repr for float, 8 for numpy).
641
641
642 This parameter can be set via the '%precision' magic.
642 This parameter can be set via the '%precision' magic.
643 """
643 """
644 new = change['new']
644 new = change['new']
645 if '%' in new:
645 if '%' in new:
646 # got explicit format string
646 # got explicit format string
647 fmt = new
647 fmt = new
648 try:
648 try:
649 fmt%3.14159
649 fmt%3.14159
650 except Exception as e:
650 except Exception as e:
651 raise ValueError("Precision must be int or format string, not %r"%new) from e
651 raise ValueError("Precision must be int or format string, not %r"%new) from e
652 elif new:
652 elif new:
653 # otherwise, should be an int
653 # otherwise, should be an int
654 try:
654 try:
655 i = int(new)
655 i = int(new)
656 assert i >= 0
656 assert i >= 0
657 except ValueError as e:
657 except ValueError as e:
658 raise ValueError("Precision must be int or format string, not %r"%new) from e
658 raise ValueError("Precision must be int or format string, not %r"%new) from e
659 except AssertionError as e:
659 except AssertionError as e:
660 raise ValueError("int precision must be non-negative, not %r"%i) from e
660 raise ValueError("int precision must be non-negative, not %r"%i) from e
661
661
662 fmt = '%%.%if'%i
662 fmt = '%%.%if'%i
663 if 'numpy' in sys.modules:
663 if 'numpy' in sys.modules:
664 # set numpy precision if it has been imported
664 # set numpy precision if it has been imported
665 import numpy
665 import numpy
666 numpy.set_printoptions(precision=i)
666 numpy.set_printoptions(precision=i)
667 else:
667 else:
668 # default back to repr
668 # default back to repr
669 fmt = '%r'
669 fmt = '%r'
670 if 'numpy' in sys.modules:
670 if 'numpy' in sys.modules:
671 import numpy
671 import numpy
672 # numpy default is 8
672 # numpy default is 8
673 numpy.set_printoptions(precision=8)
673 numpy.set_printoptions(precision=8)
674 self.float_format = fmt
674 self.float_format = fmt
675
675
676 # Use the default pretty printers from IPython.lib.pretty.
676 # Use the default pretty printers from IPython.lib.pretty.
677 @default('singleton_printers')
677 @default('singleton_printers')
678 def _singleton_printers_default(self):
678 def _singleton_printers_default(self):
679 return pretty._singleton_pprinters.copy()
679 return pretty._singleton_pprinters.copy()
680
680
681 @default('type_printers')
681 @default('type_printers')
682 def _type_printers_default(self):
682 def _type_printers_default(self):
683 d = pretty._type_pprinters.copy()
683 d = pretty._type_pprinters.copy()
684 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
684 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
685 # if NumPy is used, set precision for its float64 type
685 # if NumPy is used, set precision for its float64 type
686 if "numpy" in sys.modules:
686 if "numpy" in sys.modules:
687 import numpy
687 import numpy
688
688
689 d[numpy.float64] = lambda obj, p, cycle: p.text(self.float_format % obj)
689 d[numpy.float64] = lambda obj, p, cycle: p.text(self.float_format % obj)
690 return d
690 return d
691
691
692 @default('deferred_printers')
692 @default('deferred_printers')
693 def _deferred_printers_default(self):
693 def _deferred_printers_default(self):
694 return pretty._deferred_type_pprinters.copy()
694 return pretty._deferred_type_pprinters.copy()
695
695
696 #### FormatterABC interface ####
696 #### FormatterABC interface ####
697
697
698 @catch_format_error
698 @catch_format_error
699 def __call__(self, obj):
699 def __call__(self, obj):
700 """Compute the pretty representation of the object."""
700 """Compute the pretty representation of the object."""
701 if not self.pprint:
701 if not self.pprint:
702 return repr(obj)
702 return repr(obj)
703 else:
703 else:
704 stream = StringIO()
704 stream = StringIO()
705 printer = pretty.RepresentationPrinter(stream, self.verbose,
705 printer = pretty.RepresentationPrinter(stream, self.verbose,
706 self.max_width, self.newline,
706 self.max_width, self.newline,
707 max_seq_length=self.max_seq_length,
707 max_seq_length=self.max_seq_length,
708 singleton_pprinters=self.singleton_printers,
708 singleton_pprinters=self.singleton_printers,
709 type_pprinters=self.type_printers,
709 type_pprinters=self.type_printers,
710 deferred_pprinters=self.deferred_printers)
710 deferred_pprinters=self.deferred_printers)
711 printer.pretty(obj)
711 printer.pretty(obj)
712 printer.flush()
712 printer.flush()
713 return stream.getvalue()
713 return stream.getvalue()
714
714
715
715
716 class HTMLFormatter(BaseFormatter):
716 class HTMLFormatter(BaseFormatter):
717 """An HTML formatter.
717 """An HTML formatter.
718
718
719 To define the callables that compute the HTML representation of your
719 To define the callables that compute the HTML representation of your
720 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
720 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
721 or :meth:`for_type_by_name` methods to register functions that handle
721 or :meth:`for_type_by_name` methods to register functions that handle
722 this.
722 this.
723
723
724 The return value of this formatter should be a valid HTML snippet that
724 The return value of this formatter should be a valid HTML snippet that
725 could be injected into an existing DOM. It should *not* include the
725 could be injected into an existing DOM. It should *not* include the
726 ```<html>`` or ```<body>`` tags.
726 ```<html>`` or ```<body>`` tags.
727 """
727 """
728 format_type = Unicode('text/html')
728 format_type = Unicode('text/html')
729
729
730 print_method = ObjectName('_repr_html_')
730 print_method = ObjectName('_repr_html_')
731
731
732
732
733 class MarkdownFormatter(BaseFormatter):
733 class MarkdownFormatter(BaseFormatter):
734 """A Markdown formatter.
734 """A Markdown formatter.
735
735
736 To define the callables that compute the Markdown representation of your
736 To define the callables that compute the Markdown representation of your
737 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
737 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
738 or :meth:`for_type_by_name` methods to register functions that handle
738 or :meth:`for_type_by_name` methods to register functions that handle
739 this.
739 this.
740
740
741 The return value of this formatter should be a valid Markdown.
741 The return value of this formatter should be a valid Markdown.
742 """
742 """
743 format_type = Unicode('text/markdown')
743 format_type = Unicode('text/markdown')
744
744
745 print_method = ObjectName('_repr_markdown_')
745 print_method = ObjectName('_repr_markdown_')
746
746
747 class SVGFormatter(BaseFormatter):
747 class SVGFormatter(BaseFormatter):
748 """An SVG formatter.
748 """An SVG formatter.
749
749
750 To define the callables that compute the SVG representation of your
750 To define the callables that compute the SVG representation of your
751 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
751 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
752 or :meth:`for_type_by_name` methods to register functions that handle
752 or :meth:`for_type_by_name` methods to register functions that handle
753 this.
753 this.
754
754
755 The return value of this formatter should be valid SVG enclosed in
755 The return value of this formatter should be valid SVG enclosed in
756 ```<svg>``` tags, that could be injected into an existing DOM. It should
756 ```<svg>``` tags, that could be injected into an existing DOM. It should
757 *not* include the ```<html>`` or ```<body>`` tags.
757 *not* include the ```<html>`` or ```<body>`` tags.
758 """
758 """
759 format_type = Unicode('image/svg+xml')
759 format_type = Unicode('image/svg+xml')
760
760
761 print_method = ObjectName('_repr_svg_')
761 print_method = ObjectName('_repr_svg_')
762
762
763
763
764 class PNGFormatter(BaseFormatter):
764 class PNGFormatter(BaseFormatter):
765 """A PNG formatter.
765 """A PNG formatter.
766
766
767 To define the callables that compute the PNG representation of your
767 To define the callables that compute the PNG representation of your
768 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
768 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
769 or :meth:`for_type_by_name` methods to register functions that handle
769 or :meth:`for_type_by_name` methods to register functions that handle
770 this.
770 this.
771
771
772 The return value of this formatter should be raw PNG data, *not*
772 The return value of this formatter should be raw PNG data, *not*
773 base64 encoded.
773 base64 encoded.
774 """
774 """
775 format_type = Unicode('image/png')
775 format_type = Unicode('image/png')
776
776
777 print_method = ObjectName('_repr_png_')
777 print_method = ObjectName('_repr_png_')
778
778
779 _return_type = (bytes, str)
779 _return_type = (bytes, str)
780
780
781
781
782 class JPEGFormatter(BaseFormatter):
782 class JPEGFormatter(BaseFormatter):
783 """A JPEG formatter.
783 """A JPEG formatter.
784
784
785 To define the callables that compute the JPEG representation of your
785 To define the callables that compute the JPEG representation of your
786 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
786 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
787 or :meth:`for_type_by_name` methods to register functions that handle
787 or :meth:`for_type_by_name` methods to register functions that handle
788 this.
788 this.
789
789
790 The return value of this formatter should be raw JPEG data, *not*
790 The return value of this formatter should be raw JPEG data, *not*
791 base64 encoded.
791 base64 encoded.
792 """
792 """
793 format_type = Unicode('image/jpeg')
793 format_type = Unicode('image/jpeg')
794
794
795 print_method = ObjectName('_repr_jpeg_')
795 print_method = ObjectName('_repr_jpeg_')
796
796
797 _return_type = (bytes, str)
797 _return_type = (bytes, str)
798
798
799
799
800 class LatexFormatter(BaseFormatter):
800 class LatexFormatter(BaseFormatter):
801 """A LaTeX formatter.
801 """A LaTeX formatter.
802
802
803 To define the callables that compute the LaTeX representation of your
803 To define the callables that compute the LaTeX representation of your
804 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
804 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
805 or :meth:`for_type_by_name` methods to register functions that handle
805 or :meth:`for_type_by_name` methods to register functions that handle
806 this.
806 this.
807
807
808 The return value of this formatter should be a valid LaTeX equation,
808 The return value of this formatter should be a valid LaTeX equation,
809 enclosed in either ```$```, ```$$``` or another LaTeX equation
809 enclosed in either ```$```, ```$$``` or another LaTeX equation
810 environment.
810 environment.
811 """
811 """
812 format_type = Unicode('text/latex')
812 format_type = Unicode('text/latex')
813
813
814 print_method = ObjectName('_repr_latex_')
814 print_method = ObjectName('_repr_latex_')
815
815
816
816
817 class JSONFormatter(BaseFormatter):
817 class JSONFormatter(BaseFormatter):
818 """A JSON string formatter.
818 """A JSON string formatter.
819
819
820 To define the callables that compute the JSONable representation of
820 To define the callables that compute the JSONable representation of
821 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
821 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
822 or :meth:`for_type_by_name` methods to register functions that handle
822 or :meth:`for_type_by_name` methods to register functions that handle
823 this.
823 this.
824
824
825 The return value of this formatter should be a JSONable list or dict.
825 The return value of this formatter should be a JSONable list or dict.
826 JSON scalars (None, number, string) are not allowed, only dict or list containers.
826 JSON scalars (None, number, string) are not allowed, only dict or list containers.
827 """
827 """
828 format_type = Unicode('application/json')
828 format_type = Unicode('application/json')
829 _return_type = (list, dict)
829 _return_type = (list, dict)
830
830
831 print_method = ObjectName('_repr_json_')
831 print_method = ObjectName('_repr_json_')
832
832
833 def _check_return(self, r, obj):
833 def _check_return(self, r, obj):
834 """Check that a return value is appropriate
834 """Check that a return value is appropriate
835
835
836 Return the value if so, None otherwise, warning if invalid.
836 Return the value if so, None otherwise, warning if invalid.
837 """
837 """
838 if r is None:
838 if r is None:
839 return
839 return
840 md = None
840 md = None
841 if isinstance(r, tuple):
841 if isinstance(r, tuple):
842 # unpack data, metadata tuple for type checking on first element
842 # unpack data, metadata tuple for type checking on first element
843 r, md = r
843 r, md = r
844
844
845 assert not isinstance(
845 assert not isinstance(
846 r, str
846 r, str
847 ), "JSON-as-string has been deprecated since IPython < 3"
847 ), "JSON-as-string has been deprecated since IPython < 3"
848
848
849 if md is not None:
849 if md is not None:
850 # put the tuple back together
850 # put the tuple back together
851 r = (r, md)
851 r = (r, md)
852 return super(JSONFormatter, self)._check_return(r, obj)
852 return super(JSONFormatter, self)._check_return(r, obj)
853
853
854
854
855 class JavascriptFormatter(BaseFormatter):
855 class JavascriptFormatter(BaseFormatter):
856 """A Javascript formatter.
856 """A Javascript formatter.
857
857
858 To define the callables that compute the Javascript representation of
858 To define the callables that compute the Javascript representation of
859 your objects, define a :meth:`_repr_javascript_` method or use the
859 your objects, define a :meth:`_repr_javascript_` method or use the
860 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
860 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
861 that handle this.
861 that handle this.
862
862
863 The return value of this formatter should be valid Javascript code and
863 The return value of this formatter should be valid Javascript code and
864 should *not* be enclosed in ```<script>``` tags.
864 should *not* be enclosed in ```<script>``` tags.
865 """
865 """
866 format_type = Unicode('application/javascript')
866 format_type = Unicode('application/javascript')
867
867
868 print_method = ObjectName('_repr_javascript_')
868 print_method = ObjectName('_repr_javascript_')
869
869
870
870
871 class PDFFormatter(BaseFormatter):
871 class PDFFormatter(BaseFormatter):
872 """A PDF formatter.
872 """A PDF formatter.
873
873
874 To define the callables that compute the PDF representation of your
874 To define the callables that compute the PDF representation of your
875 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
875 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
876 or :meth:`for_type_by_name` methods to register functions that handle
876 or :meth:`for_type_by_name` methods to register functions that handle
877 this.
877 this.
878
878
879 The return value of this formatter should be raw PDF data, *not*
879 The return value of this formatter should be raw PDF data, *not*
880 base64 encoded.
880 base64 encoded.
881 """
881 """
882 format_type = Unicode('application/pdf')
882 format_type = Unicode('application/pdf')
883
883
884 print_method = ObjectName('_repr_pdf_')
884 print_method = ObjectName('_repr_pdf_')
885
885
886 _return_type = (bytes, str)
886 _return_type = (bytes, str)
887
887
888 class IPythonDisplayFormatter(BaseFormatter):
888 class IPythonDisplayFormatter(BaseFormatter):
889 """An escape-hatch Formatter for objects that know how to display themselves.
889 """An escape-hatch Formatter for objects that know how to display themselves.
890
890
891 To define the callables that compute the representation of your
891 To define the callables that compute the representation of your
892 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
892 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
893 or :meth:`for_type_by_name` methods to register functions that handle
893 or :meth:`for_type_by_name` methods to register functions that handle
894 this. Unlike mime-type displays, this method should not return anything,
894 this. Unlike mime-type displays, this method should not return anything,
895 instead calling any appropriate display methods itself.
895 instead calling any appropriate display methods itself.
896
896
897 This display formatter has highest priority.
897 This display formatter has highest priority.
898 If it fires, no other display formatter will be called.
898 If it fires, no other display formatter will be called.
899
899
900 Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types
900 Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types
901 without registering a new Formatter.
901 without registering a new Formatter.
902
902
903 IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types,
903 IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types,
904 so `_ipython_display_` should only be used for objects that require unusual
904 so `_ipython_display_` should only be used for objects that require unusual
905 display patterns, such as multiple display calls.
905 display patterns, such as multiple display calls.
906 """
906 """
907 print_method = ObjectName('_ipython_display_')
907 print_method = ObjectName('_ipython_display_')
908 _return_type = (type(None), bool)
908 _return_type = (type(None), bool)
909
909
910 @catch_format_error
910 @catch_format_error
911 def __call__(self, obj):
911 def __call__(self, obj):
912 """Compute the format for an object."""
912 """Compute the format for an object."""
913 if self.enabled:
913 if self.enabled:
914 # lookup registered printer
914 # lookup registered printer
915 try:
915 try:
916 printer = self.lookup(obj)
916 printer = self.lookup(obj)
917 except KeyError:
917 except KeyError:
918 pass
918 pass
919 else:
919 else:
920 printer(obj)
920 printer(obj)
921 return True
921 return True
922 # Finally look for special method names
922 # Finally look for special method names
923 method = get_real_method(obj, self.print_method)
923 method = get_real_method(obj, self.print_method)
924 if method is not None:
924 if method is not None:
925 method()
925 method()
926 return True
926 return True
927
927
928
928
929 class MimeBundleFormatter(BaseFormatter):
929 class MimeBundleFormatter(BaseFormatter):
930 """A Formatter for arbitrary mime-types.
930 """A Formatter for arbitrary mime-types.
931
931
932 Unlike other `_repr_<mimetype>_` methods,
932 Unlike other `_repr_<mimetype>_` methods,
933 `_repr_mimebundle_` should return mime-bundle data,
933 `_repr_mimebundle_` should return mime-bundle data,
934 either the mime-keyed `data` dictionary or the tuple `(data, metadata)`.
934 either the mime-keyed `data` dictionary or the tuple `(data, metadata)`.
935 Any mime-type is valid.
935 Any mime-type is valid.
936
936
937 To define the callables that compute the mime-bundle representation of your
937 To define the callables that compute the mime-bundle representation of your
938 objects, define a :meth:`_repr_mimebundle_` method or use the :meth:`for_type`
938 objects, define a :meth:`_repr_mimebundle_` method or use the :meth:`for_type`
939 or :meth:`for_type_by_name` methods to register functions that handle
939 or :meth:`for_type_by_name` methods to register functions that handle
940 this.
940 this.
941
941
942 .. versionadded:: 6.1
942 .. versionadded:: 6.1
943 """
943 """
944 print_method = ObjectName('_repr_mimebundle_')
944 print_method = ObjectName('_repr_mimebundle_')
945 _return_type = dict
945 _return_type = dict
946
946
947 def _check_return(self, r, obj):
947 def _check_return(self, r, obj):
948 r = super(MimeBundleFormatter, self)._check_return(r, obj)
948 r = super(MimeBundleFormatter, self)._check_return(r, obj)
949 # always return (data, metadata):
949 # always return (data, metadata):
950 if r is None:
950 if r is None:
951 return {}, {}
951 return {}, {}
952 if not isinstance(r, tuple):
952 if not isinstance(r, tuple):
953 return r, {}
953 return r, {}
954 return r
954 return r
955
955
956 @catch_format_error
956 @catch_format_error
957 def __call__(self, obj, include=None, exclude=None):
957 def __call__(self, obj, include=None, exclude=None):
958 """Compute the format for an object.
958 """Compute the format for an object.
959
959
960 Identical to parent's method but we pass extra parameters to the method.
960 Identical to parent's method but we pass extra parameters to the method.
961
961
962 Unlike other _repr_*_ `_repr_mimebundle_` should allow extra kwargs, in
962 Unlike other _repr_*_ `_repr_mimebundle_` should allow extra kwargs, in
963 particular `include` and `exclude`.
963 particular `include` and `exclude`.
964 """
964 """
965 if self.enabled:
965 if self.enabled:
966 # lookup registered printer
966 # lookup registered printer
967 try:
967 try:
968 printer = self.lookup(obj)
968 printer = self.lookup(obj)
969 except KeyError:
969 except KeyError:
970 pass
970 pass
971 else:
971 else:
972 return printer(obj)
972 return printer(obj)
973 # Finally look for special method names
973 # Finally look for special method names
974 method = get_real_method(obj, self.print_method)
974 method = get_real_method(obj, self.print_method)
975
975
976 if method is not None:
976 if method is not None:
977 return method(include=include, exclude=exclude)
977 return method(include=include, exclude=exclude)
978 return None
978 return None
979 else:
979 else:
980 return None
980 return None
981
981
982
982
983 FormatterABC.register(BaseFormatter)
983 FormatterABC.register(BaseFormatter)
984 FormatterABC.register(PlainTextFormatter)
984 FormatterABC.register(PlainTextFormatter)
985 FormatterABC.register(HTMLFormatter)
985 FormatterABC.register(HTMLFormatter)
986 FormatterABC.register(MarkdownFormatter)
986 FormatterABC.register(MarkdownFormatter)
987 FormatterABC.register(SVGFormatter)
987 FormatterABC.register(SVGFormatter)
988 FormatterABC.register(PNGFormatter)
988 FormatterABC.register(PNGFormatter)
989 FormatterABC.register(PDFFormatter)
989 FormatterABC.register(PDFFormatter)
990 FormatterABC.register(JPEGFormatter)
990 FormatterABC.register(JPEGFormatter)
991 FormatterABC.register(LatexFormatter)
991 FormatterABC.register(LatexFormatter)
992 FormatterABC.register(JSONFormatter)
992 FormatterABC.register(JSONFormatter)
993 FormatterABC.register(JavascriptFormatter)
993 FormatterABC.register(JavascriptFormatter)
994 FormatterABC.register(IPythonDisplayFormatter)
994 FormatterABC.register(IPythonDisplayFormatter)
995 FormatterABC.register(MimeBundleFormatter)
995 FormatterABC.register(MimeBundleFormatter)
996
996
997
997
998 def format_display_data(obj, include=None, exclude=None):
998 def format_display_data(obj, include=None, exclude=None):
999 """Return a format data dict for an object.
999 """Return a format data dict for an object.
1000
1000
1001 By default all format types will be computed.
1001 By default all format types will be computed.
1002
1002
1003 Parameters
1003 Parameters
1004 ----------
1004 ----------
1005 obj : object
1005 obj : object
1006 The Python object whose format data will be computed.
1006 The Python object whose format data will be computed.
1007
1007
1008 Returns
1008 Returns
1009 -------
1009 -------
1010 format_dict : dict
1010 format_dict : dict
1011 A dictionary of key/value pairs, one or each format that was
1011 A dictionary of key/value pairs, one or each format that was
1012 generated for the object. The keys are the format types, which
1012 generated for the object. The keys are the format types, which
1013 will usually be MIME type strings and the values and JSON'able
1013 will usually be MIME type strings and the values and JSON'able
1014 data structure containing the raw data for the representation in
1014 data structure containing the raw data for the representation in
1015 that format.
1015 that format.
1016 include : list or tuple, optional
1016 include : list or tuple, optional
1017 A list of format type strings (MIME types) to include in the
1017 A list of format type strings (MIME types) to include in the
1018 format data dict. If this is set *only* the format types included
1018 format data dict. If this is set *only* the format types included
1019 in this list will be computed.
1019 in this list will be computed.
1020 exclude : list or tuple, optional
1020 exclude : list or tuple, optional
1021 A list of format type string (MIME types) to exclude in the format
1021 A list of format type string (MIME types) to exclude in the format
1022 data dict. If this is set all format types will be computed,
1022 data dict. If this is set all format types will be computed,
1023 except for those included in this argument.
1023 except for those included in this argument.
1024 """
1024 """
1025 from .interactiveshell import InteractiveShell
1025 from .interactiveshell import InteractiveShell
1026
1026
1027 return InteractiveShell.instance().display_formatter.format(
1027 return InteractiveShell.instance().display_formatter.format(
1028 obj,
1028 obj,
1029 include,
1029 include,
1030 exclude
1030 exclude
1031 )
1031 )
@@ -1,978 +1,979 b''
1 """ History related magics and functionality """
1 """ History related magics and functionality """
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6
6
7 import atexit
7 import atexit
8 import datetime
8 import datetime
9 from pathlib import Path
9 from pathlib import Path
10 import re
10 import re
11 import sqlite3
11 import sqlite3
12 import threading
12 import threading
13
13
14 from traitlets.config.configurable import LoggingConfigurable
14 from traitlets.config.configurable import LoggingConfigurable
15 from decorator import decorator
15 from decorator import decorator
16 from IPython.utils.decorators import undoc
16 from IPython.utils.decorators import undoc
17 from IPython.paths import locate_profile
17 from IPython.paths import locate_profile
18 from traitlets import (
18 from traitlets import (
19 Any,
19 Any,
20 Bool,
20 Bool,
21 Dict,
21 Dict,
22 Instance,
22 Instance,
23 Integer,
23 Integer,
24 List,
24 List,
25 Unicode,
25 Unicode,
26 Union,
26 Union,
27 TraitError,
27 TraitError,
28 default,
28 default,
29 observe,
29 observe,
30 )
30 )
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Classes and functions
33 # Classes and functions
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36 @undoc
36 @undoc
37 class DummyDB(object):
37 class DummyDB(object):
38 """Dummy DB that will act as a black hole for history.
38 """Dummy DB that will act as a black hole for history.
39
39
40 Only used in the absence of sqlite"""
40 Only used in the absence of sqlite"""
41 def execute(*args, **kwargs):
41 def execute(*args, **kwargs):
42 return []
42 return []
43
43
44 def commit(self, *args, **kwargs):
44 def commit(self, *args, **kwargs):
45 pass
45 pass
46
46
47 def __enter__(self, *args, **kwargs):
47 def __enter__(self, *args, **kwargs):
48 pass
48 pass
49
49
50 def __exit__(self, *args, **kwargs):
50 def __exit__(self, *args, **kwargs):
51 pass
51 pass
52
52
53
53
54 @decorator
54 @decorator
55 def only_when_enabled(f, self, *a, **kw):
55 def only_when_enabled(f, self, *a, **kw):
56 """Decorator: return an empty list in the absence of sqlite."""
56 """Decorator: return an empty list in the absence of sqlite."""
57 if not self.enabled:
57 if not self.enabled:
58 return []
58 return []
59 else:
59 else:
60 return f(self, *a, **kw)
60 return f(self, *a, **kw)
61
61
62
62
63 # use 16kB as threshold for whether a corrupt history db should be saved
63 # use 16kB as threshold for whether a corrupt history db should be saved
64 # that should be at least 100 entries or so
64 # that should be at least 100 entries or so
65 _SAVE_DB_SIZE = 16384
65 _SAVE_DB_SIZE = 16384
66
66
67 @decorator
67 @decorator
68 def catch_corrupt_db(f, self, *a, **kw):
68 def catch_corrupt_db(f, self, *a, **kw):
69 """A decorator which wraps HistoryAccessor method calls to catch errors from
69 """A decorator which wraps HistoryAccessor method calls to catch errors from
70 a corrupt SQLite database, move the old database out of the way, and create
70 a corrupt SQLite database, move the old database out of the way, and create
71 a new one.
71 a new one.
72
72
73 We avoid clobbering larger databases because this may be triggered due to filesystem issues,
73 We avoid clobbering larger databases because this may be triggered due to filesystem issues,
74 not just a corrupt file.
74 not just a corrupt file.
75 """
75 """
76 try:
76 try:
77 return f(self, *a, **kw)
77 return f(self, *a, **kw)
78 except (sqlite3.DatabaseError, sqlite3.OperationalError) as e:
78 except (sqlite3.DatabaseError, sqlite3.OperationalError) as e:
79 self._corrupt_db_counter += 1
79 self._corrupt_db_counter += 1
80 self.log.error("Failed to open SQLite history %s (%s).", self.hist_file, e)
80 self.log.error("Failed to open SQLite history %s (%s).", self.hist_file, e)
81 if self.hist_file != ':memory:':
81 if self.hist_file != ':memory:':
82 if self._corrupt_db_counter > self._corrupt_db_limit:
82 if self._corrupt_db_counter > self._corrupt_db_limit:
83 self.hist_file = ':memory:'
83 self.hist_file = ':memory:'
84 self.log.error("Failed to load history too many times, history will not be saved.")
84 self.log.error("Failed to load history too many times, history will not be saved.")
85 elif self.hist_file.is_file():
85 elif self.hist_file.is_file():
86 # move the file out of the way
86 # move the file out of the way
87 base = str(self.hist_file.parent / self.hist_file.stem)
87 base = str(self.hist_file.parent / self.hist_file.stem)
88 ext = self.hist_file.suffix
88 ext = self.hist_file.suffix
89 size = self.hist_file.stat().st_size
89 size = self.hist_file.stat().st_size
90 if size >= _SAVE_DB_SIZE:
90 if size >= _SAVE_DB_SIZE:
91 # if there's significant content, avoid clobbering
91 # if there's significant content, avoid clobbering
92 now = datetime.datetime.now().isoformat().replace(':', '.')
92 now = datetime.datetime.now().isoformat().replace(':', '.')
93 newpath = base + '-corrupt-' + now + ext
93 newpath = base + '-corrupt-' + now + ext
94 # don't clobber previous corrupt backups
94 # don't clobber previous corrupt backups
95 for i in range(100):
95 for i in range(100):
96 if not Path(newpath).exists():
96 if not Path(newpath).exists():
97 break
97 break
98 else:
98 else:
99 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
99 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
100 else:
100 else:
101 # not much content, possibly empty; don't worry about clobbering
101 # not much content, possibly empty; don't worry about clobbering
102 # maybe we should just delete it?
102 # maybe we should just delete it?
103 newpath = base + '-corrupt' + ext
103 newpath = base + '-corrupt' + ext
104 self.hist_file.rename(newpath)
104 self.hist_file.rename(newpath)
105 self.log.error("History file was moved to %s and a new file created.", newpath)
105 self.log.error("History file was moved to %s and a new file created.", newpath)
106 self.init_db()
106 self.init_db()
107 return []
107 return []
108 else:
108 else:
109 # Failed with :memory:, something serious is wrong
109 # Failed with :memory:, something serious is wrong
110 raise
110 raise
111
111
112
112
113 class HistoryAccessorBase(LoggingConfigurable):
113 class HistoryAccessorBase(LoggingConfigurable):
114 """An abstract class for History Accessors """
114 """An abstract class for History Accessors """
115
115
116 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
116 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
117 raise NotImplementedError
117 raise NotImplementedError
118
118
119 def search(self, pattern="*", raw=True, search_raw=True,
119 def search(self, pattern="*", raw=True, search_raw=True,
120 output=False, n=None, unique=False):
120 output=False, n=None, unique=False):
121 raise NotImplementedError
121 raise NotImplementedError
122
122
123 def get_range(self, session, start=1, stop=None, raw=True,output=False):
123 def get_range(self, session, start=1, stop=None, raw=True,output=False):
124 raise NotImplementedError
124 raise NotImplementedError
125
125
126 def get_range_by_str(self, rangestr, raw=True, output=False):
126 def get_range_by_str(self, rangestr, raw=True, output=False):
127 raise NotImplementedError
127 raise NotImplementedError
128
128
129
129
130 class HistoryAccessor(HistoryAccessorBase):
130 class HistoryAccessor(HistoryAccessorBase):
131 """Access the history database without adding to it.
131 """Access the history database without adding to it.
132
132
133 This is intended for use by standalone history tools. IPython shells use
133 This is intended for use by standalone history tools. IPython shells use
134 HistoryManager, below, which is a subclass of this."""
134 HistoryManager, below, which is a subclass of this."""
135
135
136 # counter for init_db retries, so we don't keep trying over and over
136 # counter for init_db retries, so we don't keep trying over and over
137 _corrupt_db_counter = 0
137 _corrupt_db_counter = 0
138 # after two failures, fallback on :memory:
138 # after two failures, fallback on :memory:
139 _corrupt_db_limit = 2
139 _corrupt_db_limit = 2
140
140
141 # String holding the path to the history file
141 # String holding the path to the history file
142 hist_file = Union(
142 hist_file = Union(
143 [Instance(Path), Unicode()],
143 [Instance(Path), Unicode()],
144 help="""Path to file to use for SQLite history database.
144 help="""Path to file to use for SQLite history database.
145
145
146 By default, IPython will put the history database in the IPython
146 By default, IPython will put the history database in the IPython
147 profile directory. If you would rather share one history among
147 profile directory. If you would rather share one history among
148 profiles, you can set this value in each, so that they are consistent.
148 profiles, you can set this value in each, so that they are consistent.
149
149
150 Due to an issue with fcntl, SQLite is known to misbehave on some NFS
150 Due to an issue with fcntl, SQLite is known to misbehave on some NFS
151 mounts. If you see IPython hanging, try setting this to something on a
151 mounts. If you see IPython hanging, try setting this to something on a
152 local disk, e.g::
152 local disk, e.g::
153
153
154 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
154 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
155
155
156 you can also use the specific value `:memory:` (including the colon
156 you can also use the specific value `:memory:` (including the colon
157 at both end but not the back ticks), to avoid creating an history file.
157 at both end but not the back ticks), to avoid creating an history file.
158
158
159 """,
159 """,
160 ).tag(config=True)
160 ).tag(config=True)
161
161
162 enabled = Bool(True,
162 enabled = Bool(True,
163 help="""enable the SQLite history
163 help="""enable the SQLite history
164
164
165 set enabled=False to disable the SQLite history,
165 set enabled=False to disable the SQLite history,
166 in which case there will be no stored history, no SQLite connection,
166 in which case there will be no stored history, no SQLite connection,
167 and no background saving thread. This may be necessary in some
167 and no background saving thread. This may be necessary in some
168 threaded environments where IPython is embedded.
168 threaded environments where IPython is embedded.
169 """,
169 """,
170 ).tag(config=True)
170 ).tag(config=True)
171
171
172 connection_options = Dict(
172 connection_options = Dict(
173 help="""Options for configuring the SQLite connection
173 help="""Options for configuring the SQLite connection
174
174
175 These options are passed as keyword args to sqlite3.connect
175 These options are passed as keyword args to sqlite3.connect
176 when establishing database connections.
176 when establishing database connections.
177 """
177 """
178 ).tag(config=True)
178 ).tag(config=True)
179
179
180 @default("connection_options")
180 @default("connection_options")
181 def _default_connection_options(self):
181 def _default_connection_options(self):
182 return dict(check_same_thread=False)
182 return dict(check_same_thread=False)
183
183
184 # The SQLite database
184 # The SQLite database
185 db = Any()
185 db = Any()
186 @observe('db')
186 @observe('db')
187 def _db_changed(self, change):
187 def _db_changed(self, change):
188 """validate the db, since it can be an Instance of two different types"""
188 """validate the db, since it can be an Instance of two different types"""
189 new = change['new']
189 new = change['new']
190 connection_types = (DummyDB, sqlite3.Connection)
190 connection_types = (DummyDB, sqlite3.Connection)
191 if not isinstance(new, connection_types):
191 if not isinstance(new, connection_types):
192 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
192 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
193 (self.__class__.__name__, new)
193 (self.__class__.__name__, new)
194 raise TraitError(msg)
194 raise TraitError(msg)
195
195
196 def __init__(self, profile="default", hist_file="", **traits):
196 def __init__(self, profile="default", hist_file="", **traits):
197 """Create a new history accessor.
197 """Create a new history accessor.
198
198
199 Parameters
199 Parameters
200 ----------
200 ----------
201 profile : str
201 profile : str
202 The name of the profile from which to open history.
202 The name of the profile from which to open history.
203 hist_file : str
203 hist_file : str
204 Path to an SQLite history database stored by IPython. If specified,
204 Path to an SQLite history database stored by IPython. If specified,
205 hist_file overrides profile.
205 hist_file overrides profile.
206 config : :class:`~traitlets.config.loader.Config`
206 config : :class:`~traitlets.config.loader.Config`
207 Config object. hist_file can also be set through this.
207 Config object. hist_file can also be set through this.
208 """
208 """
209 super(HistoryAccessor, self).__init__(**traits)
209 super(HistoryAccessor, self).__init__(**traits)
210 # defer setting hist_file from kwarg until after init,
210 # defer setting hist_file from kwarg until after init,
211 # otherwise the default kwarg value would clobber any value
211 # otherwise the default kwarg value would clobber any value
212 # set by config
212 # set by config
213 if hist_file:
213 if hist_file:
214 self.hist_file = hist_file
214 self.hist_file = hist_file
215
215
216 try:
216 try:
217 self.hist_file
217 self.hist_file
218 except TraitError:
218 except TraitError:
219 # No one has set the hist_file, yet.
219 # No one has set the hist_file, yet.
220 self.hist_file = self._get_hist_file_name(profile)
220 self.hist_file = self._get_hist_file_name(profile)
221
221
222 self.init_db()
222 self.init_db()
223
223
224 def _get_hist_file_name(self, profile='default'):
224 def _get_hist_file_name(self, profile='default'):
225 """Find the history file for the given profile name.
225 """Find the history file for the given profile name.
226
226
227 This is overridden by the HistoryManager subclass, to use the shell's
227 This is overridden by the HistoryManager subclass, to use the shell's
228 active profile.
228 active profile.
229
229
230 Parameters
230 Parameters
231 ----------
231 ----------
232 profile : str
232 profile : str
233 The name of a profile which has a history file.
233 The name of a profile which has a history file.
234 """
234 """
235 return Path(locate_profile(profile)) / "history.sqlite"
235 return Path(locate_profile(profile)) / "history.sqlite"
236
236
237 @catch_corrupt_db
237 @catch_corrupt_db
238 def init_db(self):
238 def init_db(self):
239 """Connect to the database, and create tables if necessary."""
239 """Connect to the database, and create tables if necessary."""
240 if not self.enabled:
240 if not self.enabled:
241 self.db = DummyDB()
241 self.db = DummyDB()
242 return
242 return
243
243
244 # use detect_types so that timestamps return datetime objects
244 # use detect_types so that timestamps return datetime objects
245 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
245 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
246 kwargs.update(self.connection_options)
246 kwargs.update(self.connection_options)
247 self.db = sqlite3.connect(str(self.hist_file), **kwargs)
247 self.db = sqlite3.connect(str(self.hist_file), **kwargs)
248 with self.db:
248 with self.db:
249 self.db.execute(
249 self.db.execute(
250 """CREATE TABLE IF NOT EXISTS sessions (session integer
250 """CREATE TABLE IF NOT EXISTS sessions (session integer
251 primary key autoincrement, start timestamp,
251 primary key autoincrement, start timestamp,
252 end timestamp, num_cmds integer, remark text)"""
252 end timestamp, num_cmds integer, remark text)"""
253 )
253 )
254 self.db.execute(
254 self.db.execute(
255 """CREATE TABLE IF NOT EXISTS history
255 """CREATE TABLE IF NOT EXISTS history
256 (session integer, line integer, source text, source_raw text,
256 (session integer, line integer, source text, source_raw text,
257 PRIMARY KEY (session, line))"""
257 PRIMARY KEY (session, line))"""
258 )
258 )
259 # Output history is optional, but ensure the table's there so it can be
259 # Output history is optional, but ensure the table's there so it can be
260 # enabled later.
260 # enabled later.
261 self.db.execute(
261 self.db.execute(
262 """CREATE TABLE IF NOT EXISTS output_history
262 """CREATE TABLE IF NOT EXISTS output_history
263 (session integer, line integer, output text,
263 (session integer, line integer, output text,
264 PRIMARY KEY (session, line))"""
264 PRIMARY KEY (session, line))"""
265 )
265 )
266 # success! reset corrupt db count
266 # success! reset corrupt db count
267 self._corrupt_db_counter = 0
267 self._corrupt_db_counter = 0
268
268
269 def writeout_cache(self):
269 def writeout_cache(self):
270 """Overridden by HistoryManager to dump the cache before certain
270 """Overridden by HistoryManager to dump the cache before certain
271 database lookups."""
271 database lookups."""
272 pass
272 pass
273
273
274 ## -------------------------------
274 ## -------------------------------
275 ## Methods for retrieving history:
275 ## Methods for retrieving history:
276 ## -------------------------------
276 ## -------------------------------
277 def _run_sql(self, sql, params, raw=True, output=False, latest=False):
277 def _run_sql(self, sql, params, raw=True, output=False, latest=False):
278 """Prepares and runs an SQL query for the history database.
278 """Prepares and runs an SQL query for the history database.
279
279
280 Parameters
280 Parameters
281 ----------
281 ----------
282 sql : str
282 sql : str
283 Any filtering expressions to go after SELECT ... FROM ...
283 Any filtering expressions to go after SELECT ... FROM ...
284 params : tuple
284 params : tuple
285 Parameters passed to the SQL query (to replace "?")
285 Parameters passed to the SQL query (to replace "?")
286 raw, output : bool
286 raw, output : bool
287 See :meth:`get_range`
287 See :meth:`get_range`
288 latest : bool
288 latest : bool
289 Select rows with max (session, line)
289 Select rows with max (session, line)
290
290
291 Returns
291 Returns
292 -------
292 -------
293 Tuples as :meth:`get_range`
293 Tuples as :meth:`get_range`
294 """
294 """
295 toget = 'source_raw' if raw else 'source'
295 toget = 'source_raw' if raw else 'source'
296 sqlfrom = "history"
296 sqlfrom = "history"
297 if output:
297 if output:
298 sqlfrom = "history LEFT JOIN output_history USING (session, line)"
298 sqlfrom = "history LEFT JOIN output_history USING (session, line)"
299 toget = "history.%s, output_history.output" % toget
299 toget = "history.%s, output_history.output" % toget
300 if latest:
300 if latest:
301 toget += ", MAX(session * 128 * 1024 + line)"
301 toget += ", MAX(session * 128 * 1024 + line)"
302 this_querry = "SELECT session, line, %s FROM %s " % (toget, sqlfrom) + sql
302 this_querry = "SELECT session, line, %s FROM %s " % (toget, sqlfrom) + sql
303 cur = self.db.execute(this_querry, params)
303 cur = self.db.execute(this_querry, params)
304 if latest:
304 if latest:
305 cur = (row[:-1] for row in cur)
305 cur = (row[:-1] for row in cur)
306 if output: # Regroup into 3-tuples, and parse JSON
306 if output: # Regroup into 3-tuples, and parse JSON
307 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
307 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
308 return cur
308 return cur
309
309
310 @only_when_enabled
310 @only_when_enabled
311 @catch_corrupt_db
311 @catch_corrupt_db
312 def get_session_info(self, session):
312 def get_session_info(self, session):
313 """Get info about a session.
313 """Get info about a session.
314
314
315 Parameters
315 Parameters
316 ----------
316 ----------
317 session : int
317 session : int
318 Session number to retrieve.
318 Session number to retrieve.
319
319
320 Returns
320 Returns
321 -------
321 -------
322 session_id : int
322 session_id : int
323 Session ID number
323 Session ID number
324 start : datetime
324 start : datetime
325 Timestamp for the start of the session.
325 Timestamp for the start of the session.
326 end : datetime
326 end : datetime
327 Timestamp for the end of the session, or None if IPython crashed.
327 Timestamp for the end of the session, or None if IPython crashed.
328 num_cmds : int
328 num_cmds : int
329 Number of commands run, or None if IPython crashed.
329 Number of commands run, or None if IPython crashed.
330 remark : unicode
330 remark : unicode
331 A manually set description.
331 A manually set description.
332 """
332 """
333 query = "SELECT * from sessions where session == ?"
333 query = "SELECT * from sessions where session == ?"
334 return self.db.execute(query, (session,)).fetchone()
334 return self.db.execute(query, (session,)).fetchone()
335
335
336 @catch_corrupt_db
336 @catch_corrupt_db
337 def get_last_session_id(self):
337 def get_last_session_id(self):
338 """Get the last session ID currently in the database.
338 """Get the last session ID currently in the database.
339
339
340 Within IPython, this should be the same as the value stored in
340 Within IPython, this should be the same as the value stored in
341 :attr:`HistoryManager.session_number`.
341 :attr:`HistoryManager.session_number`.
342 """
342 """
343 for record in self.get_tail(n=1, include_latest=True):
343 for record in self.get_tail(n=1, include_latest=True):
344 return record[0]
344 return record[0]
345
345
346 @catch_corrupt_db
346 @catch_corrupt_db
347 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
347 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
348 """Get the last n lines from the history database.
348 """Get the last n lines from the history database.
349
349
350 Parameters
350 Parameters
351 ----------
351 ----------
352 n : int
352 n : int
353 The number of lines to get
353 The number of lines to get
354 raw, output : bool
354 raw, output : bool
355 See :meth:`get_range`
355 See :meth:`get_range`
356 include_latest : bool
356 include_latest : bool
357 If False (default), n+1 lines are fetched, and the latest one
357 If False (default), n+1 lines are fetched, and the latest one
358 is discarded. This is intended to be used where the function
358 is discarded. This is intended to be used where the function
359 is called by a user command, which it should not return.
359 is called by a user command, which it should not return.
360
360
361 Returns
361 Returns
362 -------
362 -------
363 Tuples as :meth:`get_range`
363 Tuples as :meth:`get_range`
364 """
364 """
365 self.writeout_cache()
365 self.writeout_cache()
366 if not include_latest:
366 if not include_latest:
367 n += 1
367 n += 1
368 cur = self._run_sql(
368 cur = self._run_sql(
369 "ORDER BY session DESC, line DESC LIMIT ?", (n,), raw=raw, output=output
369 "ORDER BY session DESC, line DESC LIMIT ?", (n,), raw=raw, output=output
370 )
370 )
371 if not include_latest:
371 if not include_latest:
372 return reversed(list(cur)[1:])
372 return reversed(list(cur)[1:])
373 return reversed(list(cur))
373 return reversed(list(cur))
374
374
375 @catch_corrupt_db
375 @catch_corrupt_db
376 def search(self, pattern="*", raw=True, search_raw=True,
376 def search(self, pattern="*", raw=True, search_raw=True,
377 output=False, n=None, unique=False):
377 output=False, n=None, unique=False):
378 """Search the database using unix glob-style matching (wildcards
378 """Search the database using unix glob-style matching (wildcards
379 * and ?).
379 * and ?).
380
380
381 Parameters
381 Parameters
382 ----------
382 ----------
383 pattern : str
383 pattern : str
384 The wildcarded pattern to match when searching
384 The wildcarded pattern to match when searching
385 search_raw : bool
385 search_raw : bool
386 If True, search the raw input, otherwise, the parsed input
386 If True, search the raw input, otherwise, the parsed input
387 raw, output : bool
387 raw, output : bool
388 See :meth:`get_range`
388 See :meth:`get_range`
389 n : None or int
389 n : None or int
390 If an integer is given, it defines the limit of
390 If an integer is given, it defines the limit of
391 returned entries.
391 returned entries.
392 unique : bool
392 unique : bool
393 When it is true, return only unique entries.
393 When it is true, return only unique entries.
394
394
395 Returns
395 Returns
396 -------
396 -------
397 Tuples as :meth:`get_range`
397 Tuples as :meth:`get_range`
398 """
398 """
399 tosearch = "source_raw" if search_raw else "source"
399 tosearch = "source_raw" if search_raw else "source"
400 if output:
400 if output:
401 tosearch = "history." + tosearch
401 tosearch = "history." + tosearch
402 self.writeout_cache()
402 self.writeout_cache()
403 sqlform = "WHERE %s GLOB ?" % tosearch
403 sqlform = "WHERE %s GLOB ?" % tosearch
404 params = (pattern,)
404 params = (pattern,)
405 if unique:
405 if unique:
406 sqlform += ' GROUP BY {0}'.format(tosearch)
406 sqlform += ' GROUP BY {0}'.format(tosearch)
407 if n is not None:
407 if n is not None:
408 sqlform += " ORDER BY session DESC, line DESC LIMIT ?"
408 sqlform += " ORDER BY session DESC, line DESC LIMIT ?"
409 params += (n,)
409 params += (n,)
410 elif unique:
410 elif unique:
411 sqlform += " ORDER BY session, line"
411 sqlform += " ORDER BY session, line"
412 cur = self._run_sql(sqlform, params, raw=raw, output=output, latest=unique)
412 cur = self._run_sql(sqlform, params, raw=raw, output=output, latest=unique)
413 if n is not None:
413 if n is not None:
414 return reversed(list(cur))
414 return reversed(list(cur))
415 return cur
415 return cur
416
416
417 @catch_corrupt_db
417 @catch_corrupt_db
418 def get_range(self, session, start=1, stop=None, raw=True,output=False):
418 def get_range(self, session, start=1, stop=None, raw=True,output=False):
419 """Retrieve input by session.
419 """Retrieve input by session.
420
420
421 Parameters
421 Parameters
422 ----------
422 ----------
423 session : int
423 session : int
424 Session number to retrieve.
424 Session number to retrieve.
425 start : int
425 start : int
426 First line to retrieve.
426 First line to retrieve.
427 stop : int
427 stop : int
428 End of line range (excluded from output itself). If None, retrieve
428 End of line range (excluded from output itself). If None, retrieve
429 to the end of the session.
429 to the end of the session.
430 raw : bool
430 raw : bool
431 If True, return untranslated input
431 If True, return untranslated input
432 output : bool
432 output : bool
433 If True, attempt to include output. This will be 'real' Python
433 If True, attempt to include output. This will be 'real' Python
434 objects for the current session, or text reprs from previous
434 objects for the current session, or text reprs from previous
435 sessions if db_log_output was enabled at the time. Where no output
435 sessions if db_log_output was enabled at the time. Where no output
436 is found, None is used.
436 is found, None is used.
437
437
438 Returns
438 Returns
439 -------
439 -------
440 entries
440 entries
441 An iterator over the desired lines. Each line is a 3-tuple, either
441 An iterator over the desired lines. Each line is a 3-tuple, either
442 (session, line, input) if output is False, or
442 (session, line, input) if output is False, or
443 (session, line, (input, output)) if output is True.
443 (session, line, (input, output)) if output is True.
444 """
444 """
445 if stop:
445 if stop:
446 lineclause = "line >= ? AND line < ?"
446 lineclause = "line >= ? AND line < ?"
447 params = (session, start, stop)
447 params = (session, start, stop)
448 else:
448 else:
449 lineclause = "line>=?"
449 lineclause = "line>=?"
450 params = (session, start)
450 params = (session, start)
451
451
452 return self._run_sql("WHERE session==? AND %s" % lineclause,
452 return self._run_sql("WHERE session==? AND %s" % lineclause,
453 params, raw=raw, output=output)
453 params, raw=raw, output=output)
454
454
455 def get_range_by_str(self, rangestr, raw=True, output=False):
455 def get_range_by_str(self, rangestr, raw=True, output=False):
456 """Get lines of history from a string of ranges, as used by magic
456 """Get lines of history from a string of ranges, as used by magic
457 commands %hist, %save, %macro, etc.
457 commands %hist, %save, %macro, etc.
458
458
459 Parameters
459 Parameters
460 ----------
460 ----------
461 rangestr : str
461 rangestr : str
462 A string specifying ranges, e.g. "5 ~2/1-4". If empty string is used,
462 A string specifying ranges, e.g. "5 ~2/1-4". If empty string is used,
463 this will return everything from current session's history.
463 this will return everything from current session's history.
464
464
465 See the documentation of :func:`%history` for the full details.
465 See the documentation of :func:`%history` for the full details.
466
466
467 raw, output : bool
467 raw, output : bool
468 As :meth:`get_range`
468 As :meth:`get_range`
469
469
470 Returns
470 Returns
471 -------
471 -------
472 Tuples as :meth:`get_range`
472 Tuples as :meth:`get_range`
473 """
473 """
474 for sess, s, e in extract_hist_ranges(rangestr):
474 for sess, s, e in extract_hist_ranges(rangestr):
475 for line in self.get_range(sess, s, e, raw=raw, output=output):
475 for line in self.get_range(sess, s, e, raw=raw, output=output):
476 yield line
476 yield line
477
477
478
478
479 class HistoryManager(HistoryAccessor):
479 class HistoryManager(HistoryAccessor):
480 """A class to organize all history-related functionality in one place.
480 """A class to organize all history-related functionality in one place.
481 """
481 """
482 # Public interface
482 # Public interface
483
483
484 # An instance of the IPython shell we are attached to
484 # An instance of the IPython shell we are attached to
485 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
485 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
486 allow_none=True)
486 allow_none=True)
487 # Lists to hold processed and raw history. These start with a blank entry
487 # Lists to hold processed and raw history. These start with a blank entry
488 # so that we can index them starting from 1
488 # so that we can index them starting from 1
489 input_hist_parsed = List([""])
489 input_hist_parsed = List([""])
490 input_hist_raw = List([""])
490 input_hist_raw = List([""])
491 # A list of directories visited during session
491 # A list of directories visited during session
492 dir_hist = List()
492 dir_hist: List = List()
493 @default('dir_hist')
493
494 @default("dir_hist")
494 def _dir_hist_default(self):
495 def _dir_hist_default(self):
495 try:
496 try:
496 return [Path.cwd()]
497 return [Path.cwd()]
497 except OSError:
498 except OSError:
498 return []
499 return []
499
500
500 # A dict of output history, keyed with ints from the shell's
501 # A dict of output history, keyed with ints from the shell's
501 # execution count.
502 # execution count.
502 output_hist = Dict()
503 output_hist = Dict()
503 # The text/plain repr of outputs.
504 # The text/plain repr of outputs.
504 output_hist_reprs = Dict()
505 output_hist_reprs = Dict()
505
506
506 # The number of the current session in the history database
507 # The number of the current session in the history database
507 session_number = Integer()
508 session_number = Integer()
508
509
509 db_log_output = Bool(False,
510 db_log_output = Bool(False,
510 help="Should the history database include output? (default: no)"
511 help="Should the history database include output? (default: no)"
511 ).tag(config=True)
512 ).tag(config=True)
512 db_cache_size = Integer(0,
513 db_cache_size = Integer(0,
513 help="Write to database every x commands (higher values save disk access & power).\n"
514 help="Write to database every x commands (higher values save disk access & power).\n"
514 "Values of 1 or less effectively disable caching."
515 "Values of 1 or less effectively disable caching."
515 ).tag(config=True)
516 ).tag(config=True)
516 # The input and output caches
517 # The input and output caches
517 db_input_cache = List()
518 db_input_cache: List = List()
518 db_output_cache = List()
519 db_output_cache: List = List()
519
520
520 # History saving in separate thread
521 # History saving in separate thread
521 save_thread = Instance('IPython.core.history.HistorySavingThread',
522 save_thread = Instance('IPython.core.history.HistorySavingThread',
522 allow_none=True)
523 allow_none=True)
523 save_flag = Instance(threading.Event, allow_none=True)
524 save_flag = Instance(threading.Event, allow_none=True)
524
525
525 # Private interface
526 # Private interface
526 # Variables used to store the three last inputs from the user. On each new
527 # Variables used to store the three last inputs from the user. On each new
527 # history update, we populate the user's namespace with these, shifted as
528 # history update, we populate the user's namespace with these, shifted as
528 # necessary.
529 # necessary.
529 _i00 = Unicode(u'')
530 _i00 = Unicode("")
530 _i = Unicode(u'')
531 _i = Unicode("")
531 _ii = Unicode(u'')
532 _ii = Unicode("")
532 _iii = Unicode(u'')
533 _iii = Unicode("")
533
534
534 # A regex matching all forms of the exit command, so that we don't store
535 # A regex matching all forms of the exit command, so that we don't store
535 # them in the history (it's annoying to rewind the first entry and land on
536 # them in the history (it's annoying to rewind the first entry and land on
536 # an exit call).
537 # an exit call).
537 _exit_re = re.compile(r"(exit|quit)(\s*\(.*\))?$")
538 _exit_re = re.compile(r"(exit|quit)(\s*\(.*\))?$")
538
539
539 def __init__(self, shell=None, config=None, **traits):
540 def __init__(self, shell=None, config=None, **traits):
540 """Create a new history manager associated with a shell instance.
541 """Create a new history manager associated with a shell instance.
541 """
542 """
542 super(HistoryManager, self).__init__(shell=shell, config=config,
543 super(HistoryManager, self).__init__(shell=shell, config=config,
543 **traits)
544 **traits)
544 self.save_flag = threading.Event()
545 self.save_flag = threading.Event()
545 self.db_input_cache_lock = threading.Lock()
546 self.db_input_cache_lock = threading.Lock()
546 self.db_output_cache_lock = threading.Lock()
547 self.db_output_cache_lock = threading.Lock()
547
548
548 try:
549 try:
549 self.new_session()
550 self.new_session()
550 except sqlite3.OperationalError:
551 except sqlite3.OperationalError:
551 self.log.error("Failed to create history session in %s. History will not be saved.",
552 self.log.error("Failed to create history session in %s. History will not be saved.",
552 self.hist_file, exc_info=True)
553 self.hist_file, exc_info=True)
553 self.hist_file = ':memory:'
554 self.hist_file = ':memory:'
554
555
555 if self.enabled and self.hist_file != ':memory:':
556 if self.enabled and self.hist_file != ':memory:':
556 self.save_thread = HistorySavingThread(self)
557 self.save_thread = HistorySavingThread(self)
557 self.save_thread.start()
558 self.save_thread.start()
558
559
559 def _get_hist_file_name(self, profile=None):
560 def _get_hist_file_name(self, profile=None):
560 """Get default history file name based on the Shell's profile.
561 """Get default history file name based on the Shell's profile.
561
562
562 The profile parameter is ignored, but must exist for compatibility with
563 The profile parameter is ignored, but must exist for compatibility with
563 the parent class."""
564 the parent class."""
564 profile_dir = self.shell.profile_dir.location
565 profile_dir = self.shell.profile_dir.location
565 return Path(profile_dir) / "history.sqlite"
566 return Path(profile_dir) / "history.sqlite"
566
567
567 @only_when_enabled
568 @only_when_enabled
568 def new_session(self, conn=None):
569 def new_session(self, conn=None):
569 """Get a new session number."""
570 """Get a new session number."""
570 if conn is None:
571 if conn is None:
571 conn = self.db
572 conn = self.db
572
573
573 with conn:
574 with conn:
574 cur = conn.execute(
575 cur = conn.execute(
575 """INSERT INTO sessions VALUES (NULL, ?, NULL,
576 """INSERT INTO sessions VALUES (NULL, ?, NULL,
576 NULL, '') """,
577 NULL, '') """,
577 (datetime.datetime.now().isoformat(" "),),
578 (datetime.datetime.now().isoformat(" "),),
578 )
579 )
579 self.session_number = cur.lastrowid
580 self.session_number = cur.lastrowid
580
581
581 def end_session(self):
582 def end_session(self):
582 """Close the database session, filling in the end time and line count."""
583 """Close the database session, filling in the end time and line count."""
583 self.writeout_cache()
584 self.writeout_cache()
584 with self.db:
585 with self.db:
585 self.db.execute(
586 self.db.execute(
586 """UPDATE sessions SET end=?, num_cmds=? WHERE
587 """UPDATE sessions SET end=?, num_cmds=? WHERE
587 session==?""",
588 session==?""",
588 (
589 (
589 datetime.datetime.now().isoformat(" "),
590 datetime.datetime.now().isoformat(" "),
590 len(self.input_hist_parsed) - 1,
591 len(self.input_hist_parsed) - 1,
591 self.session_number,
592 self.session_number,
592 ),
593 ),
593 )
594 )
594 self.session_number = 0
595 self.session_number = 0
595
596
596 def name_session(self, name):
597 def name_session(self, name):
597 """Give the current session a name in the history database."""
598 """Give the current session a name in the history database."""
598 with self.db:
599 with self.db:
599 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
600 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
600 (name, self.session_number))
601 (name, self.session_number))
601
602
602 def reset(self, new_session=True):
603 def reset(self, new_session=True):
603 """Clear the session history, releasing all object references, and
604 """Clear the session history, releasing all object references, and
604 optionally open a new session."""
605 optionally open a new session."""
605 self.output_hist.clear()
606 self.output_hist.clear()
606 # The directory history can't be completely empty
607 # The directory history can't be completely empty
607 self.dir_hist[:] = [Path.cwd()]
608 self.dir_hist[:] = [Path.cwd()]
608
609
609 if new_session:
610 if new_session:
610 if self.session_number:
611 if self.session_number:
611 self.end_session()
612 self.end_session()
612 self.input_hist_parsed[:] = [""]
613 self.input_hist_parsed[:] = [""]
613 self.input_hist_raw[:] = [""]
614 self.input_hist_raw[:] = [""]
614 self.new_session()
615 self.new_session()
615
616
616 # ------------------------------
617 # ------------------------------
617 # Methods for retrieving history
618 # Methods for retrieving history
618 # ------------------------------
619 # ------------------------------
619 def get_session_info(self, session=0):
620 def get_session_info(self, session=0):
620 """Get info about a session.
621 """Get info about a session.
621
622
622 Parameters
623 Parameters
623 ----------
624 ----------
624 session : int
625 session : int
625 Session number to retrieve. The current session is 0, and negative
626 Session number to retrieve. The current session is 0, and negative
626 numbers count back from current session, so -1 is the previous session.
627 numbers count back from current session, so -1 is the previous session.
627
628
628 Returns
629 Returns
629 -------
630 -------
630 session_id : int
631 session_id : int
631 Session ID number
632 Session ID number
632 start : datetime
633 start : datetime
633 Timestamp for the start of the session.
634 Timestamp for the start of the session.
634 end : datetime
635 end : datetime
635 Timestamp for the end of the session, or None if IPython crashed.
636 Timestamp for the end of the session, or None if IPython crashed.
636 num_cmds : int
637 num_cmds : int
637 Number of commands run, or None if IPython crashed.
638 Number of commands run, or None if IPython crashed.
638 remark : unicode
639 remark : unicode
639 A manually set description.
640 A manually set description.
640 """
641 """
641 if session <= 0:
642 if session <= 0:
642 session += self.session_number
643 session += self.session_number
643
644
644 return super(HistoryManager, self).get_session_info(session=session)
645 return super(HistoryManager, self).get_session_info(session=session)
645
646
646 @catch_corrupt_db
647 @catch_corrupt_db
647 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
648 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
648 """Get the last n lines from the history database.
649 """Get the last n lines from the history database.
649
650
650 Most recent entry last.
651 Most recent entry last.
651
652
652 Completion will be reordered so that that the last ones are when
653 Completion will be reordered so that that the last ones are when
653 possible from current session.
654 possible from current session.
654
655
655 Parameters
656 Parameters
656 ----------
657 ----------
657 n : int
658 n : int
658 The number of lines to get
659 The number of lines to get
659 raw, output : bool
660 raw, output : bool
660 See :meth:`get_range`
661 See :meth:`get_range`
661 include_latest : bool
662 include_latest : bool
662 If False (default), n+1 lines are fetched, and the latest one
663 If False (default), n+1 lines are fetched, and the latest one
663 is discarded. This is intended to be used where the function
664 is discarded. This is intended to be used where the function
664 is called by a user command, which it should not return.
665 is called by a user command, which it should not return.
665
666
666 Returns
667 Returns
667 -------
668 -------
668 Tuples as :meth:`get_range`
669 Tuples as :meth:`get_range`
669 """
670 """
670 self.writeout_cache()
671 self.writeout_cache()
671 if not include_latest:
672 if not include_latest:
672 n += 1
673 n += 1
673 # cursor/line/entry
674 # cursor/line/entry
674 this_cur = list(
675 this_cur = list(
675 self._run_sql(
676 self._run_sql(
676 "WHERE session == ? ORDER BY line DESC LIMIT ? ",
677 "WHERE session == ? ORDER BY line DESC LIMIT ? ",
677 (self.session_number, n),
678 (self.session_number, n),
678 raw=raw,
679 raw=raw,
679 output=output,
680 output=output,
680 )
681 )
681 )
682 )
682 other_cur = list(
683 other_cur = list(
683 self._run_sql(
684 self._run_sql(
684 "WHERE session != ? ORDER BY session DESC, line DESC LIMIT ?",
685 "WHERE session != ? ORDER BY session DESC, line DESC LIMIT ?",
685 (self.session_number, n),
686 (self.session_number, n),
686 raw=raw,
687 raw=raw,
687 output=output,
688 output=output,
688 )
689 )
689 )
690 )
690
691
691 everything = this_cur + other_cur
692 everything = this_cur + other_cur
692
693
693 everything = everything[:n]
694 everything = everything[:n]
694
695
695 if not include_latest:
696 if not include_latest:
696 return list(everything)[:0:-1]
697 return list(everything)[:0:-1]
697 return list(everything)[::-1]
698 return list(everything)[::-1]
698
699
699 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
700 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
700 """Get input and output history from the current session. Called by
701 """Get input and output history from the current session. Called by
701 get_range, and takes similar parameters."""
702 get_range, and takes similar parameters."""
702 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
703 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
703
704
704 n = len(input_hist)
705 n = len(input_hist)
705 if start < 0:
706 if start < 0:
706 start += n
707 start += n
707 if not stop or (stop > n):
708 if not stop or (stop > n):
708 stop = n
709 stop = n
709 elif stop < 0:
710 elif stop < 0:
710 stop += n
711 stop += n
711
712
712 for i in range(start, stop):
713 for i in range(start, stop):
713 if output:
714 if output:
714 line = (input_hist[i], self.output_hist_reprs.get(i))
715 line = (input_hist[i], self.output_hist_reprs.get(i))
715 else:
716 else:
716 line = input_hist[i]
717 line = input_hist[i]
717 yield (0, i, line)
718 yield (0, i, line)
718
719
719 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
720 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
720 """Retrieve input by session.
721 """Retrieve input by session.
721
722
722 Parameters
723 Parameters
723 ----------
724 ----------
724 session : int
725 session : int
725 Session number to retrieve. The current session is 0, and negative
726 Session number to retrieve. The current session is 0, and negative
726 numbers count back from current session, so -1 is previous session.
727 numbers count back from current session, so -1 is previous session.
727 start : int
728 start : int
728 First line to retrieve.
729 First line to retrieve.
729 stop : int
730 stop : int
730 End of line range (excluded from output itself). If None, retrieve
731 End of line range (excluded from output itself). If None, retrieve
731 to the end of the session.
732 to the end of the session.
732 raw : bool
733 raw : bool
733 If True, return untranslated input
734 If True, return untranslated input
734 output : bool
735 output : bool
735 If True, attempt to include output. This will be 'real' Python
736 If True, attempt to include output. This will be 'real' Python
736 objects for the current session, or text reprs from previous
737 objects for the current session, or text reprs from previous
737 sessions if db_log_output was enabled at the time. Where no output
738 sessions if db_log_output was enabled at the time. Where no output
738 is found, None is used.
739 is found, None is used.
739
740
740 Returns
741 Returns
741 -------
742 -------
742 entries
743 entries
743 An iterator over the desired lines. Each line is a 3-tuple, either
744 An iterator over the desired lines. Each line is a 3-tuple, either
744 (session, line, input) if output is False, or
745 (session, line, input) if output is False, or
745 (session, line, (input, output)) if output is True.
746 (session, line, (input, output)) if output is True.
746 """
747 """
747 if session <= 0:
748 if session <= 0:
748 session += self.session_number
749 session += self.session_number
749 if session==self.session_number: # Current session
750 if session==self.session_number: # Current session
750 return self._get_range_session(start, stop, raw, output)
751 return self._get_range_session(start, stop, raw, output)
751 return super(HistoryManager, self).get_range(session, start, stop, raw,
752 return super(HistoryManager, self).get_range(session, start, stop, raw,
752 output)
753 output)
753
754
754 ## ----------------------------
755 ## ----------------------------
755 ## Methods for storing history:
756 ## Methods for storing history:
756 ## ----------------------------
757 ## ----------------------------
757 def store_inputs(self, line_num, source, source_raw=None):
758 def store_inputs(self, line_num, source, source_raw=None):
758 """Store source and raw input in history and create input cache
759 """Store source and raw input in history and create input cache
759 variables ``_i*``.
760 variables ``_i*``.
760
761
761 Parameters
762 Parameters
762 ----------
763 ----------
763 line_num : int
764 line_num : int
764 The prompt number of this input.
765 The prompt number of this input.
765 source : str
766 source : str
766 Python input.
767 Python input.
767 source_raw : str, optional
768 source_raw : str, optional
768 If given, this is the raw input without any IPython transformations
769 If given, this is the raw input without any IPython transformations
769 applied to it. If not given, ``source`` is used.
770 applied to it. If not given, ``source`` is used.
770 """
771 """
771 if source_raw is None:
772 if source_raw is None:
772 source_raw = source
773 source_raw = source
773 source = source.rstrip('\n')
774 source = source.rstrip('\n')
774 source_raw = source_raw.rstrip('\n')
775 source_raw = source_raw.rstrip('\n')
775
776
776 # do not store exit/quit commands
777 # do not store exit/quit commands
777 if self._exit_re.match(source_raw.strip()):
778 if self._exit_re.match(source_raw.strip()):
778 return
779 return
779
780
780 self.input_hist_parsed.append(source)
781 self.input_hist_parsed.append(source)
781 self.input_hist_raw.append(source_raw)
782 self.input_hist_raw.append(source_raw)
782
783
783 with self.db_input_cache_lock:
784 with self.db_input_cache_lock:
784 self.db_input_cache.append((line_num, source, source_raw))
785 self.db_input_cache.append((line_num, source, source_raw))
785 # Trigger to flush cache and write to DB.
786 # Trigger to flush cache and write to DB.
786 if len(self.db_input_cache) >= self.db_cache_size:
787 if len(self.db_input_cache) >= self.db_cache_size:
787 self.save_flag.set()
788 self.save_flag.set()
788
789
789 # update the auto _i variables
790 # update the auto _i variables
790 self._iii = self._ii
791 self._iii = self._ii
791 self._ii = self._i
792 self._ii = self._i
792 self._i = self._i00
793 self._i = self._i00
793 self._i00 = source_raw
794 self._i00 = source_raw
794
795
795 # hackish access to user namespace to create _i1,_i2... dynamically
796 # hackish access to user namespace to create _i1,_i2... dynamically
796 new_i = '_i%s' % line_num
797 new_i = '_i%s' % line_num
797 to_main = {'_i': self._i,
798 to_main = {'_i': self._i,
798 '_ii': self._ii,
799 '_ii': self._ii,
799 '_iii': self._iii,
800 '_iii': self._iii,
800 new_i : self._i00 }
801 new_i : self._i00 }
801
802
802 if self.shell is not None:
803 if self.shell is not None:
803 self.shell.push(to_main, interactive=False)
804 self.shell.push(to_main, interactive=False)
804
805
805 def store_output(self, line_num):
806 def store_output(self, line_num):
806 """If database output logging is enabled, this saves all the
807 """If database output logging is enabled, this saves all the
807 outputs from the indicated prompt number to the database. It's
808 outputs from the indicated prompt number to the database. It's
808 called by run_cell after code has been executed.
809 called by run_cell after code has been executed.
809
810
810 Parameters
811 Parameters
811 ----------
812 ----------
812 line_num : int
813 line_num : int
813 The line number from which to save outputs
814 The line number from which to save outputs
814 """
815 """
815 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
816 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
816 return
817 return
817 output = self.output_hist_reprs[line_num]
818 output = self.output_hist_reprs[line_num]
818
819
819 with self.db_output_cache_lock:
820 with self.db_output_cache_lock:
820 self.db_output_cache.append((line_num, output))
821 self.db_output_cache.append((line_num, output))
821 if self.db_cache_size <= 1:
822 if self.db_cache_size <= 1:
822 self.save_flag.set()
823 self.save_flag.set()
823
824
824 def _writeout_input_cache(self, conn):
825 def _writeout_input_cache(self, conn):
825 with conn:
826 with conn:
826 for line in self.db_input_cache:
827 for line in self.db_input_cache:
827 conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)",
828 conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)",
828 (self.session_number,)+line)
829 (self.session_number,)+line)
829
830
830 def _writeout_output_cache(self, conn):
831 def _writeout_output_cache(self, conn):
831 with conn:
832 with conn:
832 for line in self.db_output_cache:
833 for line in self.db_output_cache:
833 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
834 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
834 (self.session_number,)+line)
835 (self.session_number,)+line)
835
836
836 @only_when_enabled
837 @only_when_enabled
837 def writeout_cache(self, conn=None):
838 def writeout_cache(self, conn=None):
838 """Write any entries in the cache to the database."""
839 """Write any entries in the cache to the database."""
839 if conn is None:
840 if conn is None:
840 conn = self.db
841 conn = self.db
841
842
842 with self.db_input_cache_lock:
843 with self.db_input_cache_lock:
843 try:
844 try:
844 self._writeout_input_cache(conn)
845 self._writeout_input_cache(conn)
845 except sqlite3.IntegrityError:
846 except sqlite3.IntegrityError:
846 self.new_session(conn)
847 self.new_session(conn)
847 print("ERROR! Session/line number was not unique in",
848 print("ERROR! Session/line number was not unique in",
848 "database. History logging moved to new session",
849 "database. History logging moved to new session",
849 self.session_number)
850 self.session_number)
850 try:
851 try:
851 # Try writing to the new session. If this fails, don't
852 # Try writing to the new session. If this fails, don't
852 # recurse
853 # recurse
853 self._writeout_input_cache(conn)
854 self._writeout_input_cache(conn)
854 except sqlite3.IntegrityError:
855 except sqlite3.IntegrityError:
855 pass
856 pass
856 finally:
857 finally:
857 self.db_input_cache = []
858 self.db_input_cache = []
858
859
859 with self.db_output_cache_lock:
860 with self.db_output_cache_lock:
860 try:
861 try:
861 self._writeout_output_cache(conn)
862 self._writeout_output_cache(conn)
862 except sqlite3.IntegrityError:
863 except sqlite3.IntegrityError:
863 print("!! Session/line number for output was not unique",
864 print("!! Session/line number for output was not unique",
864 "in database. Output will not be stored.")
865 "in database. Output will not be stored.")
865 finally:
866 finally:
866 self.db_output_cache = []
867 self.db_output_cache = []
867
868
868
869
869 class HistorySavingThread(threading.Thread):
870 class HistorySavingThread(threading.Thread):
870 """This thread takes care of writing history to the database, so that
871 """This thread takes care of writing history to the database, so that
871 the UI isn't held up while that happens.
872 the UI isn't held up while that happens.
872
873
873 It waits for the HistoryManager's save_flag to be set, then writes out
874 It waits for the HistoryManager's save_flag to be set, then writes out
874 the history cache. The main thread is responsible for setting the flag when
875 the history cache. The main thread is responsible for setting the flag when
875 the cache size reaches a defined threshold."""
876 the cache size reaches a defined threshold."""
876 daemon = True
877 daemon = True
877 stop_now = False
878 stop_now = False
878 enabled = True
879 enabled = True
879 def __init__(self, history_manager):
880 def __init__(self, history_manager):
880 super(HistorySavingThread, self).__init__(name="IPythonHistorySavingThread")
881 super(HistorySavingThread, self).__init__(name="IPythonHistorySavingThread")
881 self.history_manager = history_manager
882 self.history_manager = history_manager
882 self.enabled = history_manager.enabled
883 self.enabled = history_manager.enabled
883 atexit.register(self.stop)
884 atexit.register(self.stop)
884
885
885 @only_when_enabled
886 @only_when_enabled
886 def run(self):
887 def run(self):
887 # We need a separate db connection per thread:
888 # We need a separate db connection per thread:
888 try:
889 try:
889 self.db = sqlite3.connect(
890 self.db = sqlite3.connect(
890 str(self.history_manager.hist_file),
891 str(self.history_manager.hist_file),
891 **self.history_manager.connection_options,
892 **self.history_manager.connection_options,
892 )
893 )
893 while True:
894 while True:
894 self.history_manager.save_flag.wait()
895 self.history_manager.save_flag.wait()
895 if self.stop_now:
896 if self.stop_now:
896 self.db.close()
897 self.db.close()
897 return
898 return
898 self.history_manager.save_flag.clear()
899 self.history_manager.save_flag.clear()
899 self.history_manager.writeout_cache(self.db)
900 self.history_manager.writeout_cache(self.db)
900 except Exception as e:
901 except Exception as e:
901 print(("The history saving thread hit an unexpected error (%s)."
902 print(("The history saving thread hit an unexpected error (%s)."
902 "History will not be written to the database.") % repr(e))
903 "History will not be written to the database.") % repr(e))
903
904
904 def stop(self):
905 def stop(self):
905 """This can be called from the main thread to safely stop this thread.
906 """This can be called from the main thread to safely stop this thread.
906
907
907 Note that it does not attempt to write out remaining history before
908 Note that it does not attempt to write out remaining history before
908 exiting. That should be done by calling the HistoryManager's
909 exiting. That should be done by calling the HistoryManager's
909 end_session method."""
910 end_session method."""
910 self.stop_now = True
911 self.stop_now = True
911 self.history_manager.save_flag.set()
912 self.history_manager.save_flag.set()
912 self.join()
913 self.join()
913
914
914
915
915 # To match, e.g. ~5/8-~2/3
916 # To match, e.g. ~5/8-~2/3
916 range_re = re.compile(r"""
917 range_re = re.compile(r"""
917 ((?P<startsess>~?\d+)/)?
918 ((?P<startsess>~?\d+)/)?
918 (?P<start>\d+)?
919 (?P<start>\d+)?
919 ((?P<sep>[\-:])
920 ((?P<sep>[\-:])
920 ((?P<endsess>~?\d+)/)?
921 ((?P<endsess>~?\d+)/)?
921 (?P<end>\d+))?
922 (?P<end>\d+))?
922 $""", re.VERBOSE)
923 $""", re.VERBOSE)
923
924
924
925
925 def extract_hist_ranges(ranges_str):
926 def extract_hist_ranges(ranges_str):
926 """Turn a string of history ranges into 3-tuples of (session, start, stop).
927 """Turn a string of history ranges into 3-tuples of (session, start, stop).
927
928
928 Empty string results in a `[(0, 1, None)]`, i.e. "everything from current
929 Empty string results in a `[(0, 1, None)]`, i.e. "everything from current
929 session".
930 session".
930
931
931 Examples
932 Examples
932 --------
933 --------
933 >>> list(extract_hist_ranges("~8/5-~7/4 2"))
934 >>> list(extract_hist_ranges("~8/5-~7/4 2"))
934 [(-8, 5, None), (-7, 1, 5), (0, 2, 3)]
935 [(-8, 5, None), (-7, 1, 5), (0, 2, 3)]
935 """
936 """
936 if ranges_str == "":
937 if ranges_str == "":
937 yield (0, 1, None) # Everything from current session
938 yield (0, 1, None) # Everything from current session
938 return
939 return
939
940
940 for range_str in ranges_str.split():
941 for range_str in ranges_str.split():
941 rmatch = range_re.match(range_str)
942 rmatch = range_re.match(range_str)
942 if not rmatch:
943 if not rmatch:
943 continue
944 continue
944 start = rmatch.group("start")
945 start = rmatch.group("start")
945 if start:
946 if start:
946 start = int(start)
947 start = int(start)
947 end = rmatch.group("end")
948 end = rmatch.group("end")
948 # If no end specified, get (a, a + 1)
949 # If no end specified, get (a, a + 1)
949 end = int(end) if end else start + 1
950 end = int(end) if end else start + 1
950 else: # start not specified
951 else: # start not specified
951 if not rmatch.group('startsess'): # no startsess
952 if not rmatch.group('startsess'): # no startsess
952 continue
953 continue
953 start = 1
954 start = 1
954 end = None # provide the entire session hist
955 end = None # provide the entire session hist
955
956
956 if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3]
957 if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3]
957 end += 1
958 end += 1
958 startsess = rmatch.group("startsess") or "0"
959 startsess = rmatch.group("startsess") or "0"
959 endsess = rmatch.group("endsess") or startsess
960 endsess = rmatch.group("endsess") or startsess
960 startsess = int(startsess.replace("~","-"))
961 startsess = int(startsess.replace("~","-"))
961 endsess = int(endsess.replace("~","-"))
962 endsess = int(endsess.replace("~","-"))
962 assert endsess >= startsess, "start session must be earlier than end session"
963 assert endsess >= startsess, "start session must be earlier than end session"
963
964
964 if endsess == startsess:
965 if endsess == startsess:
965 yield (startsess, start, end)
966 yield (startsess, start, end)
966 continue
967 continue
967 # Multiple sessions in one range:
968 # Multiple sessions in one range:
968 yield (startsess, start, None)
969 yield (startsess, start, None)
969 for sess in range(startsess+1, endsess):
970 for sess in range(startsess+1, endsess):
970 yield (sess, 1, None)
971 yield (sess, 1, None)
971 yield (endsess, 1, end)
972 yield (endsess, 1, end)
972
973
973
974
974 def _format_lineno(session, line):
975 def _format_lineno(session, line):
975 """Helper function to format line numbers properly."""
976 """Helper function to format line numbers properly."""
976 if session == 0:
977 if session == 0:
977 return str(line)
978 return str(line)
978 return "%s#%s" % (session, line)
979 return "%s#%s" % (session, line)
@@ -1,3955 +1,3963 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Main IPython class."""
2 """Main IPython class."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13
13
14 import abc
14 import abc
15 import ast
15 import ast
16 import atexit
16 import atexit
17 import bdb
17 import bdb
18 import builtins as builtin_mod
18 import builtins as builtin_mod
19 import functools
19 import functools
20 import inspect
20 import inspect
21 import os
21 import os
22 import re
22 import re
23 import runpy
23 import runpy
24 import shutil
24 import shutil
25 import subprocess
25 import subprocess
26 import sys
26 import sys
27 import tempfile
27 import tempfile
28 import traceback
28 import traceback
29 import types
29 import types
30 import warnings
30 import warnings
31 from ast import stmt
31 from ast import stmt
32 from io import open as io_open
32 from io import open as io_open
33 from logging import error
33 from logging import error
34 from pathlib import Path
34 from pathlib import Path
35 from typing import Callable
35 from typing import Callable
36 from typing import List as ListType, Dict as DictType, Any as AnyType
36 from typing import List as ListType, Dict as DictType, Any as AnyType
37 from typing import Optional, Sequence, Tuple
37 from typing import Optional, Sequence, Tuple
38 from warnings import warn
38 from warnings import warn
39
39
40 try:
40 try:
41 from pickleshare import PickleShareDB
41 from pickleshare import PickleShareDB
42 except ModuleNotFoundError:
42 except ModuleNotFoundError:
43
43
44 class PickleShareDB: # type: ignore [no-redef]
44 class PickleShareDB: # type: ignore [no-redef]
45 _mock = True
45 _mock = True
46
46
47 def __init__(self, path):
47 def __init__(self, path):
48 pass
48 pass
49
49
50 def get(self, key, default):
50 def get(self, key, default):
51 warn(
51 warn(
52 f"using {key} requires you to install the `pickleshare` library.",
52 f"using {key} requires you to install the `pickleshare` library.",
53 stacklevel=2,
53 stacklevel=2,
54 )
54 )
55 return default
55 return default
56
56
57 def __setitem__(self, key, value):
57 def __setitem__(self, key, value):
58 warn(
58 warn(
59 f"using {key} requires you to install the `pickleshare` library.",
59 f"using {key} requires you to install the `pickleshare` library.",
60 stacklevel=2,
60 stacklevel=2,
61 )
61 )
62
62
63
63
64 from tempfile import TemporaryDirectory
64 from tempfile import TemporaryDirectory
65 from traitlets import (
65 from traitlets import (
66 Any,
66 Any,
67 Bool,
67 Bool,
68 CaselessStrEnum,
68 CaselessStrEnum,
69 Dict,
69 Dict,
70 Enum,
70 Enum,
71 Instance,
71 Instance,
72 Integer,
72 Integer,
73 List,
73 List,
74 Type,
74 Type,
75 Unicode,
75 Unicode,
76 default,
76 default,
77 observe,
77 observe,
78 validate,
78 validate,
79 )
79 )
80 from traitlets.config.configurable import SingletonConfigurable
80 from traitlets.config.configurable import SingletonConfigurable
81 from traitlets.utils.importstring import import_item
81 from traitlets.utils.importstring import import_item
82
82
83 import IPython.core.hooks
83 import IPython.core.hooks
84 from IPython.core import magic, oinspect, page, prefilter, ultratb
84 from IPython.core import magic, oinspect, page, prefilter, ultratb
85 from IPython.core.alias import Alias, AliasManager
85 from IPython.core.alias import Alias, AliasManager
86 from IPython.core.autocall import ExitAutocall
86 from IPython.core.autocall import ExitAutocall
87 from IPython.core.builtin_trap import BuiltinTrap
87 from IPython.core.builtin_trap import BuiltinTrap
88 from IPython.core.compilerop import CachingCompiler
88 from IPython.core.compilerop import CachingCompiler
89 from IPython.core.debugger import InterruptiblePdb
89 from IPython.core.debugger import InterruptiblePdb
90 from IPython.core.display_trap import DisplayTrap
90 from IPython.core.display_trap import DisplayTrap
91 from IPython.core.displayhook import DisplayHook
91 from IPython.core.displayhook import DisplayHook
92 from IPython.core.displaypub import DisplayPublisher
92 from IPython.core.displaypub import DisplayPublisher
93 from IPython.core.error import InputRejected, UsageError
93 from IPython.core.error import InputRejected, UsageError
94 from IPython.core.events import EventManager, available_events
94 from IPython.core.events import EventManager, available_events
95 from IPython.core.extensions import ExtensionManager
95 from IPython.core.extensions import ExtensionManager
96 from IPython.core.formatters import DisplayFormatter
96 from IPython.core.formatters import DisplayFormatter
97 from IPython.core.history import HistoryManager
97 from IPython.core.history import HistoryManager
98 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
98 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
99 from IPython.core.logger import Logger
99 from IPython.core.logger import Logger
100 from IPython.core.macro import Macro
100 from IPython.core.macro import Macro
101 from IPython.core.payload import PayloadManager
101 from IPython.core.payload import PayloadManager
102 from IPython.core.prefilter import PrefilterManager
102 from IPython.core.prefilter import PrefilterManager
103 from IPython.core.profiledir import ProfileDir
103 from IPython.core.profiledir import ProfileDir
104 from IPython.core.usage import default_banner
104 from IPython.core.usage import default_banner
105 from IPython.display import display
105 from IPython.display import display
106 from IPython.paths import get_ipython_dir
106 from IPython.paths import get_ipython_dir
107 from IPython.testing.skipdoctest import skip_doctest
107 from IPython.testing.skipdoctest import skip_doctest
108 from IPython.utils import PyColorize, io, openpy, py3compat
108 from IPython.utils import PyColorize, io, openpy, py3compat
109 from IPython.utils.decorators import undoc
109 from IPython.utils.decorators import undoc
110 from IPython.utils.io import ask_yes_no
110 from IPython.utils.io import ask_yes_no
111 from IPython.utils.ipstruct import Struct
111 from IPython.utils.ipstruct import Struct
112 from IPython.utils.path import ensure_dir_exists, get_home_dir, get_py_filename
112 from IPython.utils.path import ensure_dir_exists, get_home_dir, get_py_filename
113 from IPython.utils.process import getoutput, system
113 from IPython.utils.process import getoutput, system
114 from IPython.utils.strdispatch import StrDispatch
114 from IPython.utils.strdispatch import StrDispatch
115 from IPython.utils.syspathcontext import prepended_to_syspath
115 from IPython.utils.syspathcontext import prepended_to_syspath
116 from IPython.utils.text import DollarFormatter, LSString, SList, format_screen
116 from IPython.utils.text import DollarFormatter, LSString, SList, format_screen
117 from IPython.core.oinspect import OInfo
117 from IPython.core.oinspect import OInfo
118
118
119
119
120 sphinxify: Optional[Callable]
120 sphinxify: Optional[Callable]
121
121
122 try:
122 try:
123 import docrepr.sphinxify as sphx
123 import docrepr.sphinxify as sphx
124
124
125 def sphinxify(oinfo):
125 def sphinxify(oinfo):
126 wrapped_docstring = sphx.wrap_main_docstring(oinfo)
126 wrapped_docstring = sphx.wrap_main_docstring(oinfo)
127
127
128 def sphinxify_docstring(docstring):
128 def sphinxify_docstring(docstring):
129 with TemporaryDirectory() as dirname:
129 with TemporaryDirectory() as dirname:
130 return {
130 return {
131 "text/html": sphx.sphinxify(wrapped_docstring, dirname),
131 "text/html": sphx.sphinxify(wrapped_docstring, dirname),
132 "text/plain": docstring,
132 "text/plain": docstring,
133 }
133 }
134
134
135 return sphinxify_docstring
135 return sphinxify_docstring
136 except ImportError:
136 except ImportError:
137 sphinxify = None
137 sphinxify = None
138
138
139 if sys.version_info[:2] < (3, 11):
139 if sys.version_info[:2] < (3, 11):
140 from exceptiongroup import BaseExceptionGroup
140 from exceptiongroup import BaseExceptionGroup
141
141
142 class ProvisionalWarning(DeprecationWarning):
142 class ProvisionalWarning(DeprecationWarning):
143 """
143 """
144 Warning class for unstable features
144 Warning class for unstable features
145 """
145 """
146 pass
146 pass
147
147
148 from ast import Module
148 from ast import Module
149
149
150 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
150 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
151 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
151 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
152
152
153 #-----------------------------------------------------------------------------
153 #-----------------------------------------------------------------------------
154 # Await Helpers
154 # Await Helpers
155 #-----------------------------------------------------------------------------
155 #-----------------------------------------------------------------------------
156
156
157 # we still need to run things using the asyncio eventloop, but there is no
157 # we still need to run things using the asyncio eventloop, but there is no
158 # async integration
158 # async integration
159 from .async_helpers import (
159 from .async_helpers import (
160 _asyncio_runner,
160 _asyncio_runner,
161 _curio_runner,
161 _curio_runner,
162 _pseudo_sync_runner,
162 _pseudo_sync_runner,
163 _should_be_async,
163 _should_be_async,
164 _trio_runner,
164 _trio_runner,
165 )
165 )
166
166
167 #-----------------------------------------------------------------------------
167 #-----------------------------------------------------------------------------
168 # Globals
168 # Globals
169 #-----------------------------------------------------------------------------
169 #-----------------------------------------------------------------------------
170
170
171 # compiled regexps for autoindent management
171 # compiled regexps for autoindent management
172 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
172 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
173
173
174 #-----------------------------------------------------------------------------
174 #-----------------------------------------------------------------------------
175 # Utilities
175 # Utilities
176 #-----------------------------------------------------------------------------
176 #-----------------------------------------------------------------------------
177
177
178
178
179 def is_integer_string(s: str):
179 def is_integer_string(s: str):
180 """
180 """
181 Variant of "str.isnumeric()" that allow negative values and other ints.
181 Variant of "str.isnumeric()" that allow negative values and other ints.
182 """
182 """
183 try:
183 try:
184 int(s)
184 int(s)
185 return True
185 return True
186 except ValueError:
186 except ValueError:
187 return False
187 return False
188 raise ValueError("Unexpected error")
188 raise ValueError("Unexpected error")
189
189
190
190
191 @undoc
191 @undoc
192 def softspace(file, newvalue):
192 def softspace(file, newvalue):
193 """Copied from code.py, to remove the dependency"""
193 """Copied from code.py, to remove the dependency"""
194
194
195 oldvalue = 0
195 oldvalue = 0
196 try:
196 try:
197 oldvalue = file.softspace
197 oldvalue = file.softspace
198 except AttributeError:
198 except AttributeError:
199 pass
199 pass
200 try:
200 try:
201 file.softspace = newvalue
201 file.softspace = newvalue
202 except (AttributeError, TypeError):
202 except (AttributeError, TypeError):
203 # "attribute-less object" or "read-only attributes"
203 # "attribute-less object" or "read-only attributes"
204 pass
204 pass
205 return oldvalue
205 return oldvalue
206
206
207 @undoc
207 @undoc
208 def no_op(*a, **kw):
208 def no_op(*a, **kw):
209 pass
209 pass
210
210
211
211
212 class SpaceInInput(Exception): pass
212 class SpaceInInput(Exception): pass
213
213
214
214
215 class SeparateUnicode(Unicode):
215 class SeparateUnicode(Unicode):
216 r"""A Unicode subclass to validate separate_in, separate_out, etc.
216 r"""A Unicode subclass to validate separate_in, separate_out, etc.
217
217
218 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
218 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
219 """
219 """
220
220
221 def validate(self, obj, value):
221 def validate(self, obj, value):
222 if value == '0': value = ''
222 if value == '0': value = ''
223 value = value.replace('\\n','\n')
223 value = value.replace('\\n','\n')
224 return super(SeparateUnicode, self).validate(obj, value)
224 return super(SeparateUnicode, self).validate(obj, value)
225
225
226
226
227 @undoc
227 @undoc
228 class DummyMod(object):
228 class DummyMod(object):
229 """A dummy module used for IPython's interactive module when
229 """A dummy module used for IPython's interactive module when
230 a namespace must be assigned to the module's __dict__."""
230 a namespace must be assigned to the module's __dict__."""
231 __spec__ = None
231 __spec__ = None
232
232
233
233
234 class ExecutionInfo(object):
234 class ExecutionInfo(object):
235 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
235 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
236
236
237 Stores information about what is going to happen.
237 Stores information about what is going to happen.
238 """
238 """
239 raw_cell = None
239 raw_cell = None
240 store_history = False
240 store_history = False
241 silent = False
241 silent = False
242 shell_futures = True
242 shell_futures = True
243 cell_id = None
243 cell_id = None
244
244
245 def __init__(self, raw_cell, store_history, silent, shell_futures, cell_id):
245 def __init__(self, raw_cell, store_history, silent, shell_futures, cell_id):
246 self.raw_cell = raw_cell
246 self.raw_cell = raw_cell
247 self.store_history = store_history
247 self.store_history = store_history
248 self.silent = silent
248 self.silent = silent
249 self.shell_futures = shell_futures
249 self.shell_futures = shell_futures
250 self.cell_id = cell_id
250 self.cell_id = cell_id
251
251
252 def __repr__(self):
252 def __repr__(self):
253 name = self.__class__.__qualname__
253 name = self.__class__.__qualname__
254 raw_cell = (
254 raw_cell = (
255 (self.raw_cell[:50] + "..") if len(self.raw_cell) > 50 else self.raw_cell
255 (self.raw_cell[:50] + "..") if len(self.raw_cell) > 50 else self.raw_cell
256 )
256 )
257 return (
257 return (
258 '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s cell_id=%s>'
258 '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s cell_id=%s>'
259 % (
259 % (
260 name,
260 name,
261 id(self),
261 id(self),
262 raw_cell,
262 raw_cell,
263 self.store_history,
263 self.store_history,
264 self.silent,
264 self.silent,
265 self.shell_futures,
265 self.shell_futures,
266 self.cell_id,
266 self.cell_id,
267 )
267 )
268 )
268 )
269
269
270
270
271 class ExecutionResult(object):
271 class ExecutionResult(object):
272 """The result of a call to :meth:`InteractiveShell.run_cell`
272 """The result of a call to :meth:`InteractiveShell.run_cell`
273
273
274 Stores information about what took place.
274 Stores information about what took place.
275 """
275 """
276 execution_count = None
276 execution_count = None
277 error_before_exec = None
277 error_before_exec = None
278 error_in_exec: Optional[BaseException] = None
278 error_in_exec: Optional[BaseException] = None
279 info = None
279 info = None
280 result = None
280 result = None
281
281
282 def __init__(self, info):
282 def __init__(self, info):
283 self.info = info
283 self.info = info
284
284
285 @property
285 @property
286 def success(self):
286 def success(self):
287 return (self.error_before_exec is None) and (self.error_in_exec is None)
287 return (self.error_before_exec is None) and (self.error_in_exec is None)
288
288
289 def raise_error(self):
289 def raise_error(self):
290 """Reraises error if `success` is `False`, otherwise does nothing"""
290 """Reraises error if `success` is `False`, otherwise does nothing"""
291 if self.error_before_exec is not None:
291 if self.error_before_exec is not None:
292 raise self.error_before_exec
292 raise self.error_before_exec
293 if self.error_in_exec is not None:
293 if self.error_in_exec is not None:
294 raise self.error_in_exec
294 raise self.error_in_exec
295
295
296 def __repr__(self):
296 def __repr__(self):
297 name = self.__class__.__qualname__
297 name = self.__class__.__qualname__
298 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\
298 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\
299 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
299 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
300
300
301 @functools.wraps(io_open)
301 @functools.wraps(io_open)
302 def _modified_open(file, *args, **kwargs):
302 def _modified_open(file, *args, **kwargs):
303 if file in {0, 1, 2}:
303 if file in {0, 1, 2}:
304 raise ValueError(
304 raise ValueError(
305 f"IPython won't let you open fd={file} by default "
305 f"IPython won't let you open fd={file} by default "
306 "as it is likely to crash IPython. If you know what you are doing, "
306 "as it is likely to crash IPython. If you know what you are doing, "
307 "you can use builtins' open."
307 "you can use builtins' open."
308 )
308 )
309
309
310 return io_open(file, *args, **kwargs)
310 return io_open(file, *args, **kwargs)
311
311
312 class InteractiveShell(SingletonConfigurable):
312 class InteractiveShell(SingletonConfigurable):
313 """An enhanced, interactive shell for Python."""
313 """An enhanced, interactive shell for Python."""
314
314
315 _instance = None
315 _instance = None
316
316
317 ast_transformers = List([], help=
317 ast_transformers: List[ast.NodeTransformer] = List(
318 """
318 [],
319 help="""
319 A list of ast.NodeTransformer subclass instances, which will be applied
320 A list of ast.NodeTransformer subclass instances, which will be applied
320 to user input before code is run.
321 to user input before code is run.
321 """
322 """,
322 ).tag(config=True)
323 ).tag(config=True)
323
324
324 autocall = Enum((0,1,2), default_value=0, help=
325 autocall = Enum((0,1,2), default_value=0, help=
325 """
326 """
326 Make IPython automatically call any callable object even if you didn't
327 Make IPython automatically call any callable object even if you didn't
327 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
328 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
328 automatically. The value can be '0' to disable the feature, '1' for
329 automatically. The value can be '0' to disable the feature, '1' for
329 'smart' autocall, where it is not applied if there are no more
330 'smart' autocall, where it is not applied if there are no more
330 arguments on the line, and '2' for 'full' autocall, where all callable
331 arguments on the line, and '2' for 'full' autocall, where all callable
331 objects are automatically called (even if no arguments are present).
332 objects are automatically called (even if no arguments are present).
332 """
333 """
333 ).tag(config=True)
334 ).tag(config=True)
334
335
335 autoindent = Bool(True, help=
336 autoindent = Bool(True, help=
336 """
337 """
337 Autoindent IPython code entered interactively.
338 Autoindent IPython code entered interactively.
338 """
339 """
339 ).tag(config=True)
340 ).tag(config=True)
340
341
341 autoawait = Bool(True, help=
342 autoawait = Bool(True, help=
342 """
343 """
343 Automatically run await statement in the top level repl.
344 Automatically run await statement in the top level repl.
344 """
345 """
345 ).tag(config=True)
346 ).tag(config=True)
346
347
347 loop_runner_map ={
348 loop_runner_map ={
348 'asyncio':(_asyncio_runner, True),
349 'asyncio':(_asyncio_runner, True),
349 'curio':(_curio_runner, True),
350 'curio':(_curio_runner, True),
350 'trio':(_trio_runner, True),
351 'trio':(_trio_runner, True),
351 'sync': (_pseudo_sync_runner, False)
352 'sync': (_pseudo_sync_runner, False)
352 }
353 }
353
354
354 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
355 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
355 allow_none=True,
356 allow_none=True,
356 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
357 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
357 ).tag(config=True)
358 ).tag(config=True)
358
359
359 @default('loop_runner')
360 @default('loop_runner')
360 def _default_loop_runner(self):
361 def _default_loop_runner(self):
361 return import_item("IPython.core.interactiveshell._asyncio_runner")
362 return import_item("IPython.core.interactiveshell._asyncio_runner")
362
363
363 @validate('loop_runner')
364 @validate('loop_runner')
364 def _import_runner(self, proposal):
365 def _import_runner(self, proposal):
365 if isinstance(proposal.value, str):
366 if isinstance(proposal.value, str):
366 if proposal.value in self.loop_runner_map:
367 if proposal.value in self.loop_runner_map:
367 runner, autoawait = self.loop_runner_map[proposal.value]
368 runner, autoawait = self.loop_runner_map[proposal.value]
368 self.autoawait = autoawait
369 self.autoawait = autoawait
369 return runner
370 return runner
370 runner = import_item(proposal.value)
371 runner = import_item(proposal.value)
371 if not callable(runner):
372 if not callable(runner):
372 raise ValueError('loop_runner must be callable')
373 raise ValueError('loop_runner must be callable')
373 return runner
374 return runner
374 if not callable(proposal.value):
375 if not callable(proposal.value):
375 raise ValueError('loop_runner must be callable')
376 raise ValueError('loop_runner must be callable')
376 return proposal.value
377 return proposal.value
377
378
378 automagic = Bool(True, help=
379 automagic = Bool(True, help=
379 """
380 """
380 Enable magic commands to be called without the leading %.
381 Enable magic commands to be called without the leading %.
381 """
382 """
382 ).tag(config=True)
383 ).tag(config=True)
383
384
384 banner1 = Unicode(default_banner,
385 banner1 = Unicode(default_banner,
385 help="""The part of the banner to be printed before the profile"""
386 help="""The part of the banner to be printed before the profile"""
386 ).tag(config=True)
387 ).tag(config=True)
387 banner2 = Unicode('',
388 banner2 = Unicode('',
388 help="""The part of the banner to be printed after the profile"""
389 help="""The part of the banner to be printed after the profile"""
389 ).tag(config=True)
390 ).tag(config=True)
390
391
391 cache_size = Integer(1000, help=
392 cache_size = Integer(1000, help=
392 """
393 """
393 Set the size of the output cache. The default is 1000, you can
394 Set the size of the output cache. The default is 1000, you can
394 change it permanently in your config file. Setting it to 0 completely
395 change it permanently in your config file. Setting it to 0 completely
395 disables the caching system, and the minimum value accepted is 3 (if
396 disables the caching system, and the minimum value accepted is 3 (if
396 you provide a value less than 3, it is reset to 0 and a warning is
397 you provide a value less than 3, it is reset to 0 and a warning is
397 issued). This limit is defined because otherwise you'll spend more
398 issued). This limit is defined because otherwise you'll spend more
398 time re-flushing a too small cache than working
399 time re-flushing a too small cache than working
399 """
400 """
400 ).tag(config=True)
401 ).tag(config=True)
401 color_info = Bool(True, help=
402 color_info = Bool(True, help=
402 """
403 """
403 Use colors for displaying information about objects. Because this
404 Use colors for displaying information about objects. Because this
404 information is passed through a pager (like 'less'), and some pagers
405 information is passed through a pager (like 'less'), and some pagers
405 get confused with color codes, this capability can be turned off.
406 get confused with color codes, this capability can be turned off.
406 """
407 """
407 ).tag(config=True)
408 ).tag(config=True)
408 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
409 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
409 default_value='Neutral',
410 default_value='Neutral',
410 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
411 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
411 ).tag(config=True)
412 ).tag(config=True)
412 debug = Bool(False).tag(config=True)
413 debug = Bool(False).tag(config=True)
413 disable_failing_post_execute = Bool(False,
414 disable_failing_post_execute = Bool(False,
414 help="Don't call post-execute functions that have failed in the past."
415 help="Don't call post-execute functions that have failed in the past."
415 ).tag(config=True)
416 ).tag(config=True)
416 display_formatter = Instance(DisplayFormatter, allow_none=True)
417 display_formatter = Instance(DisplayFormatter, allow_none=True)
417 displayhook_class = Type(DisplayHook)
418 displayhook_class = Type(DisplayHook)
418 display_pub_class = Type(DisplayPublisher)
419 display_pub_class = Type(DisplayPublisher)
419 compiler_class = Type(CachingCompiler)
420 compiler_class = Type(CachingCompiler)
420 inspector_class = Type(
421 inspector_class = Type(
421 oinspect.Inspector, help="Class to use to instantiate the shell inspector"
422 oinspect.Inspector, help="Class to use to instantiate the shell inspector"
422 ).tag(config=True)
423 ).tag(config=True)
423
424
424 sphinxify_docstring = Bool(False, help=
425 sphinxify_docstring = Bool(False, help=
425 """
426 """
426 Enables rich html representation of docstrings. (This requires the
427 Enables rich html representation of docstrings. (This requires the
427 docrepr module).
428 docrepr module).
428 """).tag(config=True)
429 """).tag(config=True)
429
430
430 @observe("sphinxify_docstring")
431 @observe("sphinxify_docstring")
431 def _sphinxify_docstring_changed(self, change):
432 def _sphinxify_docstring_changed(self, change):
432 if change['new']:
433 if change['new']:
433 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
434 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
434
435
435 enable_html_pager = Bool(False, help=
436 enable_html_pager = Bool(False, help=
436 """
437 """
437 (Provisional API) enables html representation in mime bundles sent
438 (Provisional API) enables html representation in mime bundles sent
438 to pagers.
439 to pagers.
439 """).tag(config=True)
440 """).tag(config=True)
440
441
441 @observe("enable_html_pager")
442 @observe("enable_html_pager")
442 def _enable_html_pager_changed(self, change):
443 def _enable_html_pager_changed(self, change):
443 if change['new']:
444 if change['new']:
444 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
445 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
445
446
446 data_pub_class = None
447 data_pub_class = None
447
448
448 exit_now = Bool(False)
449 exit_now = Bool(False)
449 exiter = Instance(ExitAutocall)
450 exiter = Instance(ExitAutocall)
450 @default('exiter')
451 @default('exiter')
451 def _exiter_default(self):
452 def _exiter_default(self):
452 return ExitAutocall(self)
453 return ExitAutocall(self)
453 # Monotonically increasing execution counter
454 # Monotonically increasing execution counter
454 execution_count = Integer(1)
455 execution_count = Integer(1)
455 filename = Unicode("<ipython console>")
456 filename = Unicode("<ipython console>")
456 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
457 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
457
458
458 # Used to transform cells before running them, and check whether code is complete
459 # Used to transform cells before running them, and check whether code is complete
459 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
460 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
460 ())
461 ())
461
462
462 @property
463 @property
463 def input_transformers_cleanup(self):
464 def input_transformers_cleanup(self):
464 return self.input_transformer_manager.cleanup_transforms
465 return self.input_transformer_manager.cleanup_transforms
465
466
466 input_transformers_post = List([],
467 input_transformers_post = List([],
467 help="A list of string input transformers, to be applied after IPython's "
468 help="A list of string input transformers, to be applied after IPython's "
468 "own input transformations."
469 "own input transformations."
469 )
470 )
470
471
471 @property
472 @property
472 def input_splitter(self):
473 def input_splitter(self):
473 """Make this available for backward compatibility (pre-7.0 release) with existing code.
474 """Make this available for backward compatibility (pre-7.0 release) with existing code.
474
475
475 For example, ipykernel ipykernel currently uses
476 For example, ipykernel ipykernel currently uses
476 `shell.input_splitter.check_complete`
477 `shell.input_splitter.check_complete`
477 """
478 """
478 from warnings import warn
479 from warnings import warn
479 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
480 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
480 DeprecationWarning, stacklevel=2
481 DeprecationWarning, stacklevel=2
481 )
482 )
482 return self.input_transformer_manager
483 return self.input_transformer_manager
483
484
484 logstart = Bool(False, help=
485 logstart = Bool(False, help=
485 """
486 """
486 Start logging to the default log file in overwrite mode.
487 Start logging to the default log file in overwrite mode.
487 Use `logappend` to specify a log file to **append** logs to.
488 Use `logappend` to specify a log file to **append** logs to.
488 """
489 """
489 ).tag(config=True)
490 ).tag(config=True)
490 logfile = Unicode('', help=
491 logfile = Unicode('', help=
491 """
492 """
492 The name of the logfile to use.
493 The name of the logfile to use.
493 """
494 """
494 ).tag(config=True)
495 ).tag(config=True)
495 logappend = Unicode('', help=
496 logappend = Unicode('', help=
496 """
497 """
497 Start logging to the given file in append mode.
498 Start logging to the given file in append mode.
498 Use `logfile` to specify a log file to **overwrite** logs to.
499 Use `logfile` to specify a log file to **overwrite** logs to.
499 """
500 """
500 ).tag(config=True)
501 ).tag(config=True)
501 object_info_string_level = Enum((0,1,2), default_value=0,
502 object_info_string_level = Enum((0,1,2), default_value=0,
502 ).tag(config=True)
503 ).tag(config=True)
503 pdb = Bool(False, help=
504 pdb = Bool(False, help=
504 """
505 """
505 Automatically call the pdb debugger after every exception.
506 Automatically call the pdb debugger after every exception.
506 """
507 """
507 ).tag(config=True)
508 ).tag(config=True)
508 display_page = Bool(False,
509 display_page = Bool(False,
509 help="""If True, anything that would be passed to the pager
510 help="""If True, anything that would be passed to the pager
510 will be displayed as regular output instead."""
511 will be displayed as regular output instead."""
511 ).tag(config=True)
512 ).tag(config=True)
512
513
513
514
514 show_rewritten_input = Bool(True,
515 show_rewritten_input = Bool(True,
515 help="Show rewritten input, e.g. for autocall."
516 help="Show rewritten input, e.g. for autocall."
516 ).tag(config=True)
517 ).tag(config=True)
517
518
518 quiet = Bool(False).tag(config=True)
519 quiet = Bool(False).tag(config=True)
519
520
520 history_length = Integer(10000,
521 history_length = Integer(10000,
521 help='Total length of command history'
522 help='Total length of command history'
522 ).tag(config=True)
523 ).tag(config=True)
523
524
524 history_load_length = Integer(1000, help=
525 history_load_length = Integer(1000, help=
525 """
526 """
526 The number of saved history entries to be loaded
527 The number of saved history entries to be loaded
527 into the history buffer at startup.
528 into the history buffer at startup.
528 """
529 """
529 ).tag(config=True)
530 ).tag(config=True)
530
531
531 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
532 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
532 default_value='last_expr',
533 default_value='last_expr',
533 help="""
534 help="""
534 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
535 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
535 which nodes should be run interactively (displaying output from expressions).
536 which nodes should be run interactively (displaying output from expressions).
536 """
537 """
537 ).tag(config=True)
538 ).tag(config=True)
538
539
539 warn_venv = Bool(
540 warn_venv = Bool(
540 True,
541 True,
541 help="Warn if running in a virtual environment with no IPython installed (so IPython from the global environment is used).",
542 help="Warn if running in a virtual environment with no IPython installed (so IPython from the global environment is used).",
542 ).tag(config=True)
543 ).tag(config=True)
543
544
544 # TODO: this part of prompt management should be moved to the frontends.
545 # TODO: this part of prompt management should be moved to the frontends.
545 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
546 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
546 separate_in = SeparateUnicode('\n').tag(config=True)
547 separate_in = SeparateUnicode('\n').tag(config=True)
547 separate_out = SeparateUnicode('').tag(config=True)
548 separate_out = SeparateUnicode('').tag(config=True)
548 separate_out2 = SeparateUnicode('').tag(config=True)
549 separate_out2 = SeparateUnicode('').tag(config=True)
549 wildcards_case_sensitive = Bool(True).tag(config=True)
550 wildcards_case_sensitive = Bool(True).tag(config=True)
550 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
551 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
551 default_value='Context',
552 default_value='Context',
552 help="Switch modes for the IPython exception handlers."
553 help="Switch modes for the IPython exception handlers."
553 ).tag(config=True)
554 ).tag(config=True)
554
555
555 # Subcomponents of InteractiveShell
556 # Subcomponents of InteractiveShell
556 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
557 alias_manager = Instance("IPython.core.alias.AliasManager", allow_none=True)
557 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
558 prefilter_manager = Instance(
558 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
559 "IPython.core.prefilter.PrefilterManager", allow_none=True
559 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
560 )
560 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
561 builtin_trap = Instance("IPython.core.builtin_trap.BuiltinTrap")
561 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
562 display_trap = Instance("IPython.core.display_trap.DisplayTrap")
562 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
563 extension_manager = Instance(
563 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
564 "IPython.core.extensions.ExtensionManager", allow_none=True
565 )
566 payload_manager = Instance("IPython.core.payload.PayloadManager", allow_none=True)
567 history_manager = Instance(
568 "IPython.core.history.HistoryAccessorBase", allow_none=True
569 )
570 magics_manager = Instance("IPython.core.magic.MagicsManager")
564
571
565 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
572 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
566 @property
573 @property
567 def profile(self):
574 def profile(self):
568 if self.profile_dir is not None:
575 if self.profile_dir is not None:
569 name = os.path.basename(self.profile_dir.location)
576 name = os.path.basename(self.profile_dir.location)
570 return name.replace('profile_','')
577 return name.replace('profile_','')
571
578
572
579
573 # Private interface
580 # Private interface
574 _post_execute = Dict()
581 _post_execute = Dict()
575
582
576 # Tracks any GUI loop loaded for pylab
583 # Tracks any GUI loop loaded for pylab
577 pylab_gui_select = None
584 pylab_gui_select = None
578
585
579 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
586 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
580
587
581 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
588 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
582
589
583 def __init__(self, ipython_dir=None, profile_dir=None,
590 def __init__(self, ipython_dir=None, profile_dir=None,
584 user_module=None, user_ns=None,
591 user_module=None, user_ns=None,
585 custom_exceptions=((), None), **kwargs):
592 custom_exceptions=((), None), **kwargs):
586 # This is where traits with a config_key argument are updated
593 # This is where traits with a config_key argument are updated
587 # from the values on config.
594 # from the values on config.
588 super(InteractiveShell, self).__init__(**kwargs)
595 super(InteractiveShell, self).__init__(**kwargs)
589 if 'PromptManager' in self.config:
596 if 'PromptManager' in self.config:
590 warn('As of IPython 5.0 `PromptManager` config will have no effect'
597 warn('As of IPython 5.0 `PromptManager` config will have no effect'
591 ' and has been replaced by TerminalInteractiveShell.prompts_class')
598 ' and has been replaced by TerminalInteractiveShell.prompts_class')
592 self.configurables = [self]
599 self.configurables = [self]
593
600
594 # These are relatively independent and stateless
601 # These are relatively independent and stateless
595 self.init_ipython_dir(ipython_dir)
602 self.init_ipython_dir(ipython_dir)
596 self.init_profile_dir(profile_dir)
603 self.init_profile_dir(profile_dir)
597 self.init_instance_attrs()
604 self.init_instance_attrs()
598 self.init_environment()
605 self.init_environment()
599
606
600 # Check if we're in a virtualenv, and set up sys.path.
607 # Check if we're in a virtualenv, and set up sys.path.
601 self.init_virtualenv()
608 self.init_virtualenv()
602
609
603 # Create namespaces (user_ns, user_global_ns, etc.)
610 # Create namespaces (user_ns, user_global_ns, etc.)
604 self.init_create_namespaces(user_module, user_ns)
611 self.init_create_namespaces(user_module, user_ns)
605 # This has to be done after init_create_namespaces because it uses
612 # This has to be done after init_create_namespaces because it uses
606 # something in self.user_ns, but before init_sys_modules, which
613 # something in self.user_ns, but before init_sys_modules, which
607 # is the first thing to modify sys.
614 # is the first thing to modify sys.
608 # TODO: When we override sys.stdout and sys.stderr before this class
615 # TODO: When we override sys.stdout and sys.stderr before this class
609 # is created, we are saving the overridden ones here. Not sure if this
616 # is created, we are saving the overridden ones here. Not sure if this
610 # is what we want to do.
617 # is what we want to do.
611 self.save_sys_module_state()
618 self.save_sys_module_state()
612 self.init_sys_modules()
619 self.init_sys_modules()
613
620
614 # While we're trying to have each part of the code directly access what
621 # While we're trying to have each part of the code directly access what
615 # it needs without keeping redundant references to objects, we have too
622 # it needs without keeping redundant references to objects, we have too
616 # much legacy code that expects ip.db to exist.
623 # much legacy code that expects ip.db to exist.
617 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
624 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
618
625
619 self.init_history()
626 self.init_history()
620 self.init_encoding()
627 self.init_encoding()
621 self.init_prefilter()
628 self.init_prefilter()
622
629
623 self.init_syntax_highlighting()
630 self.init_syntax_highlighting()
624 self.init_hooks()
631 self.init_hooks()
625 self.init_events()
632 self.init_events()
626 self.init_pushd_popd_magic()
633 self.init_pushd_popd_magic()
627 self.init_user_ns()
634 self.init_user_ns()
628 self.init_logger()
635 self.init_logger()
629 self.init_builtins()
636 self.init_builtins()
630
637
631 # The following was in post_config_initialization
638 # The following was in post_config_initialization
632 self.init_inspector()
639 self.init_inspector()
633 self.raw_input_original = input
640 self.raw_input_original = input
634 self.init_completer()
641 self.init_completer()
635 # TODO: init_io() needs to happen before init_traceback handlers
642 # TODO: init_io() needs to happen before init_traceback handlers
636 # because the traceback handlers hardcode the stdout/stderr streams.
643 # because the traceback handlers hardcode the stdout/stderr streams.
637 # This logic in in debugger.Pdb and should eventually be changed.
644 # This logic in in debugger.Pdb and should eventually be changed.
638 self.init_io()
645 self.init_io()
639 self.init_traceback_handlers(custom_exceptions)
646 self.init_traceback_handlers(custom_exceptions)
640 self.init_prompts()
647 self.init_prompts()
641 self.init_display_formatter()
648 self.init_display_formatter()
642 self.init_display_pub()
649 self.init_display_pub()
643 self.init_data_pub()
650 self.init_data_pub()
644 self.init_displayhook()
651 self.init_displayhook()
645 self.init_magics()
652 self.init_magics()
646 self.init_alias()
653 self.init_alias()
647 self.init_logstart()
654 self.init_logstart()
648 self.init_pdb()
655 self.init_pdb()
649 self.init_extension_manager()
656 self.init_extension_manager()
650 self.init_payload()
657 self.init_payload()
651 self.events.trigger('shell_initialized', self)
658 self.events.trigger('shell_initialized', self)
652 atexit.register(self.atexit_operations)
659 atexit.register(self.atexit_operations)
653
660
654 # The trio runner is used for running Trio in the foreground thread. It
661 # The trio runner is used for running Trio in the foreground thread. It
655 # is different from `_trio_runner(async_fn)` in `async_helpers.py`
662 # is different from `_trio_runner(async_fn)` in `async_helpers.py`
656 # which calls `trio.run()` for every cell. This runner runs all cells
663 # which calls `trio.run()` for every cell. This runner runs all cells
657 # inside a single Trio event loop. If used, it is set from
664 # inside a single Trio event loop. If used, it is set from
658 # `ipykernel.kernelapp`.
665 # `ipykernel.kernelapp`.
659 self.trio_runner = None
666 self.trio_runner = None
660
667
661 def get_ipython(self):
668 def get_ipython(self):
662 """Return the currently running IPython instance."""
669 """Return the currently running IPython instance."""
663 return self
670 return self
664
671
665 #-------------------------------------------------------------------------
672 #-------------------------------------------------------------------------
666 # Trait changed handlers
673 # Trait changed handlers
667 #-------------------------------------------------------------------------
674 #-------------------------------------------------------------------------
668 @observe('ipython_dir')
675 @observe('ipython_dir')
669 def _ipython_dir_changed(self, change):
676 def _ipython_dir_changed(self, change):
670 ensure_dir_exists(change['new'])
677 ensure_dir_exists(change['new'])
671
678
672 def set_autoindent(self,value=None):
679 def set_autoindent(self,value=None):
673 """Set the autoindent flag.
680 """Set the autoindent flag.
674
681
675 If called with no arguments, it acts as a toggle."""
682 If called with no arguments, it acts as a toggle."""
676 if value is None:
683 if value is None:
677 self.autoindent = not self.autoindent
684 self.autoindent = not self.autoindent
678 else:
685 else:
679 self.autoindent = value
686 self.autoindent = value
680
687
681 def set_trio_runner(self, tr):
688 def set_trio_runner(self, tr):
682 self.trio_runner = tr
689 self.trio_runner = tr
683
690
684 #-------------------------------------------------------------------------
691 #-------------------------------------------------------------------------
685 # init_* methods called by __init__
692 # init_* methods called by __init__
686 #-------------------------------------------------------------------------
693 #-------------------------------------------------------------------------
687
694
688 def init_ipython_dir(self, ipython_dir):
695 def init_ipython_dir(self, ipython_dir):
689 if ipython_dir is not None:
696 if ipython_dir is not None:
690 self.ipython_dir = ipython_dir
697 self.ipython_dir = ipython_dir
691 return
698 return
692
699
693 self.ipython_dir = get_ipython_dir()
700 self.ipython_dir = get_ipython_dir()
694
701
695 def init_profile_dir(self, profile_dir):
702 def init_profile_dir(self, profile_dir):
696 if profile_dir is not None:
703 if profile_dir is not None:
697 self.profile_dir = profile_dir
704 self.profile_dir = profile_dir
698 return
705 return
699 self.profile_dir = ProfileDir.create_profile_dir_by_name(
706 self.profile_dir = ProfileDir.create_profile_dir_by_name(
700 self.ipython_dir, "default"
707 self.ipython_dir, "default"
701 )
708 )
702
709
703 def init_instance_attrs(self):
710 def init_instance_attrs(self):
704 self.more = False
711 self.more = False
705
712
706 # command compiler
713 # command compiler
707 self.compile = self.compiler_class()
714 self.compile = self.compiler_class()
708
715
709 # Make an empty namespace, which extension writers can rely on both
716 # Make an empty namespace, which extension writers can rely on both
710 # existing and NEVER being used by ipython itself. This gives them a
717 # existing and NEVER being used by ipython itself. This gives them a
711 # convenient location for storing additional information and state
718 # convenient location for storing additional information and state
712 # their extensions may require, without fear of collisions with other
719 # their extensions may require, without fear of collisions with other
713 # ipython names that may develop later.
720 # ipython names that may develop later.
714 self.meta = Struct()
721 self.meta = Struct()
715
722
716 # Temporary files used for various purposes. Deleted at exit.
723 # Temporary files used for various purposes. Deleted at exit.
717 # The files here are stored with Path from Pathlib
724 # The files here are stored with Path from Pathlib
718 self.tempfiles = []
725 self.tempfiles = []
719 self.tempdirs = []
726 self.tempdirs = []
720
727
721 # keep track of where we started running (mainly for crash post-mortem)
728 # keep track of where we started running (mainly for crash post-mortem)
722 # This is not being used anywhere currently.
729 # This is not being used anywhere currently.
723 self.starting_dir = os.getcwd()
730 self.starting_dir = os.getcwd()
724
731
725 # Indentation management
732 # Indentation management
726 self.indent_current_nsp = 0
733 self.indent_current_nsp = 0
727
734
728 # Dict to track post-execution functions that have been registered
735 # Dict to track post-execution functions that have been registered
729 self._post_execute = {}
736 self._post_execute = {}
730
737
731 def init_environment(self):
738 def init_environment(self):
732 """Any changes we need to make to the user's environment."""
739 """Any changes we need to make to the user's environment."""
733 pass
740 pass
734
741
735 def init_encoding(self):
742 def init_encoding(self):
736 # Get system encoding at startup time. Certain terminals (like Emacs
743 # Get system encoding at startup time. Certain terminals (like Emacs
737 # under Win32 have it set to None, and we need to have a known valid
744 # under Win32 have it set to None, and we need to have a known valid
738 # encoding to use in the raw_input() method
745 # encoding to use in the raw_input() method
739 try:
746 try:
740 self.stdin_encoding = sys.stdin.encoding or 'ascii'
747 self.stdin_encoding = sys.stdin.encoding or 'ascii'
741 except AttributeError:
748 except AttributeError:
742 self.stdin_encoding = 'ascii'
749 self.stdin_encoding = 'ascii'
743
750
744
751
745 @observe('colors')
752 @observe('colors')
746 def init_syntax_highlighting(self, changes=None):
753 def init_syntax_highlighting(self, changes=None):
747 # Python source parser/formatter for syntax highlighting
754 # Python source parser/formatter for syntax highlighting
748 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
755 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
749 self.pycolorize = lambda src: pyformat(src,'str')
756 self.pycolorize = lambda src: pyformat(src,'str')
750
757
751 def refresh_style(self):
758 def refresh_style(self):
752 # No-op here, used in subclass
759 # No-op here, used in subclass
753 pass
760 pass
754
761
755 def init_pushd_popd_magic(self):
762 def init_pushd_popd_magic(self):
756 # for pushd/popd management
763 # for pushd/popd management
757 self.home_dir = get_home_dir()
764 self.home_dir = get_home_dir()
758
765
759 self.dir_stack = []
766 self.dir_stack = []
760
767
761 def init_logger(self):
768 def init_logger(self):
762 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
769 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
763 logmode='rotate')
770 logmode='rotate')
764
771
765 def init_logstart(self):
772 def init_logstart(self):
766 """Initialize logging in case it was requested at the command line.
773 """Initialize logging in case it was requested at the command line.
767 """
774 """
768 if self.logappend:
775 if self.logappend:
769 self.magic('logstart %s append' % self.logappend)
776 self.magic('logstart %s append' % self.logappend)
770 elif self.logfile:
777 elif self.logfile:
771 self.magic('logstart %s' % self.logfile)
778 self.magic('logstart %s' % self.logfile)
772 elif self.logstart:
779 elif self.logstart:
773 self.magic('logstart')
780 self.magic('logstart')
774
781
775
782
776 def init_builtins(self):
783 def init_builtins(self):
777 # A single, static flag that we set to True. Its presence indicates
784 # A single, static flag that we set to True. Its presence indicates
778 # that an IPython shell has been created, and we make no attempts at
785 # that an IPython shell has been created, and we make no attempts at
779 # removing on exit or representing the existence of more than one
786 # removing on exit or representing the existence of more than one
780 # IPython at a time.
787 # IPython at a time.
781 builtin_mod.__dict__['__IPYTHON__'] = True
788 builtin_mod.__dict__['__IPYTHON__'] = True
782 builtin_mod.__dict__['display'] = display
789 builtin_mod.__dict__['display'] = display
783
790
784 self.builtin_trap = BuiltinTrap(shell=self)
791 self.builtin_trap = BuiltinTrap(shell=self)
785
792
786 @observe('colors')
793 @observe('colors')
787 def init_inspector(self, changes=None):
794 def init_inspector(self, changes=None):
788 # Object inspector
795 # Object inspector
789 self.inspector = self.inspector_class(
796 self.inspector = self.inspector_class(
790 oinspect.InspectColors,
797 oinspect.InspectColors,
791 PyColorize.ANSICodeColors,
798 PyColorize.ANSICodeColors,
792 self.colors,
799 self.colors,
793 self.object_info_string_level,
800 self.object_info_string_level,
794 )
801 )
795
802
796 def init_io(self):
803 def init_io(self):
797 # implemented in subclasses, TerminalInteractiveShell does call
804 # implemented in subclasses, TerminalInteractiveShell does call
798 # colorama.init().
805 # colorama.init().
799 pass
806 pass
800
807
801 def init_prompts(self):
808 def init_prompts(self):
802 # Set system prompts, so that scripts can decide if they are running
809 # Set system prompts, so that scripts can decide if they are running
803 # interactively.
810 # interactively.
804 sys.ps1 = 'In : '
811 sys.ps1 = 'In : '
805 sys.ps2 = '...: '
812 sys.ps2 = '...: '
806 sys.ps3 = 'Out: '
813 sys.ps3 = 'Out: '
807
814
808 def init_display_formatter(self):
815 def init_display_formatter(self):
809 self.display_formatter = DisplayFormatter(parent=self)
816 self.display_formatter = DisplayFormatter(parent=self)
810 self.configurables.append(self.display_formatter)
817 self.configurables.append(self.display_formatter)
811
818
812 def init_display_pub(self):
819 def init_display_pub(self):
813 self.display_pub = self.display_pub_class(parent=self, shell=self)
820 self.display_pub = self.display_pub_class(parent=self, shell=self)
814 self.configurables.append(self.display_pub)
821 self.configurables.append(self.display_pub)
815
822
816 def init_data_pub(self):
823 def init_data_pub(self):
817 if not self.data_pub_class:
824 if not self.data_pub_class:
818 self.data_pub = None
825 self.data_pub = None
819 return
826 return
820 self.data_pub = self.data_pub_class(parent=self)
827 self.data_pub = self.data_pub_class(parent=self)
821 self.configurables.append(self.data_pub)
828 self.configurables.append(self.data_pub)
822
829
823 def init_displayhook(self):
830 def init_displayhook(self):
824 # Initialize displayhook, set in/out prompts and printing system
831 # Initialize displayhook, set in/out prompts and printing system
825 self.displayhook = self.displayhook_class(
832 self.displayhook = self.displayhook_class(
826 parent=self,
833 parent=self,
827 shell=self,
834 shell=self,
828 cache_size=self.cache_size,
835 cache_size=self.cache_size,
829 )
836 )
830 self.configurables.append(self.displayhook)
837 self.configurables.append(self.displayhook)
831 # This is a context manager that installs/revmoes the displayhook at
838 # This is a context manager that installs/revmoes the displayhook at
832 # the appropriate time.
839 # the appropriate time.
833 self.display_trap = DisplayTrap(hook=self.displayhook)
840 self.display_trap = DisplayTrap(hook=self.displayhook)
834
841
835 @staticmethod
842 @staticmethod
836 def get_path_links(p: Path):
843 def get_path_links(p: Path):
837 """Gets path links including all symlinks
844 """Gets path links including all symlinks
838
845
839 Examples
846 Examples
840 --------
847 --------
841 In [1]: from IPython.core.interactiveshell import InteractiveShell
848 In [1]: from IPython.core.interactiveshell import InteractiveShell
842
849
843 In [2]: import sys, pathlib
850 In [2]: import sys, pathlib
844
851
845 In [3]: paths = InteractiveShell.get_path_links(pathlib.Path(sys.executable))
852 In [3]: paths = InteractiveShell.get_path_links(pathlib.Path(sys.executable))
846
853
847 In [4]: len(paths) == len(set(paths))
854 In [4]: len(paths) == len(set(paths))
848 Out[4]: True
855 Out[4]: True
849
856
850 In [5]: bool(paths)
857 In [5]: bool(paths)
851 Out[5]: True
858 Out[5]: True
852 """
859 """
853 paths = [p]
860 paths = [p]
854 while p.is_symlink():
861 while p.is_symlink():
855 new_path = Path(os.readlink(p))
862 new_path = Path(os.readlink(p))
856 if not new_path.is_absolute():
863 if not new_path.is_absolute():
857 new_path = p.parent / new_path
864 new_path = p.parent / new_path
858 p = new_path
865 p = new_path
859 paths.append(p)
866 paths.append(p)
860 return paths
867 return paths
861
868
862 def init_virtualenv(self):
869 def init_virtualenv(self):
863 """Add the current virtualenv to sys.path so the user can import modules from it.
870 """Add the current virtualenv to sys.path so the user can import modules from it.
864 This isn't perfect: it doesn't use the Python interpreter with which the
871 This isn't perfect: it doesn't use the Python interpreter with which the
865 virtualenv was built, and it ignores the --no-site-packages option. A
872 virtualenv was built, and it ignores the --no-site-packages option. A
866 warning will appear suggesting the user installs IPython in the
873 warning will appear suggesting the user installs IPython in the
867 virtualenv, but for many cases, it probably works well enough.
874 virtualenv, but for many cases, it probably works well enough.
868
875
869 Adapted from code snippets online.
876 Adapted from code snippets online.
870
877
871 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
878 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
872 """
879 """
873 if 'VIRTUAL_ENV' not in os.environ:
880 if 'VIRTUAL_ENV' not in os.environ:
874 # Not in a virtualenv
881 # Not in a virtualenv
875 return
882 return
876 elif os.environ["VIRTUAL_ENV"] == "":
883 elif os.environ["VIRTUAL_ENV"] == "":
877 warn("Virtual env path set to '', please check if this is intended.")
884 warn("Virtual env path set to '', please check if this is intended.")
878 return
885 return
879
886
880 p = Path(sys.executable)
887 p = Path(sys.executable)
881 p_venv = Path(os.environ["VIRTUAL_ENV"])
888 p_venv = Path(os.environ["VIRTUAL_ENV"])
882
889
883 # fallback venv detection:
890 # fallback venv detection:
884 # stdlib venv may symlink sys.executable, so we can't use realpath.
891 # stdlib venv may symlink sys.executable, so we can't use realpath.
885 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
892 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
886 # So we just check every item in the symlink tree (generally <= 3)
893 # So we just check every item in the symlink tree (generally <= 3)
887 paths = self.get_path_links(p)
894 paths = self.get_path_links(p)
888
895
889 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
896 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
890 if p_venv.parts[1] == "cygdrive":
897 if p_venv.parts[1] == "cygdrive":
891 drive_name = p_venv.parts[2]
898 drive_name = p_venv.parts[2]
892 p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
899 p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
893
900
894 if any(p_venv == p.parents[1] for p in paths):
901 if any(p_venv == p.parents[1] for p in paths):
895 # Our exe is inside or has access to the virtualenv, don't need to do anything.
902 # Our exe is inside or has access to the virtualenv, don't need to do anything.
896 return
903 return
897
904
898 if sys.platform == "win32":
905 if sys.platform == "win32":
899 virtual_env = str(Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages"))
906 virtual_env = str(Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages"))
900 else:
907 else:
901 virtual_env_path = Path(
908 virtual_env_path = Path(
902 os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages"
909 os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages"
903 )
910 )
904 p_ver = sys.version_info[:2]
911 p_ver = sys.version_info[:2]
905
912
906 # Predict version from py[thon]-x.x in the $VIRTUAL_ENV
913 # Predict version from py[thon]-x.x in the $VIRTUAL_ENV
907 re_m = re.search(r"\bpy(?:thon)?([23])\.(\d+)\b", os.environ["VIRTUAL_ENV"])
914 re_m = re.search(r"\bpy(?:thon)?([23])\.(\d+)\b", os.environ["VIRTUAL_ENV"])
908 if re_m:
915 if re_m:
909 predicted_path = Path(str(virtual_env_path).format(*re_m.groups()))
916 predicted_path = Path(str(virtual_env_path).format(*re_m.groups()))
910 if predicted_path.exists():
917 if predicted_path.exists():
911 p_ver = re_m.groups()
918 p_ver = re_m.groups()
912
919
913 virtual_env = str(virtual_env_path).format(*p_ver)
920 virtual_env = str(virtual_env_path).format(*p_ver)
914 if self.warn_venv:
921 if self.warn_venv:
915 warn(
922 warn(
916 "Attempting to work in a virtualenv. If you encounter problems, "
923 "Attempting to work in a virtualenv. If you encounter problems, "
917 "please install IPython inside the virtualenv."
924 "please install IPython inside the virtualenv."
918 )
925 )
919 import site
926 import site
920 sys.path.insert(0, virtual_env)
927 sys.path.insert(0, virtual_env)
921 site.addsitedir(virtual_env)
928 site.addsitedir(virtual_env)
922
929
923 #-------------------------------------------------------------------------
930 #-------------------------------------------------------------------------
924 # Things related to injections into the sys module
931 # Things related to injections into the sys module
925 #-------------------------------------------------------------------------
932 #-------------------------------------------------------------------------
926
933
927 def save_sys_module_state(self):
934 def save_sys_module_state(self):
928 """Save the state of hooks in the sys module.
935 """Save the state of hooks in the sys module.
929
936
930 This has to be called after self.user_module is created.
937 This has to be called after self.user_module is created.
931 """
938 """
932 self._orig_sys_module_state = {'stdin': sys.stdin,
939 self._orig_sys_module_state = {'stdin': sys.stdin,
933 'stdout': sys.stdout,
940 'stdout': sys.stdout,
934 'stderr': sys.stderr,
941 'stderr': sys.stderr,
935 'excepthook': sys.excepthook}
942 'excepthook': sys.excepthook}
936 self._orig_sys_modules_main_name = self.user_module.__name__
943 self._orig_sys_modules_main_name = self.user_module.__name__
937 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
944 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
938
945
939 def restore_sys_module_state(self):
946 def restore_sys_module_state(self):
940 """Restore the state of the sys module."""
947 """Restore the state of the sys module."""
941 try:
948 try:
942 for k, v in self._orig_sys_module_state.items():
949 for k, v in self._orig_sys_module_state.items():
943 setattr(sys, k, v)
950 setattr(sys, k, v)
944 except AttributeError:
951 except AttributeError:
945 pass
952 pass
946 # Reset what what done in self.init_sys_modules
953 # Reset what what done in self.init_sys_modules
947 if self._orig_sys_modules_main_mod is not None:
954 if self._orig_sys_modules_main_mod is not None:
948 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
955 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
949
956
950 #-------------------------------------------------------------------------
957 #-------------------------------------------------------------------------
951 # Things related to the banner
958 # Things related to the banner
952 #-------------------------------------------------------------------------
959 #-------------------------------------------------------------------------
953
960
954 @property
961 @property
955 def banner(self):
962 def banner(self):
956 banner = self.banner1
963 banner = self.banner1
957 if self.profile and self.profile != 'default':
964 if self.profile and self.profile != 'default':
958 banner += '\nIPython profile: %s\n' % self.profile
965 banner += '\nIPython profile: %s\n' % self.profile
959 if self.banner2:
966 if self.banner2:
960 banner += '\n' + self.banner2
967 banner += '\n' + self.banner2
961 return banner
968 return banner
962
969
963 def show_banner(self, banner=None):
970 def show_banner(self, banner=None):
964 if banner is None:
971 if banner is None:
965 banner = self.banner
972 banner = self.banner
966 sys.stdout.write(banner)
973 sys.stdout.write(banner)
967
974
968 #-------------------------------------------------------------------------
975 #-------------------------------------------------------------------------
969 # Things related to hooks
976 # Things related to hooks
970 #-------------------------------------------------------------------------
977 #-------------------------------------------------------------------------
971
978
972 def init_hooks(self):
979 def init_hooks(self):
973 # hooks holds pointers used for user-side customizations
980 # hooks holds pointers used for user-side customizations
974 self.hooks = Struct()
981 self.hooks = Struct()
975
982
976 self.strdispatchers = {}
983 self.strdispatchers = {}
977
984
978 # Set all default hooks, defined in the IPython.hooks module.
985 # Set all default hooks, defined in the IPython.hooks module.
979 hooks = IPython.core.hooks
986 hooks = IPython.core.hooks
980 for hook_name in hooks.__all__:
987 for hook_name in hooks.__all__:
981 # default hooks have priority 100, i.e. low; user hooks should have
988 # default hooks have priority 100, i.e. low; user hooks should have
982 # 0-100 priority
989 # 0-100 priority
983 self.set_hook(hook_name, getattr(hooks, hook_name), 100)
990 self.set_hook(hook_name, getattr(hooks, hook_name), 100)
984
991
985 if self.display_page:
992 if self.display_page:
986 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
993 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
987
994
988 def set_hook(self, name, hook, priority=50, str_key=None, re_key=None):
995 def set_hook(self, name, hook, priority=50, str_key=None, re_key=None):
989 """set_hook(name,hook) -> sets an internal IPython hook.
996 """set_hook(name,hook) -> sets an internal IPython hook.
990
997
991 IPython exposes some of its internal API as user-modifiable hooks. By
998 IPython exposes some of its internal API as user-modifiable hooks. By
992 adding your function to one of these hooks, you can modify IPython's
999 adding your function to one of these hooks, you can modify IPython's
993 behavior to call at runtime your own routines."""
1000 behavior to call at runtime your own routines."""
994
1001
995 # At some point in the future, this should validate the hook before it
1002 # At some point in the future, this should validate the hook before it
996 # accepts it. Probably at least check that the hook takes the number
1003 # accepts it. Probably at least check that the hook takes the number
997 # of args it's supposed to.
1004 # of args it's supposed to.
998
1005
999 f = types.MethodType(hook,self)
1006 f = types.MethodType(hook,self)
1000
1007
1001 # check if the hook is for strdispatcher first
1008 # check if the hook is for strdispatcher first
1002 if str_key is not None:
1009 if str_key is not None:
1003 sdp = self.strdispatchers.get(name, StrDispatch())
1010 sdp = self.strdispatchers.get(name, StrDispatch())
1004 sdp.add_s(str_key, f, priority )
1011 sdp.add_s(str_key, f, priority )
1005 self.strdispatchers[name] = sdp
1012 self.strdispatchers[name] = sdp
1006 return
1013 return
1007 if re_key is not None:
1014 if re_key is not None:
1008 sdp = self.strdispatchers.get(name, StrDispatch())
1015 sdp = self.strdispatchers.get(name, StrDispatch())
1009 sdp.add_re(re.compile(re_key), f, priority )
1016 sdp.add_re(re.compile(re_key), f, priority )
1010 self.strdispatchers[name] = sdp
1017 self.strdispatchers[name] = sdp
1011 return
1018 return
1012
1019
1013 dp = getattr(self.hooks, name, None)
1020 dp = getattr(self.hooks, name, None)
1014 if name not in IPython.core.hooks.__all__:
1021 if name not in IPython.core.hooks.__all__:
1015 print("Warning! Hook '%s' is not one of %s" % \
1022 print("Warning! Hook '%s' is not one of %s" % \
1016 (name, IPython.core.hooks.__all__ ))
1023 (name, IPython.core.hooks.__all__ ))
1017
1024
1018 if name in IPython.core.hooks.deprecated:
1025 if name in IPython.core.hooks.deprecated:
1019 alternative = IPython.core.hooks.deprecated[name]
1026 alternative = IPython.core.hooks.deprecated[name]
1020 raise ValueError(
1027 raise ValueError(
1021 "Hook {} has been deprecated since IPython 5.0. Use {} instead.".format(
1028 "Hook {} has been deprecated since IPython 5.0. Use {} instead.".format(
1022 name, alternative
1029 name, alternative
1023 )
1030 )
1024 )
1031 )
1025
1032
1026 if not dp:
1033 if not dp:
1027 dp = IPython.core.hooks.CommandChainDispatcher()
1034 dp = IPython.core.hooks.CommandChainDispatcher()
1028
1035
1029 try:
1036 try:
1030 dp.add(f,priority)
1037 dp.add(f,priority)
1031 except AttributeError:
1038 except AttributeError:
1032 # it was not commandchain, plain old func - replace
1039 # it was not commandchain, plain old func - replace
1033 dp = f
1040 dp = f
1034
1041
1035 setattr(self.hooks,name, dp)
1042 setattr(self.hooks,name, dp)
1036
1043
1037 #-------------------------------------------------------------------------
1044 #-------------------------------------------------------------------------
1038 # Things related to events
1045 # Things related to events
1039 #-------------------------------------------------------------------------
1046 #-------------------------------------------------------------------------
1040
1047
1041 def init_events(self):
1048 def init_events(self):
1042 self.events = EventManager(self, available_events)
1049 self.events = EventManager(self, available_events)
1043
1050
1044 self.events.register("pre_execute", self._clear_warning_registry)
1051 self.events.register("pre_execute", self._clear_warning_registry)
1045
1052
1046 def register_post_execute(self, func):
1053 def register_post_execute(self, func):
1047 """DEPRECATED: Use ip.events.register('post_run_cell', func)
1054 """DEPRECATED: Use ip.events.register('post_run_cell', func)
1048
1055
1049 Register a function for calling after code execution.
1056 Register a function for calling after code execution.
1050 """
1057 """
1051 raise ValueError(
1058 raise ValueError(
1052 "ip.register_post_execute is deprecated since IPython 1.0, use "
1059 "ip.register_post_execute is deprecated since IPython 1.0, use "
1053 "ip.events.register('post_run_cell', func) instead."
1060 "ip.events.register('post_run_cell', func) instead."
1054 )
1061 )
1055
1062
1056 def _clear_warning_registry(self):
1063 def _clear_warning_registry(self):
1057 # clear the warning registry, so that different code blocks with
1064 # clear the warning registry, so that different code blocks with
1058 # overlapping line number ranges don't cause spurious suppression of
1065 # overlapping line number ranges don't cause spurious suppression of
1059 # warnings (see gh-6611 for details)
1066 # warnings (see gh-6611 for details)
1060 if "__warningregistry__" in self.user_global_ns:
1067 if "__warningregistry__" in self.user_global_ns:
1061 del self.user_global_ns["__warningregistry__"]
1068 del self.user_global_ns["__warningregistry__"]
1062
1069
1063 #-------------------------------------------------------------------------
1070 #-------------------------------------------------------------------------
1064 # Things related to the "main" module
1071 # Things related to the "main" module
1065 #-------------------------------------------------------------------------
1072 #-------------------------------------------------------------------------
1066
1073
1067 def new_main_mod(self, filename, modname):
1074 def new_main_mod(self, filename, modname):
1068 """Return a new 'main' module object for user code execution.
1075 """Return a new 'main' module object for user code execution.
1069
1076
1070 ``filename`` should be the path of the script which will be run in the
1077 ``filename`` should be the path of the script which will be run in the
1071 module. Requests with the same filename will get the same module, with
1078 module. Requests with the same filename will get the same module, with
1072 its namespace cleared.
1079 its namespace cleared.
1073
1080
1074 ``modname`` should be the module name - normally either '__main__' or
1081 ``modname`` should be the module name - normally either '__main__' or
1075 the basename of the file without the extension.
1082 the basename of the file without the extension.
1076
1083
1077 When scripts are executed via %run, we must keep a reference to their
1084 When scripts are executed via %run, we must keep a reference to their
1078 __main__ module around so that Python doesn't
1085 __main__ module around so that Python doesn't
1079 clear it, rendering references to module globals useless.
1086 clear it, rendering references to module globals useless.
1080
1087
1081 This method keeps said reference in a private dict, keyed by the
1088 This method keeps said reference in a private dict, keyed by the
1082 absolute path of the script. This way, for multiple executions of the
1089 absolute path of the script. This way, for multiple executions of the
1083 same script we only keep one copy of the namespace (the last one),
1090 same script we only keep one copy of the namespace (the last one),
1084 thus preventing memory leaks from old references while allowing the
1091 thus preventing memory leaks from old references while allowing the
1085 objects from the last execution to be accessible.
1092 objects from the last execution to be accessible.
1086 """
1093 """
1087 filename = os.path.abspath(filename)
1094 filename = os.path.abspath(filename)
1088 try:
1095 try:
1089 main_mod = self._main_mod_cache[filename]
1096 main_mod = self._main_mod_cache[filename]
1090 except KeyError:
1097 except KeyError:
1091 main_mod = self._main_mod_cache[filename] = types.ModuleType(
1098 main_mod = self._main_mod_cache[filename] = types.ModuleType(
1092 modname,
1099 modname,
1093 doc="Module created for script run in IPython")
1100 doc="Module created for script run in IPython")
1094 else:
1101 else:
1095 main_mod.__dict__.clear()
1102 main_mod.__dict__.clear()
1096 main_mod.__name__ = modname
1103 main_mod.__name__ = modname
1097
1104
1098 main_mod.__file__ = filename
1105 main_mod.__file__ = filename
1099 # It seems pydoc (and perhaps others) needs any module instance to
1106 # It seems pydoc (and perhaps others) needs any module instance to
1100 # implement a __nonzero__ method
1107 # implement a __nonzero__ method
1101 main_mod.__nonzero__ = lambda : True
1108 main_mod.__nonzero__ = lambda : True
1102
1109
1103 return main_mod
1110 return main_mod
1104
1111
1105 def clear_main_mod_cache(self):
1112 def clear_main_mod_cache(self):
1106 """Clear the cache of main modules.
1113 """Clear the cache of main modules.
1107
1114
1108 Mainly for use by utilities like %reset.
1115 Mainly for use by utilities like %reset.
1109
1116
1110 Examples
1117 Examples
1111 --------
1118 --------
1112 In [15]: import IPython
1119 In [15]: import IPython
1113
1120
1114 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1121 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1115
1122
1116 In [17]: len(_ip._main_mod_cache) > 0
1123 In [17]: len(_ip._main_mod_cache) > 0
1117 Out[17]: True
1124 Out[17]: True
1118
1125
1119 In [18]: _ip.clear_main_mod_cache()
1126 In [18]: _ip.clear_main_mod_cache()
1120
1127
1121 In [19]: len(_ip._main_mod_cache) == 0
1128 In [19]: len(_ip._main_mod_cache) == 0
1122 Out[19]: True
1129 Out[19]: True
1123 """
1130 """
1124 self._main_mod_cache.clear()
1131 self._main_mod_cache.clear()
1125
1132
1126 #-------------------------------------------------------------------------
1133 #-------------------------------------------------------------------------
1127 # Things related to debugging
1134 # Things related to debugging
1128 #-------------------------------------------------------------------------
1135 #-------------------------------------------------------------------------
1129
1136
1130 def init_pdb(self):
1137 def init_pdb(self):
1131 # Set calling of pdb on exceptions
1138 # Set calling of pdb on exceptions
1132 # self.call_pdb is a property
1139 # self.call_pdb is a property
1133 self.call_pdb = self.pdb
1140 self.call_pdb = self.pdb
1134
1141
1135 def _get_call_pdb(self):
1142 def _get_call_pdb(self):
1136 return self._call_pdb
1143 return self._call_pdb
1137
1144
1138 def _set_call_pdb(self,val):
1145 def _set_call_pdb(self,val):
1139
1146
1140 if val not in (0,1,False,True):
1147 if val not in (0,1,False,True):
1141 raise ValueError('new call_pdb value must be boolean')
1148 raise ValueError('new call_pdb value must be boolean')
1142
1149
1143 # store value in instance
1150 # store value in instance
1144 self._call_pdb = val
1151 self._call_pdb = val
1145
1152
1146 # notify the actual exception handlers
1153 # notify the actual exception handlers
1147 self.InteractiveTB.call_pdb = val
1154 self.InteractiveTB.call_pdb = val
1148
1155
1149 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1156 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1150 'Control auto-activation of pdb at exceptions')
1157 'Control auto-activation of pdb at exceptions')
1151
1158
1152 def debugger(self,force=False):
1159 def debugger(self,force=False):
1153 """Call the pdb debugger.
1160 """Call the pdb debugger.
1154
1161
1155 Keywords:
1162 Keywords:
1156
1163
1157 - force(False): by default, this routine checks the instance call_pdb
1164 - force(False): by default, this routine checks the instance call_pdb
1158 flag and does not actually invoke the debugger if the flag is false.
1165 flag and does not actually invoke the debugger if the flag is false.
1159 The 'force' option forces the debugger to activate even if the flag
1166 The 'force' option forces the debugger to activate even if the flag
1160 is false.
1167 is false.
1161 """
1168 """
1162
1169
1163 if not (force or self.call_pdb):
1170 if not (force or self.call_pdb):
1164 return
1171 return
1165
1172
1166 if not hasattr(sys,'last_traceback'):
1173 if not hasattr(sys,'last_traceback'):
1167 error('No traceback has been produced, nothing to debug.')
1174 error('No traceback has been produced, nothing to debug.')
1168 return
1175 return
1169
1176
1170 self.InteractiveTB.debugger(force=True)
1177 self.InteractiveTB.debugger(force=True)
1171
1178
1172 #-------------------------------------------------------------------------
1179 #-------------------------------------------------------------------------
1173 # Things related to IPython's various namespaces
1180 # Things related to IPython's various namespaces
1174 #-------------------------------------------------------------------------
1181 #-------------------------------------------------------------------------
1175 default_user_namespaces = True
1182 default_user_namespaces = True
1176
1183
1177 def init_create_namespaces(self, user_module=None, user_ns=None):
1184 def init_create_namespaces(self, user_module=None, user_ns=None):
1178 # Create the namespace where the user will operate. user_ns is
1185 # Create the namespace where the user will operate. user_ns is
1179 # normally the only one used, and it is passed to the exec calls as
1186 # normally the only one used, and it is passed to the exec calls as
1180 # the locals argument. But we do carry a user_global_ns namespace
1187 # the locals argument. But we do carry a user_global_ns namespace
1181 # given as the exec 'globals' argument, This is useful in embedding
1188 # given as the exec 'globals' argument, This is useful in embedding
1182 # situations where the ipython shell opens in a context where the
1189 # situations where the ipython shell opens in a context where the
1183 # distinction between locals and globals is meaningful. For
1190 # distinction between locals and globals is meaningful. For
1184 # non-embedded contexts, it is just the same object as the user_ns dict.
1191 # non-embedded contexts, it is just the same object as the user_ns dict.
1185
1192
1186 # FIXME. For some strange reason, __builtins__ is showing up at user
1193 # FIXME. For some strange reason, __builtins__ is showing up at user
1187 # level as a dict instead of a module. This is a manual fix, but I
1194 # level as a dict instead of a module. This is a manual fix, but I
1188 # should really track down where the problem is coming from. Alex
1195 # should really track down where the problem is coming from. Alex
1189 # Schmolck reported this problem first.
1196 # Schmolck reported this problem first.
1190
1197
1191 # A useful post by Alex Martelli on this topic:
1198 # A useful post by Alex Martelli on this topic:
1192 # Re: inconsistent value from __builtins__
1199 # Re: inconsistent value from __builtins__
1193 # Von: Alex Martelli <aleaxit@yahoo.com>
1200 # Von: Alex Martelli <aleaxit@yahoo.com>
1194 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1201 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1195 # Gruppen: comp.lang.python
1202 # Gruppen: comp.lang.python
1196
1203
1197 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1204 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1198 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1205 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1199 # > <type 'dict'>
1206 # > <type 'dict'>
1200 # > >>> print type(__builtins__)
1207 # > >>> print type(__builtins__)
1201 # > <type 'module'>
1208 # > <type 'module'>
1202 # > Is this difference in return value intentional?
1209 # > Is this difference in return value intentional?
1203
1210
1204 # Well, it's documented that '__builtins__' can be either a dictionary
1211 # Well, it's documented that '__builtins__' can be either a dictionary
1205 # or a module, and it's been that way for a long time. Whether it's
1212 # or a module, and it's been that way for a long time. Whether it's
1206 # intentional (or sensible), I don't know. In any case, the idea is
1213 # intentional (or sensible), I don't know. In any case, the idea is
1207 # that if you need to access the built-in namespace directly, you
1214 # that if you need to access the built-in namespace directly, you
1208 # should start with "import __builtin__" (note, no 's') which will
1215 # should start with "import __builtin__" (note, no 's') which will
1209 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1216 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1210
1217
1211 # These routines return a properly built module and dict as needed by
1218 # These routines return a properly built module and dict as needed by
1212 # the rest of the code, and can also be used by extension writers to
1219 # the rest of the code, and can also be used by extension writers to
1213 # generate properly initialized namespaces.
1220 # generate properly initialized namespaces.
1214 if (user_ns is not None) or (user_module is not None):
1221 if (user_ns is not None) or (user_module is not None):
1215 self.default_user_namespaces = False
1222 self.default_user_namespaces = False
1216 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1223 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1217
1224
1218 # A record of hidden variables we have added to the user namespace, so
1225 # A record of hidden variables we have added to the user namespace, so
1219 # we can list later only variables defined in actual interactive use.
1226 # we can list later only variables defined in actual interactive use.
1220 self.user_ns_hidden = {}
1227 self.user_ns_hidden = {}
1221
1228
1222 # Now that FakeModule produces a real module, we've run into a nasty
1229 # Now that FakeModule produces a real module, we've run into a nasty
1223 # problem: after script execution (via %run), the module where the user
1230 # problem: after script execution (via %run), the module where the user
1224 # code ran is deleted. Now that this object is a true module (needed
1231 # code ran is deleted. Now that this object is a true module (needed
1225 # so doctest and other tools work correctly), the Python module
1232 # so doctest and other tools work correctly), the Python module
1226 # teardown mechanism runs over it, and sets to None every variable
1233 # teardown mechanism runs over it, and sets to None every variable
1227 # present in that module. Top-level references to objects from the
1234 # present in that module. Top-level references to objects from the
1228 # script survive, because the user_ns is updated with them. However,
1235 # script survive, because the user_ns is updated with them. However,
1229 # calling functions defined in the script that use other things from
1236 # calling functions defined in the script that use other things from
1230 # the script will fail, because the function's closure had references
1237 # the script will fail, because the function's closure had references
1231 # to the original objects, which are now all None. So we must protect
1238 # to the original objects, which are now all None. So we must protect
1232 # these modules from deletion by keeping a cache.
1239 # these modules from deletion by keeping a cache.
1233 #
1240 #
1234 # To avoid keeping stale modules around (we only need the one from the
1241 # To avoid keeping stale modules around (we only need the one from the
1235 # last run), we use a dict keyed with the full path to the script, so
1242 # last run), we use a dict keyed with the full path to the script, so
1236 # only the last version of the module is held in the cache. Note,
1243 # only the last version of the module is held in the cache. Note,
1237 # however, that we must cache the module *namespace contents* (their
1244 # however, that we must cache the module *namespace contents* (their
1238 # __dict__). Because if we try to cache the actual modules, old ones
1245 # __dict__). Because if we try to cache the actual modules, old ones
1239 # (uncached) could be destroyed while still holding references (such as
1246 # (uncached) could be destroyed while still holding references (such as
1240 # those held by GUI objects that tend to be long-lived)>
1247 # those held by GUI objects that tend to be long-lived)>
1241 #
1248 #
1242 # The %reset command will flush this cache. See the cache_main_mod()
1249 # The %reset command will flush this cache. See the cache_main_mod()
1243 # and clear_main_mod_cache() methods for details on use.
1250 # and clear_main_mod_cache() methods for details on use.
1244
1251
1245 # This is the cache used for 'main' namespaces
1252 # This is the cache used for 'main' namespaces
1246 self._main_mod_cache = {}
1253 self._main_mod_cache = {}
1247
1254
1248 # A table holding all the namespaces IPython deals with, so that
1255 # A table holding all the namespaces IPython deals with, so that
1249 # introspection facilities can search easily.
1256 # introspection facilities can search easily.
1250 self.ns_table = {'user_global':self.user_module.__dict__,
1257 self.ns_table = {'user_global':self.user_module.__dict__,
1251 'user_local':self.user_ns,
1258 'user_local':self.user_ns,
1252 'builtin':builtin_mod.__dict__
1259 'builtin':builtin_mod.__dict__
1253 }
1260 }
1254
1261
1255 @property
1262 @property
1256 def user_global_ns(self):
1263 def user_global_ns(self):
1257 return self.user_module.__dict__
1264 return self.user_module.__dict__
1258
1265
1259 def prepare_user_module(self, user_module=None, user_ns=None):
1266 def prepare_user_module(self, user_module=None, user_ns=None):
1260 """Prepare the module and namespace in which user code will be run.
1267 """Prepare the module and namespace in which user code will be run.
1261
1268
1262 When IPython is started normally, both parameters are None: a new module
1269 When IPython is started normally, both parameters are None: a new module
1263 is created automatically, and its __dict__ used as the namespace.
1270 is created automatically, and its __dict__ used as the namespace.
1264
1271
1265 If only user_module is provided, its __dict__ is used as the namespace.
1272 If only user_module is provided, its __dict__ is used as the namespace.
1266 If only user_ns is provided, a dummy module is created, and user_ns
1273 If only user_ns is provided, a dummy module is created, and user_ns
1267 becomes the global namespace. If both are provided (as they may be
1274 becomes the global namespace. If both are provided (as they may be
1268 when embedding), user_ns is the local namespace, and user_module
1275 when embedding), user_ns is the local namespace, and user_module
1269 provides the global namespace.
1276 provides the global namespace.
1270
1277
1271 Parameters
1278 Parameters
1272 ----------
1279 ----------
1273 user_module : module, optional
1280 user_module : module, optional
1274 The current user module in which IPython is being run. If None,
1281 The current user module in which IPython is being run. If None,
1275 a clean module will be created.
1282 a clean module will be created.
1276 user_ns : dict, optional
1283 user_ns : dict, optional
1277 A namespace in which to run interactive commands.
1284 A namespace in which to run interactive commands.
1278
1285
1279 Returns
1286 Returns
1280 -------
1287 -------
1281 A tuple of user_module and user_ns, each properly initialised.
1288 A tuple of user_module and user_ns, each properly initialised.
1282 """
1289 """
1283 if user_module is None and user_ns is not None:
1290 if user_module is None and user_ns is not None:
1284 user_ns.setdefault("__name__", "__main__")
1291 user_ns.setdefault("__name__", "__main__")
1285 user_module = DummyMod()
1292 user_module = DummyMod()
1286 user_module.__dict__ = user_ns
1293 user_module.__dict__ = user_ns
1287
1294
1288 if user_module is None:
1295 if user_module is None:
1289 user_module = types.ModuleType("__main__",
1296 user_module = types.ModuleType("__main__",
1290 doc="Automatically created module for IPython interactive environment")
1297 doc="Automatically created module for IPython interactive environment")
1291
1298
1292 # We must ensure that __builtin__ (without the final 's') is always
1299 # We must ensure that __builtin__ (without the final 's') is always
1293 # available and pointing to the __builtin__ *module*. For more details:
1300 # available and pointing to the __builtin__ *module*. For more details:
1294 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1301 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1295 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1302 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1296 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1303 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1297
1304
1298 if user_ns is None:
1305 if user_ns is None:
1299 user_ns = user_module.__dict__
1306 user_ns = user_module.__dict__
1300
1307
1301 return user_module, user_ns
1308 return user_module, user_ns
1302
1309
1303 def init_sys_modules(self):
1310 def init_sys_modules(self):
1304 # We need to insert into sys.modules something that looks like a
1311 # We need to insert into sys.modules something that looks like a
1305 # module but which accesses the IPython namespace, for shelve and
1312 # module but which accesses the IPython namespace, for shelve and
1306 # pickle to work interactively. Normally they rely on getting
1313 # pickle to work interactively. Normally they rely on getting
1307 # everything out of __main__, but for embedding purposes each IPython
1314 # everything out of __main__, but for embedding purposes each IPython
1308 # instance has its own private namespace, so we can't go shoving
1315 # instance has its own private namespace, so we can't go shoving
1309 # everything into __main__.
1316 # everything into __main__.
1310
1317
1311 # note, however, that we should only do this for non-embedded
1318 # note, however, that we should only do this for non-embedded
1312 # ipythons, which really mimic the __main__.__dict__ with their own
1319 # ipythons, which really mimic the __main__.__dict__ with their own
1313 # namespace. Embedded instances, on the other hand, should not do
1320 # namespace. Embedded instances, on the other hand, should not do
1314 # this because they need to manage the user local/global namespaces
1321 # this because they need to manage the user local/global namespaces
1315 # only, but they live within a 'normal' __main__ (meaning, they
1322 # only, but they live within a 'normal' __main__ (meaning, they
1316 # shouldn't overtake the execution environment of the script they're
1323 # shouldn't overtake the execution environment of the script they're
1317 # embedded in).
1324 # embedded in).
1318
1325
1319 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1326 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1320 main_name = self.user_module.__name__
1327 main_name = self.user_module.__name__
1321 sys.modules[main_name] = self.user_module
1328 sys.modules[main_name] = self.user_module
1322
1329
1323 def init_user_ns(self):
1330 def init_user_ns(self):
1324 """Initialize all user-visible namespaces to their minimum defaults.
1331 """Initialize all user-visible namespaces to their minimum defaults.
1325
1332
1326 Certain history lists are also initialized here, as they effectively
1333 Certain history lists are also initialized here, as they effectively
1327 act as user namespaces.
1334 act as user namespaces.
1328
1335
1329 Notes
1336 Notes
1330 -----
1337 -----
1331 All data structures here are only filled in, they are NOT reset by this
1338 All data structures here are only filled in, they are NOT reset by this
1332 method. If they were not empty before, data will simply be added to
1339 method. If they were not empty before, data will simply be added to
1333 them.
1340 them.
1334 """
1341 """
1335 # This function works in two parts: first we put a few things in
1342 # This function works in two parts: first we put a few things in
1336 # user_ns, and we sync that contents into user_ns_hidden so that these
1343 # user_ns, and we sync that contents into user_ns_hidden so that these
1337 # initial variables aren't shown by %who. After the sync, we add the
1344 # initial variables aren't shown by %who. After the sync, we add the
1338 # rest of what we *do* want the user to see with %who even on a new
1345 # rest of what we *do* want the user to see with %who even on a new
1339 # session (probably nothing, so they really only see their own stuff)
1346 # session (probably nothing, so they really only see their own stuff)
1340
1347
1341 # The user dict must *always* have a __builtin__ reference to the
1348 # The user dict must *always* have a __builtin__ reference to the
1342 # Python standard __builtin__ namespace, which must be imported.
1349 # Python standard __builtin__ namespace, which must be imported.
1343 # This is so that certain operations in prompt evaluation can be
1350 # This is so that certain operations in prompt evaluation can be
1344 # reliably executed with builtins. Note that we can NOT use
1351 # reliably executed with builtins. Note that we can NOT use
1345 # __builtins__ (note the 's'), because that can either be a dict or a
1352 # __builtins__ (note the 's'), because that can either be a dict or a
1346 # module, and can even mutate at runtime, depending on the context
1353 # module, and can even mutate at runtime, depending on the context
1347 # (Python makes no guarantees on it). In contrast, __builtin__ is
1354 # (Python makes no guarantees on it). In contrast, __builtin__ is
1348 # always a module object, though it must be explicitly imported.
1355 # always a module object, though it must be explicitly imported.
1349
1356
1350 # For more details:
1357 # For more details:
1351 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1358 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1352 ns = {}
1359 ns = {}
1353
1360
1354 # make global variables for user access to the histories
1361 # make global variables for user access to the histories
1355 ns['_ih'] = self.history_manager.input_hist_parsed
1362 ns['_ih'] = self.history_manager.input_hist_parsed
1356 ns['_oh'] = self.history_manager.output_hist
1363 ns['_oh'] = self.history_manager.output_hist
1357 ns['_dh'] = self.history_manager.dir_hist
1364 ns['_dh'] = self.history_manager.dir_hist
1358
1365
1359 # user aliases to input and output histories. These shouldn't show up
1366 # user aliases to input and output histories. These shouldn't show up
1360 # in %who, as they can have very large reprs.
1367 # in %who, as they can have very large reprs.
1361 ns['In'] = self.history_manager.input_hist_parsed
1368 ns['In'] = self.history_manager.input_hist_parsed
1362 ns['Out'] = self.history_manager.output_hist
1369 ns['Out'] = self.history_manager.output_hist
1363
1370
1364 # Store myself as the public api!!!
1371 # Store myself as the public api!!!
1365 ns['get_ipython'] = self.get_ipython
1372 ns['get_ipython'] = self.get_ipython
1366
1373
1367 ns['exit'] = self.exiter
1374 ns['exit'] = self.exiter
1368 ns['quit'] = self.exiter
1375 ns['quit'] = self.exiter
1369 ns["open"] = _modified_open
1376 ns["open"] = _modified_open
1370
1377
1371 # Sync what we've added so far to user_ns_hidden so these aren't seen
1378 # Sync what we've added so far to user_ns_hidden so these aren't seen
1372 # by %who
1379 # by %who
1373 self.user_ns_hidden.update(ns)
1380 self.user_ns_hidden.update(ns)
1374
1381
1375 # Anything put into ns now would show up in %who. Think twice before
1382 # Anything put into ns now would show up in %who. Think twice before
1376 # putting anything here, as we really want %who to show the user their
1383 # putting anything here, as we really want %who to show the user their
1377 # stuff, not our variables.
1384 # stuff, not our variables.
1378
1385
1379 # Finally, update the real user's namespace
1386 # Finally, update the real user's namespace
1380 self.user_ns.update(ns)
1387 self.user_ns.update(ns)
1381
1388
1382 @property
1389 @property
1383 def all_ns_refs(self):
1390 def all_ns_refs(self):
1384 """Get a list of references to all the namespace dictionaries in which
1391 """Get a list of references to all the namespace dictionaries in which
1385 IPython might store a user-created object.
1392 IPython might store a user-created object.
1386
1393
1387 Note that this does not include the displayhook, which also caches
1394 Note that this does not include the displayhook, which also caches
1388 objects from the output."""
1395 objects from the output."""
1389 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1396 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1390 [m.__dict__ for m in self._main_mod_cache.values()]
1397 [m.__dict__ for m in self._main_mod_cache.values()]
1391
1398
1392 def reset(self, new_session=True, aggressive=False):
1399 def reset(self, new_session=True, aggressive=False):
1393 """Clear all internal namespaces, and attempt to release references to
1400 """Clear all internal namespaces, and attempt to release references to
1394 user objects.
1401 user objects.
1395
1402
1396 If new_session is True, a new history session will be opened.
1403 If new_session is True, a new history session will be opened.
1397 """
1404 """
1398 # Clear histories
1405 # Clear histories
1406 assert self.history_manager is not None
1399 self.history_manager.reset(new_session)
1407 self.history_manager.reset(new_session)
1400 # Reset counter used to index all histories
1408 # Reset counter used to index all histories
1401 if new_session:
1409 if new_session:
1402 self.execution_count = 1
1410 self.execution_count = 1
1403
1411
1404 # Reset last execution result
1412 # Reset last execution result
1405 self.last_execution_succeeded = True
1413 self.last_execution_succeeded = True
1406 self.last_execution_result = None
1414 self.last_execution_result = None
1407
1415
1408 # Flush cached output items
1416 # Flush cached output items
1409 if self.displayhook.do_full_cache:
1417 if self.displayhook.do_full_cache:
1410 self.displayhook.flush()
1418 self.displayhook.flush()
1411
1419
1412 # The main execution namespaces must be cleared very carefully,
1420 # The main execution namespaces must be cleared very carefully,
1413 # skipping the deletion of the builtin-related keys, because doing so
1421 # skipping the deletion of the builtin-related keys, because doing so
1414 # would cause errors in many object's __del__ methods.
1422 # would cause errors in many object's __del__ methods.
1415 if self.user_ns is not self.user_global_ns:
1423 if self.user_ns is not self.user_global_ns:
1416 self.user_ns.clear()
1424 self.user_ns.clear()
1417 ns = self.user_global_ns
1425 ns = self.user_global_ns
1418 drop_keys = set(ns.keys())
1426 drop_keys = set(ns.keys())
1419 drop_keys.discard('__builtin__')
1427 drop_keys.discard('__builtin__')
1420 drop_keys.discard('__builtins__')
1428 drop_keys.discard('__builtins__')
1421 drop_keys.discard('__name__')
1429 drop_keys.discard('__name__')
1422 for k in drop_keys:
1430 for k in drop_keys:
1423 del ns[k]
1431 del ns[k]
1424
1432
1425 self.user_ns_hidden.clear()
1433 self.user_ns_hidden.clear()
1426
1434
1427 # Restore the user namespaces to minimal usability
1435 # Restore the user namespaces to minimal usability
1428 self.init_user_ns()
1436 self.init_user_ns()
1429 if aggressive and not hasattr(self, "_sys_modules_keys"):
1437 if aggressive and not hasattr(self, "_sys_modules_keys"):
1430 print("Cannot restore sys.module, no snapshot")
1438 print("Cannot restore sys.module, no snapshot")
1431 elif aggressive:
1439 elif aggressive:
1432 print("culling sys module...")
1440 print("culling sys module...")
1433 current_keys = set(sys.modules.keys())
1441 current_keys = set(sys.modules.keys())
1434 for k in current_keys - self._sys_modules_keys:
1442 for k in current_keys - self._sys_modules_keys:
1435 if k.startswith("multiprocessing"):
1443 if k.startswith("multiprocessing"):
1436 continue
1444 continue
1437 del sys.modules[k]
1445 del sys.modules[k]
1438
1446
1439 # Restore the default and user aliases
1447 # Restore the default and user aliases
1440 self.alias_manager.clear_aliases()
1448 self.alias_manager.clear_aliases()
1441 self.alias_manager.init_aliases()
1449 self.alias_manager.init_aliases()
1442
1450
1443 # Now define aliases that only make sense on the terminal, because they
1451 # Now define aliases that only make sense on the terminal, because they
1444 # need direct access to the console in a way that we can't emulate in
1452 # need direct access to the console in a way that we can't emulate in
1445 # GUI or web frontend
1453 # GUI or web frontend
1446 if os.name == 'posix':
1454 if os.name == 'posix':
1447 for cmd in ('clear', 'more', 'less', 'man'):
1455 for cmd in ('clear', 'more', 'less', 'man'):
1448 if cmd not in self.magics_manager.magics['line']:
1456 if cmd not in self.magics_manager.magics['line']:
1449 self.alias_manager.soft_define_alias(cmd, cmd)
1457 self.alias_manager.soft_define_alias(cmd, cmd)
1450
1458
1451 # Flush the private list of module references kept for script
1459 # Flush the private list of module references kept for script
1452 # execution protection
1460 # execution protection
1453 self.clear_main_mod_cache()
1461 self.clear_main_mod_cache()
1454
1462
1455 def del_var(self, varname, by_name=False):
1463 def del_var(self, varname, by_name=False):
1456 """Delete a variable from the various namespaces, so that, as
1464 """Delete a variable from the various namespaces, so that, as
1457 far as possible, we're not keeping any hidden references to it.
1465 far as possible, we're not keeping any hidden references to it.
1458
1466
1459 Parameters
1467 Parameters
1460 ----------
1468 ----------
1461 varname : str
1469 varname : str
1462 The name of the variable to delete.
1470 The name of the variable to delete.
1463 by_name : bool
1471 by_name : bool
1464 If True, delete variables with the given name in each
1472 If True, delete variables with the given name in each
1465 namespace. If False (default), find the variable in the user
1473 namespace. If False (default), find the variable in the user
1466 namespace, and delete references to it.
1474 namespace, and delete references to it.
1467 """
1475 """
1468 if varname in ('__builtin__', '__builtins__'):
1476 if varname in ('__builtin__', '__builtins__'):
1469 raise ValueError("Refusing to delete %s" % varname)
1477 raise ValueError("Refusing to delete %s" % varname)
1470
1478
1471 ns_refs = self.all_ns_refs
1479 ns_refs = self.all_ns_refs
1472
1480
1473 if by_name: # Delete by name
1481 if by_name: # Delete by name
1474 for ns in ns_refs:
1482 for ns in ns_refs:
1475 try:
1483 try:
1476 del ns[varname]
1484 del ns[varname]
1477 except KeyError:
1485 except KeyError:
1478 pass
1486 pass
1479 else: # Delete by object
1487 else: # Delete by object
1480 try:
1488 try:
1481 obj = self.user_ns[varname]
1489 obj = self.user_ns[varname]
1482 except KeyError as e:
1490 except KeyError as e:
1483 raise NameError("name '%s' is not defined" % varname) from e
1491 raise NameError("name '%s' is not defined" % varname) from e
1484 # Also check in output history
1492 # Also check in output history
1493 assert self.history_manager is not None
1485 ns_refs.append(self.history_manager.output_hist)
1494 ns_refs.append(self.history_manager.output_hist)
1486 for ns in ns_refs:
1495 for ns in ns_refs:
1487 to_delete = [n for n, o in ns.items() if o is obj]
1496 to_delete = [n for n, o in ns.items() if o is obj]
1488 for name in to_delete:
1497 for name in to_delete:
1489 del ns[name]
1498 del ns[name]
1490
1499
1491 # Ensure it is removed from the last execution result
1500 # Ensure it is removed from the last execution result
1492 if self.last_execution_result.result is obj:
1501 if self.last_execution_result.result is obj:
1493 self.last_execution_result = None
1502 self.last_execution_result = None
1494
1503
1495 # displayhook keeps extra references, but not in a dictionary
1504 # displayhook keeps extra references, but not in a dictionary
1496 for name in ('_', '__', '___'):
1505 for name in ('_', '__', '___'):
1497 if getattr(self.displayhook, name) is obj:
1506 if getattr(self.displayhook, name) is obj:
1498 setattr(self.displayhook, name, None)
1507 setattr(self.displayhook, name, None)
1499
1508
1500 def reset_selective(self, regex=None):
1509 def reset_selective(self, regex=None):
1501 """Clear selective variables from internal namespaces based on a
1510 """Clear selective variables from internal namespaces based on a
1502 specified regular expression.
1511 specified regular expression.
1503
1512
1504 Parameters
1513 Parameters
1505 ----------
1514 ----------
1506 regex : string or compiled pattern, optional
1515 regex : string or compiled pattern, optional
1507 A regular expression pattern that will be used in searching
1516 A regular expression pattern that will be used in searching
1508 variable names in the users namespaces.
1517 variable names in the users namespaces.
1509 """
1518 """
1510 if regex is not None:
1519 if regex is not None:
1511 try:
1520 try:
1512 m = re.compile(regex)
1521 m = re.compile(regex)
1513 except TypeError as e:
1522 except TypeError as e:
1514 raise TypeError('regex must be a string or compiled pattern') from e
1523 raise TypeError('regex must be a string or compiled pattern') from e
1515 # Search for keys in each namespace that match the given regex
1524 # Search for keys in each namespace that match the given regex
1516 # If a match is found, delete the key/value pair.
1525 # If a match is found, delete the key/value pair.
1517 for ns in self.all_ns_refs:
1526 for ns in self.all_ns_refs:
1518 for var in ns:
1527 for var in ns:
1519 if m.search(var):
1528 if m.search(var):
1520 del ns[var]
1529 del ns[var]
1521
1530
1522 def push(self, variables, interactive=True):
1531 def push(self, variables, interactive=True):
1523 """Inject a group of variables into the IPython user namespace.
1532 """Inject a group of variables into the IPython user namespace.
1524
1533
1525 Parameters
1534 Parameters
1526 ----------
1535 ----------
1527 variables : dict, str or list/tuple of str
1536 variables : dict, str or list/tuple of str
1528 The variables to inject into the user's namespace. If a dict, a
1537 The variables to inject into the user's namespace. If a dict, a
1529 simple update is done. If a str, the string is assumed to have
1538 simple update is done. If a str, the string is assumed to have
1530 variable names separated by spaces. A list/tuple of str can also
1539 variable names separated by spaces. A list/tuple of str can also
1531 be used to give the variable names. If just the variable names are
1540 be used to give the variable names. If just the variable names are
1532 give (list/tuple/str) then the variable values looked up in the
1541 give (list/tuple/str) then the variable values looked up in the
1533 callers frame.
1542 callers frame.
1534 interactive : bool
1543 interactive : bool
1535 If True (default), the variables will be listed with the ``who``
1544 If True (default), the variables will be listed with the ``who``
1536 magic.
1545 magic.
1537 """
1546 """
1538 vdict = None
1547 vdict = None
1539
1548
1540 # We need a dict of name/value pairs to do namespace updates.
1549 # We need a dict of name/value pairs to do namespace updates.
1541 if isinstance(variables, dict):
1550 if isinstance(variables, dict):
1542 vdict = variables
1551 vdict = variables
1543 elif isinstance(variables, (str, list, tuple)):
1552 elif isinstance(variables, (str, list, tuple)):
1544 if isinstance(variables, str):
1553 if isinstance(variables, str):
1545 vlist = variables.split()
1554 vlist = variables.split()
1546 else:
1555 else:
1547 vlist = variables
1556 vlist = variables
1548 vdict = {}
1557 vdict = {}
1549 cf = sys._getframe(1)
1558 cf = sys._getframe(1)
1550 for name in vlist:
1559 for name in vlist:
1551 try:
1560 try:
1552 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1561 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1553 except:
1562 except:
1554 print('Could not get variable %s from %s' %
1563 print('Could not get variable %s from %s' %
1555 (name,cf.f_code.co_name))
1564 (name,cf.f_code.co_name))
1556 else:
1565 else:
1557 raise ValueError('variables must be a dict/str/list/tuple')
1566 raise ValueError('variables must be a dict/str/list/tuple')
1558
1567
1559 # Propagate variables to user namespace
1568 # Propagate variables to user namespace
1560 self.user_ns.update(vdict)
1569 self.user_ns.update(vdict)
1561
1570
1562 # And configure interactive visibility
1571 # And configure interactive visibility
1563 user_ns_hidden = self.user_ns_hidden
1572 user_ns_hidden = self.user_ns_hidden
1564 if interactive:
1573 if interactive:
1565 for name in vdict:
1574 for name in vdict:
1566 user_ns_hidden.pop(name, None)
1575 user_ns_hidden.pop(name, None)
1567 else:
1576 else:
1568 user_ns_hidden.update(vdict)
1577 user_ns_hidden.update(vdict)
1569
1578
1570 def drop_by_id(self, variables):
1579 def drop_by_id(self, variables):
1571 """Remove a dict of variables from the user namespace, if they are the
1580 """Remove a dict of variables from the user namespace, if they are the
1572 same as the values in the dictionary.
1581 same as the values in the dictionary.
1573
1582
1574 This is intended for use by extensions: variables that they've added can
1583 This is intended for use by extensions: variables that they've added can
1575 be taken back out if they are unloaded, without removing any that the
1584 be taken back out if they are unloaded, without removing any that the
1576 user has overwritten.
1585 user has overwritten.
1577
1586
1578 Parameters
1587 Parameters
1579 ----------
1588 ----------
1580 variables : dict
1589 variables : dict
1581 A dictionary mapping object names (as strings) to the objects.
1590 A dictionary mapping object names (as strings) to the objects.
1582 """
1591 """
1583 for name, obj in variables.items():
1592 for name, obj in variables.items():
1584 if name in self.user_ns and self.user_ns[name] is obj:
1593 if name in self.user_ns and self.user_ns[name] is obj:
1585 del self.user_ns[name]
1594 del self.user_ns[name]
1586 self.user_ns_hidden.pop(name, None)
1595 self.user_ns_hidden.pop(name, None)
1587
1596
1588 #-------------------------------------------------------------------------
1597 #-------------------------------------------------------------------------
1589 # Things related to object introspection
1598 # Things related to object introspection
1590 #-------------------------------------------------------------------------
1599 #-------------------------------------------------------------------------
1591 @staticmethod
1600 @staticmethod
1592 def _find_parts(oname: str) -> Tuple[bool, ListType[str]]:
1601 def _find_parts(oname: str) -> Tuple[bool, ListType[str]]:
1593 """
1602 """
1594 Given an object name, return a list of parts of this object name.
1603 Given an object name, return a list of parts of this object name.
1595
1604
1596 Basically split on docs when using attribute access,
1605 Basically split on docs when using attribute access,
1597 and extract the value when using square bracket.
1606 and extract the value when using square bracket.
1598
1607
1599
1608
1600 For example foo.bar[3].baz[x] -> foo, bar, 3, baz, x
1609 For example foo.bar[3].baz[x] -> foo, bar, 3, baz, x
1601
1610
1602
1611
1603 Returns
1612 Returns
1604 -------
1613 -------
1605 parts_ok: bool
1614 parts_ok: bool
1606 wether we were properly able to parse parts.
1615 wether we were properly able to parse parts.
1607 parts: list of str
1616 parts: list of str
1608 extracted parts
1617 extracted parts
1609
1618
1610
1619
1611
1620
1612 """
1621 """
1613 raw_parts = oname.split(".")
1622 raw_parts = oname.split(".")
1614 parts = []
1623 parts = []
1615 parts_ok = True
1624 parts_ok = True
1616 for p in raw_parts:
1625 for p in raw_parts:
1617 if p.endswith("]"):
1626 if p.endswith("]"):
1618 var, *indices = p.split("[")
1627 var, *indices = p.split("[")
1619 if not var.isidentifier():
1628 if not var.isidentifier():
1620 parts_ok = False
1629 parts_ok = False
1621 break
1630 break
1622 parts.append(var)
1631 parts.append(var)
1623 for ind in indices:
1632 for ind in indices:
1624 if ind[-1] != "]" and not is_integer_string(ind[:-1]):
1633 if ind[-1] != "]" and not is_integer_string(ind[:-1]):
1625 parts_ok = False
1634 parts_ok = False
1626 break
1635 break
1627 parts.append(ind[:-1])
1636 parts.append(ind[:-1])
1628 continue
1637 continue
1629
1638
1630 if not p.isidentifier():
1639 if not p.isidentifier():
1631 parts_ok = False
1640 parts_ok = False
1632 parts.append(p)
1641 parts.append(p)
1633
1642
1634 return parts_ok, parts
1643 return parts_ok, parts
1635
1644
1636 def _ofind(
1645 def _ofind(
1637 self, oname: str, namespaces: Optional[Sequence[Tuple[str, AnyType]]] = None
1646 self, oname: str, namespaces: Optional[Sequence[Tuple[str, AnyType]]] = None
1638 ) -> OInfo:
1647 ) -> OInfo:
1639 """Find an object in the available namespaces.
1648 """Find an object in the available namespaces.
1640
1649
1641
1650
1642 Returns
1651 Returns
1643 -------
1652 -------
1644 OInfo with fields:
1653 OInfo with fields:
1645 - ismagic
1654 - ismagic
1646 - isalias
1655 - isalias
1647 - found
1656 - found
1648 - obj
1657 - obj
1649 - namespac
1658 - namespac
1650 - parent
1659 - parent
1651
1660
1652 Has special code to detect magic functions.
1661 Has special code to detect magic functions.
1653 """
1662 """
1654 oname = oname.strip()
1663 oname = oname.strip()
1655 parts_ok, parts = self._find_parts(oname)
1664 parts_ok, parts = self._find_parts(oname)
1656
1665
1657 if (
1666 if (
1658 not oname.startswith(ESC_MAGIC)
1667 not oname.startswith(ESC_MAGIC)
1659 and not oname.startswith(ESC_MAGIC2)
1668 and not oname.startswith(ESC_MAGIC2)
1660 and not parts_ok
1669 and not parts_ok
1661 ):
1670 ):
1662 return OInfo(
1671 return OInfo(
1663 ismagic=False,
1672 ismagic=False,
1664 isalias=False,
1673 isalias=False,
1665 found=False,
1674 found=False,
1666 obj=None,
1675 obj=None,
1667 namespace=None,
1676 namespace=None,
1668 parent=None,
1677 parent=None,
1669 )
1678 )
1670
1679
1671 if namespaces is None:
1680 if namespaces is None:
1672 # Namespaces to search in:
1681 # Namespaces to search in:
1673 # Put them in a list. The order is important so that we
1682 # Put them in a list. The order is important so that we
1674 # find things in the same order that Python finds them.
1683 # find things in the same order that Python finds them.
1675 namespaces = [ ('Interactive', self.user_ns),
1684 namespaces = [ ('Interactive', self.user_ns),
1676 ('Interactive (global)', self.user_global_ns),
1685 ('Interactive (global)', self.user_global_ns),
1677 ('Python builtin', builtin_mod.__dict__),
1686 ('Python builtin', builtin_mod.__dict__),
1678 ]
1687 ]
1679
1688
1680 ismagic = False
1689 ismagic = False
1681 isalias = False
1690 isalias = False
1682 found = False
1691 found = False
1683 ospace = None
1692 ospace = None
1684 parent = None
1693 parent = None
1685 obj = None
1694 obj = None
1686
1695
1687
1696
1688 # Look for the given name by splitting it in parts. If the head is
1697 # Look for the given name by splitting it in parts. If the head is
1689 # found, then we look for all the remaining parts as members, and only
1698 # found, then we look for all the remaining parts as members, and only
1690 # declare success if we can find them all.
1699 # declare success if we can find them all.
1691 oname_parts = parts
1700 oname_parts = parts
1692 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1701 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1693 for nsname,ns in namespaces:
1702 for nsname,ns in namespaces:
1694 try:
1703 try:
1695 obj = ns[oname_head]
1704 obj = ns[oname_head]
1696 except KeyError:
1705 except KeyError:
1697 continue
1706 continue
1698 else:
1707 else:
1699 for idx, part in enumerate(oname_rest):
1708 for idx, part in enumerate(oname_rest):
1700 try:
1709 try:
1701 parent = obj
1710 parent = obj
1702 # The last part is looked up in a special way to avoid
1711 # The last part is looked up in a special way to avoid
1703 # descriptor invocation as it may raise or have side
1712 # descriptor invocation as it may raise or have side
1704 # effects.
1713 # effects.
1705 if idx == len(oname_rest) - 1:
1714 if idx == len(oname_rest) - 1:
1706 obj = self._getattr_property(obj, part)
1715 obj = self._getattr_property(obj, part)
1707 else:
1716 else:
1708 if is_integer_string(part):
1717 if is_integer_string(part):
1709 obj = obj[int(part)]
1718 obj = obj[int(part)]
1710 else:
1719 else:
1711 obj = getattr(obj, part)
1720 obj = getattr(obj, part)
1712 except:
1721 except:
1713 # Blanket except b/c some badly implemented objects
1722 # Blanket except b/c some badly implemented objects
1714 # allow __getattr__ to raise exceptions other than
1723 # allow __getattr__ to raise exceptions other than
1715 # AttributeError, which then crashes IPython.
1724 # AttributeError, which then crashes IPython.
1716 break
1725 break
1717 else:
1726 else:
1718 # If we finish the for loop (no break), we got all members
1727 # If we finish the for loop (no break), we got all members
1719 found = True
1728 found = True
1720 ospace = nsname
1729 ospace = nsname
1721 break # namespace loop
1730 break # namespace loop
1722
1731
1723 # Try to see if it's magic
1732 # Try to see if it's magic
1724 if not found:
1733 if not found:
1725 obj = None
1734 obj = None
1726 if oname.startswith(ESC_MAGIC2):
1735 if oname.startswith(ESC_MAGIC2):
1727 oname = oname.lstrip(ESC_MAGIC2)
1736 oname = oname.lstrip(ESC_MAGIC2)
1728 obj = self.find_cell_magic(oname)
1737 obj = self.find_cell_magic(oname)
1729 elif oname.startswith(ESC_MAGIC):
1738 elif oname.startswith(ESC_MAGIC):
1730 oname = oname.lstrip(ESC_MAGIC)
1739 oname = oname.lstrip(ESC_MAGIC)
1731 obj = self.find_line_magic(oname)
1740 obj = self.find_line_magic(oname)
1732 else:
1741 else:
1733 # search without prefix, so run? will find %run?
1742 # search without prefix, so run? will find %run?
1734 obj = self.find_line_magic(oname)
1743 obj = self.find_line_magic(oname)
1735 if obj is None:
1744 if obj is None:
1736 obj = self.find_cell_magic(oname)
1745 obj = self.find_cell_magic(oname)
1737 if obj is not None:
1746 if obj is not None:
1738 found = True
1747 found = True
1739 ospace = 'IPython internal'
1748 ospace = 'IPython internal'
1740 ismagic = True
1749 ismagic = True
1741 isalias = isinstance(obj, Alias)
1750 isalias = isinstance(obj, Alias)
1742
1751
1743 # Last try: special-case some literals like '', [], {}, etc:
1752 # Last try: special-case some literals like '', [], {}, etc:
1744 if not found and oname_head in ["''",'""','[]','{}','()']:
1753 if not found and oname_head in ["''",'""','[]','{}','()']:
1745 obj = eval(oname_head)
1754 obj = eval(oname_head)
1746 found = True
1755 found = True
1747 ospace = 'Interactive'
1756 ospace = 'Interactive'
1748
1757
1749 return OInfo(
1758 return OInfo(
1750 obj=obj,
1759 obj=obj,
1751 found=found,
1760 found=found,
1752 parent=parent,
1761 parent=parent,
1753 ismagic=ismagic,
1762 ismagic=ismagic,
1754 isalias=isalias,
1763 isalias=isalias,
1755 namespace=ospace,
1764 namespace=ospace,
1756 )
1765 )
1757
1766
1758 @staticmethod
1767 @staticmethod
1759 def _getattr_property(obj, attrname):
1768 def _getattr_property(obj, attrname):
1760 """Property-aware getattr to use in object finding.
1769 """Property-aware getattr to use in object finding.
1761
1770
1762 If attrname represents a property, return it unevaluated (in case it has
1771 If attrname represents a property, return it unevaluated (in case it has
1763 side effects or raises an error.
1772 side effects or raises an error.
1764
1773
1765 """
1774 """
1766 if not isinstance(obj, type):
1775 if not isinstance(obj, type):
1767 try:
1776 try:
1768 # `getattr(type(obj), attrname)` is not guaranteed to return
1777 # `getattr(type(obj), attrname)` is not guaranteed to return
1769 # `obj`, but does so for property:
1778 # `obj`, but does so for property:
1770 #
1779 #
1771 # property.__get__(self, None, cls) -> self
1780 # property.__get__(self, None, cls) -> self
1772 #
1781 #
1773 # The universal alternative is to traverse the mro manually
1782 # The universal alternative is to traverse the mro manually
1774 # searching for attrname in class dicts.
1783 # searching for attrname in class dicts.
1775 if is_integer_string(attrname):
1784 if is_integer_string(attrname):
1776 return obj[int(attrname)]
1785 return obj[int(attrname)]
1777 else:
1786 else:
1778 attr = getattr(type(obj), attrname)
1787 attr = getattr(type(obj), attrname)
1779 except AttributeError:
1788 except AttributeError:
1780 pass
1789 pass
1781 else:
1790 else:
1782 # This relies on the fact that data descriptors (with both
1791 # This relies on the fact that data descriptors (with both
1783 # __get__ & __set__ magic methods) take precedence over
1792 # __get__ & __set__ magic methods) take precedence over
1784 # instance-level attributes:
1793 # instance-level attributes:
1785 #
1794 #
1786 # class A(object):
1795 # class A(object):
1787 # @property
1796 # @property
1788 # def foobar(self): return 123
1797 # def foobar(self): return 123
1789 # a = A()
1798 # a = A()
1790 # a.__dict__['foobar'] = 345
1799 # a.__dict__['foobar'] = 345
1791 # a.foobar # == 123
1800 # a.foobar # == 123
1792 #
1801 #
1793 # So, a property may be returned right away.
1802 # So, a property may be returned right away.
1794 if isinstance(attr, property):
1803 if isinstance(attr, property):
1795 return attr
1804 return attr
1796
1805
1797 # Nothing helped, fall back.
1806 # Nothing helped, fall back.
1798 return getattr(obj, attrname)
1807 return getattr(obj, attrname)
1799
1808
1800 def _object_find(self, oname, namespaces=None) -> OInfo:
1809 def _object_find(self, oname, namespaces=None) -> OInfo:
1801 """Find an object and return a struct with info about it."""
1810 """Find an object and return a struct with info about it."""
1802 return self._ofind(oname, namespaces)
1811 return self._ofind(oname, namespaces)
1803
1812
1804 def _inspect(self, meth, oname, namespaces=None, **kw):
1813 def _inspect(self, meth, oname: str, namespaces=None, **kw):
1805 """Generic interface to the inspector system.
1814 """Generic interface to the inspector system.
1806
1815
1807 This function is meant to be called by pdef, pdoc & friends.
1816 This function is meant to be called by pdef, pdoc & friends.
1808 """
1817 """
1809 info: OInfo = self._object_find(oname, namespaces)
1818 info: OInfo = self._object_find(oname, namespaces)
1810 if self.sphinxify_docstring:
1819 if self.sphinxify_docstring:
1811 if sphinxify is None:
1820 if sphinxify is None:
1812 raise ImportError("Module ``docrepr`` required but missing")
1821 raise ImportError("Module ``docrepr`` required but missing")
1813 docformat = sphinxify(self.object_inspect(oname))
1822 docformat = sphinxify(self.object_inspect(oname))
1814 else:
1823 else:
1815 docformat = None
1824 docformat = None
1816 if info.found or hasattr(info.parent, oinspect.HOOK_NAME):
1825 if info.found or hasattr(info.parent, oinspect.HOOK_NAME):
1817 pmethod = getattr(self.inspector, meth)
1826 pmethod = getattr(self.inspector, meth)
1818 # TODO: only apply format_screen to the plain/text repr of the mime
1827 # TODO: only apply format_screen to the plain/text repr of the mime
1819 # bundle.
1828 # bundle.
1820 formatter = format_screen if info.ismagic else docformat
1829 formatter = format_screen if info.ismagic else docformat
1821 if meth == 'pdoc':
1830 if meth == 'pdoc':
1822 pmethod(info.obj, oname, formatter)
1831 pmethod(info.obj, oname, formatter)
1823 elif meth == 'pinfo':
1832 elif meth == 'pinfo':
1824 pmethod(
1833 pmethod(
1825 info.obj,
1834 info.obj,
1826 oname,
1835 oname,
1827 formatter,
1836 formatter,
1828 info,
1837 info,
1829 enable_html_pager=self.enable_html_pager,
1838 enable_html_pager=self.enable_html_pager,
1830 **kw,
1839 **kw,
1831 )
1840 )
1832 else:
1841 else:
1833 pmethod(info.obj, oname)
1842 pmethod(info.obj, oname)
1834 else:
1843 else:
1835 print('Object `%s` not found.' % oname)
1844 print('Object `%s` not found.' % oname)
1836 return 'not found' # so callers can take other action
1845 return 'not found' # so callers can take other action
1837
1846
1838 def object_inspect(self, oname, detail_level=0):
1847 def object_inspect(self, oname, detail_level=0):
1839 """Get object info about oname"""
1848 """Get object info about oname"""
1840 with self.builtin_trap:
1849 with self.builtin_trap:
1841 info = self._object_find(oname)
1850 info = self._object_find(oname)
1842 if info.found:
1851 if info.found:
1843 return self.inspector.info(info.obj, oname, info=info,
1852 return self.inspector.info(info.obj, oname, info=info,
1844 detail_level=detail_level
1853 detail_level=detail_level
1845 )
1854 )
1846 else:
1855 else:
1847 return oinspect.object_info(name=oname, found=False)
1856 return oinspect.object_info(name=oname, found=False)
1848
1857
1849 def object_inspect_text(self, oname, detail_level=0):
1858 def object_inspect_text(self, oname, detail_level=0):
1850 """Get object info as formatted text"""
1859 """Get object info as formatted text"""
1851 return self.object_inspect_mime(oname, detail_level)['text/plain']
1860 return self.object_inspect_mime(oname, detail_level)['text/plain']
1852
1861
1853 def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
1862 def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
1854 """Get object info as a mimebundle of formatted representations.
1863 """Get object info as a mimebundle of formatted representations.
1855
1864
1856 A mimebundle is a dictionary, keyed by mime-type.
1865 A mimebundle is a dictionary, keyed by mime-type.
1857 It must always have the key `'text/plain'`.
1866 It must always have the key `'text/plain'`.
1858 """
1867 """
1859 with self.builtin_trap:
1868 with self.builtin_trap:
1860 info = self._object_find(oname)
1869 info = self._object_find(oname)
1861 if info.found:
1870 if info.found:
1862 docformat = (
1871 docformat = (
1863 sphinxify(self.object_inspect(oname))
1872 sphinxify(self.object_inspect(oname))
1864 if self.sphinxify_docstring
1873 if self.sphinxify_docstring
1865 else None
1874 else None
1866 )
1875 )
1867 return self.inspector._get_info(
1876 return self.inspector._get_info(
1868 info.obj,
1877 info.obj,
1869 oname,
1878 oname,
1870 info=info,
1879 info=info,
1871 detail_level=detail_level,
1880 detail_level=detail_level,
1872 formatter=docformat,
1881 formatter=docformat,
1873 omit_sections=omit_sections,
1882 omit_sections=omit_sections,
1874 )
1883 )
1875 else:
1884 else:
1876 raise KeyError(oname)
1885 raise KeyError(oname)
1877
1886
1878 #-------------------------------------------------------------------------
1887 #-------------------------------------------------------------------------
1879 # Things related to history management
1888 # Things related to history management
1880 #-------------------------------------------------------------------------
1889 #-------------------------------------------------------------------------
1881
1890
1882 def init_history(self):
1891 def init_history(self):
1883 """Sets up the command history, and starts regular autosaves."""
1892 """Sets up the command history, and starts regular autosaves."""
1884 self.history_manager = HistoryManager(shell=self, parent=self)
1893 self.history_manager = HistoryManager(shell=self, parent=self)
1885 self.configurables.append(self.history_manager)
1894 self.configurables.append(self.history_manager)
1886
1895
1887 #-------------------------------------------------------------------------
1896 #-------------------------------------------------------------------------
1888 # Things related to exception handling and tracebacks (not debugging)
1897 # Things related to exception handling and tracebacks (not debugging)
1889 #-------------------------------------------------------------------------
1898 #-------------------------------------------------------------------------
1890
1899
1891 debugger_cls = InterruptiblePdb
1900 debugger_cls = InterruptiblePdb
1892
1901
1893 def init_traceback_handlers(self, custom_exceptions):
1902 def init_traceback_handlers(self, custom_exceptions):
1894 # Syntax error handler.
1903 # Syntax error handler.
1895 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1904 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1896
1905
1897 # The interactive one is initialized with an offset, meaning we always
1906 # The interactive one is initialized with an offset, meaning we always
1898 # want to remove the topmost item in the traceback, which is our own
1907 # want to remove the topmost item in the traceback, which is our own
1899 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1908 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1900 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1909 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1901 color_scheme='NoColor',
1910 color_scheme='NoColor',
1902 tb_offset = 1,
1911 tb_offset = 1,
1903 debugger_cls=self.debugger_cls, parent=self)
1912 debugger_cls=self.debugger_cls, parent=self)
1904
1913
1905 # The instance will store a pointer to the system-wide exception hook,
1914 # The instance will store a pointer to the system-wide exception hook,
1906 # so that runtime code (such as magics) can access it. This is because
1915 # so that runtime code (such as magics) can access it. This is because
1907 # during the read-eval loop, it may get temporarily overwritten.
1916 # during the read-eval loop, it may get temporarily overwritten.
1908 self.sys_excepthook = sys.excepthook
1917 self.sys_excepthook = sys.excepthook
1909
1918
1910 # and add any custom exception handlers the user may have specified
1919 # and add any custom exception handlers the user may have specified
1911 self.set_custom_exc(*custom_exceptions)
1920 self.set_custom_exc(*custom_exceptions)
1912
1921
1913 # Set the exception mode
1922 # Set the exception mode
1914 self.InteractiveTB.set_mode(mode=self.xmode)
1923 self.InteractiveTB.set_mode(mode=self.xmode)
1915
1924
1916 def set_custom_exc(self, exc_tuple, handler):
1925 def set_custom_exc(self, exc_tuple, handler):
1917 """set_custom_exc(exc_tuple, handler)
1926 """set_custom_exc(exc_tuple, handler)
1918
1927
1919 Set a custom exception handler, which will be called if any of the
1928 Set a custom exception handler, which will be called if any of the
1920 exceptions in exc_tuple occur in the mainloop (specifically, in the
1929 exceptions in exc_tuple occur in the mainloop (specifically, in the
1921 run_code() method).
1930 run_code() method).
1922
1931
1923 Parameters
1932 Parameters
1924 ----------
1933 ----------
1925 exc_tuple : tuple of exception classes
1934 exc_tuple : tuple of exception classes
1926 A *tuple* of exception classes, for which to call the defined
1935 A *tuple* of exception classes, for which to call the defined
1927 handler. It is very important that you use a tuple, and NOT A
1936 handler. It is very important that you use a tuple, and NOT A
1928 LIST here, because of the way Python's except statement works. If
1937 LIST here, because of the way Python's except statement works. If
1929 you only want to trap a single exception, use a singleton tuple::
1938 you only want to trap a single exception, use a singleton tuple::
1930
1939
1931 exc_tuple == (MyCustomException,)
1940 exc_tuple == (MyCustomException,)
1932
1941
1933 handler : callable
1942 handler : callable
1934 handler must have the following signature::
1943 handler must have the following signature::
1935
1944
1936 def my_handler(self, etype, value, tb, tb_offset=None):
1945 def my_handler(self, etype, value, tb, tb_offset=None):
1937 ...
1946 ...
1938 return structured_traceback
1947 return structured_traceback
1939
1948
1940 Your handler must return a structured traceback (a list of strings),
1949 Your handler must return a structured traceback (a list of strings),
1941 or None.
1950 or None.
1942
1951
1943 This will be made into an instance method (via types.MethodType)
1952 This will be made into an instance method (via types.MethodType)
1944 of IPython itself, and it will be called if any of the exceptions
1953 of IPython itself, and it will be called if any of the exceptions
1945 listed in the exc_tuple are caught. If the handler is None, an
1954 listed in the exc_tuple are caught. If the handler is None, an
1946 internal basic one is used, which just prints basic info.
1955 internal basic one is used, which just prints basic info.
1947
1956
1948 To protect IPython from crashes, if your handler ever raises an
1957 To protect IPython from crashes, if your handler ever raises an
1949 exception or returns an invalid result, it will be immediately
1958 exception or returns an invalid result, it will be immediately
1950 disabled.
1959 disabled.
1951
1960
1952 Notes
1961 Notes
1953 -----
1962 -----
1954 WARNING: by putting in your own exception handler into IPython's main
1963 WARNING: by putting in your own exception handler into IPython's main
1955 execution loop, you run a very good chance of nasty crashes. This
1964 execution loop, you run a very good chance of nasty crashes. This
1956 facility should only be used if you really know what you are doing.
1965 facility should only be used if you really know what you are doing.
1957 """
1966 """
1958
1967
1959 if not isinstance(exc_tuple, tuple):
1968 if not isinstance(exc_tuple, tuple):
1960 raise TypeError("The custom exceptions must be given as a tuple.")
1969 raise TypeError("The custom exceptions must be given as a tuple.")
1961
1970
1962 def dummy_handler(self, etype, value, tb, tb_offset=None):
1971 def dummy_handler(self, etype, value, tb, tb_offset=None):
1963 print('*** Simple custom exception handler ***')
1972 print('*** Simple custom exception handler ***')
1964 print('Exception type :', etype)
1973 print('Exception type :', etype)
1965 print('Exception value:', value)
1974 print('Exception value:', value)
1966 print('Traceback :', tb)
1975 print('Traceback :', tb)
1967
1976
1968 def validate_stb(stb):
1977 def validate_stb(stb):
1969 """validate structured traceback return type
1978 """validate structured traceback return type
1970
1979
1971 return type of CustomTB *should* be a list of strings, but allow
1980 return type of CustomTB *should* be a list of strings, but allow
1972 single strings or None, which are harmless.
1981 single strings or None, which are harmless.
1973
1982
1974 This function will *always* return a list of strings,
1983 This function will *always* return a list of strings,
1975 and will raise a TypeError if stb is inappropriate.
1984 and will raise a TypeError if stb is inappropriate.
1976 """
1985 """
1977 msg = "CustomTB must return list of strings, not %r" % stb
1986 msg = "CustomTB must return list of strings, not %r" % stb
1978 if stb is None:
1987 if stb is None:
1979 return []
1988 return []
1980 elif isinstance(stb, str):
1989 elif isinstance(stb, str):
1981 return [stb]
1990 return [stb]
1982 elif not isinstance(stb, list):
1991 elif not isinstance(stb, list):
1983 raise TypeError(msg)
1992 raise TypeError(msg)
1984 # it's a list
1993 # it's a list
1985 for line in stb:
1994 for line in stb:
1986 # check every element
1995 # check every element
1987 if not isinstance(line, str):
1996 if not isinstance(line, str):
1988 raise TypeError(msg)
1997 raise TypeError(msg)
1989 return stb
1998 return stb
1990
1999
1991 if handler is None:
2000 if handler is None:
1992 wrapped = dummy_handler
2001 wrapped = dummy_handler
1993 else:
2002 else:
1994 def wrapped(self,etype,value,tb,tb_offset=None):
2003 def wrapped(self,etype,value,tb,tb_offset=None):
1995 """wrap CustomTB handler, to protect IPython from user code
2004 """wrap CustomTB handler, to protect IPython from user code
1996
2005
1997 This makes it harder (but not impossible) for custom exception
2006 This makes it harder (but not impossible) for custom exception
1998 handlers to crash IPython.
2007 handlers to crash IPython.
1999 """
2008 """
2000 try:
2009 try:
2001 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
2010 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
2002 return validate_stb(stb)
2011 return validate_stb(stb)
2003 except:
2012 except:
2004 # clear custom handler immediately
2013 # clear custom handler immediately
2005 self.set_custom_exc((), None)
2014 self.set_custom_exc((), None)
2006 print("Custom TB Handler failed, unregistering", file=sys.stderr)
2015 print("Custom TB Handler failed, unregistering", file=sys.stderr)
2007 # show the exception in handler first
2016 # show the exception in handler first
2008 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
2017 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
2009 print(self.InteractiveTB.stb2text(stb))
2018 print(self.InteractiveTB.stb2text(stb))
2010 print("The original exception:")
2019 print("The original exception:")
2011 stb = self.InteractiveTB.structured_traceback(
2020 stb = self.InteractiveTB.structured_traceback(
2012 (etype,value,tb), tb_offset=tb_offset
2021 (etype,value,tb), tb_offset=tb_offset
2013 )
2022 )
2014 return stb
2023 return stb
2015
2024
2016 self.CustomTB = types.MethodType(wrapped,self)
2025 self.CustomTB = types.MethodType(wrapped,self)
2017 self.custom_exceptions = exc_tuple
2026 self.custom_exceptions = exc_tuple
2018
2027
2019 def excepthook(self, etype, value, tb):
2028 def excepthook(self, etype, value, tb):
2020 """One more defense for GUI apps that call sys.excepthook.
2029 """One more defense for GUI apps that call sys.excepthook.
2021
2030
2022 GUI frameworks like wxPython trap exceptions and call
2031 GUI frameworks like wxPython trap exceptions and call
2023 sys.excepthook themselves. I guess this is a feature that
2032 sys.excepthook themselves. I guess this is a feature that
2024 enables them to keep running after exceptions that would
2033 enables them to keep running after exceptions that would
2025 otherwise kill their mainloop. This is a bother for IPython
2034 otherwise kill their mainloop. This is a bother for IPython
2026 which expects to catch all of the program exceptions with a try:
2035 which expects to catch all of the program exceptions with a try:
2027 except: statement.
2036 except: statement.
2028
2037
2029 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
2038 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
2030 any app directly invokes sys.excepthook, it will look to the user like
2039 any app directly invokes sys.excepthook, it will look to the user like
2031 IPython crashed. In order to work around this, we can disable the
2040 IPython crashed. In order to work around this, we can disable the
2032 CrashHandler and replace it with this excepthook instead, which prints a
2041 CrashHandler and replace it with this excepthook instead, which prints a
2033 regular traceback using our InteractiveTB. In this fashion, apps which
2042 regular traceback using our InteractiveTB. In this fashion, apps which
2034 call sys.excepthook will generate a regular-looking exception from
2043 call sys.excepthook will generate a regular-looking exception from
2035 IPython, and the CrashHandler will only be triggered by real IPython
2044 IPython, and the CrashHandler will only be triggered by real IPython
2036 crashes.
2045 crashes.
2037
2046
2038 This hook should be used sparingly, only in places which are not likely
2047 This hook should be used sparingly, only in places which are not likely
2039 to be true IPython errors.
2048 to be true IPython errors.
2040 """
2049 """
2041 self.showtraceback((etype, value, tb), tb_offset=0)
2050 self.showtraceback((etype, value, tb), tb_offset=0)
2042
2051
2043 def _get_exc_info(self, exc_tuple=None):
2052 def _get_exc_info(self, exc_tuple=None):
2044 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
2053 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
2045
2054
2046 Ensures sys.last_type,value,traceback hold the exc_info we found,
2055 Ensures sys.last_type,value,traceback hold the exc_info we found,
2047 from whichever source.
2056 from whichever source.
2048
2057
2049 raises ValueError if none of these contain any information
2058 raises ValueError if none of these contain any information
2050 """
2059 """
2051 if exc_tuple is None:
2060 if exc_tuple is None:
2052 etype, value, tb = sys.exc_info()
2061 etype, value, tb = sys.exc_info()
2053 else:
2062 else:
2054 etype, value, tb = exc_tuple
2063 etype, value, tb = exc_tuple
2055
2064
2056 if etype is None:
2065 if etype is None:
2057 if hasattr(sys, 'last_type'):
2066 if hasattr(sys, 'last_type'):
2058 etype, value, tb = sys.last_type, sys.last_value, \
2067 etype, value, tb = sys.last_type, sys.last_value, \
2059 sys.last_traceback
2068 sys.last_traceback
2060
2069
2061 if etype is None:
2070 if etype is None:
2062 raise ValueError("No exception to find")
2071 raise ValueError("No exception to find")
2063
2072
2064 # Now store the exception info in sys.last_type etc.
2073 # Now store the exception info in sys.last_type etc.
2065 # WARNING: these variables are somewhat deprecated and not
2074 # WARNING: these variables are somewhat deprecated and not
2066 # necessarily safe to use in a threaded environment, but tools
2075 # necessarily safe to use in a threaded environment, but tools
2067 # like pdb depend on their existence, so let's set them. If we
2076 # like pdb depend on their existence, so let's set them. If we
2068 # find problems in the field, we'll need to revisit their use.
2077 # find problems in the field, we'll need to revisit their use.
2069 sys.last_type = etype
2078 sys.last_type = etype
2070 sys.last_value = value
2079 sys.last_value = value
2071 sys.last_traceback = tb
2080 sys.last_traceback = tb
2072
2081
2073 return etype, value, tb
2082 return etype, value, tb
2074
2083
2075 def show_usage_error(self, exc):
2084 def show_usage_error(self, exc):
2076 """Show a short message for UsageErrors
2085 """Show a short message for UsageErrors
2077
2086
2078 These are special exceptions that shouldn't show a traceback.
2087 These are special exceptions that shouldn't show a traceback.
2079 """
2088 """
2080 print("UsageError: %s" % exc, file=sys.stderr)
2089 print("UsageError: %s" % exc, file=sys.stderr)
2081
2090
2082 def get_exception_only(self, exc_tuple=None):
2091 def get_exception_only(self, exc_tuple=None):
2083 """
2092 """
2084 Return as a string (ending with a newline) the exception that
2093 Return as a string (ending with a newline) the exception that
2085 just occurred, without any traceback.
2094 just occurred, without any traceback.
2086 """
2095 """
2087 etype, value, tb = self._get_exc_info(exc_tuple)
2096 etype, value, tb = self._get_exc_info(exc_tuple)
2088 msg = traceback.format_exception_only(etype, value)
2097 msg = traceback.format_exception_only(etype, value)
2089 return ''.join(msg)
2098 return ''.join(msg)
2090
2099
2091 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
2100 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
2092 exception_only=False, running_compiled_code=False):
2101 exception_only=False, running_compiled_code=False):
2093 """Display the exception that just occurred.
2102 """Display the exception that just occurred.
2094
2103
2095 If nothing is known about the exception, this is the method which
2104 If nothing is known about the exception, this is the method which
2096 should be used throughout the code for presenting user tracebacks,
2105 should be used throughout the code for presenting user tracebacks,
2097 rather than directly invoking the InteractiveTB object.
2106 rather than directly invoking the InteractiveTB object.
2098
2107
2099 A specific showsyntaxerror() also exists, but this method can take
2108 A specific showsyntaxerror() also exists, but this method can take
2100 care of calling it if needed, so unless you are explicitly catching a
2109 care of calling it if needed, so unless you are explicitly catching a
2101 SyntaxError exception, don't try to analyze the stack manually and
2110 SyntaxError exception, don't try to analyze the stack manually and
2102 simply call this method."""
2111 simply call this method."""
2103
2112
2104 try:
2113 try:
2105 try:
2114 try:
2106 etype, value, tb = self._get_exc_info(exc_tuple)
2115 etype, value, tb = self._get_exc_info(exc_tuple)
2107 except ValueError:
2116 except ValueError:
2108 print('No traceback available to show.', file=sys.stderr)
2117 print('No traceback available to show.', file=sys.stderr)
2109 return
2118 return
2110
2119
2111 if issubclass(etype, SyntaxError):
2120 if issubclass(etype, SyntaxError):
2112 # Though this won't be called by syntax errors in the input
2121 # Though this won't be called by syntax errors in the input
2113 # line, there may be SyntaxError cases with imported code.
2122 # line, there may be SyntaxError cases with imported code.
2114 self.showsyntaxerror(filename, running_compiled_code)
2123 self.showsyntaxerror(filename, running_compiled_code)
2115 elif etype is UsageError:
2124 elif etype is UsageError:
2116 self.show_usage_error(value)
2125 self.show_usage_error(value)
2117 else:
2126 else:
2118 if exception_only:
2127 if exception_only:
2119 stb = ['An exception has occurred, use %tb to see '
2128 stb = ['An exception has occurred, use %tb to see '
2120 'the full traceback.\n']
2129 'the full traceback.\n']
2121 stb.extend(self.InteractiveTB.get_exception_only(etype,
2130 stb.extend(self.InteractiveTB.get_exception_only(etype,
2122 value))
2131 value))
2123 else:
2132 else:
2124
2133
2125 def contains_exceptiongroup(val):
2134 def contains_exceptiongroup(val):
2126 if val is None:
2135 if val is None:
2127 return False
2136 return False
2128 return isinstance(
2137 return isinstance(
2129 val, BaseExceptionGroup
2138 val, BaseExceptionGroup
2130 ) or contains_exceptiongroup(val.__context__)
2139 ) or contains_exceptiongroup(val.__context__)
2131
2140
2132 if contains_exceptiongroup(value):
2141 if contains_exceptiongroup(value):
2133 # fall back to native exception formatting until ultratb
2142 # fall back to native exception formatting until ultratb
2134 # supports exception groups
2143 # supports exception groups
2135 traceback.print_exc()
2144 traceback.print_exc()
2136 else:
2145 else:
2137 try:
2146 try:
2138 # Exception classes can customise their traceback - we
2147 # Exception classes can customise their traceback - we
2139 # use this in IPython.parallel for exceptions occurring
2148 # use this in IPython.parallel for exceptions occurring
2140 # in the engines. This should return a list of strings.
2149 # in the engines. This should return a list of strings.
2141 if hasattr(value, "_render_traceback_"):
2150 if hasattr(value, "_render_traceback_"):
2142 stb = value._render_traceback_()
2151 stb = value._render_traceback_()
2143 else:
2152 else:
2144 stb = self.InteractiveTB.structured_traceback(
2153 stb = self.InteractiveTB.structured_traceback(
2145 etype, value, tb, tb_offset=tb_offset
2154 etype, value, tb, tb_offset=tb_offset
2146 )
2155 )
2147
2156
2148 except Exception:
2157 except Exception:
2149 print(
2158 print(
2150 "Unexpected exception formatting exception. Falling back to standard exception"
2159 "Unexpected exception formatting exception. Falling back to standard exception"
2151 )
2160 )
2152 traceback.print_exc()
2161 traceback.print_exc()
2153 return None
2162 return None
2154
2163
2155 self._showtraceback(etype, value, stb)
2164 self._showtraceback(etype, value, stb)
2156 if self.call_pdb:
2165 if self.call_pdb:
2157 # drop into debugger
2166 # drop into debugger
2158 self.debugger(force=True)
2167 self.debugger(force=True)
2159 return
2168 return
2160
2169
2161 # Actually show the traceback
2170 # Actually show the traceback
2162 self._showtraceback(etype, value, stb)
2171 self._showtraceback(etype, value, stb)
2163
2172
2164 except KeyboardInterrupt:
2173 except KeyboardInterrupt:
2165 print('\n' + self.get_exception_only(), file=sys.stderr)
2174 print('\n' + self.get_exception_only(), file=sys.stderr)
2166
2175
2167 def _showtraceback(self, etype, evalue, stb: str):
2176 def _showtraceback(self, etype, evalue, stb: str):
2168 """Actually show a traceback.
2177 """Actually show a traceback.
2169
2178
2170 Subclasses may override this method to put the traceback on a different
2179 Subclasses may override this method to put the traceback on a different
2171 place, like a side channel.
2180 place, like a side channel.
2172 """
2181 """
2173 val = self.InteractiveTB.stb2text(stb)
2182 val = self.InteractiveTB.stb2text(stb)
2174 try:
2183 try:
2175 print(val)
2184 print(val)
2176 except UnicodeEncodeError:
2185 except UnicodeEncodeError:
2177 print(val.encode("utf-8", "backslashreplace").decode())
2186 print(val.encode("utf-8", "backslashreplace").decode())
2178
2187
2179 def showsyntaxerror(self, filename=None, running_compiled_code=False):
2188 def showsyntaxerror(self, filename=None, running_compiled_code=False):
2180 """Display the syntax error that just occurred.
2189 """Display the syntax error that just occurred.
2181
2190
2182 This doesn't display a stack trace because there isn't one.
2191 This doesn't display a stack trace because there isn't one.
2183
2192
2184 If a filename is given, it is stuffed in the exception instead
2193 If a filename is given, it is stuffed in the exception instead
2185 of what was there before (because Python's parser always uses
2194 of what was there before (because Python's parser always uses
2186 "<string>" when reading from a string).
2195 "<string>" when reading from a string).
2187
2196
2188 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
2197 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
2189 longer stack trace will be displayed.
2198 longer stack trace will be displayed.
2190 """
2199 """
2191 etype, value, last_traceback = self._get_exc_info()
2200 etype, value, last_traceback = self._get_exc_info()
2192
2201
2193 if filename and issubclass(etype, SyntaxError):
2202 if filename and issubclass(etype, SyntaxError):
2194 try:
2203 try:
2195 value.filename = filename
2204 value.filename = filename
2196 except:
2205 except:
2197 # Not the format we expect; leave it alone
2206 # Not the format we expect; leave it alone
2198 pass
2207 pass
2199
2208
2200 # If the error occurred when executing compiled code, we should provide full stacktrace.
2209 # If the error occurred when executing compiled code, we should provide full stacktrace.
2201 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
2210 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
2202 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
2211 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
2203 self._showtraceback(etype, value, stb)
2212 self._showtraceback(etype, value, stb)
2204
2213
2205 # This is overridden in TerminalInteractiveShell to show a message about
2214 # This is overridden in TerminalInteractiveShell to show a message about
2206 # the %paste magic.
2215 # the %paste magic.
2207 def showindentationerror(self):
2216 def showindentationerror(self):
2208 """Called by _run_cell when there's an IndentationError in code entered
2217 """Called by _run_cell when there's an IndentationError in code entered
2209 at the prompt.
2218 at the prompt.
2210
2219
2211 This is overridden in TerminalInteractiveShell to show a message about
2220 This is overridden in TerminalInteractiveShell to show a message about
2212 the %paste magic."""
2221 the %paste magic."""
2213 self.showsyntaxerror()
2222 self.showsyntaxerror()
2214
2223
2215 @skip_doctest
2224 @skip_doctest
2216 def set_next_input(self, s, replace=False):
2225 def set_next_input(self, s, replace=False):
2217 """ Sets the 'default' input string for the next command line.
2226 """ Sets the 'default' input string for the next command line.
2218
2227
2219 Example::
2228 Example::
2220
2229
2221 In [1]: _ip.set_next_input("Hello Word")
2230 In [1]: _ip.set_next_input("Hello Word")
2222 In [2]: Hello Word_ # cursor is here
2231 In [2]: Hello Word_ # cursor is here
2223 """
2232 """
2224 self.rl_next_input = s
2233 self.rl_next_input = s
2225
2234
2226 def _indent_current_str(self):
2235 def _indent_current_str(self):
2227 """return the current level of indentation as a string"""
2236 """return the current level of indentation as a string"""
2228 return self.input_splitter.get_indent_spaces() * ' '
2237 return self.input_splitter.get_indent_spaces() * ' '
2229
2238
2230 #-------------------------------------------------------------------------
2239 #-------------------------------------------------------------------------
2231 # Things related to text completion
2240 # Things related to text completion
2232 #-------------------------------------------------------------------------
2241 #-------------------------------------------------------------------------
2233
2242
2234 def init_completer(self):
2243 def init_completer(self):
2235 """Initialize the completion machinery.
2244 """Initialize the completion machinery.
2236
2245
2237 This creates completion machinery that can be used by client code,
2246 This creates completion machinery that can be used by client code,
2238 either interactively in-process (typically triggered by the readline
2247 either interactively in-process (typically triggered by the readline
2239 library), programmatically (such as in test suites) or out-of-process
2248 library), programmatically (such as in test suites) or out-of-process
2240 (typically over the network by remote frontends).
2249 (typically over the network by remote frontends).
2241 """
2250 """
2242 from IPython.core.completer import IPCompleter
2251 from IPython.core.completer import IPCompleter
2243 from IPython.core.completerlib import (
2252 from IPython.core.completerlib import (
2244 cd_completer,
2253 cd_completer,
2245 magic_run_completer,
2254 magic_run_completer,
2246 module_completer,
2255 module_completer,
2247 reset_completer,
2256 reset_completer,
2248 )
2257 )
2249
2258
2250 self.Completer = IPCompleter(shell=self,
2259 self.Completer = IPCompleter(shell=self,
2251 namespace=self.user_ns,
2260 namespace=self.user_ns,
2252 global_namespace=self.user_global_ns,
2261 global_namespace=self.user_global_ns,
2253 parent=self,
2262 parent=self,
2254 )
2263 )
2255 self.configurables.append(self.Completer)
2264 self.configurables.append(self.Completer)
2256
2265
2257 # Add custom completers to the basic ones built into IPCompleter
2266 # Add custom completers to the basic ones built into IPCompleter
2258 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2267 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2259 self.strdispatchers['complete_command'] = sdisp
2268 self.strdispatchers['complete_command'] = sdisp
2260 self.Completer.custom_completers = sdisp
2269 self.Completer.custom_completers = sdisp
2261
2270
2262 self.set_hook('complete_command', module_completer, str_key = 'import')
2271 self.set_hook('complete_command', module_completer, str_key = 'import')
2263 self.set_hook('complete_command', module_completer, str_key = 'from')
2272 self.set_hook('complete_command', module_completer, str_key = 'from')
2264 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2273 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2265 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2274 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2266 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2275 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2267 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2276 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2268
2277
2269 @skip_doctest
2278 @skip_doctest
2270 def complete(self, text, line=None, cursor_pos=None):
2279 def complete(self, text, line=None, cursor_pos=None):
2271 """Return the completed text and a list of completions.
2280 """Return the completed text and a list of completions.
2272
2281
2273 Parameters
2282 Parameters
2274 ----------
2283 ----------
2275 text : string
2284 text : string
2276 A string of text to be completed on. It can be given as empty and
2285 A string of text to be completed on. It can be given as empty and
2277 instead a line/position pair are given. In this case, the
2286 instead a line/position pair are given. In this case, the
2278 completer itself will split the line like readline does.
2287 completer itself will split the line like readline does.
2279 line : string, optional
2288 line : string, optional
2280 The complete line that text is part of.
2289 The complete line that text is part of.
2281 cursor_pos : int, optional
2290 cursor_pos : int, optional
2282 The position of the cursor on the input line.
2291 The position of the cursor on the input line.
2283
2292
2284 Returns
2293 Returns
2285 -------
2294 -------
2286 text : string
2295 text : string
2287 The actual text that was completed.
2296 The actual text that was completed.
2288 matches : list
2297 matches : list
2289 A sorted list with all possible completions.
2298 A sorted list with all possible completions.
2290
2299
2291 Notes
2300 Notes
2292 -----
2301 -----
2293 The optional arguments allow the completion to take more context into
2302 The optional arguments allow the completion to take more context into
2294 account, and are part of the low-level completion API.
2303 account, and are part of the low-level completion API.
2295
2304
2296 This is a wrapper around the completion mechanism, similar to what
2305 This is a wrapper around the completion mechanism, similar to what
2297 readline does at the command line when the TAB key is hit. By
2306 readline does at the command line when the TAB key is hit. By
2298 exposing it as a method, it can be used by other non-readline
2307 exposing it as a method, it can be used by other non-readline
2299 environments (such as GUIs) for text completion.
2308 environments (such as GUIs) for text completion.
2300
2309
2301 Examples
2310 Examples
2302 --------
2311 --------
2303 In [1]: x = 'hello'
2312 In [1]: x = 'hello'
2304
2313
2305 In [2]: _ip.complete('x.l')
2314 In [2]: _ip.complete('x.l')
2306 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2315 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2307 """
2316 """
2308
2317
2309 # Inject names into __builtin__ so we can complete on the added names.
2318 # Inject names into __builtin__ so we can complete on the added names.
2310 with self.builtin_trap:
2319 with self.builtin_trap:
2311 return self.Completer.complete(text, line, cursor_pos)
2320 return self.Completer.complete(text, line, cursor_pos)
2312
2321
2313 def set_custom_completer(self, completer, pos=0) -> None:
2322 def set_custom_completer(self, completer, pos=0) -> None:
2314 """Adds a new custom completer function.
2323 """Adds a new custom completer function.
2315
2324
2316 The position argument (defaults to 0) is the index in the completers
2325 The position argument (defaults to 0) is the index in the completers
2317 list where you want the completer to be inserted.
2326 list where you want the completer to be inserted.
2318
2327
2319 `completer` should have the following signature::
2328 `completer` should have the following signature::
2320
2329
2321 def completion(self: Completer, text: string) -> List[str]:
2330 def completion(self: Completer, text: string) -> List[str]:
2322 raise NotImplementedError
2331 raise NotImplementedError
2323
2332
2324 It will be bound to the current Completer instance and pass some text
2333 It will be bound to the current Completer instance and pass some text
2325 and return a list with current completions to suggest to the user.
2334 and return a list with current completions to suggest to the user.
2326 """
2335 """
2327
2336
2328 newcomp = types.MethodType(completer, self.Completer)
2337 newcomp = types.MethodType(completer, self.Completer)
2329 self.Completer.custom_matchers.insert(pos,newcomp)
2338 self.Completer.custom_matchers.insert(pos,newcomp)
2330
2339
2331 def set_completer_frame(self, frame=None):
2340 def set_completer_frame(self, frame=None):
2332 """Set the frame of the completer."""
2341 """Set the frame of the completer."""
2333 if frame:
2342 if frame:
2334 self.Completer.namespace = frame.f_locals
2343 self.Completer.namespace = frame.f_locals
2335 self.Completer.global_namespace = frame.f_globals
2344 self.Completer.global_namespace = frame.f_globals
2336 else:
2345 else:
2337 self.Completer.namespace = self.user_ns
2346 self.Completer.namespace = self.user_ns
2338 self.Completer.global_namespace = self.user_global_ns
2347 self.Completer.global_namespace = self.user_global_ns
2339
2348
2340 #-------------------------------------------------------------------------
2349 #-------------------------------------------------------------------------
2341 # Things related to magics
2350 # Things related to magics
2342 #-------------------------------------------------------------------------
2351 #-------------------------------------------------------------------------
2343
2352
2344 def init_magics(self):
2353 def init_magics(self):
2345 from IPython.core import magics as m
2354 from IPython.core import magics as m
2346 self.magics_manager = magic.MagicsManager(shell=self,
2355 self.magics_manager = magic.MagicsManager(shell=self,
2347 parent=self,
2356 parent=self,
2348 user_magics=m.UserMagics(self))
2357 user_magics=m.UserMagics(self))
2349 self.configurables.append(self.magics_manager)
2358 self.configurables.append(self.magics_manager)
2350
2359
2351 # Expose as public API from the magics manager
2360 # Expose as public API from the magics manager
2352 self.register_magics = self.magics_manager.register
2361 self.register_magics = self.magics_manager.register
2353
2362
2354 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2363 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2355 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2364 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2356 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2365 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2357 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2366 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2358 m.PylabMagics, m.ScriptMagics,
2367 m.PylabMagics, m.ScriptMagics,
2359 )
2368 )
2360 self.register_magics(m.AsyncMagics)
2369 self.register_magics(m.AsyncMagics)
2361
2370
2362 # Register Magic Aliases
2371 # Register Magic Aliases
2363 mman = self.magics_manager
2372 mman = self.magics_manager
2364 # FIXME: magic aliases should be defined by the Magics classes
2373 # FIXME: magic aliases should be defined by the Magics classes
2365 # or in MagicsManager, not here
2374 # or in MagicsManager, not here
2366 mman.register_alias('ed', 'edit')
2375 mman.register_alias('ed', 'edit')
2367 mman.register_alias('hist', 'history')
2376 mman.register_alias('hist', 'history')
2368 mman.register_alias('rep', 'recall')
2377 mman.register_alias('rep', 'recall')
2369 mman.register_alias('SVG', 'svg', 'cell')
2378 mman.register_alias('SVG', 'svg', 'cell')
2370 mman.register_alias('HTML', 'html', 'cell')
2379 mman.register_alias('HTML', 'html', 'cell')
2371 mman.register_alias('file', 'writefile', 'cell')
2380 mman.register_alias('file', 'writefile', 'cell')
2372
2381
2373 # FIXME: Move the color initialization to the DisplayHook, which
2382 # FIXME: Move the color initialization to the DisplayHook, which
2374 # should be split into a prompt manager and displayhook. We probably
2383 # should be split into a prompt manager and displayhook. We probably
2375 # even need a centralize colors management object.
2384 # even need a centralize colors management object.
2376 self.run_line_magic('colors', self.colors)
2385 self.run_line_magic('colors', self.colors)
2377
2386
2378 # Defined here so that it's included in the documentation
2387 # Defined here so that it's included in the documentation
2379 @functools.wraps(magic.MagicsManager.register_function)
2388 @functools.wraps(magic.MagicsManager.register_function)
2380 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2389 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2381 self.magics_manager.register_function(
2390 self.magics_manager.register_function(
2382 func, magic_kind=magic_kind, magic_name=magic_name
2391 func, magic_kind=magic_kind, magic_name=magic_name
2383 )
2392 )
2384
2393
2385 def _find_with_lazy_load(self, /, type_, magic_name: str):
2394 def _find_with_lazy_load(self, /, type_, magic_name: str):
2386 """
2395 """
2387 Try to find a magic potentially lazy-loading it.
2396 Try to find a magic potentially lazy-loading it.
2388
2397
2389 Parameters
2398 Parameters
2390 ----------
2399 ----------
2391
2400
2392 type_: "line"|"cell"
2401 type_: "line"|"cell"
2393 the type of magics we are trying to find/lazy load.
2402 the type of magics we are trying to find/lazy load.
2394 magic_name: str
2403 magic_name: str
2395 The name of the magic we are trying to find/lazy load
2404 The name of the magic we are trying to find/lazy load
2396
2405
2397
2406
2398 Note that this may have any side effects
2407 Note that this may have any side effects
2399 """
2408 """
2400 finder = {"line": self.find_line_magic, "cell": self.find_cell_magic}[type_]
2409 finder = {"line": self.find_line_magic, "cell": self.find_cell_magic}[type_]
2401 fn = finder(magic_name)
2410 fn = finder(magic_name)
2402 if fn is not None:
2411 if fn is not None:
2403 return fn
2412 return fn
2404 lazy = self.magics_manager.lazy_magics.get(magic_name)
2413 lazy = self.magics_manager.lazy_magics.get(magic_name)
2405 if lazy is None:
2414 if lazy is None:
2406 return None
2415 return None
2407
2416
2408 self.run_line_magic("load_ext", lazy)
2417 self.run_line_magic("load_ext", lazy)
2409 res = finder(magic_name)
2418 res = finder(magic_name)
2410 return res
2419 return res
2411
2420
2412 def run_line_magic(self, magic_name: str, line, _stack_depth=1):
2421 def run_line_magic(self, magic_name: str, line: str, _stack_depth=1):
2413 """Execute the given line magic.
2422 """Execute the given line magic.
2414
2423
2415 Parameters
2424 Parameters
2416 ----------
2425 ----------
2417 magic_name : str
2426 magic_name : str
2418 Name of the desired magic function, without '%' prefix.
2427 Name of the desired magic function, without '%' prefix.
2419 line : str
2428 line : str
2420 The rest of the input line as a single string.
2429 The rest of the input line as a single string.
2421 _stack_depth : int
2430 _stack_depth : int
2422 If run_line_magic() is called from magic() then _stack_depth=2.
2431 If run_line_magic() is called from magic() then _stack_depth=2.
2423 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2432 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2424 """
2433 """
2425 fn = self._find_with_lazy_load("line", magic_name)
2434 fn = self._find_with_lazy_load("line", magic_name)
2426 if fn is None:
2435 if fn is None:
2427 lazy = self.magics_manager.lazy_magics.get(magic_name)
2436 lazy = self.magics_manager.lazy_magics.get(magic_name)
2428 if lazy:
2437 if lazy:
2429 self.run_line_magic("load_ext", lazy)
2438 self.run_line_magic("load_ext", lazy)
2430 fn = self.find_line_magic(magic_name)
2439 fn = self.find_line_magic(magic_name)
2431 if fn is None:
2440 if fn is None:
2432 cm = self.find_cell_magic(magic_name)
2441 cm = self.find_cell_magic(magic_name)
2433 etpl = "Line magic function `%%%s` not found%s."
2442 etpl = "Line magic function `%%%s` not found%s."
2434 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2443 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2435 'did you mean that instead?)' % magic_name )
2444 'did you mean that instead?)' % magic_name )
2436 raise UsageError(etpl % (magic_name, extra))
2445 raise UsageError(etpl % (magic_name, extra))
2437 else:
2446 else:
2438 # Note: this is the distance in the stack to the user's frame.
2447 # Note: this is the distance in the stack to the user's frame.
2439 # This will need to be updated if the internal calling logic gets
2448 # This will need to be updated if the internal calling logic gets
2440 # refactored, or else we'll be expanding the wrong variables.
2449 # refactored, or else we'll be expanding the wrong variables.
2441
2450
2442 # Determine stack_depth depending on where run_line_magic() has been called
2451 # Determine stack_depth depending on where run_line_magic() has been called
2443 stack_depth = _stack_depth
2452 stack_depth = _stack_depth
2444 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2453 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2445 # magic has opted out of var_expand
2454 # magic has opted out of var_expand
2446 magic_arg_s = line
2455 magic_arg_s = line
2447 else:
2456 else:
2448 magic_arg_s = self.var_expand(line, stack_depth)
2457 magic_arg_s = self.var_expand(line, stack_depth)
2449 # Put magic args in a list so we can call with f(*a) syntax
2458 # Put magic args in a list so we can call with f(*a) syntax
2450 args = [magic_arg_s]
2459 args = [magic_arg_s]
2451 kwargs = {}
2460 kwargs = {}
2452 # Grab local namespace if we need it:
2461 # Grab local namespace if we need it:
2453 if getattr(fn, "needs_local_scope", False):
2462 if getattr(fn, "needs_local_scope", False):
2454 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2463 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2455 with self.builtin_trap:
2464 with self.builtin_trap:
2456 result = fn(*args, **kwargs)
2465 result = fn(*args, **kwargs)
2457
2466
2458 # The code below prevents the output from being displayed
2467 # The code below prevents the output from being displayed
2459 # when using magics with decorator @output_can_be_silenced
2468 # when using magics with decorator @output_can_be_silenced
2460 # when the last Python token in the expression is a ';'.
2469 # when the last Python token in the expression is a ';'.
2461 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2470 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2462 if DisplayHook.semicolon_at_end_of_expression(magic_arg_s):
2471 if DisplayHook.semicolon_at_end_of_expression(magic_arg_s):
2463 return None
2472 return None
2464
2473
2465 return result
2474 return result
2466
2475
2467 def get_local_scope(self, stack_depth):
2476 def get_local_scope(self, stack_depth):
2468 """Get local scope at given stack depth.
2477 """Get local scope at given stack depth.
2469
2478
2470 Parameters
2479 Parameters
2471 ----------
2480 ----------
2472 stack_depth : int
2481 stack_depth : int
2473 Depth relative to calling frame
2482 Depth relative to calling frame
2474 """
2483 """
2475 return sys._getframe(stack_depth + 1).f_locals
2484 return sys._getframe(stack_depth + 1).f_locals
2476
2485
2477 def run_cell_magic(self, magic_name, line, cell):
2486 def run_cell_magic(self, magic_name, line, cell):
2478 """Execute the given cell magic.
2487 """Execute the given cell magic.
2479
2488
2480 Parameters
2489 Parameters
2481 ----------
2490 ----------
2482 magic_name : str
2491 magic_name : str
2483 Name of the desired magic function, without '%' prefix.
2492 Name of the desired magic function, without '%' prefix.
2484 line : str
2493 line : str
2485 The rest of the first input line as a single string.
2494 The rest of the first input line as a single string.
2486 cell : str
2495 cell : str
2487 The body of the cell as a (possibly multiline) string.
2496 The body of the cell as a (possibly multiline) string.
2488 """
2497 """
2489 fn = self._find_with_lazy_load("cell", magic_name)
2498 fn = self._find_with_lazy_load("cell", magic_name)
2490 if fn is None:
2499 if fn is None:
2491 lm = self.find_line_magic(magic_name)
2500 lm = self.find_line_magic(magic_name)
2492 etpl = "Cell magic `%%{0}` not found{1}."
2501 etpl = "Cell magic `%%{0}` not found{1}."
2493 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2502 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2494 'did you mean that instead?)'.format(magic_name))
2503 'did you mean that instead?)'.format(magic_name))
2495 raise UsageError(etpl.format(magic_name, extra))
2504 raise UsageError(etpl.format(magic_name, extra))
2496 elif cell == '':
2505 elif cell == '':
2497 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2506 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2498 if self.find_line_magic(magic_name) is not None:
2507 if self.find_line_magic(magic_name) is not None:
2499 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2508 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2500 raise UsageError(message)
2509 raise UsageError(message)
2501 else:
2510 else:
2502 # Note: this is the distance in the stack to the user's frame.
2511 # Note: this is the distance in the stack to the user's frame.
2503 # This will need to be updated if the internal calling logic gets
2512 # This will need to be updated if the internal calling logic gets
2504 # refactored, or else we'll be expanding the wrong variables.
2513 # refactored, or else we'll be expanding the wrong variables.
2505 stack_depth = 2
2514 stack_depth = 2
2506 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2515 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2507 # magic has opted out of var_expand
2516 # magic has opted out of var_expand
2508 magic_arg_s = line
2517 magic_arg_s = line
2509 else:
2518 else:
2510 magic_arg_s = self.var_expand(line, stack_depth)
2519 magic_arg_s = self.var_expand(line, stack_depth)
2511 kwargs = {}
2520 kwargs = {}
2512 if getattr(fn, "needs_local_scope", False):
2521 if getattr(fn, "needs_local_scope", False):
2513 kwargs['local_ns'] = self.user_ns
2522 kwargs['local_ns'] = self.user_ns
2514
2523
2515 with self.builtin_trap:
2524 with self.builtin_trap:
2516 args = (magic_arg_s, cell)
2525 args = (magic_arg_s, cell)
2517 result = fn(*args, **kwargs)
2526 result = fn(*args, **kwargs)
2518
2527
2519 # The code below prevents the output from being displayed
2528 # The code below prevents the output from being displayed
2520 # when using magics with decorator @output_can_be_silenced
2529 # when using magics with decorator @output_can_be_silenced
2521 # when the last Python token in the expression is a ';'.
2530 # when the last Python token in the expression is a ';'.
2522 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2531 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2523 if DisplayHook.semicolon_at_end_of_expression(cell):
2532 if DisplayHook.semicolon_at_end_of_expression(cell):
2524 return None
2533 return None
2525
2534
2526 return result
2535 return result
2527
2536
2528 def find_line_magic(self, magic_name):
2537 def find_line_magic(self, magic_name):
2529 """Find and return a line magic by name.
2538 """Find and return a line magic by name.
2530
2539
2531 Returns None if the magic isn't found."""
2540 Returns None if the magic isn't found."""
2532 return self.magics_manager.magics['line'].get(magic_name)
2541 return self.magics_manager.magics['line'].get(magic_name)
2533
2542
2534 def find_cell_magic(self, magic_name):
2543 def find_cell_magic(self, magic_name):
2535 """Find and return a cell magic by name.
2544 """Find and return a cell magic by name.
2536
2545
2537 Returns None if the magic isn't found."""
2546 Returns None if the magic isn't found."""
2538 return self.magics_manager.magics['cell'].get(magic_name)
2547 return self.magics_manager.magics['cell'].get(magic_name)
2539
2548
2540 def find_magic(self, magic_name, magic_kind='line'):
2549 def find_magic(self, magic_name, magic_kind='line'):
2541 """Find and return a magic of the given type by name.
2550 """Find and return a magic of the given type by name.
2542
2551
2543 Returns None if the magic isn't found."""
2552 Returns None if the magic isn't found."""
2544 return self.magics_manager.magics[magic_kind].get(magic_name)
2553 return self.magics_manager.magics[magic_kind].get(magic_name)
2545
2554
2546 def magic(self, arg_s):
2555 def magic(self, arg_s):
2547 """
2556 """
2548 DEPRECATED
2557 DEPRECATED
2549
2558
2550 Deprecated since IPython 0.13 (warning added in
2559 Deprecated since IPython 0.13 (warning added in
2551 8.1), use run_line_magic(magic_name, parameter_s).
2560 8.1), use run_line_magic(magic_name, parameter_s).
2552
2561
2553 Call a magic function by name.
2562 Call a magic function by name.
2554
2563
2555 Input: a string containing the name of the magic function to call and
2564 Input: a string containing the name of the magic function to call and
2556 any additional arguments to be passed to the magic.
2565 any additional arguments to be passed to the magic.
2557
2566
2558 magic('name -opt foo bar') is equivalent to typing at the ipython
2567 magic('name -opt foo bar') is equivalent to typing at the ipython
2559 prompt:
2568 prompt:
2560
2569
2561 In[1]: %name -opt foo bar
2570 In[1]: %name -opt foo bar
2562
2571
2563 To call a magic without arguments, simply use magic('name').
2572 To call a magic without arguments, simply use magic('name').
2564
2573
2565 This provides a proper Python function to call IPython's magics in any
2574 This provides a proper Python function to call IPython's magics in any
2566 valid Python code you can type at the interpreter, including loops and
2575 valid Python code you can type at the interpreter, including loops and
2567 compound statements.
2576 compound statements.
2568 """
2577 """
2569 warnings.warn(
2578 warnings.warn(
2570 "`magic(...)` is deprecated since IPython 0.13 (warning added in "
2579 "`magic(...)` is deprecated since IPython 0.13 (warning added in "
2571 "8.1), use run_line_magic(magic_name, parameter_s).",
2580 "8.1), use run_line_magic(magic_name, parameter_s).",
2572 DeprecationWarning,
2581 DeprecationWarning,
2573 stacklevel=2,
2582 stacklevel=2,
2574 )
2583 )
2575 # TODO: should we issue a loud deprecation warning here?
2584 # TODO: should we issue a loud deprecation warning here?
2576 magic_name, _, magic_arg_s = arg_s.partition(' ')
2585 magic_name, _, magic_arg_s = arg_s.partition(' ')
2577 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2586 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2578 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2587 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2579
2588
2580 #-------------------------------------------------------------------------
2589 #-------------------------------------------------------------------------
2581 # Things related to macros
2590 # Things related to macros
2582 #-------------------------------------------------------------------------
2591 #-------------------------------------------------------------------------
2583
2592
2584 def define_macro(self, name, themacro):
2593 def define_macro(self, name, themacro):
2585 """Define a new macro
2594 """Define a new macro
2586
2595
2587 Parameters
2596 Parameters
2588 ----------
2597 ----------
2589 name : str
2598 name : str
2590 The name of the macro.
2599 The name of the macro.
2591 themacro : str or Macro
2600 themacro : str or Macro
2592 The action to do upon invoking the macro. If a string, a new
2601 The action to do upon invoking the macro. If a string, a new
2593 Macro object is created by passing the string to it.
2602 Macro object is created by passing the string to it.
2594 """
2603 """
2595
2604
2596 from IPython.core import macro
2605 from IPython.core import macro
2597
2606
2598 if isinstance(themacro, str):
2607 if isinstance(themacro, str):
2599 themacro = macro.Macro(themacro)
2608 themacro = macro.Macro(themacro)
2600 if not isinstance(themacro, macro.Macro):
2609 if not isinstance(themacro, macro.Macro):
2601 raise ValueError('A macro must be a string or a Macro instance.')
2610 raise ValueError('A macro must be a string or a Macro instance.')
2602 self.user_ns[name] = themacro
2611 self.user_ns[name] = themacro
2603
2612
2604 #-------------------------------------------------------------------------
2613 #-------------------------------------------------------------------------
2605 # Things related to the running of system commands
2614 # Things related to the running of system commands
2606 #-------------------------------------------------------------------------
2615 #-------------------------------------------------------------------------
2607
2616
2608 def system_piped(self, cmd):
2617 def system_piped(self, cmd):
2609 """Call the given cmd in a subprocess, piping stdout/err
2618 """Call the given cmd in a subprocess, piping stdout/err
2610
2619
2611 Parameters
2620 Parameters
2612 ----------
2621 ----------
2613 cmd : str
2622 cmd : str
2614 Command to execute (can not end in '&', as background processes are
2623 Command to execute (can not end in '&', as background processes are
2615 not supported. Should not be a command that expects input
2624 not supported. Should not be a command that expects input
2616 other than simple text.
2625 other than simple text.
2617 """
2626 """
2618 if cmd.rstrip().endswith('&'):
2627 if cmd.rstrip().endswith('&'):
2619 # this is *far* from a rigorous test
2628 # this is *far* from a rigorous test
2620 # We do not support backgrounding processes because we either use
2629 # We do not support backgrounding processes because we either use
2621 # pexpect or pipes to read from. Users can always just call
2630 # pexpect or pipes to read from. Users can always just call
2622 # os.system() or use ip.system=ip.system_raw
2631 # os.system() or use ip.system=ip.system_raw
2623 # if they really want a background process.
2632 # if they really want a background process.
2624 raise OSError("Background processes not supported.")
2633 raise OSError("Background processes not supported.")
2625
2634
2626 # we explicitly do NOT return the subprocess status code, because
2635 # we explicitly do NOT return the subprocess status code, because
2627 # a non-None value would trigger :func:`sys.displayhook` calls.
2636 # a non-None value would trigger :func:`sys.displayhook` calls.
2628 # Instead, we store the exit_code in user_ns.
2637 # Instead, we store the exit_code in user_ns.
2629 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2638 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2630
2639
2631 def system_raw(self, cmd):
2640 def system_raw(self, cmd):
2632 """Call the given cmd in a subprocess using os.system on Windows or
2641 """Call the given cmd in a subprocess using os.system on Windows or
2633 subprocess.call using the system shell on other platforms.
2642 subprocess.call using the system shell on other platforms.
2634
2643
2635 Parameters
2644 Parameters
2636 ----------
2645 ----------
2637 cmd : str
2646 cmd : str
2638 Command to execute.
2647 Command to execute.
2639 """
2648 """
2640 cmd = self.var_expand(cmd, depth=1)
2649 cmd = self.var_expand(cmd, depth=1)
2641 # warn if there is an IPython magic alternative.
2650 # warn if there is an IPython magic alternative.
2642 if cmd == "":
2651 if cmd == "":
2643 main_cmd = ""
2652 main_cmd = ""
2644 else:
2653 else:
2645 main_cmd = cmd.split()[0]
2654 main_cmd = cmd.split()[0]
2646 has_magic_alternatives = ("pip", "conda", "cd")
2655 has_magic_alternatives = ("pip", "conda", "cd")
2647
2656
2648 if main_cmd in has_magic_alternatives:
2657 if main_cmd in has_magic_alternatives:
2649 warnings.warn(
2658 warnings.warn(
2650 (
2659 (
2651 "You executed the system command !{0} which may not work "
2660 "You executed the system command !{0} which may not work "
2652 "as expected. Try the IPython magic %{0} instead."
2661 "as expected. Try the IPython magic %{0} instead."
2653 ).format(main_cmd)
2662 ).format(main_cmd)
2654 )
2663 )
2655
2664
2656 # protect os.system from UNC paths on Windows, which it can't handle:
2665 # protect os.system from UNC paths on Windows, which it can't handle:
2657 if sys.platform == 'win32':
2666 if sys.platform == 'win32':
2658 from IPython.utils._process_win32 import AvoidUNCPath
2667 from IPython.utils._process_win32 import AvoidUNCPath
2659 with AvoidUNCPath() as path:
2668 with AvoidUNCPath() as path:
2660 if path is not None:
2669 if path is not None:
2661 cmd = '"pushd %s &&"%s' % (path, cmd)
2670 cmd = '"pushd %s &&"%s' % (path, cmd)
2662 try:
2671 try:
2663 ec = os.system(cmd)
2672 ec = os.system(cmd)
2664 except KeyboardInterrupt:
2673 except KeyboardInterrupt:
2665 print('\n' + self.get_exception_only(), file=sys.stderr)
2674 print('\n' + self.get_exception_only(), file=sys.stderr)
2666 ec = -2
2675 ec = -2
2667 else:
2676 else:
2668 # For posix the result of the subprocess.call() below is an exit
2677 # For posix the result of the subprocess.call() below is an exit
2669 # code, which by convention is zero for success, positive for
2678 # code, which by convention is zero for success, positive for
2670 # program failure. Exit codes above 128 are reserved for signals,
2679 # program failure. Exit codes above 128 are reserved for signals,
2671 # and the formula for converting a signal to an exit code is usually
2680 # and the formula for converting a signal to an exit code is usually
2672 # signal_number+128. To more easily differentiate between exit
2681 # signal_number+128. To more easily differentiate between exit
2673 # codes and signals, ipython uses negative numbers. For instance
2682 # codes and signals, ipython uses negative numbers. For instance
2674 # since control-c is signal 2 but exit code 130, ipython's
2683 # since control-c is signal 2 but exit code 130, ipython's
2675 # _exit_code variable will read -2. Note that some shells like
2684 # _exit_code variable will read -2. Note that some shells like
2676 # csh and fish don't follow sh/bash conventions for exit codes.
2685 # csh and fish don't follow sh/bash conventions for exit codes.
2677 executable = os.environ.get('SHELL', None)
2686 executable = os.environ.get('SHELL', None)
2678 try:
2687 try:
2679 # Use env shell instead of default /bin/sh
2688 # Use env shell instead of default /bin/sh
2680 ec = subprocess.call(cmd, shell=True, executable=executable)
2689 ec = subprocess.call(cmd, shell=True, executable=executable)
2681 except KeyboardInterrupt:
2690 except KeyboardInterrupt:
2682 # intercept control-C; a long traceback is not useful here
2691 # intercept control-C; a long traceback is not useful here
2683 print('\n' + self.get_exception_only(), file=sys.stderr)
2692 print('\n' + self.get_exception_only(), file=sys.stderr)
2684 ec = 130
2693 ec = 130
2685 if ec > 128:
2694 if ec > 128:
2686 ec = -(ec - 128)
2695 ec = -(ec - 128)
2687
2696
2688 # We explicitly do NOT return the subprocess status code, because
2697 # We explicitly do NOT return the subprocess status code, because
2689 # a non-None value would trigger :func:`sys.displayhook` calls.
2698 # a non-None value would trigger :func:`sys.displayhook` calls.
2690 # Instead, we store the exit_code in user_ns. Note the semantics
2699 # Instead, we store the exit_code in user_ns. Note the semantics
2691 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2700 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2692 # but raising SystemExit(_exit_code) will give status 254!
2701 # but raising SystemExit(_exit_code) will give status 254!
2693 self.user_ns['_exit_code'] = ec
2702 self.user_ns['_exit_code'] = ec
2694
2703
2695 # use piped system by default, because it is better behaved
2704 # use piped system by default, because it is better behaved
2696 system = system_piped
2705 system = system_piped
2697
2706
2698 def getoutput(self, cmd, split=True, depth=0):
2707 def getoutput(self, cmd, split=True, depth=0):
2699 """Get output (possibly including stderr) from a subprocess.
2708 """Get output (possibly including stderr) from a subprocess.
2700
2709
2701 Parameters
2710 Parameters
2702 ----------
2711 ----------
2703 cmd : str
2712 cmd : str
2704 Command to execute (can not end in '&', as background processes are
2713 Command to execute (can not end in '&', as background processes are
2705 not supported.
2714 not supported.
2706 split : bool, optional
2715 split : bool, optional
2707 If True, split the output into an IPython SList. Otherwise, an
2716 If True, split the output into an IPython SList. Otherwise, an
2708 IPython LSString is returned. These are objects similar to normal
2717 IPython LSString is returned. These are objects similar to normal
2709 lists and strings, with a few convenience attributes for easier
2718 lists and strings, with a few convenience attributes for easier
2710 manipulation of line-based output. You can use '?' on them for
2719 manipulation of line-based output. You can use '?' on them for
2711 details.
2720 details.
2712 depth : int, optional
2721 depth : int, optional
2713 How many frames above the caller are the local variables which should
2722 How many frames above the caller are the local variables which should
2714 be expanded in the command string? The default (0) assumes that the
2723 be expanded in the command string? The default (0) assumes that the
2715 expansion variables are in the stack frame calling this function.
2724 expansion variables are in the stack frame calling this function.
2716 """
2725 """
2717 if cmd.rstrip().endswith('&'):
2726 if cmd.rstrip().endswith('&'):
2718 # this is *far* from a rigorous test
2727 # this is *far* from a rigorous test
2719 raise OSError("Background processes not supported.")
2728 raise OSError("Background processes not supported.")
2720 out = getoutput(self.var_expand(cmd, depth=depth+1))
2729 out = getoutput(self.var_expand(cmd, depth=depth+1))
2721 if split:
2730 if split:
2722 out = SList(out.splitlines())
2731 out = SList(out.splitlines())
2723 else:
2732 else:
2724 out = LSString(out)
2733 out = LSString(out)
2725 return out
2734 return out
2726
2735
2727 #-------------------------------------------------------------------------
2736 #-------------------------------------------------------------------------
2728 # Things related to aliases
2737 # Things related to aliases
2729 #-------------------------------------------------------------------------
2738 #-------------------------------------------------------------------------
2730
2739
2731 def init_alias(self):
2740 def init_alias(self):
2732 self.alias_manager = AliasManager(shell=self, parent=self)
2741 self.alias_manager = AliasManager(shell=self, parent=self)
2733 self.configurables.append(self.alias_manager)
2742 self.configurables.append(self.alias_manager)
2734
2743
2735 #-------------------------------------------------------------------------
2744 #-------------------------------------------------------------------------
2736 # Things related to extensions
2745 # Things related to extensions
2737 #-------------------------------------------------------------------------
2746 #-------------------------------------------------------------------------
2738
2747
2739 def init_extension_manager(self):
2748 def init_extension_manager(self):
2740 self.extension_manager = ExtensionManager(shell=self, parent=self)
2749 self.extension_manager = ExtensionManager(shell=self, parent=self)
2741 self.configurables.append(self.extension_manager)
2750 self.configurables.append(self.extension_manager)
2742
2751
2743 #-------------------------------------------------------------------------
2752 #-------------------------------------------------------------------------
2744 # Things related to payloads
2753 # Things related to payloads
2745 #-------------------------------------------------------------------------
2754 #-------------------------------------------------------------------------
2746
2755
2747 def init_payload(self):
2756 def init_payload(self):
2748 self.payload_manager = PayloadManager(parent=self)
2757 self.payload_manager = PayloadManager(parent=self)
2749 self.configurables.append(self.payload_manager)
2758 self.configurables.append(self.payload_manager)
2750
2759
2751 #-------------------------------------------------------------------------
2760 #-------------------------------------------------------------------------
2752 # Things related to the prefilter
2761 # Things related to the prefilter
2753 #-------------------------------------------------------------------------
2762 #-------------------------------------------------------------------------
2754
2763
2755 def init_prefilter(self):
2764 def init_prefilter(self):
2756 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2765 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2757 self.configurables.append(self.prefilter_manager)
2766 self.configurables.append(self.prefilter_manager)
2758 # Ultimately this will be refactored in the new interpreter code, but
2767 # Ultimately this will be refactored in the new interpreter code, but
2759 # for now, we should expose the main prefilter method (there's legacy
2768 # for now, we should expose the main prefilter method (there's legacy
2760 # code out there that may rely on this).
2769 # code out there that may rely on this).
2761 self.prefilter = self.prefilter_manager.prefilter_lines
2770 self.prefilter = self.prefilter_manager.prefilter_lines
2762
2771
2763 def auto_rewrite_input(self, cmd):
2772 def auto_rewrite_input(self, cmd):
2764 """Print to the screen the rewritten form of the user's command.
2773 """Print to the screen the rewritten form of the user's command.
2765
2774
2766 This shows visual feedback by rewriting input lines that cause
2775 This shows visual feedback by rewriting input lines that cause
2767 automatic calling to kick in, like::
2776 automatic calling to kick in, like::
2768
2777
2769 /f x
2778 /f x
2770
2779
2771 into::
2780 into::
2772
2781
2773 ------> f(x)
2782 ------> f(x)
2774
2783
2775 after the user's input prompt. This helps the user understand that the
2784 after the user's input prompt. This helps the user understand that the
2776 input line was transformed automatically by IPython.
2785 input line was transformed automatically by IPython.
2777 """
2786 """
2778 if not self.show_rewritten_input:
2787 if not self.show_rewritten_input:
2779 return
2788 return
2780
2789
2781 # This is overridden in TerminalInteractiveShell to use fancy prompts
2790 # This is overridden in TerminalInteractiveShell to use fancy prompts
2782 print("------> " + cmd)
2791 print("------> " + cmd)
2783
2792
2784 #-------------------------------------------------------------------------
2793 #-------------------------------------------------------------------------
2785 # Things related to extracting values/expressions from kernel and user_ns
2794 # Things related to extracting values/expressions from kernel and user_ns
2786 #-------------------------------------------------------------------------
2795 #-------------------------------------------------------------------------
2787
2796
2788 def _user_obj_error(self):
2797 def _user_obj_error(self):
2789 """return simple exception dict
2798 """return simple exception dict
2790
2799
2791 for use in user_expressions
2800 for use in user_expressions
2792 """
2801 """
2793
2802
2794 etype, evalue, tb = self._get_exc_info()
2803 etype, evalue, tb = self._get_exc_info()
2795 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2804 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2796
2805
2797 exc_info = {
2806 exc_info = {
2798 "status": "error",
2807 "status": "error",
2799 "traceback": stb,
2808 "traceback": stb,
2800 "ename": etype.__name__,
2809 "ename": etype.__name__,
2801 "evalue": py3compat.safe_unicode(evalue),
2810 "evalue": py3compat.safe_unicode(evalue),
2802 }
2811 }
2803
2812
2804 return exc_info
2813 return exc_info
2805
2814
2806 def _format_user_obj(self, obj):
2815 def _format_user_obj(self, obj):
2807 """format a user object to display dict
2816 """format a user object to display dict
2808
2817
2809 for use in user_expressions
2818 for use in user_expressions
2810 """
2819 """
2811
2820
2812 data, md = self.display_formatter.format(obj)
2821 data, md = self.display_formatter.format(obj)
2813 value = {
2822 value = {
2814 'status' : 'ok',
2823 'status' : 'ok',
2815 'data' : data,
2824 'data' : data,
2816 'metadata' : md,
2825 'metadata' : md,
2817 }
2826 }
2818 return value
2827 return value
2819
2828
2820 def user_expressions(self, expressions):
2829 def user_expressions(self, expressions):
2821 """Evaluate a dict of expressions in the user's namespace.
2830 """Evaluate a dict of expressions in the user's namespace.
2822
2831
2823 Parameters
2832 Parameters
2824 ----------
2833 ----------
2825 expressions : dict
2834 expressions : dict
2826 A dict with string keys and string values. The expression values
2835 A dict with string keys and string values. The expression values
2827 should be valid Python expressions, each of which will be evaluated
2836 should be valid Python expressions, each of which will be evaluated
2828 in the user namespace.
2837 in the user namespace.
2829
2838
2830 Returns
2839 Returns
2831 -------
2840 -------
2832 A dict, keyed like the input expressions dict, with the rich mime-typed
2841 A dict, keyed like the input expressions dict, with the rich mime-typed
2833 display_data of each value.
2842 display_data of each value.
2834 """
2843 """
2835 out = {}
2844 out = {}
2836 user_ns = self.user_ns
2845 user_ns = self.user_ns
2837 global_ns = self.user_global_ns
2846 global_ns = self.user_global_ns
2838
2847
2839 for key, expr in expressions.items():
2848 for key, expr in expressions.items():
2840 try:
2849 try:
2841 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2850 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2842 except:
2851 except:
2843 value = self._user_obj_error()
2852 value = self._user_obj_error()
2844 out[key] = value
2853 out[key] = value
2845 return out
2854 return out
2846
2855
2847 #-------------------------------------------------------------------------
2856 #-------------------------------------------------------------------------
2848 # Things related to the running of code
2857 # Things related to the running of code
2849 #-------------------------------------------------------------------------
2858 #-------------------------------------------------------------------------
2850
2859
2851 def ex(self, cmd):
2860 def ex(self, cmd):
2852 """Execute a normal python statement in user namespace."""
2861 """Execute a normal python statement in user namespace."""
2853 with self.builtin_trap:
2862 with self.builtin_trap:
2854 exec(cmd, self.user_global_ns, self.user_ns)
2863 exec(cmd, self.user_global_ns, self.user_ns)
2855
2864
2856 def ev(self, expr):
2865 def ev(self, expr):
2857 """Evaluate python expression expr in user namespace.
2866 """Evaluate python expression expr in user namespace.
2858
2867
2859 Returns the result of evaluation
2868 Returns the result of evaluation
2860 """
2869 """
2861 with self.builtin_trap:
2870 with self.builtin_trap:
2862 return eval(expr, self.user_global_ns, self.user_ns)
2871 return eval(expr, self.user_global_ns, self.user_ns)
2863
2872
2864 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2873 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2865 """A safe version of the builtin execfile().
2874 """A safe version of the builtin execfile().
2866
2875
2867 This version will never throw an exception, but instead print
2876 This version will never throw an exception, but instead print
2868 helpful error messages to the screen. This only works on pure
2877 helpful error messages to the screen. This only works on pure
2869 Python files with the .py extension.
2878 Python files with the .py extension.
2870
2879
2871 Parameters
2880 Parameters
2872 ----------
2881 ----------
2873 fname : string
2882 fname : string
2874 The name of the file to be executed.
2883 The name of the file to be executed.
2875 *where : tuple
2884 *where : tuple
2876 One or two namespaces, passed to execfile() as (globals,locals).
2885 One or two namespaces, passed to execfile() as (globals,locals).
2877 If only one is given, it is passed as both.
2886 If only one is given, it is passed as both.
2878 exit_ignore : bool (False)
2887 exit_ignore : bool (False)
2879 If True, then silence SystemExit for non-zero status (it is always
2888 If True, then silence SystemExit for non-zero status (it is always
2880 silenced for zero status, as it is so common).
2889 silenced for zero status, as it is so common).
2881 raise_exceptions : bool (False)
2890 raise_exceptions : bool (False)
2882 If True raise exceptions everywhere. Meant for testing.
2891 If True raise exceptions everywhere. Meant for testing.
2883 shell_futures : bool (False)
2892 shell_futures : bool (False)
2884 If True, the code will share future statements with the interactive
2893 If True, the code will share future statements with the interactive
2885 shell. It will both be affected by previous __future__ imports, and
2894 shell. It will both be affected by previous __future__ imports, and
2886 any __future__ imports in the code will affect the shell. If False,
2895 any __future__ imports in the code will affect the shell. If False,
2887 __future__ imports are not shared in either direction.
2896 __future__ imports are not shared in either direction.
2888
2897
2889 """
2898 """
2890 fname = Path(fname).expanduser().resolve()
2899 fname = Path(fname).expanduser().resolve()
2891
2900
2892 # Make sure we can open the file
2901 # Make sure we can open the file
2893 try:
2902 try:
2894 with fname.open("rb"):
2903 with fname.open("rb"):
2895 pass
2904 pass
2896 except:
2905 except:
2897 warn('Could not open file <%s> for safe execution.' % fname)
2906 warn('Could not open file <%s> for safe execution.' % fname)
2898 return
2907 return
2899
2908
2900 # Find things also in current directory. This is needed to mimic the
2909 # Find things also in current directory. This is needed to mimic the
2901 # behavior of running a script from the system command line, where
2910 # behavior of running a script from the system command line, where
2902 # Python inserts the script's directory into sys.path
2911 # Python inserts the script's directory into sys.path
2903 dname = str(fname.parent)
2912 dname = str(fname.parent)
2904
2913
2905 with prepended_to_syspath(dname), self.builtin_trap:
2914 with prepended_to_syspath(dname), self.builtin_trap:
2906 try:
2915 try:
2907 glob, loc = (where + (None, ))[:2]
2916 glob, loc = (where + (None, ))[:2]
2908 py3compat.execfile(
2917 py3compat.execfile(
2909 fname, glob, loc,
2918 fname, glob, loc,
2910 self.compile if shell_futures else None)
2919 self.compile if shell_futures else None)
2911 except SystemExit as status:
2920 except SystemExit as status:
2912 # If the call was made with 0 or None exit status (sys.exit(0)
2921 # If the call was made with 0 or None exit status (sys.exit(0)
2913 # or sys.exit() ), don't bother showing a traceback, as both of
2922 # or sys.exit() ), don't bother showing a traceback, as both of
2914 # these are considered normal by the OS:
2923 # these are considered normal by the OS:
2915 # > python -c'import sys;sys.exit(0)'; echo $?
2924 # > python -c'import sys;sys.exit(0)'; echo $?
2916 # 0
2925 # 0
2917 # > python -c'import sys;sys.exit()'; echo $?
2926 # > python -c'import sys;sys.exit()'; echo $?
2918 # 0
2927 # 0
2919 # For other exit status, we show the exception unless
2928 # For other exit status, we show the exception unless
2920 # explicitly silenced, but only in short form.
2929 # explicitly silenced, but only in short form.
2921 if status.code:
2930 if status.code:
2922 if raise_exceptions:
2931 if raise_exceptions:
2923 raise
2932 raise
2924 if not exit_ignore:
2933 if not exit_ignore:
2925 self.showtraceback(exception_only=True)
2934 self.showtraceback(exception_only=True)
2926 except:
2935 except:
2927 if raise_exceptions:
2936 if raise_exceptions:
2928 raise
2937 raise
2929 # tb offset is 2 because we wrap execfile
2938 # tb offset is 2 because we wrap execfile
2930 self.showtraceback(tb_offset=2)
2939 self.showtraceback(tb_offset=2)
2931
2940
2932 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2941 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2933 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2942 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2934
2943
2935 Parameters
2944 Parameters
2936 ----------
2945 ----------
2937 fname : str
2946 fname : str
2938 The name of the file to execute. The filename must have a
2947 The name of the file to execute. The filename must have a
2939 .ipy or .ipynb extension.
2948 .ipy or .ipynb extension.
2940 shell_futures : bool (False)
2949 shell_futures : bool (False)
2941 If True, the code will share future statements with the interactive
2950 If True, the code will share future statements with the interactive
2942 shell. It will both be affected by previous __future__ imports, and
2951 shell. It will both be affected by previous __future__ imports, and
2943 any __future__ imports in the code will affect the shell. If False,
2952 any __future__ imports in the code will affect the shell. If False,
2944 __future__ imports are not shared in either direction.
2953 __future__ imports are not shared in either direction.
2945 raise_exceptions : bool (False)
2954 raise_exceptions : bool (False)
2946 If True raise exceptions everywhere. Meant for testing.
2955 If True raise exceptions everywhere. Meant for testing.
2947 """
2956 """
2948 fname = Path(fname).expanduser().resolve()
2957 fname = Path(fname).expanduser().resolve()
2949
2958
2950 # Make sure we can open the file
2959 # Make sure we can open the file
2951 try:
2960 try:
2952 with fname.open("rb"):
2961 with fname.open("rb"):
2953 pass
2962 pass
2954 except:
2963 except:
2955 warn('Could not open file <%s> for safe execution.' % fname)
2964 warn('Could not open file <%s> for safe execution.' % fname)
2956 return
2965 return
2957
2966
2958 # Find things also in current directory. This is needed to mimic the
2967 # Find things also in current directory. This is needed to mimic the
2959 # behavior of running a script from the system command line, where
2968 # behavior of running a script from the system command line, where
2960 # Python inserts the script's directory into sys.path
2969 # Python inserts the script's directory into sys.path
2961 dname = str(fname.parent)
2970 dname = str(fname.parent)
2962
2971
2963 def get_cells():
2972 def get_cells():
2964 """generator for sequence of code blocks to run"""
2973 """generator for sequence of code blocks to run"""
2965 if fname.suffix == ".ipynb":
2974 if fname.suffix == ".ipynb":
2966 from nbformat import read
2975 from nbformat import read
2967 nb = read(fname, as_version=4)
2976 nb = read(fname, as_version=4)
2968 if not nb.cells:
2977 if not nb.cells:
2969 return
2978 return
2970 for cell in nb.cells:
2979 for cell in nb.cells:
2971 if cell.cell_type == 'code':
2980 if cell.cell_type == 'code':
2972 yield cell.source
2981 yield cell.source
2973 else:
2982 else:
2974 yield fname.read_text(encoding="utf-8")
2983 yield fname.read_text(encoding="utf-8")
2975
2984
2976 with prepended_to_syspath(dname):
2985 with prepended_to_syspath(dname):
2977 try:
2986 try:
2978 for cell in get_cells():
2987 for cell in get_cells():
2979 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2988 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2980 if raise_exceptions:
2989 if raise_exceptions:
2981 result.raise_error()
2990 result.raise_error()
2982 elif not result.success:
2991 elif not result.success:
2983 break
2992 break
2984 except:
2993 except:
2985 if raise_exceptions:
2994 if raise_exceptions:
2986 raise
2995 raise
2987 self.showtraceback()
2996 self.showtraceback()
2988 warn('Unknown failure executing file: <%s>' % fname)
2997 warn('Unknown failure executing file: <%s>' % fname)
2989
2998
2990 def safe_run_module(self, mod_name, where):
2999 def safe_run_module(self, mod_name, where):
2991 """A safe version of runpy.run_module().
3000 """A safe version of runpy.run_module().
2992
3001
2993 This version will never throw an exception, but instead print
3002 This version will never throw an exception, but instead print
2994 helpful error messages to the screen.
3003 helpful error messages to the screen.
2995
3004
2996 `SystemExit` exceptions with status code 0 or None are ignored.
3005 `SystemExit` exceptions with status code 0 or None are ignored.
2997
3006
2998 Parameters
3007 Parameters
2999 ----------
3008 ----------
3000 mod_name : string
3009 mod_name : string
3001 The name of the module to be executed.
3010 The name of the module to be executed.
3002 where : dict
3011 where : dict
3003 The globals namespace.
3012 The globals namespace.
3004 """
3013 """
3005 try:
3014 try:
3006 try:
3015 try:
3007 where.update(
3016 where.update(
3008 runpy.run_module(str(mod_name), run_name="__main__",
3017 runpy.run_module(str(mod_name), run_name="__main__",
3009 alter_sys=True)
3018 alter_sys=True)
3010 )
3019 )
3011 except SystemExit as status:
3020 except SystemExit as status:
3012 if status.code:
3021 if status.code:
3013 raise
3022 raise
3014 except:
3023 except:
3015 self.showtraceback()
3024 self.showtraceback()
3016 warn('Unknown failure executing module: <%s>' % mod_name)
3025 warn('Unknown failure executing module: <%s>' % mod_name)
3017
3026
3018 def run_cell(
3027 def run_cell(
3019 self,
3028 self,
3020 raw_cell,
3029 raw_cell,
3021 store_history=False,
3030 store_history=False,
3022 silent=False,
3031 silent=False,
3023 shell_futures=True,
3032 shell_futures=True,
3024 cell_id=None,
3033 cell_id=None,
3025 ):
3034 ):
3026 """Run a complete IPython cell.
3035 """Run a complete IPython cell.
3027
3036
3028 Parameters
3037 Parameters
3029 ----------
3038 ----------
3030 raw_cell : str
3039 raw_cell : str
3031 The code (including IPython code such as %magic functions) to run.
3040 The code (including IPython code such as %magic functions) to run.
3032 store_history : bool
3041 store_history : bool
3033 If True, the raw and translated cell will be stored in IPython's
3042 If True, the raw and translated cell will be stored in IPython's
3034 history. For user code calling back into IPython's machinery, this
3043 history. For user code calling back into IPython's machinery, this
3035 should be set to False.
3044 should be set to False.
3036 silent : bool
3045 silent : bool
3037 If True, avoid side-effects, such as implicit displayhooks and
3046 If True, avoid side-effects, such as implicit displayhooks and
3038 and logging. silent=True forces store_history=False.
3047 and logging. silent=True forces store_history=False.
3039 shell_futures : bool
3048 shell_futures : bool
3040 If True, the code will share future statements with the interactive
3049 If True, the code will share future statements with the interactive
3041 shell. It will both be affected by previous __future__ imports, and
3050 shell. It will both be affected by previous __future__ imports, and
3042 any __future__ imports in the code will affect the shell. If False,
3051 any __future__ imports in the code will affect the shell. If False,
3043 __future__ imports are not shared in either direction.
3052 __future__ imports are not shared in either direction.
3044
3053
3045 Returns
3054 Returns
3046 -------
3055 -------
3047 result : :class:`ExecutionResult`
3056 result : :class:`ExecutionResult`
3048 """
3057 """
3049 result = None
3058 result = None
3050 try:
3059 try:
3051 result = self._run_cell(
3060 result = self._run_cell(
3052 raw_cell, store_history, silent, shell_futures, cell_id
3061 raw_cell, store_history, silent, shell_futures, cell_id
3053 )
3062 )
3054 finally:
3063 finally:
3055 self.events.trigger('post_execute')
3064 self.events.trigger('post_execute')
3056 if not silent:
3065 if not silent:
3057 self.events.trigger('post_run_cell', result)
3066 self.events.trigger('post_run_cell', result)
3058 return result
3067 return result
3059
3068
3060 def _run_cell(
3069 def _run_cell(
3061 self,
3070 self,
3062 raw_cell: str,
3071 raw_cell: str,
3063 store_history: bool,
3072 store_history: bool,
3064 silent: bool,
3073 silent: bool,
3065 shell_futures: bool,
3074 shell_futures: bool,
3066 cell_id: str,
3075 cell_id: str,
3067 ) -> ExecutionResult:
3076 ) -> ExecutionResult:
3068 """Internal method to run a complete IPython cell."""
3077 """Internal method to run a complete IPython cell."""
3069
3078
3070 # we need to avoid calling self.transform_cell multiple time on the same thing
3079 # we need to avoid calling self.transform_cell multiple time on the same thing
3071 # so we need to store some results:
3080 # so we need to store some results:
3072 preprocessing_exc_tuple = None
3081 preprocessing_exc_tuple = None
3073 try:
3082 try:
3074 transformed_cell = self.transform_cell(raw_cell)
3083 transformed_cell = self.transform_cell(raw_cell)
3075 except Exception:
3084 except Exception:
3076 transformed_cell = raw_cell
3085 transformed_cell = raw_cell
3077 preprocessing_exc_tuple = sys.exc_info()
3086 preprocessing_exc_tuple = sys.exc_info()
3078
3087
3079 assert transformed_cell is not None
3088 assert transformed_cell is not None
3080 coro = self.run_cell_async(
3089 coro = self.run_cell_async(
3081 raw_cell,
3090 raw_cell,
3082 store_history=store_history,
3091 store_history=store_history,
3083 silent=silent,
3092 silent=silent,
3084 shell_futures=shell_futures,
3093 shell_futures=shell_futures,
3085 transformed_cell=transformed_cell,
3094 transformed_cell=transformed_cell,
3086 preprocessing_exc_tuple=preprocessing_exc_tuple,
3095 preprocessing_exc_tuple=preprocessing_exc_tuple,
3087 cell_id=cell_id,
3096 cell_id=cell_id,
3088 )
3097 )
3089
3098
3090 # run_cell_async is async, but may not actually need an eventloop.
3099 # run_cell_async is async, but may not actually need an eventloop.
3091 # when this is the case, we want to run it using the pseudo_sync_runner
3100 # when this is the case, we want to run it using the pseudo_sync_runner
3092 # so that code can invoke eventloops (for example via the %run , and
3101 # so that code can invoke eventloops (for example via the %run , and
3093 # `%paste` magic.
3102 # `%paste` magic.
3094 if self.trio_runner:
3103 if self.trio_runner:
3095 runner = self.trio_runner
3104 runner = self.trio_runner
3096 elif self.should_run_async(
3105 elif self.should_run_async(
3097 raw_cell,
3106 raw_cell,
3098 transformed_cell=transformed_cell,
3107 transformed_cell=transformed_cell,
3099 preprocessing_exc_tuple=preprocessing_exc_tuple,
3108 preprocessing_exc_tuple=preprocessing_exc_tuple,
3100 ):
3109 ):
3101 runner = self.loop_runner
3110 runner = self.loop_runner
3102 else:
3111 else:
3103 runner = _pseudo_sync_runner
3112 runner = _pseudo_sync_runner
3104
3113
3105 try:
3114 try:
3106 result = runner(coro)
3115 result = runner(coro)
3107 except BaseException as e:
3116 except BaseException as e:
3108 info = ExecutionInfo(
3117 info = ExecutionInfo(
3109 raw_cell, store_history, silent, shell_futures, cell_id
3118 raw_cell, store_history, silent, shell_futures, cell_id
3110 )
3119 )
3111 result = ExecutionResult(info)
3120 result = ExecutionResult(info)
3112 result.error_in_exec = e
3121 result.error_in_exec = e
3113 self.showtraceback(running_compiled_code=True)
3122 self.showtraceback(running_compiled_code=True)
3114 finally:
3123 finally:
3115 return result
3124 return result
3116
3125
3117 def should_run_async(
3126 def should_run_async(
3118 self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None
3127 self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None
3119 ) -> bool:
3128 ) -> bool:
3120 """Return whether a cell should be run asynchronously via a coroutine runner
3129 """Return whether a cell should be run asynchronously via a coroutine runner
3121
3130
3122 Parameters
3131 Parameters
3123 ----------
3132 ----------
3124 raw_cell : str
3133 raw_cell : str
3125 The code to be executed
3134 The code to be executed
3126
3135
3127 Returns
3136 Returns
3128 -------
3137 -------
3129 result: bool
3138 result: bool
3130 Whether the code needs to be run with a coroutine runner or not
3139 Whether the code needs to be run with a coroutine runner or not
3131 .. versionadded:: 7.0
3140 .. versionadded:: 7.0
3132 """
3141 """
3133 if not self.autoawait:
3142 if not self.autoawait:
3134 return False
3143 return False
3135 if preprocessing_exc_tuple is not None:
3144 if preprocessing_exc_tuple is not None:
3136 return False
3145 return False
3137 assert preprocessing_exc_tuple is None
3146 assert preprocessing_exc_tuple is None
3138 if transformed_cell is None:
3147 if transformed_cell is None:
3139 warnings.warn(
3148 warnings.warn(
3140 "`should_run_async` will not call `transform_cell`"
3149 "`should_run_async` will not call `transform_cell`"
3141 " automatically in the future. Please pass the result to"
3150 " automatically in the future. Please pass the result to"
3142 " `transformed_cell` argument and any exception that happen"
3151 " `transformed_cell` argument and any exception that happen"
3143 " during the"
3152 " during the"
3144 "transform in `preprocessing_exc_tuple` in"
3153 "transform in `preprocessing_exc_tuple` in"
3145 " IPython 7.17 and above.",
3154 " IPython 7.17 and above.",
3146 DeprecationWarning,
3155 DeprecationWarning,
3147 stacklevel=2,
3156 stacklevel=2,
3148 )
3157 )
3149 try:
3158 try:
3150 cell = self.transform_cell(raw_cell)
3159 cell = self.transform_cell(raw_cell)
3151 except Exception:
3160 except Exception:
3152 # any exception during transform will be raised
3161 # any exception during transform will be raised
3153 # prior to execution
3162 # prior to execution
3154 return False
3163 return False
3155 else:
3164 else:
3156 cell = transformed_cell
3165 cell = transformed_cell
3157 return _should_be_async(cell)
3166 return _should_be_async(cell)
3158
3167
3159 async def run_cell_async(
3168 async def run_cell_async(
3160 self,
3169 self,
3161 raw_cell: str,
3170 raw_cell: str,
3162 store_history=False,
3171 store_history=False,
3163 silent=False,
3172 silent=False,
3164 shell_futures=True,
3173 shell_futures=True,
3165 *,
3174 *,
3166 transformed_cell: Optional[str] = None,
3175 transformed_cell: Optional[str] = None,
3167 preprocessing_exc_tuple: Optional[AnyType] = None,
3176 preprocessing_exc_tuple: Optional[AnyType] = None,
3168 cell_id=None,
3177 cell_id=None,
3169 ) -> ExecutionResult:
3178 ) -> ExecutionResult:
3170 """Run a complete IPython cell asynchronously.
3179 """Run a complete IPython cell asynchronously.
3171
3180
3172 Parameters
3181 Parameters
3173 ----------
3182 ----------
3174 raw_cell : str
3183 raw_cell : str
3175 The code (including IPython code such as %magic functions) to run.
3184 The code (including IPython code such as %magic functions) to run.
3176 store_history : bool
3185 store_history : bool
3177 If True, the raw and translated cell will be stored in IPython's
3186 If True, the raw and translated cell will be stored in IPython's
3178 history. For user code calling back into IPython's machinery, this
3187 history. For user code calling back into IPython's machinery, this
3179 should be set to False.
3188 should be set to False.
3180 silent : bool
3189 silent : bool
3181 If True, avoid side-effects, such as implicit displayhooks and
3190 If True, avoid side-effects, such as implicit displayhooks and
3182 and logging. silent=True forces store_history=False.
3191 and logging. silent=True forces store_history=False.
3183 shell_futures : bool
3192 shell_futures : bool
3184 If True, the code will share future statements with the interactive
3193 If True, the code will share future statements with the interactive
3185 shell. It will both be affected by previous __future__ imports, and
3194 shell. It will both be affected by previous __future__ imports, and
3186 any __future__ imports in the code will affect the shell. If False,
3195 any __future__ imports in the code will affect the shell. If False,
3187 __future__ imports are not shared in either direction.
3196 __future__ imports are not shared in either direction.
3188 transformed_cell: str
3197 transformed_cell: str
3189 cell that was passed through transformers
3198 cell that was passed through transformers
3190 preprocessing_exc_tuple:
3199 preprocessing_exc_tuple:
3191 trace if the transformation failed.
3200 trace if the transformation failed.
3192
3201
3193 Returns
3202 Returns
3194 -------
3203 -------
3195 result : :class:`ExecutionResult`
3204 result : :class:`ExecutionResult`
3196
3205
3197 .. versionadded:: 7.0
3206 .. versionadded:: 7.0
3198 """
3207 """
3199 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures, cell_id)
3208 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures, cell_id)
3200 result = ExecutionResult(info)
3209 result = ExecutionResult(info)
3201
3210
3202 if (not raw_cell) or raw_cell.isspace():
3211 if (not raw_cell) or raw_cell.isspace():
3203 self.last_execution_succeeded = True
3212 self.last_execution_succeeded = True
3204 self.last_execution_result = result
3213 self.last_execution_result = result
3205 return result
3214 return result
3206
3215
3207 if silent:
3216 if silent:
3208 store_history = False
3217 store_history = False
3209
3218
3210 if store_history:
3219 if store_history:
3211 result.execution_count = self.execution_count
3220 result.execution_count = self.execution_count
3212
3221
3213 def error_before_exec(value):
3222 def error_before_exec(value):
3214 if store_history:
3223 if store_history:
3215 self.execution_count += 1
3224 self.execution_count += 1
3216 result.error_before_exec = value
3225 result.error_before_exec = value
3217 self.last_execution_succeeded = False
3226 self.last_execution_succeeded = False
3218 self.last_execution_result = result
3227 self.last_execution_result = result
3219 return result
3228 return result
3220
3229
3221 self.events.trigger('pre_execute')
3230 self.events.trigger('pre_execute')
3222 if not silent:
3231 if not silent:
3223 self.events.trigger('pre_run_cell', info)
3232 self.events.trigger('pre_run_cell', info)
3224
3233
3225 if transformed_cell is None:
3234 if transformed_cell is None:
3226 warnings.warn(
3235 warnings.warn(
3227 "`run_cell_async` will not call `transform_cell`"
3236 "`run_cell_async` will not call `transform_cell`"
3228 " automatically in the future. Please pass the result to"
3237 " automatically in the future. Please pass the result to"
3229 " `transformed_cell` argument and any exception that happen"
3238 " `transformed_cell` argument and any exception that happen"
3230 " during the"
3239 " during the"
3231 "transform in `preprocessing_exc_tuple` in"
3240 "transform in `preprocessing_exc_tuple` in"
3232 " IPython 7.17 and above.",
3241 " IPython 7.17 and above.",
3233 DeprecationWarning,
3242 DeprecationWarning,
3234 stacklevel=2,
3243 stacklevel=2,
3235 )
3244 )
3236 # If any of our input transformation (input_transformer_manager or
3245 # If any of our input transformation (input_transformer_manager or
3237 # prefilter_manager) raises an exception, we store it in this variable
3246 # prefilter_manager) raises an exception, we store it in this variable
3238 # so that we can display the error after logging the input and storing
3247 # so that we can display the error after logging the input and storing
3239 # it in the history.
3248 # it in the history.
3240 try:
3249 try:
3241 cell = self.transform_cell(raw_cell)
3250 cell = self.transform_cell(raw_cell)
3242 except Exception:
3251 except Exception:
3243 preprocessing_exc_tuple = sys.exc_info()
3252 preprocessing_exc_tuple = sys.exc_info()
3244 cell = raw_cell # cell has to exist so it can be stored/logged
3253 cell = raw_cell # cell has to exist so it can be stored/logged
3245 else:
3254 else:
3246 preprocessing_exc_tuple = None
3255 preprocessing_exc_tuple = None
3247 else:
3256 else:
3248 if preprocessing_exc_tuple is None:
3257 if preprocessing_exc_tuple is None:
3249 cell = transformed_cell
3258 cell = transformed_cell
3250 else:
3259 else:
3251 cell = raw_cell
3260 cell = raw_cell
3252
3261
3253 # Do NOT store paste/cpaste magic history
3262 # Do NOT store paste/cpaste magic history
3254 if "get_ipython().run_line_magic(" in cell and "paste" in cell:
3263 if "get_ipython().run_line_magic(" in cell and "paste" in cell:
3255 store_history = False
3264 store_history = False
3256
3265
3257 # Store raw and processed history
3266 # Store raw and processed history
3258 if store_history:
3267 if store_history:
3268 assert self.history_manager is not None
3259 self.history_manager.store_inputs(self.execution_count, cell, raw_cell)
3269 self.history_manager.store_inputs(self.execution_count, cell, raw_cell)
3260 if not silent:
3270 if not silent:
3261 self.logger.log(cell, raw_cell)
3271 self.logger.log(cell, raw_cell)
3262
3272
3263 # Display the exception if input processing failed.
3273 # Display the exception if input processing failed.
3264 if preprocessing_exc_tuple is not None:
3274 if preprocessing_exc_tuple is not None:
3265 self.showtraceback(preprocessing_exc_tuple)
3275 self.showtraceback(preprocessing_exc_tuple)
3266 if store_history:
3276 if store_history:
3267 self.execution_count += 1
3277 self.execution_count += 1
3268 return error_before_exec(preprocessing_exc_tuple[1])
3278 return error_before_exec(preprocessing_exc_tuple[1])
3269
3279
3270 # Our own compiler remembers the __future__ environment. If we want to
3280 # Our own compiler remembers the __future__ environment. If we want to
3271 # run code with a separate __future__ environment, use the default
3281 # run code with a separate __future__ environment, use the default
3272 # compiler
3282 # compiler
3273 compiler = self.compile if shell_futures else self.compiler_class()
3283 compiler = self.compile if shell_futures else self.compiler_class()
3274
3284
3275 _run_async = False
3276
3277 with self.builtin_trap:
3285 with self.builtin_trap:
3278 cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell)
3286 cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell)
3279
3287
3280 with self.display_trap:
3288 with self.display_trap:
3281 # Compile to bytecode
3289 # Compile to bytecode
3282 try:
3290 try:
3283 code_ast = compiler.ast_parse(cell, filename=cell_name)
3291 code_ast = compiler.ast_parse(cell, filename=cell_name)
3284 except self.custom_exceptions as e:
3292 except self.custom_exceptions as e:
3285 etype, value, tb = sys.exc_info()
3293 etype, value, tb = sys.exc_info()
3286 self.CustomTB(etype, value, tb)
3294 self.CustomTB(etype, value, tb)
3287 return error_before_exec(e)
3295 return error_before_exec(e)
3288 except IndentationError as e:
3296 except IndentationError as e:
3289 self.showindentationerror()
3297 self.showindentationerror()
3290 return error_before_exec(e)
3298 return error_before_exec(e)
3291 except (OverflowError, SyntaxError, ValueError, TypeError,
3299 except (OverflowError, SyntaxError, ValueError, TypeError,
3292 MemoryError) as e:
3300 MemoryError) as e:
3293 self.showsyntaxerror()
3301 self.showsyntaxerror()
3294 return error_before_exec(e)
3302 return error_before_exec(e)
3295
3303
3296 # Apply AST transformations
3304 # Apply AST transformations
3297 try:
3305 try:
3298 code_ast = self.transform_ast(code_ast)
3306 code_ast = self.transform_ast(code_ast)
3299 except InputRejected as e:
3307 except InputRejected as e:
3300 self.showtraceback()
3308 self.showtraceback()
3301 return error_before_exec(e)
3309 return error_before_exec(e)
3302
3310
3303 # Give the displayhook a reference to our ExecutionResult so it
3311 # Give the displayhook a reference to our ExecutionResult so it
3304 # can fill in the output value.
3312 # can fill in the output value.
3305 self.displayhook.exec_result = result
3313 self.displayhook.exec_result = result
3306
3314
3307 # Execute the user code
3315 # Execute the user code
3308 interactivity = "none" if silent else self.ast_node_interactivity
3316 interactivity = "none" if silent else self.ast_node_interactivity
3309
3317
3310
3318
3311 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3319 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3312 interactivity=interactivity, compiler=compiler, result=result)
3320 interactivity=interactivity, compiler=compiler, result=result)
3313
3321
3314 self.last_execution_succeeded = not has_raised
3322 self.last_execution_succeeded = not has_raised
3315 self.last_execution_result = result
3323 self.last_execution_result = result
3316
3324
3317 # Reset this so later displayed values do not modify the
3325 # Reset this so later displayed values do not modify the
3318 # ExecutionResult
3326 # ExecutionResult
3319 self.displayhook.exec_result = None
3327 self.displayhook.exec_result = None
3320
3328
3321 if store_history:
3329 if store_history:
3322 # Write output to the database. Does nothing unless
3330 # Write output to the database. Does nothing unless
3323 # history output logging is enabled.
3331 # history output logging is enabled.
3324 self.history_manager.store_output(self.execution_count)
3332 self.history_manager.store_output(self.execution_count)
3325 # Each cell is a *single* input, regardless of how many lines it has
3333 # Each cell is a *single* input, regardless of how many lines it has
3326 self.execution_count += 1
3334 self.execution_count += 1
3327
3335
3328 return result
3336 return result
3329
3337
3330 def transform_cell(self, raw_cell):
3338 def transform_cell(self, raw_cell):
3331 """Transform an input cell before parsing it.
3339 """Transform an input cell before parsing it.
3332
3340
3333 Static transformations, implemented in IPython.core.inputtransformer2,
3341 Static transformations, implemented in IPython.core.inputtransformer2,
3334 deal with things like ``%magic`` and ``!system`` commands.
3342 deal with things like ``%magic`` and ``!system`` commands.
3335 These run on all input.
3343 These run on all input.
3336 Dynamic transformations, for things like unescaped magics and the exit
3344 Dynamic transformations, for things like unescaped magics and the exit
3337 autocall, depend on the state of the interpreter.
3345 autocall, depend on the state of the interpreter.
3338 These only apply to single line inputs.
3346 These only apply to single line inputs.
3339
3347
3340 These string-based transformations are followed by AST transformations;
3348 These string-based transformations are followed by AST transformations;
3341 see :meth:`transform_ast`.
3349 see :meth:`transform_ast`.
3342 """
3350 """
3343 # Static input transformations
3351 # Static input transformations
3344 cell = self.input_transformer_manager.transform_cell(raw_cell)
3352 cell = self.input_transformer_manager.transform_cell(raw_cell)
3345
3353
3346 if len(cell.splitlines()) == 1:
3354 if len(cell.splitlines()) == 1:
3347 # Dynamic transformations - only applied for single line commands
3355 # Dynamic transformations - only applied for single line commands
3348 with self.builtin_trap:
3356 with self.builtin_trap:
3349 # use prefilter_lines to handle trailing newlines
3357 # use prefilter_lines to handle trailing newlines
3350 # restore trailing newline for ast.parse
3358 # restore trailing newline for ast.parse
3351 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3359 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3352
3360
3353 lines = cell.splitlines(keepends=True)
3361 lines = cell.splitlines(keepends=True)
3354 for transform in self.input_transformers_post:
3362 for transform in self.input_transformers_post:
3355 lines = transform(lines)
3363 lines = transform(lines)
3356 cell = ''.join(lines)
3364 cell = ''.join(lines)
3357
3365
3358 return cell
3366 return cell
3359
3367
3360 def transform_ast(self, node):
3368 def transform_ast(self, node):
3361 """Apply the AST transformations from self.ast_transformers
3369 """Apply the AST transformations from self.ast_transformers
3362
3370
3363 Parameters
3371 Parameters
3364 ----------
3372 ----------
3365 node : ast.Node
3373 node : ast.Node
3366 The root node to be transformed. Typically called with the ast.Module
3374 The root node to be transformed. Typically called with the ast.Module
3367 produced by parsing user input.
3375 produced by parsing user input.
3368
3376
3369 Returns
3377 Returns
3370 -------
3378 -------
3371 An ast.Node corresponding to the node it was called with. Note that it
3379 An ast.Node corresponding to the node it was called with. Note that it
3372 may also modify the passed object, so don't rely on references to the
3380 may also modify the passed object, so don't rely on references to the
3373 original AST.
3381 original AST.
3374 """
3382 """
3375 for transformer in self.ast_transformers:
3383 for transformer in self.ast_transformers:
3376 try:
3384 try:
3377 node = transformer.visit(node)
3385 node = transformer.visit(node)
3378 except InputRejected:
3386 except InputRejected:
3379 # User-supplied AST transformers can reject an input by raising
3387 # User-supplied AST transformers can reject an input by raising
3380 # an InputRejected. Short-circuit in this case so that we
3388 # an InputRejected. Short-circuit in this case so that we
3381 # don't unregister the transform.
3389 # don't unregister the transform.
3382 raise
3390 raise
3383 except Exception as e:
3391 except Exception as e:
3384 warn(
3392 warn(
3385 "AST transformer %r threw an error. It will be unregistered. %s"
3393 "AST transformer %r threw an error. It will be unregistered. %s"
3386 % (transformer, e)
3394 % (transformer, e)
3387 )
3395 )
3388 self.ast_transformers.remove(transformer)
3396 self.ast_transformers.remove(transformer)
3389
3397
3390 if self.ast_transformers:
3398 if self.ast_transformers:
3391 ast.fix_missing_locations(node)
3399 ast.fix_missing_locations(node)
3392 return node
3400 return node
3393
3401
3394 async def run_ast_nodes(
3402 async def run_ast_nodes(
3395 self,
3403 self,
3396 nodelist: ListType[stmt],
3404 nodelist: ListType[stmt],
3397 cell_name: str,
3405 cell_name: str,
3398 interactivity="last_expr",
3406 interactivity="last_expr",
3399 compiler=compile,
3407 compiler=compile,
3400 result=None,
3408 result=None,
3401 ):
3409 ):
3402 """Run a sequence of AST nodes. The execution mode depends on the
3410 """Run a sequence of AST nodes. The execution mode depends on the
3403 interactivity parameter.
3411 interactivity parameter.
3404
3412
3405 Parameters
3413 Parameters
3406 ----------
3414 ----------
3407 nodelist : list
3415 nodelist : list
3408 A sequence of AST nodes to run.
3416 A sequence of AST nodes to run.
3409 cell_name : str
3417 cell_name : str
3410 Will be passed to the compiler as the filename of the cell. Typically
3418 Will be passed to the compiler as the filename of the cell. Typically
3411 the value returned by ip.compile.cache(cell).
3419 the value returned by ip.compile.cache(cell).
3412 interactivity : str
3420 interactivity : str
3413 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3421 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3414 specifying which nodes should be run interactively (displaying output
3422 specifying which nodes should be run interactively (displaying output
3415 from expressions). 'last_expr' will run the last node interactively
3423 from expressions). 'last_expr' will run the last node interactively
3416 only if it is an expression (i.e. expressions in loops or other blocks
3424 only if it is an expression (i.e. expressions in loops or other blocks
3417 are not displayed) 'last_expr_or_assign' will run the last expression
3425 are not displayed) 'last_expr_or_assign' will run the last expression
3418 or the last assignment. Other values for this parameter will raise a
3426 or the last assignment. Other values for this parameter will raise a
3419 ValueError.
3427 ValueError.
3420
3428
3421 compiler : callable
3429 compiler : callable
3422 A function with the same interface as the built-in compile(), to turn
3430 A function with the same interface as the built-in compile(), to turn
3423 the AST nodes into code objects. Default is the built-in compile().
3431 the AST nodes into code objects. Default is the built-in compile().
3424 result : ExecutionResult, optional
3432 result : ExecutionResult, optional
3425 An object to store exceptions that occur during execution.
3433 An object to store exceptions that occur during execution.
3426
3434
3427 Returns
3435 Returns
3428 -------
3436 -------
3429 True if an exception occurred while running code, False if it finished
3437 True if an exception occurred while running code, False if it finished
3430 running.
3438 running.
3431 """
3439 """
3432 if not nodelist:
3440 if not nodelist:
3433 return
3441 return
3434
3442
3435
3443
3436 if interactivity == 'last_expr_or_assign':
3444 if interactivity == 'last_expr_or_assign':
3437 if isinstance(nodelist[-1], _assign_nodes):
3445 if isinstance(nodelist[-1], _assign_nodes):
3438 asg = nodelist[-1]
3446 asg = nodelist[-1]
3439 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3447 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3440 target = asg.targets[0]
3448 target = asg.targets[0]
3441 elif isinstance(asg, _single_targets_nodes):
3449 elif isinstance(asg, _single_targets_nodes):
3442 target = asg.target
3450 target = asg.target
3443 else:
3451 else:
3444 target = None
3452 target = None
3445 if isinstance(target, ast.Name):
3453 if isinstance(target, ast.Name):
3446 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3454 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3447 ast.fix_missing_locations(nnode)
3455 ast.fix_missing_locations(nnode)
3448 nodelist.append(nnode)
3456 nodelist.append(nnode)
3449 interactivity = 'last_expr'
3457 interactivity = 'last_expr'
3450
3458
3451 _async = False
3459 _async = False
3452 if interactivity == 'last_expr':
3460 if interactivity == 'last_expr':
3453 if isinstance(nodelist[-1], ast.Expr):
3461 if isinstance(nodelist[-1], ast.Expr):
3454 interactivity = "last"
3462 interactivity = "last"
3455 else:
3463 else:
3456 interactivity = "none"
3464 interactivity = "none"
3457
3465
3458 if interactivity == 'none':
3466 if interactivity == 'none':
3459 to_run_exec, to_run_interactive = nodelist, []
3467 to_run_exec, to_run_interactive = nodelist, []
3460 elif interactivity == 'last':
3468 elif interactivity == 'last':
3461 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3469 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3462 elif interactivity == 'all':
3470 elif interactivity == 'all':
3463 to_run_exec, to_run_interactive = [], nodelist
3471 to_run_exec, to_run_interactive = [], nodelist
3464 else:
3472 else:
3465 raise ValueError("Interactivity was %r" % interactivity)
3473 raise ValueError("Interactivity was %r" % interactivity)
3466
3474
3467 try:
3475 try:
3468
3476
3469 def compare(code):
3477 def compare(code):
3470 is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE
3478 is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE
3471 return is_async
3479 return is_async
3472
3480
3473 # refactor that to just change the mod constructor.
3481 # refactor that to just change the mod constructor.
3474 to_run = []
3482 to_run = []
3475 for node in to_run_exec:
3483 for node in to_run_exec:
3476 to_run.append((node, "exec"))
3484 to_run.append((node, "exec"))
3477
3485
3478 for node in to_run_interactive:
3486 for node in to_run_interactive:
3479 to_run.append((node, "single"))
3487 to_run.append((node, "single"))
3480
3488
3481 for node, mode in to_run:
3489 for node, mode in to_run:
3482 if mode == "exec":
3490 if mode == "exec":
3483 mod = Module([node], [])
3491 mod = Module([node], [])
3484 elif mode == "single":
3492 elif mode == "single":
3485 mod = ast.Interactive([node]) # type: ignore
3493 mod = ast.Interactive([node]) # type: ignore
3486 with compiler.extra_flags(
3494 with compiler.extra_flags(
3487 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3495 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3488 if self.autoawait
3496 if self.autoawait
3489 else 0x0
3497 else 0x0
3490 ):
3498 ):
3491 code = compiler(mod, cell_name, mode)
3499 code = compiler(mod, cell_name, mode)
3492 asy = compare(code)
3500 asy = compare(code)
3493 if await self.run_code(code, result, async_=asy):
3501 if await self.run_code(code, result, async_=asy):
3494 return True
3502 return True
3495
3503
3496 # Flush softspace
3504 # Flush softspace
3497 if softspace(sys.stdout, 0):
3505 if softspace(sys.stdout, 0):
3498 print()
3506 print()
3499
3507
3500 except:
3508 except:
3501 # It's possible to have exceptions raised here, typically by
3509 # It's possible to have exceptions raised here, typically by
3502 # compilation of odd code (such as a naked 'return' outside a
3510 # compilation of odd code (such as a naked 'return' outside a
3503 # function) that did parse but isn't valid. Typically the exception
3511 # function) that did parse but isn't valid. Typically the exception
3504 # is a SyntaxError, but it's safest just to catch anything and show
3512 # is a SyntaxError, but it's safest just to catch anything and show
3505 # the user a traceback.
3513 # the user a traceback.
3506
3514
3507 # We do only one try/except outside the loop to minimize the impact
3515 # We do only one try/except outside the loop to minimize the impact
3508 # on runtime, and also because if any node in the node list is
3516 # on runtime, and also because if any node in the node list is
3509 # broken, we should stop execution completely.
3517 # broken, we should stop execution completely.
3510 if result:
3518 if result:
3511 result.error_before_exec = sys.exc_info()[1]
3519 result.error_before_exec = sys.exc_info()[1]
3512 self.showtraceback()
3520 self.showtraceback()
3513 return True
3521 return True
3514
3522
3515 return False
3523 return False
3516
3524
3517 async def run_code(self, code_obj, result=None, *, async_=False):
3525 async def run_code(self, code_obj, result=None, *, async_=False):
3518 """Execute a code object.
3526 """Execute a code object.
3519
3527
3520 When an exception occurs, self.showtraceback() is called to display a
3528 When an exception occurs, self.showtraceback() is called to display a
3521 traceback.
3529 traceback.
3522
3530
3523 Parameters
3531 Parameters
3524 ----------
3532 ----------
3525 code_obj : code object
3533 code_obj : code object
3526 A compiled code object, to be executed
3534 A compiled code object, to be executed
3527 result : ExecutionResult, optional
3535 result : ExecutionResult, optional
3528 An object to store exceptions that occur during execution.
3536 An object to store exceptions that occur during execution.
3529 async_ : Bool (Experimental)
3537 async_ : Bool (Experimental)
3530 Attempt to run top-level asynchronous code in a default loop.
3538 Attempt to run top-level asynchronous code in a default loop.
3531
3539
3532 Returns
3540 Returns
3533 -------
3541 -------
3534 False : successful execution.
3542 False : successful execution.
3535 True : an error occurred.
3543 True : an error occurred.
3536 """
3544 """
3537 # special value to say that anything above is IPython and should be
3545 # special value to say that anything above is IPython and should be
3538 # hidden.
3546 # hidden.
3539 __tracebackhide__ = "__ipython_bottom__"
3547 __tracebackhide__ = "__ipython_bottom__"
3540 # Set our own excepthook in case the user code tries to call it
3548 # Set our own excepthook in case the user code tries to call it
3541 # directly, so that the IPython crash handler doesn't get triggered
3549 # directly, so that the IPython crash handler doesn't get triggered
3542 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3550 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3543
3551
3544 # we save the original sys.excepthook in the instance, in case config
3552 # we save the original sys.excepthook in the instance, in case config
3545 # code (such as magics) needs access to it.
3553 # code (such as magics) needs access to it.
3546 self.sys_excepthook = old_excepthook
3554 self.sys_excepthook = old_excepthook
3547 outflag = True # happens in more places, so it's easier as default
3555 outflag = True # happens in more places, so it's easier as default
3548 try:
3556 try:
3549 try:
3557 try:
3550 if async_:
3558 if async_:
3551 await eval(code_obj, self.user_global_ns, self.user_ns)
3559 await eval(code_obj, self.user_global_ns, self.user_ns)
3552 else:
3560 else:
3553 exec(code_obj, self.user_global_ns, self.user_ns)
3561 exec(code_obj, self.user_global_ns, self.user_ns)
3554 finally:
3562 finally:
3555 # Reset our crash handler in place
3563 # Reset our crash handler in place
3556 sys.excepthook = old_excepthook
3564 sys.excepthook = old_excepthook
3557 except SystemExit as e:
3565 except SystemExit as e:
3558 if result is not None:
3566 if result is not None:
3559 result.error_in_exec = e
3567 result.error_in_exec = e
3560 self.showtraceback(exception_only=True)
3568 self.showtraceback(exception_only=True)
3561 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3569 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3562 except bdb.BdbQuit:
3570 except bdb.BdbQuit:
3563 etype, value, tb = sys.exc_info()
3571 etype, value, tb = sys.exc_info()
3564 if result is not None:
3572 if result is not None:
3565 result.error_in_exec = value
3573 result.error_in_exec = value
3566 # the BdbQuit stops here
3574 # the BdbQuit stops here
3567 except self.custom_exceptions:
3575 except self.custom_exceptions:
3568 etype, value, tb = sys.exc_info()
3576 etype, value, tb = sys.exc_info()
3569 if result is not None:
3577 if result is not None:
3570 result.error_in_exec = value
3578 result.error_in_exec = value
3571 self.CustomTB(etype, value, tb)
3579 self.CustomTB(etype, value, tb)
3572 except:
3580 except:
3573 if result is not None:
3581 if result is not None:
3574 result.error_in_exec = sys.exc_info()[1]
3582 result.error_in_exec = sys.exc_info()[1]
3575 self.showtraceback(running_compiled_code=True)
3583 self.showtraceback(running_compiled_code=True)
3576 else:
3584 else:
3577 outflag = False
3585 outflag = False
3578 return outflag
3586 return outflag
3579
3587
3580 # For backwards compatibility
3588 # For backwards compatibility
3581 runcode = run_code
3589 runcode = run_code
3582
3590
3583 def check_complete(self, code: str) -> Tuple[str, str]:
3591 def check_complete(self, code: str) -> Tuple[str, str]:
3584 """Return whether a block of code is ready to execute, or should be continued
3592 """Return whether a block of code is ready to execute, or should be continued
3585
3593
3586 Parameters
3594 Parameters
3587 ----------
3595 ----------
3588 code : string
3596 code : string
3589 Python input code, which can be multiline.
3597 Python input code, which can be multiline.
3590
3598
3591 Returns
3599 Returns
3592 -------
3600 -------
3593 status : str
3601 status : str
3594 One of 'complete', 'incomplete', or 'invalid' if source is not a
3602 One of 'complete', 'incomplete', or 'invalid' if source is not a
3595 prefix of valid code.
3603 prefix of valid code.
3596 indent : str
3604 indent : str
3597 When status is 'incomplete', this is some whitespace to insert on
3605 When status is 'incomplete', this is some whitespace to insert on
3598 the next line of the prompt.
3606 the next line of the prompt.
3599 """
3607 """
3600 status, nspaces = self.input_transformer_manager.check_complete(code)
3608 status, nspaces = self.input_transformer_manager.check_complete(code)
3601 return status, ' ' * (nspaces or 0)
3609 return status, ' ' * (nspaces or 0)
3602
3610
3603 #-------------------------------------------------------------------------
3611 #-------------------------------------------------------------------------
3604 # Things related to GUI support and pylab
3612 # Things related to GUI support and pylab
3605 #-------------------------------------------------------------------------
3613 #-------------------------------------------------------------------------
3606
3614
3607 active_eventloop: Optional[str] = None
3615 active_eventloop: Optional[str] = None
3608
3616
3609 def enable_gui(self, gui=None):
3617 def enable_gui(self, gui=None):
3610 raise NotImplementedError('Implement enable_gui in a subclass')
3618 raise NotImplementedError('Implement enable_gui in a subclass')
3611
3619
3612 def enable_matplotlib(self, gui=None):
3620 def enable_matplotlib(self, gui=None):
3613 """Enable interactive matplotlib and inline figure support.
3621 """Enable interactive matplotlib and inline figure support.
3614
3622
3615 This takes the following steps:
3623 This takes the following steps:
3616
3624
3617 1. select the appropriate eventloop and matplotlib backend
3625 1. select the appropriate eventloop and matplotlib backend
3618 2. set up matplotlib for interactive use with that backend
3626 2. set up matplotlib for interactive use with that backend
3619 3. configure formatters for inline figure display
3627 3. configure formatters for inline figure display
3620 4. enable the selected gui eventloop
3628 4. enable the selected gui eventloop
3621
3629
3622 Parameters
3630 Parameters
3623 ----------
3631 ----------
3624 gui : optional, string
3632 gui : optional, string
3625 If given, dictates the choice of matplotlib GUI backend to use
3633 If given, dictates the choice of matplotlib GUI backend to use
3626 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3634 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3627 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3635 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3628 matplotlib (as dictated by the matplotlib build-time options plus the
3636 matplotlib (as dictated by the matplotlib build-time options plus the
3629 user's matplotlibrc configuration file). Note that not all backends
3637 user's matplotlibrc configuration file). Note that not all backends
3630 make sense in all contexts, for example a terminal ipython can't
3638 make sense in all contexts, for example a terminal ipython can't
3631 display figures inline.
3639 display figures inline.
3632 """
3640 """
3633 from matplotlib_inline.backend_inline import configure_inline_support
3641 from matplotlib_inline.backend_inline import configure_inline_support
3634
3642
3635 from IPython.core import pylabtools as pt
3643 from IPython.core import pylabtools as pt
3636 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3644 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3637
3645
3638 if gui != 'inline':
3646 if gui != 'inline':
3639 # If we have our first gui selection, store it
3647 # If we have our first gui selection, store it
3640 if self.pylab_gui_select is None:
3648 if self.pylab_gui_select is None:
3641 self.pylab_gui_select = gui
3649 self.pylab_gui_select = gui
3642 # Otherwise if they are different
3650 # Otherwise if they are different
3643 elif gui != self.pylab_gui_select:
3651 elif gui != self.pylab_gui_select:
3644 print('Warning: Cannot change to a different GUI toolkit: %s.'
3652 print('Warning: Cannot change to a different GUI toolkit: %s.'
3645 ' Using %s instead.' % (gui, self.pylab_gui_select))
3653 ' Using %s instead.' % (gui, self.pylab_gui_select))
3646 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3654 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3647
3655
3648 pt.activate_matplotlib(backend)
3656 pt.activate_matplotlib(backend)
3649 configure_inline_support(self, backend)
3657 configure_inline_support(self, backend)
3650
3658
3651 # Now we must activate the gui pylab wants to use, and fix %run to take
3659 # Now we must activate the gui pylab wants to use, and fix %run to take
3652 # plot updates into account
3660 # plot updates into account
3653 self.enable_gui(gui)
3661 self.enable_gui(gui)
3654 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3662 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3655 pt.mpl_runner(self.safe_execfile)
3663 pt.mpl_runner(self.safe_execfile)
3656
3664
3657 return gui, backend
3665 return gui, backend
3658
3666
3659 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3667 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3660 """Activate pylab support at runtime.
3668 """Activate pylab support at runtime.
3661
3669
3662 This turns on support for matplotlib, preloads into the interactive
3670 This turns on support for matplotlib, preloads into the interactive
3663 namespace all of numpy and pylab, and configures IPython to correctly
3671 namespace all of numpy and pylab, and configures IPython to correctly
3664 interact with the GUI event loop. The GUI backend to be used can be
3672 interact with the GUI event loop. The GUI backend to be used can be
3665 optionally selected with the optional ``gui`` argument.
3673 optionally selected with the optional ``gui`` argument.
3666
3674
3667 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3675 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3668
3676
3669 Parameters
3677 Parameters
3670 ----------
3678 ----------
3671 gui : optional, string
3679 gui : optional, string
3672 If given, dictates the choice of matplotlib GUI backend to use
3680 If given, dictates the choice of matplotlib GUI backend to use
3673 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3681 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3674 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3682 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3675 matplotlib (as dictated by the matplotlib build-time options plus the
3683 matplotlib (as dictated by the matplotlib build-time options plus the
3676 user's matplotlibrc configuration file). Note that not all backends
3684 user's matplotlibrc configuration file). Note that not all backends
3677 make sense in all contexts, for example a terminal ipython can't
3685 make sense in all contexts, for example a terminal ipython can't
3678 display figures inline.
3686 display figures inline.
3679 import_all : optional, bool, default: True
3687 import_all : optional, bool, default: True
3680 Whether to do `from numpy import *` and `from pylab import *`
3688 Whether to do `from numpy import *` and `from pylab import *`
3681 in addition to module imports.
3689 in addition to module imports.
3682 welcome_message : deprecated
3690 welcome_message : deprecated
3683 This argument is ignored, no welcome message will be displayed.
3691 This argument is ignored, no welcome message will be displayed.
3684 """
3692 """
3685 from IPython.core.pylabtools import import_pylab
3693 from IPython.core.pylabtools import import_pylab
3686
3694
3687 gui, backend = self.enable_matplotlib(gui)
3695 gui, backend = self.enable_matplotlib(gui)
3688
3696
3689 # We want to prevent the loading of pylab to pollute the user's
3697 # We want to prevent the loading of pylab to pollute the user's
3690 # namespace as shown by the %who* magics, so we execute the activation
3698 # namespace as shown by the %who* magics, so we execute the activation
3691 # code in an empty namespace, and we update *both* user_ns and
3699 # code in an empty namespace, and we update *both* user_ns and
3692 # user_ns_hidden with this information.
3700 # user_ns_hidden with this information.
3693 ns = {}
3701 ns = {}
3694 import_pylab(ns, import_all)
3702 import_pylab(ns, import_all)
3695 # warn about clobbered names
3703 # warn about clobbered names
3696 ignored = {"__builtins__"}
3704 ignored = {"__builtins__"}
3697 both = set(ns).intersection(self.user_ns).difference(ignored)
3705 both = set(ns).intersection(self.user_ns).difference(ignored)
3698 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3706 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3699 self.user_ns.update(ns)
3707 self.user_ns.update(ns)
3700 self.user_ns_hidden.update(ns)
3708 self.user_ns_hidden.update(ns)
3701 return gui, backend, clobbered
3709 return gui, backend, clobbered
3702
3710
3703 #-------------------------------------------------------------------------
3711 #-------------------------------------------------------------------------
3704 # Utilities
3712 # Utilities
3705 #-------------------------------------------------------------------------
3713 #-------------------------------------------------------------------------
3706
3714
3707 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3715 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3708 """Expand python variables in a string.
3716 """Expand python variables in a string.
3709
3717
3710 The depth argument indicates how many frames above the caller should
3718 The depth argument indicates how many frames above the caller should
3711 be walked to look for the local namespace where to expand variables.
3719 be walked to look for the local namespace where to expand variables.
3712
3720
3713 The global namespace for expansion is always the user's interactive
3721 The global namespace for expansion is always the user's interactive
3714 namespace.
3722 namespace.
3715 """
3723 """
3716 ns = self.user_ns.copy()
3724 ns = self.user_ns.copy()
3717 try:
3725 try:
3718 frame = sys._getframe(depth+1)
3726 frame = sys._getframe(depth+1)
3719 except ValueError:
3727 except ValueError:
3720 # This is thrown if there aren't that many frames on the stack,
3728 # This is thrown if there aren't that many frames on the stack,
3721 # e.g. if a script called run_line_magic() directly.
3729 # e.g. if a script called run_line_magic() directly.
3722 pass
3730 pass
3723 else:
3731 else:
3724 ns.update(frame.f_locals)
3732 ns.update(frame.f_locals)
3725
3733
3726 try:
3734 try:
3727 # We have to use .vformat() here, because 'self' is a valid and common
3735 # We have to use .vformat() here, because 'self' is a valid and common
3728 # name, and expanding **ns for .format() would make it collide with
3736 # name, and expanding **ns for .format() would make it collide with
3729 # the 'self' argument of the method.
3737 # the 'self' argument of the method.
3730 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3738 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3731 except Exception:
3739 except Exception:
3732 # if formatter couldn't format, just let it go untransformed
3740 # if formatter couldn't format, just let it go untransformed
3733 pass
3741 pass
3734 return cmd
3742 return cmd
3735
3743
3736 def mktempfile(self, data=None, prefix='ipython_edit_'):
3744 def mktempfile(self, data=None, prefix='ipython_edit_'):
3737 """Make a new tempfile and return its filename.
3745 """Make a new tempfile and return its filename.
3738
3746
3739 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3747 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3740 but it registers the created filename internally so ipython cleans it up
3748 but it registers the created filename internally so ipython cleans it up
3741 at exit time.
3749 at exit time.
3742
3750
3743 Optional inputs:
3751 Optional inputs:
3744
3752
3745 - data(None): if data is given, it gets written out to the temp file
3753 - data(None): if data is given, it gets written out to the temp file
3746 immediately, and the file is closed again."""
3754 immediately, and the file is closed again."""
3747
3755
3748 dir_path = Path(tempfile.mkdtemp(prefix=prefix))
3756 dir_path = Path(tempfile.mkdtemp(prefix=prefix))
3749 self.tempdirs.append(dir_path)
3757 self.tempdirs.append(dir_path)
3750
3758
3751 handle, filename = tempfile.mkstemp(".py", prefix, dir=str(dir_path))
3759 handle, filename = tempfile.mkstemp(".py", prefix, dir=str(dir_path))
3752 os.close(handle) # On Windows, there can only be one open handle on a file
3760 os.close(handle) # On Windows, there can only be one open handle on a file
3753
3761
3754 file_path = Path(filename)
3762 file_path = Path(filename)
3755 self.tempfiles.append(file_path)
3763 self.tempfiles.append(file_path)
3756
3764
3757 if data:
3765 if data:
3758 file_path.write_text(data, encoding="utf-8")
3766 file_path.write_text(data, encoding="utf-8")
3759 return filename
3767 return filename
3760
3768
3761 def ask_yes_no(self, prompt, default=None, interrupt=None):
3769 def ask_yes_no(self, prompt, default=None, interrupt=None):
3762 if self.quiet:
3770 if self.quiet:
3763 return True
3771 return True
3764 return ask_yes_no(prompt,default,interrupt)
3772 return ask_yes_no(prompt,default,interrupt)
3765
3773
3766 def show_usage(self):
3774 def show_usage(self):
3767 """Show a usage message"""
3775 """Show a usage message"""
3768 page.page(IPython.core.usage.interactive_usage)
3776 page.page(IPython.core.usage.interactive_usage)
3769
3777
3770 def extract_input_lines(self, range_str, raw=False):
3778 def extract_input_lines(self, range_str, raw=False):
3771 """Return as a string a set of input history slices.
3779 """Return as a string a set of input history slices.
3772
3780
3773 Parameters
3781 Parameters
3774 ----------
3782 ----------
3775 range_str : str
3783 range_str : str
3776 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3784 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3777 since this function is for use by magic functions which get their
3785 since this function is for use by magic functions which get their
3778 arguments as strings. The number before the / is the session
3786 arguments as strings. The number before the / is the session
3779 number: ~n goes n back from the current session.
3787 number: ~n goes n back from the current session.
3780
3788
3781 If empty string is given, returns history of current session
3789 If empty string is given, returns history of current session
3782 without the last input.
3790 without the last input.
3783
3791
3784 raw : bool, optional
3792 raw : bool, optional
3785 By default, the processed input is used. If this is true, the raw
3793 By default, the processed input is used. If this is true, the raw
3786 input history is used instead.
3794 input history is used instead.
3787
3795
3788 Notes
3796 Notes
3789 -----
3797 -----
3790 Slices can be described with two notations:
3798 Slices can be described with two notations:
3791
3799
3792 * ``N:M`` -> standard python form, means including items N...(M-1).
3800 * ``N:M`` -> standard python form, means including items N...(M-1).
3793 * ``N-M`` -> include items N..M (closed endpoint).
3801 * ``N-M`` -> include items N..M (closed endpoint).
3794 """
3802 """
3795 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3803 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3796 text = "\n".join(x for _, _, x in lines)
3804 text = "\n".join(x for _, _, x in lines)
3797
3805
3798 # Skip the last line, as it's probably the magic that called this
3806 # Skip the last line, as it's probably the magic that called this
3799 if not range_str:
3807 if not range_str:
3800 if "\n" not in text:
3808 if "\n" not in text:
3801 text = ""
3809 text = ""
3802 else:
3810 else:
3803 text = text[: text.rfind("\n")]
3811 text = text[: text.rfind("\n")]
3804
3812
3805 return text
3813 return text
3806
3814
3807 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3815 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3808 """Get a code string from history, file, url, or a string or macro.
3816 """Get a code string from history, file, url, or a string or macro.
3809
3817
3810 This is mainly used by magic functions.
3818 This is mainly used by magic functions.
3811
3819
3812 Parameters
3820 Parameters
3813 ----------
3821 ----------
3814 target : str
3822 target : str
3815 A string specifying code to retrieve. This will be tried respectively
3823 A string specifying code to retrieve. This will be tried respectively
3816 as: ranges of input history (see %history for syntax), url,
3824 as: ranges of input history (see %history for syntax), url,
3817 corresponding .py file, filename, or an expression evaluating to a
3825 corresponding .py file, filename, or an expression evaluating to a
3818 string or Macro in the user namespace.
3826 string or Macro in the user namespace.
3819
3827
3820 If empty string is given, returns complete history of current
3828 If empty string is given, returns complete history of current
3821 session, without the last line.
3829 session, without the last line.
3822
3830
3823 raw : bool
3831 raw : bool
3824 If true (default), retrieve raw history. Has no effect on the other
3832 If true (default), retrieve raw history. Has no effect on the other
3825 retrieval mechanisms.
3833 retrieval mechanisms.
3826
3834
3827 py_only : bool (default False)
3835 py_only : bool (default False)
3828 Only try to fetch python code, do not try alternative methods to decode file
3836 Only try to fetch python code, do not try alternative methods to decode file
3829 if unicode fails.
3837 if unicode fails.
3830
3838
3831 Returns
3839 Returns
3832 -------
3840 -------
3833 A string of code.
3841 A string of code.
3834 ValueError is raised if nothing is found, and TypeError if it evaluates
3842 ValueError is raised if nothing is found, and TypeError if it evaluates
3835 to an object of another type. In each case, .args[0] is a printable
3843 to an object of another type. In each case, .args[0] is a printable
3836 message.
3844 message.
3837 """
3845 """
3838 code = self.extract_input_lines(target, raw=raw) # Grab history
3846 code = self.extract_input_lines(target, raw=raw) # Grab history
3839 if code:
3847 if code:
3840 return code
3848 return code
3841 try:
3849 try:
3842 if target.startswith(('http://', 'https://')):
3850 if target.startswith(('http://', 'https://')):
3843 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3851 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3844 except UnicodeDecodeError as e:
3852 except UnicodeDecodeError as e:
3845 if not py_only :
3853 if not py_only :
3846 # Deferred import
3854 # Deferred import
3847 from urllib.request import urlopen
3855 from urllib.request import urlopen
3848 response = urlopen(target)
3856 response = urlopen(target)
3849 return response.read().decode('latin1')
3857 return response.read().decode('latin1')
3850 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3858 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3851
3859
3852 potential_target = [target]
3860 potential_target = [target]
3853 try :
3861 try :
3854 potential_target.insert(0,get_py_filename(target))
3862 potential_target.insert(0,get_py_filename(target))
3855 except IOError:
3863 except IOError:
3856 pass
3864 pass
3857
3865
3858 for tgt in potential_target :
3866 for tgt in potential_target :
3859 if os.path.isfile(tgt): # Read file
3867 if os.path.isfile(tgt): # Read file
3860 try :
3868 try :
3861 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3869 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3862 except UnicodeDecodeError as e:
3870 except UnicodeDecodeError as e:
3863 if not py_only :
3871 if not py_only :
3864 with io_open(tgt,'r', encoding='latin1') as f :
3872 with io_open(tgt,'r', encoding='latin1') as f :
3865 return f.read()
3873 return f.read()
3866 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3874 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3867 elif os.path.isdir(os.path.expanduser(tgt)):
3875 elif os.path.isdir(os.path.expanduser(tgt)):
3868 raise ValueError("'%s' is a directory, not a regular file." % target)
3876 raise ValueError("'%s' is a directory, not a regular file." % target)
3869
3877
3870 if search_ns:
3878 if search_ns:
3871 # Inspect namespace to load object source
3879 # Inspect namespace to load object source
3872 object_info = self.object_inspect(target, detail_level=1)
3880 object_info = self.object_inspect(target, detail_level=1)
3873 if object_info['found'] and object_info['source']:
3881 if object_info['found'] and object_info['source']:
3874 return object_info['source']
3882 return object_info['source']
3875
3883
3876 try: # User namespace
3884 try: # User namespace
3877 codeobj = eval(target, self.user_ns)
3885 codeobj = eval(target, self.user_ns)
3878 except Exception as e:
3886 except Exception as e:
3879 raise ValueError(("'%s' was not found in history, as a file, url, "
3887 raise ValueError(("'%s' was not found in history, as a file, url, "
3880 "nor in the user namespace.") % target) from e
3888 "nor in the user namespace.") % target) from e
3881
3889
3882 if isinstance(codeobj, str):
3890 if isinstance(codeobj, str):
3883 return codeobj
3891 return codeobj
3884 elif isinstance(codeobj, Macro):
3892 elif isinstance(codeobj, Macro):
3885 return codeobj.value
3893 return codeobj.value
3886
3894
3887 raise TypeError("%s is neither a string nor a macro." % target,
3895 raise TypeError("%s is neither a string nor a macro." % target,
3888 codeobj)
3896 codeobj)
3889
3897
3890 def _atexit_once(self):
3898 def _atexit_once(self):
3891 """
3899 """
3892 At exist operation that need to be called at most once.
3900 At exist operation that need to be called at most once.
3893 Second call to this function per instance will do nothing.
3901 Second call to this function per instance will do nothing.
3894 """
3902 """
3895
3903
3896 if not getattr(self, "_atexit_once_called", False):
3904 if not getattr(self, "_atexit_once_called", False):
3897 self._atexit_once_called = True
3905 self._atexit_once_called = True
3898 # Clear all user namespaces to release all references cleanly.
3906 # Clear all user namespaces to release all references cleanly.
3899 self.reset(new_session=False)
3907 self.reset(new_session=False)
3900 # Close the history session (this stores the end time and line count)
3908 # Close the history session (this stores the end time and line count)
3901 # this must be *before* the tempfile cleanup, in case of temporary
3909 # this must be *before* the tempfile cleanup, in case of temporary
3902 # history db
3910 # history db
3903 self.history_manager.end_session()
3911 self.history_manager.end_session()
3904 self.history_manager = None
3912 self.history_manager = None
3905
3913
3906 #-------------------------------------------------------------------------
3914 #-------------------------------------------------------------------------
3907 # Things related to IPython exiting
3915 # Things related to IPython exiting
3908 #-------------------------------------------------------------------------
3916 #-------------------------------------------------------------------------
3909 def atexit_operations(self):
3917 def atexit_operations(self):
3910 """This will be executed at the time of exit.
3918 """This will be executed at the time of exit.
3911
3919
3912 Cleanup operations and saving of persistent data that is done
3920 Cleanup operations and saving of persistent data that is done
3913 unconditionally by IPython should be performed here.
3921 unconditionally by IPython should be performed here.
3914
3922
3915 For things that may depend on startup flags or platform specifics (such
3923 For things that may depend on startup flags or platform specifics (such
3916 as having readline or not), register a separate atexit function in the
3924 as having readline or not), register a separate atexit function in the
3917 code that has the appropriate information, rather than trying to
3925 code that has the appropriate information, rather than trying to
3918 clutter
3926 clutter
3919 """
3927 """
3920 self._atexit_once()
3928 self._atexit_once()
3921
3929
3922 # Cleanup all tempfiles and folders left around
3930 # Cleanup all tempfiles and folders left around
3923 for tfile in self.tempfiles:
3931 for tfile in self.tempfiles:
3924 try:
3932 try:
3925 tfile.unlink()
3933 tfile.unlink()
3926 self.tempfiles.remove(tfile)
3934 self.tempfiles.remove(tfile)
3927 except FileNotFoundError:
3935 except FileNotFoundError:
3928 pass
3936 pass
3929 del self.tempfiles
3937 del self.tempfiles
3930 for tdir in self.tempdirs:
3938 for tdir in self.tempdirs:
3931 try:
3939 try:
3932 shutil.rmtree(tdir)
3940 shutil.rmtree(tdir)
3933 self.tempdirs.remove(tdir)
3941 self.tempdirs.remove(tdir)
3934 except FileNotFoundError:
3942 except FileNotFoundError:
3935 pass
3943 pass
3936 del self.tempdirs
3944 del self.tempdirs
3937
3945
3938 # Restore user's cursor
3946 # Restore user's cursor
3939 if hasattr(self, "editing_mode") and self.editing_mode == "vi":
3947 if hasattr(self, "editing_mode") and self.editing_mode == "vi":
3940 sys.stdout.write("\x1b[0 q")
3948 sys.stdout.write("\x1b[0 q")
3941 sys.stdout.flush()
3949 sys.stdout.flush()
3942
3950
3943 def cleanup(self):
3951 def cleanup(self):
3944 self.restore_sys_module_state()
3952 self.restore_sys_module_state()
3945
3953
3946
3954
3947 # Overridden in terminal subclass to change prompts
3955 # Overridden in terminal subclass to change prompts
3948 def switch_doctest_mode(self, mode):
3956 def switch_doctest_mode(self, mode):
3949 pass
3957 pass
3950
3958
3951
3959
3952 class InteractiveShellABC(metaclass=abc.ABCMeta):
3960 class InteractiveShellABC(metaclass=abc.ABCMeta):
3953 """An abstract base class for InteractiveShell."""
3961 """An abstract base class for InteractiveShell."""
3954
3962
3955 InteractiveShellABC.register(InteractiveShell)
3963 InteractiveShellABC.register(InteractiveShell)
@@ -1,320 +1,330 b''
1 """
1 """
2 This module contains utility function and classes to inject simple ast
2 This module contains utility function and classes to inject simple ast
3 transformations based on code strings into IPython. While it is already possible
3 transformations based on code strings into IPython. While it is already possible
4 with ast-transformers it is not easy to directly manipulate ast.
4 with ast-transformers it is not easy to directly manipulate ast.
5
5
6
6
7 IPython has pre-code and post-code hooks, but are ran from within the IPython
7 IPython has pre-code and post-code hooks, but are ran from within the IPython
8 machinery so may be inappropriate, for example for performance mesurement.
8 machinery so may be inappropriate, for example for performance mesurement.
9
9
10 This module give you tools to simplify this, and expose 2 classes:
10 This module give you tools to simplify this, and expose 2 classes:
11
11
12 - `ReplaceCodeTransformer` which is a simple ast transformer based on code
12 - `ReplaceCodeTransformer` which is a simple ast transformer based on code
13 template,
13 template,
14
14
15 and for advance case:
15 and for advance case:
16
16
17 - `Mangler` which is a simple ast transformer that mangle names in the ast.
17 - `Mangler` which is a simple ast transformer that mangle names in the ast.
18
18
19
19
20 Example, let's try to make a simple version of the ``timeit`` magic, that run a
20 Example, let's try to make a simple version of the ``timeit`` magic, that run a
21 code snippet 10 times and print the average time taken.
21 code snippet 10 times and print the average time taken.
22
22
23 Basically we want to run :
23 Basically we want to run :
24
24
25 .. code-block:: python
25 .. code-block:: python
26
26
27 from time import perf_counter
27 from time import perf_counter
28 now = perf_counter()
28 now = perf_counter()
29 for i in range(10):
29 for i in range(10):
30 __code__ # our code
30 __code__ # our code
31 print(f"Time taken: {(perf_counter() - now)/10}")
31 print(f"Time taken: {(perf_counter() - now)/10}")
32 __ret__ # the result of the last statement
32 __ret__ # the result of the last statement
33
33
34 Where ``__code__`` is the code snippet we want to run, and ``__ret__`` is the
34 Where ``__code__`` is the code snippet we want to run, and ``__ret__`` is the
35 result, so that if we for example run `dataframe.head()` IPython still display
35 result, so that if we for example run `dataframe.head()` IPython still display
36 the head of dataframe instead of nothing.
36 the head of dataframe instead of nothing.
37
37
38 Here is a complete example of a file `timit2.py` that define such a magic:
38 Here is a complete example of a file `timit2.py` that define such a magic:
39
39
40 .. code-block:: python
40 .. code-block:: python
41
41
42 from IPython.core.magic import (
42 from IPython.core.magic import (
43 Magics,
43 Magics,
44 magics_class,
44 magics_class,
45 line_cell_magic,
45 line_cell_magic,
46 )
46 )
47 from IPython.core.magics.ast_mod import ReplaceCodeTransformer
47 from IPython.core.magics.ast_mod import ReplaceCodeTransformer
48 from textwrap import dedent
48 from textwrap import dedent
49 import ast
49 import ast
50
50
51 template = template = dedent('''
51 template = template = dedent('''
52 from time import perf_counter
52 from time import perf_counter
53 now = perf_counter()
53 now = perf_counter()
54 for i in range(10):
54 for i in range(10):
55 __code__
55 __code__
56 print(f"Time taken: {(perf_counter() - now)/10}")
56 print(f"Time taken: {(perf_counter() - now)/10}")
57 __ret__
57 __ret__
58 '''
58 '''
59 )
59 )
60
60
61
61
62 @magics_class
62 @magics_class
63 class AstM(Magics):
63 class AstM(Magics):
64 @line_cell_magic
64 @line_cell_magic
65 def t2(self, line, cell):
65 def t2(self, line, cell):
66 transformer = ReplaceCodeTransformer.from_string(template)
66 transformer = ReplaceCodeTransformer.from_string(template)
67 transformer.debug = True
67 transformer.debug = True
68 transformer.mangler.debug = True
68 transformer.mangler.debug = True
69 new_code = transformer.visit(ast.parse(cell))
69 new_code = transformer.visit(ast.parse(cell))
70 return exec(compile(new_code, "<ast>", "exec"))
70 return exec(compile(new_code, "<ast>", "exec"))
71
71
72
72
73 def load_ipython_extension(ip):
73 def load_ipython_extension(ip):
74 ip.register_magics(AstM)
74 ip.register_magics(AstM)
75
75
76
76
77
77
78 .. code-block:: python
78 .. code-block:: python
79
79
80 In [1]: %load_ext timit2
80 In [1]: %load_ext timit2
81
81
82 In [2]: %%t2
82 In [2]: %%t2
83 ...: import time
83 ...: import time
84 ...: time.sleep(0.05)
84 ...: time.sleep(0.05)
85 ...:
85 ...:
86 ...:
86 ...:
87 Time taken: 0.05435649999999441
87 Time taken: 0.05435649999999441
88
88
89
89
90 If you wish to ran all the code enter in IPython in an ast transformer, you can
90 If you wish to ran all the code enter in IPython in an ast transformer, you can
91 do so as well:
91 do so as well:
92
92
93 .. code-block:: python
93 .. code-block:: python
94
94
95 In [1]: from IPython.core.magics.ast_mod import ReplaceCodeTransformer
95 In [1]: from IPython.core.magics.ast_mod import ReplaceCodeTransformer
96 ...:
96 ...:
97 ...: template = '''
97 ...: template = '''
98 ...: from time import perf_counter
98 ...: from time import perf_counter
99 ...: now = perf_counter()
99 ...: now = perf_counter()
100 ...: __code__
100 ...: __code__
101 ...: print(f"Code ran in {perf_counter()-now}")
101 ...: print(f"Code ran in {perf_counter()-now}")
102 ...: __ret__'''
102 ...: __ret__'''
103 ...:
103 ...:
104 ...: get_ipython().ast_transformers.append(ReplaceCodeTransformer.from_string(template))
104 ...: get_ipython().ast_transformers.append(ReplaceCodeTransformer.from_string(template))
105
105
106 In [2]: 1+1
106 In [2]: 1+1
107 Code ran in 3.40410006174352e-05
107 Code ran in 3.40410006174352e-05
108 Out[2]: 2
108 Out[2]: 2
109
109
110
110
111
111
112 Hygiene and Mangling
112 Hygiene and Mangling
113 --------------------
113 --------------------
114
114
115 The ast transformer above is not hygienic, it may not work if the user code use
115 The ast transformer above is not hygienic, it may not work if the user code use
116 the same variable names as the ones used in the template. For example.
116 the same variable names as the ones used in the template. For example.
117
117
118 To help with this by default the `ReplaceCodeTransformer` will mangle all names
118 To help with this by default the `ReplaceCodeTransformer` will mangle all names
119 staring with 3 underscores. This is a simple heuristic that should work in most
119 staring with 3 underscores. This is a simple heuristic that should work in most
120 case, but can be cumbersome in some case. We provide a `Mangler` class that can
120 case, but can be cumbersome in some case. We provide a `Mangler` class that can
121 be overridden to change the mangling heuristic, or simply use the `mangle_all`
121 be overridden to change the mangling heuristic, or simply use the `mangle_all`
122 utility function. It will _try_ to mangle all names (except `__ret__` and
122 utility function. It will _try_ to mangle all names (except `__ret__` and
123 `__code__`), but this include builtins (``print``, ``range``, ``type``) and
123 `__code__`), but this include builtins (``print``, ``range``, ``type``) and
124 replace those by invalid identifiers py prepending ``mangle-``:
124 replace those by invalid identifiers py prepending ``mangle-``:
125 ``mangle-print``, ``mangle-range``, ``mangle-type`` etc. This is not a problem
125 ``mangle-print``, ``mangle-range``, ``mangle-type`` etc. This is not a problem
126 as currently Python AST support invalid identifiers, but it may not be the case
126 as currently Python AST support invalid identifiers, but it may not be the case
127 in the future.
127 in the future.
128
128
129 You can set `ReplaceCodeTransformer.debug=True` and
129 You can set `ReplaceCodeTransformer.debug=True` and
130 `ReplaceCodeTransformer.mangler.debug=True` to see the code after mangling and
130 `ReplaceCodeTransformer.mangler.debug=True` to see the code after mangling and
131 transforming:
131 transforming:
132
132
133 .. code-block:: python
133 .. code-block:: python
134
134
135
135
136 In [1]: from IPython.core.magics.ast_mod import ReplaceCodeTransformer, mangle_all
136 In [1]: from IPython.core.magics.ast_mod import ReplaceCodeTransformer, mangle_all
137 ...:
137 ...:
138 ...: template = '''
138 ...: template = '''
139 ...: from builtins import type, print
139 ...: from builtins import type, print
140 ...: from time import perf_counter
140 ...: from time import perf_counter
141 ...: now = perf_counter()
141 ...: now = perf_counter()
142 ...: __code__
142 ...: __code__
143 ...: print(f"Code ran in {perf_counter()-now}")
143 ...: print(f"Code ran in {perf_counter()-now}")
144 ...: __ret__'''
144 ...: __ret__'''
145 ...:
145 ...:
146 ...: transformer = ReplaceCodeTransformer.from_string(template, mangling_predicate=mangle_all)
146 ...: transformer = ReplaceCodeTransformer.from_string(template, mangling_predicate=mangle_all)
147
147
148
148
149 In [2]: transformer.debug = True
149 In [2]: transformer.debug = True
150 ...: transformer.mangler.debug = True
150 ...: transformer.mangler.debug = True
151 ...: get_ipython().ast_transformers.append(transformer)
151 ...: get_ipython().ast_transformers.append(transformer)
152
152
153 In [3]: 1+1
153 In [3]: 1+1
154 Mangling Alias mangle-type
154 Mangling Alias mangle-type
155 Mangling Alias mangle-print
155 Mangling Alias mangle-print
156 Mangling Alias mangle-perf_counter
156 Mangling Alias mangle-perf_counter
157 Mangling now
157 Mangling now
158 Mangling perf_counter
158 Mangling perf_counter
159 Not mangling __code__
159 Not mangling __code__
160 Mangling print
160 Mangling print
161 Mangling perf_counter
161 Mangling perf_counter
162 Mangling now
162 Mangling now
163 Not mangling __ret__
163 Not mangling __ret__
164 ---- Transformed code ----
164 ---- Transformed code ----
165 from builtins import type as mangle-type, print as mangle-print
165 from builtins import type as mangle-type, print as mangle-print
166 from time import perf_counter as mangle-perf_counter
166 from time import perf_counter as mangle-perf_counter
167 mangle-now = mangle-perf_counter()
167 mangle-now = mangle-perf_counter()
168 ret-tmp = 1 + 1
168 ret-tmp = 1 + 1
169 mangle-print(f'Code ran in {mangle-perf_counter() - mangle-now}')
169 mangle-print(f'Code ran in {mangle-perf_counter() - mangle-now}')
170 ret-tmp
170 ret-tmp
171 ---- ---------------- ----
171 ---- ---------------- ----
172 Code ran in 0.00013654199938173406
172 Code ran in 0.00013654199938173406
173 Out[3]: 2
173 Out[3]: 2
174
174
175
175
176 """
176 """
177
177
178 __skip_doctest__ = True
178 __skip_doctest__ = True
179
179
180
180
181 from ast import NodeTransformer, Store, Load, Name, Expr, Assign, Module, Import, ImportFrom
181 from ast import (
182 NodeTransformer,
183 Store,
184 Load,
185 Name,
186 Expr,
187 Assign,
188 Module,
189 Import,
190 ImportFrom,
191 )
182 import ast
192 import ast
183 import copy
193 import copy
184
194
185 from typing import Dict, Optional, Union
195 from typing import Dict, Optional, Union
186
196
187
197
188 mangle_all = lambda name: False if name in ("__ret__", "__code__") else True
198 mangle_all = lambda name: False if name in ("__ret__", "__code__") else True
189
199
190
200
191 class Mangler(NodeTransformer):
201 class Mangler(NodeTransformer):
192 """
202 """
193 Mangle given names in and ast tree to make sure they do not conflict with
203 Mangle given names in and ast tree to make sure they do not conflict with
194 user code.
204 user code.
195 """
205 """
196
206
197 enabled: bool = True
207 enabled: bool = True
198 debug: bool = False
208 debug: bool = False
199
209
200 def log(self, *args, **kwargs):
210 def log(self, *args, **kwargs):
201 if self.debug:
211 if self.debug:
202 print(*args, **kwargs)
212 print(*args, **kwargs)
203
213
204 def __init__(self, predicate=None):
214 def __init__(self, predicate=None):
205 if predicate is None:
215 if predicate is None:
206 predicate = lambda name: name.startswith("___")
216 predicate = lambda name: name.startswith("___")
207 self.predicate = predicate
217 self.predicate = predicate
208
218
209 def visit_Name(self, node):
219 def visit_Name(self, node):
210 if self.predicate(node.id):
220 if self.predicate(node.id):
211 self.log("Mangling", node.id)
221 self.log("Mangling", node.id)
212 # Once in the ast we do not need
222 # Once in the ast we do not need
213 # names to be valid identifiers.
223 # names to be valid identifiers.
214 node.id = "mangle-" + node.id
224 node.id = "mangle-" + node.id
215 else:
225 else:
216 self.log("Not mangling", node.id)
226 self.log("Not mangling", node.id)
217 return node
227 return node
218
228
219 def visit_FunctionDef(self, node):
229 def visit_FunctionDef(self, node):
220 if self.predicate(node.name):
230 if self.predicate(node.name):
221 self.log("Mangling", node.name)
231 self.log("Mangling", node.name)
222 node.name = "mangle-" + node.name
232 node.name = "mangle-" + node.name
223 else:
233 else:
224 self.log("Not mangling", node.name)
234 self.log("Not mangling", node.name)
225
235
226 for arg in node.args.args:
236 for arg in node.args.args:
227 if self.predicate(arg.arg):
237 if self.predicate(arg.arg):
228 self.log("Mangling function arg", arg.arg)
238 self.log("Mangling function arg", arg.arg)
229 arg.arg = "mangle-" + arg.arg
239 arg.arg = "mangle-" + arg.arg
230 else:
240 else:
231 self.log("Not mangling function arg", arg.arg)
241 self.log("Not mangling function arg", arg.arg)
232 return self.generic_visit(node)
242 return self.generic_visit(node)
233
243
234 def visit_ImportFrom(self, node:ImportFrom):
244 def visit_ImportFrom(self, node: ImportFrom):
235 return self._visit_Import_and_ImportFrom(node)
245 return self._visit_Import_and_ImportFrom(node)
236
246
237 def visit_Import(self, node:Import):
247 def visit_Import(self, node: Import):
238 return self._visit_Import_and_ImportFrom(node)
248 return self._visit_Import_and_ImportFrom(node)
239
249
240 def _visit_Import_and_ImportFrom(self, node:Union[Import, ImportFrom]):
250 def _visit_Import_and_ImportFrom(self, node: Union[Import, ImportFrom]):
241 for alias in node.names:
251 for alias in node.names:
242 asname = alias.name if alias.asname is None else alias.asname
252 asname = alias.name if alias.asname is None else alias.asname
243 if self.predicate(asname):
253 if self.predicate(asname):
244 new_name: str = "mangle-" + asname
254 new_name: str = "mangle-" + asname
245 self.log("Mangling Alias", new_name)
255 self.log("Mangling Alias", new_name)
246 alias.asname = new_name
256 alias.asname = new_name
247 else:
257 else:
248 self.log("Not mangling Alias", alias.asname)
258 self.log("Not mangling Alias", alias.asname)
249 return node
259 return node
250
260
251
261
252 class ReplaceCodeTransformer(NodeTransformer):
262 class ReplaceCodeTransformer(NodeTransformer):
253 enabled: bool = True
263 enabled: bool = True
254 debug: bool = False
264 debug: bool = False
255 mangler: Mangler
265 mangler: Mangler
256
266
257 def __init__(
267 def __init__(
258 self, template: Module, mapping: Optional[Dict] = None, mangling_predicate=None
268 self, template: Module, mapping: Optional[Dict] = None, mangling_predicate=None
259 ):
269 ):
260 assert isinstance(mapping, (dict, type(None)))
270 assert isinstance(mapping, (dict, type(None)))
261 assert isinstance(mangling_predicate, (type(None), type(lambda: None)))
271 assert isinstance(mangling_predicate, (type(None), type(lambda: None)))
262 assert isinstance(template, ast.Module)
272 assert isinstance(template, ast.Module)
263 self.template = template
273 self.template = template
264 self.mangler = Mangler(predicate=mangling_predicate)
274 self.mangler = Mangler(predicate=mangling_predicate)
265 if mapping is None:
275 if mapping is None:
266 mapping = {}
276 mapping = {}
267 self.mapping = mapping
277 self.mapping = mapping
268
278
269 @classmethod
279 @classmethod
270 def from_string(
280 def from_string(
271 cls, template: str, mapping: Optional[Dict] = None, mangling_predicate=None
281 cls, template: str, mapping: Optional[Dict] = None, mangling_predicate=None
272 ):
282 ):
273 return cls(
283 return cls(
274 ast.parse(template), mapping=mapping, mangling_predicate=mangling_predicate
284 ast.parse(template), mapping=mapping, mangling_predicate=mangling_predicate
275 )
285 )
276
286
277 def visit_Module(self, code):
287 def visit_Module(self, code):
278 if not self.enabled:
288 if not self.enabled:
279 return code
289 return code
280 # if not isinstance(code, ast.Module):
290 # if not isinstance(code, ast.Module):
281 # recursively called...
291 # recursively called...
282 # return generic_visit(self, code)
292 # return generic_visit(self, code)
283 last = code.body[-1]
293 last = code.body[-1]
284 if isinstance(last, Expr):
294 if isinstance(last, Expr):
285 code.body.pop()
295 code.body.pop()
286 code.body.append(Assign([Name("ret-tmp", ctx=Store())], value=last.value))
296 code.body.append(Assign([Name("ret-tmp", ctx=Store())], value=last.value))
287 ast.fix_missing_locations(code)
297 ast.fix_missing_locations(code)
288 ret = Expr(value=Name("ret-tmp", ctx=Load()))
298 ret = Expr(value=Name("ret-tmp", ctx=Load()))
289 ret = ast.fix_missing_locations(ret)
299 ret = ast.fix_missing_locations(ret)
290 self.mapping["__ret__"] = ret
300 self.mapping["__ret__"] = ret
291 else:
301 else:
292 self.mapping["__ret__"] = ast.parse("None").body[0]
302 self.mapping["__ret__"] = ast.parse("None").body[0]
293 self.mapping["__code__"] = code.body
303 self.mapping["__code__"] = code.body
294 tpl = ast.fix_missing_locations(self.template)
304 tpl = ast.fix_missing_locations(self.template)
295
305
296 tx = copy.deepcopy(tpl)
306 tx = copy.deepcopy(tpl)
297 tx = self.mangler.visit(tx)
307 tx = self.mangler.visit(tx)
298 node = self.generic_visit(tx)
308 node = self.generic_visit(tx)
299 node_2 = ast.fix_missing_locations(node)
309 node_2 = ast.fix_missing_locations(node)
300 if self.debug:
310 if self.debug:
301 print("---- Transformed code ----")
311 print("---- Transformed code ----")
302 print(ast.unparse(node_2))
312 print(ast.unparse(node_2))
303 print("---- ---------------- ----")
313 print("---- ---------------- ----")
304 return node_2
314 return node_2
305
315
306 # this does not work as the name might be in a list and one might want to extend the list.
316 # this does not work as the name might be in a list and one might want to extend the list.
307 # def visit_Name(self, name):
317 # def visit_Name(self, name):
308 # if name.id in self.mapping and name.id == "__ret__":
318 # if name.id in self.mapping and name.id == "__ret__":
309 # print(name, "in mapping")
319 # print(name, "in mapping")
310 # if isinstance(name.ctx, ast.Store):
320 # if isinstance(name.ctx, ast.Store):
311 # return Name("tmp", ctx=Store())
321 # return Name("tmp", ctx=Store())
312 # else:
322 # else:
313 # return copy.deepcopy(self.mapping[name.id])
323 # return copy.deepcopy(self.mapping[name.id])
314 # return name
324 # return name
315
325
316 def visit_Expr(self, expr):
326 def visit_Expr(self, expr):
317 if isinstance(expr.value, Name) and expr.value.id in self.mapping:
327 if isinstance(expr.value, Name) and expr.value.id in self.mapping:
318 if self.mapping[expr.value.id] is not None:
328 if self.mapping[expr.value.id] is not None:
319 return copy.deepcopy(self.mapping[expr.value.id])
329 return copy.deepcopy(self.mapping[expr.value.id])
320 return self.generic_visit(expr)
330 return self.generic_visit(expr)
@@ -1,371 +1,372 b''
1 """Magic functions for running cells in various scripts."""
1 """Magic functions for running cells in various scripts."""
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import asyncio
6 import asyncio
7 import asyncio.exceptions
7 import asyncio.exceptions
8 import atexit
8 import atexit
9 import errno
9 import errno
10 import os
10 import os
11 import signal
11 import signal
12 import sys
12 import sys
13 import time
13 import time
14 from subprocess import CalledProcessError
14 from subprocess import CalledProcessError
15 from threading import Thread
15 from threading import Thread
16
16
17 from traitlets import Any, Dict, List, default
17 from traitlets import Any, Dict, List, default
18
18
19 from IPython.core import magic_arguments
19 from IPython.core import magic_arguments
20 from IPython.core.async_helpers import _AsyncIOProxy
20 from IPython.core.async_helpers import _AsyncIOProxy
21 from IPython.core.magic import Magics, cell_magic, line_magic, magics_class
21 from IPython.core.magic import Magics, cell_magic, line_magic, magics_class
22 from IPython.utils.process import arg_split
22 from IPython.utils.process import arg_split
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Magic implementation classes
25 # Magic implementation classes
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 def script_args(f):
28 def script_args(f):
29 """single decorator for adding script args"""
29 """single decorator for adding script args"""
30 args = [
30 args = [
31 magic_arguments.argument(
31 magic_arguments.argument(
32 '--out', type=str,
32 '--out', type=str,
33 help="""The variable in which to store stdout from the script.
33 help="""The variable in which to store stdout from the script.
34 If the script is backgrounded, this will be the stdout *pipe*,
34 If the script is backgrounded, this will be the stdout *pipe*,
35 instead of the stderr text itself and will not be auto closed.
35 instead of the stderr text itself and will not be auto closed.
36 """
36 """
37 ),
37 ),
38 magic_arguments.argument(
38 magic_arguments.argument(
39 '--err', type=str,
39 '--err', type=str,
40 help="""The variable in which to store stderr from the script.
40 help="""The variable in which to store stderr from the script.
41 If the script is backgrounded, this will be the stderr *pipe*,
41 If the script is backgrounded, this will be the stderr *pipe*,
42 instead of the stderr text itself and will not be autoclosed.
42 instead of the stderr text itself and will not be autoclosed.
43 """
43 """
44 ),
44 ),
45 magic_arguments.argument(
45 magic_arguments.argument(
46 '--bg', action="store_true",
46 '--bg', action="store_true",
47 help="""Whether to run the script in the background.
47 help="""Whether to run the script in the background.
48 If given, the only way to see the output of the command is
48 If given, the only way to see the output of the command is
49 with --out/err.
49 with --out/err.
50 """
50 """
51 ),
51 ),
52 magic_arguments.argument(
52 magic_arguments.argument(
53 '--proc', type=str,
53 '--proc', type=str,
54 help="""The variable in which to store Popen instance.
54 help="""The variable in which to store Popen instance.
55 This is used only when --bg option is given.
55 This is used only when --bg option is given.
56 """
56 """
57 ),
57 ),
58 magic_arguments.argument(
58 magic_arguments.argument(
59 '--no-raise-error', action="store_false", dest='raise_error',
59 '--no-raise-error', action="store_false", dest='raise_error',
60 help="""Whether you should raise an error message in addition to
60 help="""Whether you should raise an error message in addition to
61 a stream on stderr if you get a nonzero exit code.
61 a stream on stderr if you get a nonzero exit code.
62 """,
62 """,
63 ),
63 ),
64 ]
64 ]
65 for arg in args:
65 for arg in args:
66 f = arg(f)
66 f = arg(f)
67 return f
67 return f
68
68
69
69
70 @magics_class
70 @magics_class
71 class ScriptMagics(Magics):
71 class ScriptMagics(Magics):
72 """Magics for talking to scripts
72 """Magics for talking to scripts
73
73
74 This defines a base `%%script` cell magic for running a cell
74 This defines a base `%%script` cell magic for running a cell
75 with a program in a subprocess, and registers a few top-level
75 with a program in a subprocess, and registers a few top-level
76 magics that call %%script with common interpreters.
76 magics that call %%script with common interpreters.
77 """
77 """
78
78
79 event_loop = Any(
79 event_loop = Any(
80 help="""
80 help="""
81 The event loop on which to run subprocesses
81 The event loop on which to run subprocesses
82
82
83 Not the main event loop,
83 Not the main event loop,
84 because we want to be able to make blocking calls
84 because we want to be able to make blocking calls
85 and have certain requirements we don't want to impose on the main loop.
85 and have certain requirements we don't want to impose on the main loop.
86 """
86 """
87 )
87 )
88
88
89 script_magics = List(
89 script_magics: List = List(
90 help="""Extra script cell magics to define
90 help="""Extra script cell magics to define
91
91
92 This generates simple wrappers of `%%script foo` as `%%foo`.
92 This generates simple wrappers of `%%script foo` as `%%foo`.
93
93
94 If you want to add script magics that aren't on your path,
94 If you want to add script magics that aren't on your path,
95 specify them in script_paths
95 specify them in script_paths
96 """,
96 """,
97 ).tag(config=True)
97 ).tag(config=True)
98
98 @default('script_magics')
99 @default('script_magics')
99 def _script_magics_default(self):
100 def _script_magics_default(self):
100 """default to a common list of programs"""
101 """default to a common list of programs"""
101
102
102 defaults = [
103 defaults = [
103 'sh',
104 'sh',
104 'bash',
105 'bash',
105 'perl',
106 'perl',
106 'ruby',
107 'ruby',
107 'python',
108 'python',
108 'python2',
109 'python2',
109 'python3',
110 'python3',
110 'pypy',
111 'pypy',
111 ]
112 ]
112 if os.name == 'nt':
113 if os.name == 'nt':
113 defaults.extend([
114 defaults.extend([
114 'cmd',
115 'cmd',
115 ])
116 ])
116
117
117 return defaults
118 return defaults
118
119
119 script_paths = Dict(
120 script_paths = Dict(
120 help="""Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby'
121 help="""Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby'
121
122
122 Only necessary for items in script_magics where the default path will not
123 Only necessary for items in script_magics where the default path will not
123 find the right interpreter.
124 find the right interpreter.
124 """
125 """
125 ).tag(config=True)
126 ).tag(config=True)
126
127
127 def __init__(self, shell=None):
128 def __init__(self, shell=None):
128 super(ScriptMagics, self).__init__(shell=shell)
129 super(ScriptMagics, self).__init__(shell=shell)
129 self._generate_script_magics()
130 self._generate_script_magics()
130 self.bg_processes = []
131 self.bg_processes = []
131 atexit.register(self.kill_bg_processes)
132 atexit.register(self.kill_bg_processes)
132
133
133 def __del__(self):
134 def __del__(self):
134 self.kill_bg_processes()
135 self.kill_bg_processes()
135
136
136 def _generate_script_magics(self):
137 def _generate_script_magics(self):
137 cell_magics = self.magics['cell']
138 cell_magics = self.magics['cell']
138 for name in self.script_magics:
139 for name in self.script_magics:
139 cell_magics[name] = self._make_script_magic(name)
140 cell_magics[name] = self._make_script_magic(name)
140
141
141 def _make_script_magic(self, name):
142 def _make_script_magic(self, name):
142 """make a named magic, that calls %%script with a particular program"""
143 """make a named magic, that calls %%script with a particular program"""
143 # expand to explicit path if necessary:
144 # expand to explicit path if necessary:
144 script = self.script_paths.get(name, name)
145 script = self.script_paths.get(name, name)
145
146
146 @magic_arguments.magic_arguments()
147 @magic_arguments.magic_arguments()
147 @script_args
148 @script_args
148 def named_script_magic(line, cell):
149 def named_script_magic(line, cell):
149 # if line, add it as cl-flags
150 # if line, add it as cl-flags
150 if line:
151 if line:
151 line = "%s %s" % (script, line)
152 line = "%s %s" % (script, line)
152 else:
153 else:
153 line = script
154 line = script
154 return self.shebang(line, cell)
155 return self.shebang(line, cell)
155
156
156 # write a basic docstring:
157 # write a basic docstring:
157 named_script_magic.__doc__ = \
158 named_script_magic.__doc__ = \
158 """%%{name} script magic
159 """%%{name} script magic
159
160
160 Run cells with {script} in a subprocess.
161 Run cells with {script} in a subprocess.
161
162
162 This is a shortcut for `%%script {script}`
163 This is a shortcut for `%%script {script}`
163 """.format(**locals())
164 """.format(**locals())
164
165
165 return named_script_magic
166 return named_script_magic
166
167
167 @magic_arguments.magic_arguments()
168 @magic_arguments.magic_arguments()
168 @script_args
169 @script_args
169 @cell_magic("script")
170 @cell_magic("script")
170 def shebang(self, line, cell):
171 def shebang(self, line, cell):
171 """Run a cell via a shell command
172 """Run a cell via a shell command
172
173
173 The `%%script` line is like the #! line of script,
174 The `%%script` line is like the #! line of script,
174 specifying a program (bash, perl, ruby, etc.) with which to run.
175 specifying a program (bash, perl, ruby, etc.) with which to run.
175
176
176 The rest of the cell is run by that program.
177 The rest of the cell is run by that program.
177
178
178 Examples
179 Examples
179 --------
180 --------
180 ::
181 ::
181
182
182 In [1]: %%script bash
183 In [1]: %%script bash
183 ...: for i in 1 2 3; do
184 ...: for i in 1 2 3; do
184 ...: echo $i
185 ...: echo $i
185 ...: done
186 ...: done
186 1
187 1
187 2
188 2
188 3
189 3
189 """
190 """
190
191
191 # Create the event loop in which to run script magics
192 # Create the event loop in which to run script magics
192 # this operates on a background thread
193 # this operates on a background thread
193 if self.event_loop is None:
194 if self.event_loop is None:
194 if sys.platform == "win32":
195 if sys.platform == "win32":
195 # don't override the current policy,
196 # don't override the current policy,
196 # just create an event loop
197 # just create an event loop
197 event_loop = asyncio.WindowsProactorEventLoopPolicy().new_event_loop()
198 event_loop = asyncio.WindowsProactorEventLoopPolicy().new_event_loop()
198 else:
199 else:
199 event_loop = asyncio.new_event_loop()
200 event_loop = asyncio.new_event_loop()
200 self.event_loop = event_loop
201 self.event_loop = event_loop
201
202
202 # start the loop in a background thread
203 # start the loop in a background thread
203 asyncio_thread = Thread(target=event_loop.run_forever, daemon=True)
204 asyncio_thread = Thread(target=event_loop.run_forever, daemon=True)
204 asyncio_thread.start()
205 asyncio_thread.start()
205 else:
206 else:
206 event_loop = self.event_loop
207 event_loop = self.event_loop
207
208
208 def in_thread(coro):
209 def in_thread(coro):
209 """Call a coroutine on the asyncio thread"""
210 """Call a coroutine on the asyncio thread"""
210 return asyncio.run_coroutine_threadsafe(coro, event_loop).result()
211 return asyncio.run_coroutine_threadsafe(coro, event_loop).result()
211
212
212 async def _readchunk(stream):
213 async def _readchunk(stream):
213 try:
214 try:
214 return await stream.readuntil(b"\n")
215 return await stream.readuntil(b"\n")
215 except asyncio.exceptions.IncompleteReadError as e:
216 except asyncio.exceptions.IncompleteReadError as e:
216 return e.partial
217 return e.partial
217 except asyncio.exceptions.LimitOverrunError as e:
218 except asyncio.exceptions.LimitOverrunError as e:
218 return await stream.read(e.consumed)
219 return await stream.read(e.consumed)
219
220
220 async def _handle_stream(stream, stream_arg, file_object):
221 async def _handle_stream(stream, stream_arg, file_object):
221 while True:
222 while True:
222 chunk = (await _readchunk(stream)).decode("utf8", errors="replace")
223 chunk = (await _readchunk(stream)).decode("utf8", errors="replace")
223 if not chunk:
224 if not chunk:
224 break
225 break
225 if stream_arg:
226 if stream_arg:
226 self.shell.user_ns[stream_arg] = chunk
227 self.shell.user_ns[stream_arg] = chunk
227 else:
228 else:
228 file_object.write(chunk)
229 file_object.write(chunk)
229 file_object.flush()
230 file_object.flush()
230
231
231 async def _stream_communicate(process, cell):
232 async def _stream_communicate(process, cell):
232 process.stdin.write(cell)
233 process.stdin.write(cell)
233 process.stdin.close()
234 process.stdin.close()
234 stdout_task = asyncio.create_task(
235 stdout_task = asyncio.create_task(
235 _handle_stream(process.stdout, args.out, sys.stdout)
236 _handle_stream(process.stdout, args.out, sys.stdout)
236 )
237 )
237 stderr_task = asyncio.create_task(
238 stderr_task = asyncio.create_task(
238 _handle_stream(process.stderr, args.err, sys.stderr)
239 _handle_stream(process.stderr, args.err, sys.stderr)
239 )
240 )
240 await asyncio.wait([stdout_task, stderr_task])
241 await asyncio.wait([stdout_task, stderr_task])
241 await process.wait()
242 await process.wait()
242
243
243 argv = arg_split(line, posix=not sys.platform.startswith("win"))
244 argv = arg_split(line, posix=not sys.platform.startswith("win"))
244 args, cmd = self.shebang.parser.parse_known_args(argv)
245 args, cmd = self.shebang.parser.parse_known_args(argv)
245
246
246 try:
247 try:
247 p = in_thread(
248 p = in_thread(
248 asyncio.create_subprocess_exec(
249 asyncio.create_subprocess_exec(
249 *cmd,
250 *cmd,
250 stdout=asyncio.subprocess.PIPE,
251 stdout=asyncio.subprocess.PIPE,
251 stderr=asyncio.subprocess.PIPE,
252 stderr=asyncio.subprocess.PIPE,
252 stdin=asyncio.subprocess.PIPE,
253 stdin=asyncio.subprocess.PIPE,
253 )
254 )
254 )
255 )
255 except OSError as e:
256 except OSError as e:
256 if e.errno == errno.ENOENT:
257 if e.errno == errno.ENOENT:
257 print("Couldn't find program: %r" % cmd[0])
258 print("Couldn't find program: %r" % cmd[0])
258 return
259 return
259 else:
260 else:
260 raise
261 raise
261
262
262 if not cell.endswith('\n'):
263 if not cell.endswith('\n'):
263 cell += '\n'
264 cell += '\n'
264 cell = cell.encode('utf8', 'replace')
265 cell = cell.encode('utf8', 'replace')
265 if args.bg:
266 if args.bg:
266 self.bg_processes.append(p)
267 self.bg_processes.append(p)
267 self._gc_bg_processes()
268 self._gc_bg_processes()
268 to_close = []
269 to_close = []
269 if args.out:
270 if args.out:
270 self.shell.user_ns[args.out] = _AsyncIOProxy(p.stdout, event_loop)
271 self.shell.user_ns[args.out] = _AsyncIOProxy(p.stdout, event_loop)
271 else:
272 else:
272 to_close.append(p.stdout)
273 to_close.append(p.stdout)
273 if args.err:
274 if args.err:
274 self.shell.user_ns[args.err] = _AsyncIOProxy(p.stderr, event_loop)
275 self.shell.user_ns[args.err] = _AsyncIOProxy(p.stderr, event_loop)
275 else:
276 else:
276 to_close.append(p.stderr)
277 to_close.append(p.stderr)
277 event_loop.call_soon_threadsafe(
278 event_loop.call_soon_threadsafe(
278 lambda: asyncio.Task(self._run_script(p, cell, to_close))
279 lambda: asyncio.Task(self._run_script(p, cell, to_close))
279 )
280 )
280 if args.proc:
281 if args.proc:
281 proc_proxy = _AsyncIOProxy(p, event_loop)
282 proc_proxy = _AsyncIOProxy(p, event_loop)
282 proc_proxy.stdout = _AsyncIOProxy(p.stdout, event_loop)
283 proc_proxy.stdout = _AsyncIOProxy(p.stdout, event_loop)
283 proc_proxy.stderr = _AsyncIOProxy(p.stderr, event_loop)
284 proc_proxy.stderr = _AsyncIOProxy(p.stderr, event_loop)
284 self.shell.user_ns[args.proc] = proc_proxy
285 self.shell.user_ns[args.proc] = proc_proxy
285 return
286 return
286
287
287 try:
288 try:
288 in_thread(_stream_communicate(p, cell))
289 in_thread(_stream_communicate(p, cell))
289 except KeyboardInterrupt:
290 except KeyboardInterrupt:
290 try:
291 try:
291 p.send_signal(signal.SIGINT)
292 p.send_signal(signal.SIGINT)
292 in_thread(asyncio.wait_for(p.wait(), timeout=0.1))
293 in_thread(asyncio.wait_for(p.wait(), timeout=0.1))
293 if p.returncode is not None:
294 if p.returncode is not None:
294 print("Process is interrupted.")
295 print("Process is interrupted.")
295 return
296 return
296 p.terminate()
297 p.terminate()
297 in_thread(asyncio.wait_for(p.wait(), timeout=0.1))
298 in_thread(asyncio.wait_for(p.wait(), timeout=0.1))
298 if p.returncode is not None:
299 if p.returncode is not None:
299 print("Process is terminated.")
300 print("Process is terminated.")
300 return
301 return
301 p.kill()
302 p.kill()
302 print("Process is killed.")
303 print("Process is killed.")
303 except OSError:
304 except OSError:
304 pass
305 pass
305 except Exception as e:
306 except Exception as e:
306 print("Error while terminating subprocess (pid=%i): %s" % (p.pid, e))
307 print("Error while terminating subprocess (pid=%i): %s" % (p.pid, e))
307 return
308 return
308
309
309 if args.raise_error and p.returncode != 0:
310 if args.raise_error and p.returncode != 0:
310 # If we get here and p.returncode is still None, we must have
311 # If we get here and p.returncode is still None, we must have
311 # killed it but not yet seen its return code. We don't wait for it,
312 # killed it but not yet seen its return code. We don't wait for it,
312 # in case it's stuck in uninterruptible sleep. -9 = SIGKILL
313 # in case it's stuck in uninterruptible sleep. -9 = SIGKILL
313 rc = p.returncode or -9
314 rc = p.returncode or -9
314 raise CalledProcessError(rc, cell)
315 raise CalledProcessError(rc, cell)
315
316
316 shebang.__skip_doctest__ = os.name != "posix"
317 shebang.__skip_doctest__ = os.name != "posix"
317
318
318 async def _run_script(self, p, cell, to_close):
319 async def _run_script(self, p, cell, to_close):
319 """callback for running the script in the background"""
320 """callback for running the script in the background"""
320
321
321 p.stdin.write(cell)
322 p.stdin.write(cell)
322 await p.stdin.drain()
323 await p.stdin.drain()
323 p.stdin.close()
324 p.stdin.close()
324 await p.stdin.wait_closed()
325 await p.stdin.wait_closed()
325 await p.wait()
326 await p.wait()
326 # asyncio read pipes have no close
327 # asyncio read pipes have no close
327 # but we should drain the data anyway
328 # but we should drain the data anyway
328 for s in to_close:
329 for s in to_close:
329 await s.read()
330 await s.read()
330 self._gc_bg_processes()
331 self._gc_bg_processes()
331
332
332 @line_magic("killbgscripts")
333 @line_magic("killbgscripts")
333 def killbgscripts(self, _nouse_=''):
334 def killbgscripts(self, _nouse_=''):
334 """Kill all BG processes started by %%script and its family."""
335 """Kill all BG processes started by %%script and its family."""
335 self.kill_bg_processes()
336 self.kill_bg_processes()
336 print("All background processes were killed.")
337 print("All background processes were killed.")
337
338
338 def kill_bg_processes(self):
339 def kill_bg_processes(self):
339 """Kill all BG processes which are still running."""
340 """Kill all BG processes which are still running."""
340 if not self.bg_processes:
341 if not self.bg_processes:
341 return
342 return
342 for p in self.bg_processes:
343 for p in self.bg_processes:
343 if p.returncode is None:
344 if p.returncode is None:
344 try:
345 try:
345 p.send_signal(signal.SIGINT)
346 p.send_signal(signal.SIGINT)
346 except:
347 except:
347 pass
348 pass
348 time.sleep(0.1)
349 time.sleep(0.1)
349 self._gc_bg_processes()
350 self._gc_bg_processes()
350 if not self.bg_processes:
351 if not self.bg_processes:
351 return
352 return
352 for p in self.bg_processes:
353 for p in self.bg_processes:
353 if p.returncode is None:
354 if p.returncode is None:
354 try:
355 try:
355 p.terminate()
356 p.terminate()
356 except:
357 except:
357 pass
358 pass
358 time.sleep(0.1)
359 time.sleep(0.1)
359 self._gc_bg_processes()
360 self._gc_bg_processes()
360 if not self.bg_processes:
361 if not self.bg_processes:
361 return
362 return
362 for p in self.bg_processes:
363 for p in self.bg_processes:
363 if p.returncode is None:
364 if p.returncode is None:
364 try:
365 try:
365 p.kill()
366 p.kill()
366 except:
367 except:
367 pass
368 pass
368 self._gc_bg_processes()
369 self._gc_bg_processes()
369
370
370 def _gc_bg_processes(self):
371 def _gc_bg_processes(self):
371 self.bg_processes = [p for p in self.bg_processes if p.returncode is None]
372 self.bg_processes = [p for p in self.bg_processes if p.returncode is None]
@@ -1,700 +1,703 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Prefiltering components.
3 Prefiltering components.
4
4
5 Prefilters transform user input before it is exec'd by Python. These
5 Prefilters transform user input before it is exec'd by Python. These
6 transforms are used to implement additional syntax such as !ls and %magic.
6 transforms are used to implement additional syntax such as !ls and %magic.
7 """
7 """
8
8
9 # Copyright (c) IPython Development Team.
9 # Copyright (c) IPython Development Team.
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11
11
12 from keyword import iskeyword
12 from keyword import iskeyword
13 import re
13 import re
14
14
15 from .autocall import IPyAutocall
15 from .autocall import IPyAutocall
16 from traitlets.config.configurable import Configurable
16 from traitlets.config.configurable import Configurable
17 from .inputtransformer2 import (
17 from .inputtransformer2 import (
18 ESC_MAGIC,
18 ESC_MAGIC,
19 ESC_QUOTE,
19 ESC_QUOTE,
20 ESC_QUOTE2,
20 ESC_QUOTE2,
21 ESC_PAREN,
21 ESC_PAREN,
22 )
22 )
23 from .macro import Macro
23 from .macro import Macro
24 from .splitinput import LineInfo
24 from .splitinput import LineInfo
25
25
26 from traitlets import (
26 from traitlets import (
27 List, Integer, Unicode, Bool, Instance, CRegExp
27 List, Integer, Unicode, Bool, Instance, CRegExp
28 )
28 )
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 # Global utilities, errors and constants
31 # Global utilities, errors and constants
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33
33
34
34
35 class PrefilterError(Exception):
35 class PrefilterError(Exception):
36 pass
36 pass
37
37
38
38
39 # RegExp to identify potential function names
39 # RegExp to identify potential function names
40 re_fun_name = re.compile(r'[^\W\d]([\w.]*) *$')
40 re_fun_name = re.compile(r'[^\W\d]([\w.]*) *$')
41
41
42 # RegExp to exclude strings with this start from autocalling. In
42 # RegExp to exclude strings with this start from autocalling. In
43 # particular, all binary operators should be excluded, so that if foo is
43 # particular, all binary operators should be excluded, so that if foo is
44 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
44 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
45 # characters '!=()' don't need to be checked for, as the checkPythonChars
45 # characters '!=()' don't need to be checked for, as the checkPythonChars
46 # routine explicitly does so, to catch direct calls and rebindings of
46 # routine explicitly does so, to catch direct calls and rebindings of
47 # existing names.
47 # existing names.
48
48
49 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
49 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
50 # it affects the rest of the group in square brackets.
50 # it affects the rest of the group in square brackets.
51 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
51 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
52 r'|^is |^not |^in |^and |^or ')
52 r'|^is |^not |^in |^and |^or ')
53
53
54 # try to catch also methods for stuff in lists/tuples/dicts: off
54 # try to catch also methods for stuff in lists/tuples/dicts: off
55 # (experimental). For this to work, the line_split regexp would need
55 # (experimental). For this to work, the line_split regexp would need
56 # to be modified so it wouldn't break things at '['. That line is
56 # to be modified so it wouldn't break things at '['. That line is
57 # nasty enough that I shouldn't change it until I can test it _well_.
57 # nasty enough that I shouldn't change it until I can test it _well_.
58 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
58 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
59
59
60
60
61 # Handler Check Utilities
61 # Handler Check Utilities
62 def is_shadowed(identifier, ip):
62 def is_shadowed(identifier, ip):
63 """Is the given identifier defined in one of the namespaces which shadow
63 """Is the given identifier defined in one of the namespaces which shadow
64 the alias and magic namespaces? Note that an identifier is different
64 the alias and magic namespaces? Note that an identifier is different
65 than ifun, because it can not contain a '.' character."""
65 than ifun, because it can not contain a '.' character."""
66 # This is much safer than calling ofind, which can change state
66 # This is much safer than calling ofind, which can change state
67 return (identifier in ip.user_ns \
67 return (identifier in ip.user_ns \
68 or identifier in ip.user_global_ns \
68 or identifier in ip.user_global_ns \
69 or identifier in ip.ns_table['builtin']\
69 or identifier in ip.ns_table['builtin']\
70 or iskeyword(identifier))
70 or iskeyword(identifier))
71
71
72
72
73 #-----------------------------------------------------------------------------
73 #-----------------------------------------------------------------------------
74 # Main Prefilter manager
74 # Main Prefilter manager
75 #-----------------------------------------------------------------------------
75 #-----------------------------------------------------------------------------
76
76
77
77
78 class PrefilterManager(Configurable):
78 class PrefilterManager(Configurable):
79 """Main prefilter component.
79 """Main prefilter component.
80
80
81 The IPython prefilter is run on all user input before it is run. The
81 The IPython prefilter is run on all user input before it is run. The
82 prefilter consumes lines of input and produces transformed lines of
82 prefilter consumes lines of input and produces transformed lines of
83 input.
83 input.
84
84
85 The implementation consists of two phases:
85 The implementation consists of two phases:
86
86
87 1. Transformers
87 1. Transformers
88 2. Checkers and handlers
88 2. Checkers and handlers
89
89
90 Over time, we plan on deprecating the checkers and handlers and doing
90 Over time, we plan on deprecating the checkers and handlers and doing
91 everything in the transformers.
91 everything in the transformers.
92
92
93 The transformers are instances of :class:`PrefilterTransformer` and have
93 The transformers are instances of :class:`PrefilterTransformer` and have
94 a single method :meth:`transform` that takes a line and returns a
94 a single method :meth:`transform` that takes a line and returns a
95 transformed line. The transformation can be accomplished using any
95 transformed line. The transformation can be accomplished using any
96 tool, but our current ones use regular expressions for speed.
96 tool, but our current ones use regular expressions for speed.
97
97
98 After all the transformers have been run, the line is fed to the checkers,
98 After all the transformers have been run, the line is fed to the checkers,
99 which are instances of :class:`PrefilterChecker`. The line is passed to
99 which are instances of :class:`PrefilterChecker`. The line is passed to
100 the :meth:`check` method, which either returns `None` or a
100 the :meth:`check` method, which either returns `None` or a
101 :class:`PrefilterHandler` instance. If `None` is returned, the other
101 :class:`PrefilterHandler` instance. If `None` is returned, the other
102 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
102 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
103 the line is passed to the :meth:`handle` method of the returned
103 the line is passed to the :meth:`handle` method of the returned
104 handler and no further checkers are tried.
104 handler and no further checkers are tried.
105
105
106 Both transformers and checkers have a `priority` attribute, that determines
106 Both transformers and checkers have a `priority` attribute, that determines
107 the order in which they are called. Smaller priorities are tried first.
107 the order in which they are called. Smaller priorities are tried first.
108
108
109 Both transformers and checkers also have `enabled` attribute, which is
109 Both transformers and checkers also have `enabled` attribute, which is
110 a boolean that determines if the instance is used.
110 a boolean that determines if the instance is used.
111
111
112 Users or developers can change the priority or enabled attribute of
112 Users or developers can change the priority or enabled attribute of
113 transformers or checkers, but they must call the :meth:`sort_checkers`
113 transformers or checkers, but they must call the :meth:`sort_checkers`
114 or :meth:`sort_transformers` method after changing the priority.
114 or :meth:`sort_transformers` method after changing the priority.
115 """
115 """
116
116
117 multi_line_specials = Bool(True).tag(config=True)
117 multi_line_specials = Bool(True).tag(config=True)
118 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
118 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
119
119
120 def __init__(self, shell=None, **kwargs):
120 def __init__(self, shell=None, **kwargs):
121 super(PrefilterManager, self).__init__(shell=shell, **kwargs)
121 super(PrefilterManager, self).__init__(shell=shell, **kwargs)
122 self.shell = shell
122 self.shell = shell
123 self._transformers = []
123 self._transformers = []
124 self.init_handlers()
124 self.init_handlers()
125 self.init_checkers()
125 self.init_checkers()
126
126
127 #-------------------------------------------------------------------------
127 #-------------------------------------------------------------------------
128 # API for managing transformers
128 # API for managing transformers
129 #-------------------------------------------------------------------------
129 #-------------------------------------------------------------------------
130
130
131 def sort_transformers(self):
131 def sort_transformers(self):
132 """Sort the transformers by priority.
132 """Sort the transformers by priority.
133
133
134 This must be called after the priority of a transformer is changed.
134 This must be called after the priority of a transformer is changed.
135 The :meth:`register_transformer` method calls this automatically.
135 The :meth:`register_transformer` method calls this automatically.
136 """
136 """
137 self._transformers.sort(key=lambda x: x.priority)
137 self._transformers.sort(key=lambda x: x.priority)
138
138
139 @property
139 @property
140 def transformers(self):
140 def transformers(self):
141 """Return a list of checkers, sorted by priority."""
141 """Return a list of checkers, sorted by priority."""
142 return self._transformers
142 return self._transformers
143
143
144 def register_transformer(self, transformer):
144 def register_transformer(self, transformer):
145 """Register a transformer instance."""
145 """Register a transformer instance."""
146 if transformer not in self._transformers:
146 if transformer not in self._transformers:
147 self._transformers.append(transformer)
147 self._transformers.append(transformer)
148 self.sort_transformers()
148 self.sort_transformers()
149
149
150 def unregister_transformer(self, transformer):
150 def unregister_transformer(self, transformer):
151 """Unregister a transformer instance."""
151 """Unregister a transformer instance."""
152 if transformer in self._transformers:
152 if transformer in self._transformers:
153 self._transformers.remove(transformer)
153 self._transformers.remove(transformer)
154
154
155 #-------------------------------------------------------------------------
155 #-------------------------------------------------------------------------
156 # API for managing checkers
156 # API for managing checkers
157 #-------------------------------------------------------------------------
157 #-------------------------------------------------------------------------
158
158
159 def init_checkers(self):
159 def init_checkers(self):
160 """Create the default checkers."""
160 """Create the default checkers."""
161 self._checkers = []
161 self._checkers = []
162 for checker in _default_checkers:
162 for checker in _default_checkers:
163 checker(
163 checker(
164 shell=self.shell, prefilter_manager=self, parent=self
164 shell=self.shell, prefilter_manager=self, parent=self
165 )
165 )
166
166
167 def sort_checkers(self):
167 def sort_checkers(self):
168 """Sort the checkers by priority.
168 """Sort the checkers by priority.
169
169
170 This must be called after the priority of a checker is changed.
170 This must be called after the priority of a checker is changed.
171 The :meth:`register_checker` method calls this automatically.
171 The :meth:`register_checker` method calls this automatically.
172 """
172 """
173 self._checkers.sort(key=lambda x: x.priority)
173 self._checkers.sort(key=lambda x: x.priority)
174
174
175 @property
175 @property
176 def checkers(self):
176 def checkers(self):
177 """Return a list of checkers, sorted by priority."""
177 """Return a list of checkers, sorted by priority."""
178 return self._checkers
178 return self._checkers
179
179
180 def register_checker(self, checker):
180 def register_checker(self, checker):
181 """Register a checker instance."""
181 """Register a checker instance."""
182 if checker not in self._checkers:
182 if checker not in self._checkers:
183 self._checkers.append(checker)
183 self._checkers.append(checker)
184 self.sort_checkers()
184 self.sort_checkers()
185
185
186 def unregister_checker(self, checker):
186 def unregister_checker(self, checker):
187 """Unregister a checker instance."""
187 """Unregister a checker instance."""
188 if checker in self._checkers:
188 if checker in self._checkers:
189 self._checkers.remove(checker)
189 self._checkers.remove(checker)
190
190
191 #-------------------------------------------------------------------------
191 #-------------------------------------------------------------------------
192 # API for managing handlers
192 # API for managing handlers
193 #-------------------------------------------------------------------------
193 #-------------------------------------------------------------------------
194
194
195 def init_handlers(self):
195 def init_handlers(self):
196 """Create the default handlers."""
196 """Create the default handlers."""
197 self._handlers = {}
197 self._handlers = {}
198 self._esc_handlers = {}
198 self._esc_handlers = {}
199 for handler in _default_handlers:
199 for handler in _default_handlers:
200 handler(
200 handler(
201 shell=self.shell, prefilter_manager=self, parent=self
201 shell=self.shell, prefilter_manager=self, parent=self
202 )
202 )
203
203
204 @property
204 @property
205 def handlers(self):
205 def handlers(self):
206 """Return a dict of all the handlers."""
206 """Return a dict of all the handlers."""
207 return self._handlers
207 return self._handlers
208
208
209 def register_handler(self, name, handler, esc_strings):
209 def register_handler(self, name, handler, esc_strings):
210 """Register a handler instance by name with esc_strings."""
210 """Register a handler instance by name with esc_strings."""
211 self._handlers[name] = handler
211 self._handlers[name] = handler
212 for esc_str in esc_strings:
212 for esc_str in esc_strings:
213 self._esc_handlers[esc_str] = handler
213 self._esc_handlers[esc_str] = handler
214
214
215 def unregister_handler(self, name, handler, esc_strings):
215 def unregister_handler(self, name, handler, esc_strings):
216 """Unregister a handler instance by name with esc_strings."""
216 """Unregister a handler instance by name with esc_strings."""
217 try:
217 try:
218 del self._handlers[name]
218 del self._handlers[name]
219 except KeyError:
219 except KeyError:
220 pass
220 pass
221 for esc_str in esc_strings:
221 for esc_str in esc_strings:
222 h = self._esc_handlers.get(esc_str)
222 h = self._esc_handlers.get(esc_str)
223 if h is handler:
223 if h is handler:
224 del self._esc_handlers[esc_str]
224 del self._esc_handlers[esc_str]
225
225
226 def get_handler_by_name(self, name):
226 def get_handler_by_name(self, name):
227 """Get a handler by its name."""
227 """Get a handler by its name."""
228 return self._handlers.get(name)
228 return self._handlers.get(name)
229
229
230 def get_handler_by_esc(self, esc_str):
230 def get_handler_by_esc(self, esc_str):
231 """Get a handler by its escape string."""
231 """Get a handler by its escape string."""
232 return self._esc_handlers.get(esc_str)
232 return self._esc_handlers.get(esc_str)
233
233
234 #-------------------------------------------------------------------------
234 #-------------------------------------------------------------------------
235 # Main prefiltering API
235 # Main prefiltering API
236 #-------------------------------------------------------------------------
236 #-------------------------------------------------------------------------
237
237
238 def prefilter_line_info(self, line_info):
238 def prefilter_line_info(self, line_info):
239 """Prefilter a line that has been converted to a LineInfo object.
239 """Prefilter a line that has been converted to a LineInfo object.
240
240
241 This implements the checker/handler part of the prefilter pipe.
241 This implements the checker/handler part of the prefilter pipe.
242 """
242 """
243 # print "prefilter_line_info: ", line_info
243 # print "prefilter_line_info: ", line_info
244 handler = self.find_handler(line_info)
244 handler = self.find_handler(line_info)
245 return handler.handle(line_info)
245 return handler.handle(line_info)
246
246
247 def find_handler(self, line_info):
247 def find_handler(self, line_info):
248 """Find a handler for the line_info by trying checkers."""
248 """Find a handler for the line_info by trying checkers."""
249 for checker in self.checkers:
249 for checker in self.checkers:
250 if checker.enabled:
250 if checker.enabled:
251 handler = checker.check(line_info)
251 handler = checker.check(line_info)
252 if handler:
252 if handler:
253 return handler
253 return handler
254 return self.get_handler_by_name('normal')
254 return self.get_handler_by_name('normal')
255
255
256 def transform_line(self, line, continue_prompt):
256 def transform_line(self, line, continue_prompt):
257 """Calls the enabled transformers in order of increasing priority."""
257 """Calls the enabled transformers in order of increasing priority."""
258 for transformer in self.transformers:
258 for transformer in self.transformers:
259 if transformer.enabled:
259 if transformer.enabled:
260 line = transformer.transform(line, continue_prompt)
260 line = transformer.transform(line, continue_prompt)
261 return line
261 return line
262
262
263 def prefilter_line(self, line, continue_prompt=False):
263 def prefilter_line(self, line, continue_prompt=False):
264 """Prefilter a single input line as text.
264 """Prefilter a single input line as text.
265
265
266 This method prefilters a single line of text by calling the
266 This method prefilters a single line of text by calling the
267 transformers and then the checkers/handlers.
267 transformers and then the checkers/handlers.
268 """
268 """
269
269
270 # print "prefilter_line: ", line, continue_prompt
270 # print "prefilter_line: ", line, continue_prompt
271 # All handlers *must* return a value, even if it's blank ('').
271 # All handlers *must* return a value, even if it's blank ('').
272
272
273 # save the line away in case we crash, so the post-mortem handler can
273 # save the line away in case we crash, so the post-mortem handler can
274 # record it
274 # record it
275 self.shell._last_input_line = line
275 self.shell._last_input_line = line
276
276
277 if not line:
277 if not line:
278 # Return immediately on purely empty lines, so that if the user
278 # Return immediately on purely empty lines, so that if the user
279 # previously typed some whitespace that started a continuation
279 # previously typed some whitespace that started a continuation
280 # prompt, he can break out of that loop with just an empty line.
280 # prompt, he can break out of that loop with just an empty line.
281 # This is how the default python prompt works.
281 # This is how the default python prompt works.
282 return ''
282 return ''
283
283
284 # At this point, we invoke our transformers.
284 # At this point, we invoke our transformers.
285 if not continue_prompt or (continue_prompt and self.multi_line_specials):
285 if not continue_prompt or (continue_prompt and self.multi_line_specials):
286 line = self.transform_line(line, continue_prompt)
286 line = self.transform_line(line, continue_prompt)
287
287
288 # Now we compute line_info for the checkers and handlers
288 # Now we compute line_info for the checkers and handlers
289 line_info = LineInfo(line, continue_prompt)
289 line_info = LineInfo(line, continue_prompt)
290
290
291 # the input history needs to track even empty lines
291 # the input history needs to track even empty lines
292 stripped = line.strip()
292 stripped = line.strip()
293
293
294 normal_handler = self.get_handler_by_name('normal')
294 normal_handler = self.get_handler_by_name('normal')
295 if not stripped:
295 if not stripped:
296 return normal_handler.handle(line_info)
296 return normal_handler.handle(line_info)
297
297
298 # special handlers are only allowed for single line statements
298 # special handlers are only allowed for single line statements
299 if continue_prompt and not self.multi_line_specials:
299 if continue_prompt and not self.multi_line_specials:
300 return normal_handler.handle(line_info)
300 return normal_handler.handle(line_info)
301
301
302 prefiltered = self.prefilter_line_info(line_info)
302 prefiltered = self.prefilter_line_info(line_info)
303 # print "prefiltered line: %r" % prefiltered
303 # print "prefiltered line: %r" % prefiltered
304 return prefiltered
304 return prefiltered
305
305
306 def prefilter_lines(self, lines, continue_prompt=False):
306 def prefilter_lines(self, lines, continue_prompt=False):
307 """Prefilter multiple input lines of text.
307 """Prefilter multiple input lines of text.
308
308
309 This is the main entry point for prefiltering multiple lines of
309 This is the main entry point for prefiltering multiple lines of
310 input. This simply calls :meth:`prefilter_line` for each line of
310 input. This simply calls :meth:`prefilter_line` for each line of
311 input.
311 input.
312
312
313 This covers cases where there are multiple lines in the user entry,
313 This covers cases where there are multiple lines in the user entry,
314 which is the case when the user goes back to a multiline history
314 which is the case when the user goes back to a multiline history
315 entry and presses enter.
315 entry and presses enter.
316 """
316 """
317 llines = lines.rstrip('\n').split('\n')
317 llines = lines.rstrip('\n').split('\n')
318 # We can get multiple lines in one shot, where multiline input 'blends'
318 # We can get multiple lines in one shot, where multiline input 'blends'
319 # into one line, in cases like recalling from the readline history
319 # into one line, in cases like recalling from the readline history
320 # buffer. We need to make sure that in such cases, we correctly
320 # buffer. We need to make sure that in such cases, we correctly
321 # communicate downstream which line is first and which are continuation
321 # communicate downstream which line is first and which are continuation
322 # ones.
322 # ones.
323 if len(llines) > 1:
323 if len(llines) > 1:
324 out = '\n'.join([self.prefilter_line(line, lnum>0)
324 out = '\n'.join([self.prefilter_line(line, lnum>0)
325 for lnum, line in enumerate(llines) ])
325 for lnum, line in enumerate(llines) ])
326 else:
326 else:
327 out = self.prefilter_line(llines[0], continue_prompt)
327 out = self.prefilter_line(llines[0], continue_prompt)
328
328
329 return out
329 return out
330
330
331 #-----------------------------------------------------------------------------
331 #-----------------------------------------------------------------------------
332 # Prefilter transformers
332 # Prefilter transformers
333 #-----------------------------------------------------------------------------
333 #-----------------------------------------------------------------------------
334
334
335
335
336 class PrefilterTransformer(Configurable):
336 class PrefilterTransformer(Configurable):
337 """Transform a line of user input."""
337 """Transform a line of user input."""
338
338
339 priority = Integer(100).tag(config=True)
339 priority = Integer(100).tag(config=True)
340 # Transformers don't currently use shell or prefilter_manager, but as we
340 # Transformers don't currently use shell or prefilter_manager, but as we
341 # move away from checkers and handlers, they will need them.
341 # move away from checkers and handlers, they will need them.
342 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
342 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
343 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
343 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
344 enabled = Bool(True).tag(config=True)
344 enabled = Bool(True).tag(config=True)
345
345
346 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
346 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
347 super(PrefilterTransformer, self).__init__(
347 super(PrefilterTransformer, self).__init__(
348 shell=shell, prefilter_manager=prefilter_manager, **kwargs
348 shell=shell, prefilter_manager=prefilter_manager, **kwargs
349 )
349 )
350 self.prefilter_manager.register_transformer(self)
350 self.prefilter_manager.register_transformer(self)
351
351
352 def transform(self, line, continue_prompt):
352 def transform(self, line, continue_prompt):
353 """Transform a line, returning the new one."""
353 """Transform a line, returning the new one."""
354 return None
354 return None
355
355
356 def __repr__(self):
356 def __repr__(self):
357 return "<%s(priority=%r, enabled=%r)>" % (
357 return "<%s(priority=%r, enabled=%r)>" % (
358 self.__class__.__name__, self.priority, self.enabled)
358 self.__class__.__name__, self.priority, self.enabled)
359
359
360
360
361 #-----------------------------------------------------------------------------
361 #-----------------------------------------------------------------------------
362 # Prefilter checkers
362 # Prefilter checkers
363 #-----------------------------------------------------------------------------
363 #-----------------------------------------------------------------------------
364
364
365
365
366 class PrefilterChecker(Configurable):
366 class PrefilterChecker(Configurable):
367 """Inspect an input line and return a handler for that line."""
367 """Inspect an input line and return a handler for that line."""
368
368
369 priority = Integer(100).tag(config=True)
369 priority = Integer(100).tag(config=True)
370 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
370 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
371 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
371 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
372 enabled = Bool(True).tag(config=True)
372 enabled = Bool(True).tag(config=True)
373
373
374 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
374 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
375 super(PrefilterChecker, self).__init__(
375 super(PrefilterChecker, self).__init__(
376 shell=shell, prefilter_manager=prefilter_manager, **kwargs
376 shell=shell, prefilter_manager=prefilter_manager, **kwargs
377 )
377 )
378 self.prefilter_manager.register_checker(self)
378 self.prefilter_manager.register_checker(self)
379
379
380 def check(self, line_info):
380 def check(self, line_info):
381 """Inspect line_info and return a handler instance or None."""
381 """Inspect line_info and return a handler instance or None."""
382 return None
382 return None
383
383
384 def __repr__(self):
384 def __repr__(self):
385 return "<%s(priority=%r, enabled=%r)>" % (
385 return "<%s(priority=%r, enabled=%r)>" % (
386 self.__class__.__name__, self.priority, self.enabled)
386 self.__class__.__name__, self.priority, self.enabled)
387
387
388
388
389 class EmacsChecker(PrefilterChecker):
389 class EmacsChecker(PrefilterChecker):
390
390
391 priority = Integer(100).tag(config=True)
391 priority = Integer(100).tag(config=True)
392 enabled = Bool(False).tag(config=True)
392 enabled = Bool(False).tag(config=True)
393
393
394 def check(self, line_info):
394 def check(self, line_info):
395 "Emacs ipython-mode tags certain input lines."
395 "Emacs ipython-mode tags certain input lines."
396 if line_info.line.endswith('# PYTHON-MODE'):
396 if line_info.line.endswith('# PYTHON-MODE'):
397 return self.prefilter_manager.get_handler_by_name('emacs')
397 return self.prefilter_manager.get_handler_by_name('emacs')
398 else:
398 else:
399 return None
399 return None
400
400
401
401
402 class MacroChecker(PrefilterChecker):
402 class MacroChecker(PrefilterChecker):
403
403
404 priority = Integer(250).tag(config=True)
404 priority = Integer(250).tag(config=True)
405
405
406 def check(self, line_info):
406 def check(self, line_info):
407 obj = self.shell.user_ns.get(line_info.ifun)
407 obj = self.shell.user_ns.get(line_info.ifun)
408 if isinstance(obj, Macro):
408 if isinstance(obj, Macro):
409 return self.prefilter_manager.get_handler_by_name('macro')
409 return self.prefilter_manager.get_handler_by_name('macro')
410 else:
410 else:
411 return None
411 return None
412
412
413
413
414 class IPyAutocallChecker(PrefilterChecker):
414 class IPyAutocallChecker(PrefilterChecker):
415
415
416 priority = Integer(300).tag(config=True)
416 priority = Integer(300).tag(config=True)
417
417
418 def check(self, line_info):
418 def check(self, line_info):
419 "Instances of IPyAutocall in user_ns get autocalled immediately"
419 "Instances of IPyAutocall in user_ns get autocalled immediately"
420 obj = self.shell.user_ns.get(line_info.ifun, None)
420 obj = self.shell.user_ns.get(line_info.ifun, None)
421 if isinstance(obj, IPyAutocall):
421 if isinstance(obj, IPyAutocall):
422 obj.set_ip(self.shell)
422 obj.set_ip(self.shell)
423 return self.prefilter_manager.get_handler_by_name('auto')
423 return self.prefilter_manager.get_handler_by_name('auto')
424 else:
424 else:
425 return None
425 return None
426
426
427
427
428 class AssignmentChecker(PrefilterChecker):
428 class AssignmentChecker(PrefilterChecker):
429
429
430 priority = Integer(600).tag(config=True)
430 priority = Integer(600).tag(config=True)
431
431
432 def check(self, line_info):
432 def check(self, line_info):
433 """Check to see if user is assigning to a var for the first time, in
433 """Check to see if user is assigning to a var for the first time, in
434 which case we want to avoid any sort of automagic / autocall games.
434 which case we want to avoid any sort of automagic / autocall games.
435
435
436 This allows users to assign to either alias or magic names true python
436 This allows users to assign to either alias or magic names true python
437 variables (the magic/alias systems always take second seat to true
437 variables (the magic/alias systems always take second seat to true
438 python code). E.g. ls='hi', or ls,that=1,2"""
438 python code). E.g. ls='hi', or ls,that=1,2"""
439 if line_info.the_rest:
439 if line_info.the_rest:
440 if line_info.the_rest[0] in '=,':
440 if line_info.the_rest[0] in '=,':
441 return self.prefilter_manager.get_handler_by_name('normal')
441 return self.prefilter_manager.get_handler_by_name('normal')
442 else:
442 else:
443 return None
443 return None
444
444
445
445
446 class AutoMagicChecker(PrefilterChecker):
446 class AutoMagicChecker(PrefilterChecker):
447
447
448 priority = Integer(700).tag(config=True)
448 priority = Integer(700).tag(config=True)
449
449
450 def check(self, line_info):
450 def check(self, line_info):
451 """If the ifun is magic, and automagic is on, run it. Note: normal,
451 """If the ifun is magic, and automagic is on, run it. Note: normal,
452 non-auto magic would already have been triggered via '%' in
452 non-auto magic would already have been triggered via '%' in
453 check_esc_chars. This just checks for automagic. Also, before
453 check_esc_chars. This just checks for automagic. Also, before
454 triggering the magic handler, make sure that there is nothing in the
454 triggering the magic handler, make sure that there is nothing in the
455 user namespace which could shadow it."""
455 user namespace which could shadow it."""
456 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
456 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
457 return None
457 return None
458
458
459 # We have a likely magic method. Make sure we should actually call it.
459 # We have a likely magic method. Make sure we should actually call it.
460 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
460 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
461 return None
461 return None
462
462
463 head = line_info.ifun.split('.',1)[0]
463 head = line_info.ifun.split('.',1)[0]
464 if is_shadowed(head, self.shell):
464 if is_shadowed(head, self.shell):
465 return None
465 return None
466
466
467 return self.prefilter_manager.get_handler_by_name('magic')
467 return self.prefilter_manager.get_handler_by_name('magic')
468
468
469
469
470 class PythonOpsChecker(PrefilterChecker):
470 class PythonOpsChecker(PrefilterChecker):
471
471
472 priority = Integer(900).tag(config=True)
472 priority = Integer(900).tag(config=True)
473
473
474 def check(self, line_info):
474 def check(self, line_info):
475 """If the 'rest' of the line begins with a function call or pretty much
475 """If the 'rest' of the line begins with a function call or pretty much
476 any python operator, we should simply execute the line (regardless of
476 any python operator, we should simply execute the line (regardless of
477 whether or not there's a possible autocall expansion). This avoids
477 whether or not there's a possible autocall expansion). This avoids
478 spurious (and very confusing) geattr() accesses."""
478 spurious (and very confusing) geattr() accesses."""
479 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
479 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
480 return self.prefilter_manager.get_handler_by_name('normal')
480 return self.prefilter_manager.get_handler_by_name('normal')
481 else:
481 else:
482 return None
482 return None
483
483
484
484
485 class AutocallChecker(PrefilterChecker):
485 class AutocallChecker(PrefilterChecker):
486
486
487 priority = Integer(1000).tag(config=True)
487 priority = Integer(1000).tag(config=True)
488
488
489 function_name_regexp = CRegExp(re_fun_name,
489 function_name_regexp = CRegExp(re_fun_name,
490 help="RegExp to identify potential function names."
490 help="RegExp to identify potential function names."
491 ).tag(config=True)
491 ).tag(config=True)
492 exclude_regexp = CRegExp(re_exclude_auto,
492 exclude_regexp = CRegExp(re_exclude_auto,
493 help="RegExp to exclude strings with this start from autocalling."
493 help="RegExp to exclude strings with this start from autocalling."
494 ).tag(config=True)
494 ).tag(config=True)
495
495
496 def check(self, line_info):
496 def check(self, line_info):
497 "Check if the initial word/function is callable and autocall is on."
497 "Check if the initial word/function is callable and autocall is on."
498 if not self.shell.autocall:
498 if not self.shell.autocall:
499 return None
499 return None
500
500
501 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
501 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
502 if not oinfo.found:
502 if not oinfo.found:
503 return None
503 return None
504
504
505 ignored_funs = ['b', 'f', 'r', 'u', 'br', 'rb', 'fr', 'rf']
505 ignored_funs = ['b', 'f', 'r', 'u', 'br', 'rb', 'fr', 'rf']
506 ifun = line_info.ifun
506 ifun = line_info.ifun
507 line = line_info.line
507 line = line_info.line
508 if ifun.lower() in ignored_funs and (line.startswith(ifun + "'") or line.startswith(ifun + '"')):
508 if ifun.lower() in ignored_funs and (line.startswith(ifun + "'") or line.startswith(ifun + '"')):
509 return None
509 return None
510
510
511 if (
511 if (
512 callable(oinfo.obj)
512 callable(oinfo.obj)
513 and (not self.exclude_regexp.match(line_info.the_rest))
513 and (not self.exclude_regexp.match(line_info.the_rest))
514 and self.function_name_regexp.match(line_info.ifun)
514 and self.function_name_regexp.match(line_info.ifun)
515 ):
515 ):
516 return self.prefilter_manager.get_handler_by_name("auto")
516 return self.prefilter_manager.get_handler_by_name("auto")
517 else:
517 else:
518 return None
518 return None
519
519
520
520
521 #-----------------------------------------------------------------------------
521 #-----------------------------------------------------------------------------
522 # Prefilter handlers
522 # Prefilter handlers
523 #-----------------------------------------------------------------------------
523 #-----------------------------------------------------------------------------
524
524
525
525
526 class PrefilterHandler(Configurable):
526 class PrefilterHandler(Configurable):
527
527 handler_name = Unicode("normal")
528 handler_name = Unicode('normal')
528 esc_strings: List = List([])
529 esc_strings = List([])
529 shell = Instance(
530 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
530 "IPython.core.interactiveshell.InteractiveShellABC", allow_none=True
531 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
531 )
532 prefilter_manager = Instance(
533 "IPython.core.prefilter.PrefilterManager", allow_none=True
534 )
532
535
533 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
536 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
534 super(PrefilterHandler, self).__init__(
537 super(PrefilterHandler, self).__init__(
535 shell=shell, prefilter_manager=prefilter_manager, **kwargs
538 shell=shell, prefilter_manager=prefilter_manager, **kwargs
536 )
539 )
537 self.prefilter_manager.register_handler(
540 self.prefilter_manager.register_handler(
538 self.handler_name,
541 self.handler_name,
539 self,
542 self,
540 self.esc_strings
543 self.esc_strings
541 )
544 )
542
545
543 def handle(self, line_info):
546 def handle(self, line_info):
544 # print "normal: ", line_info
547 # print "normal: ", line_info
545 """Handle normal input lines. Use as a template for handlers."""
548 """Handle normal input lines. Use as a template for handlers."""
546
549
547 # With autoindent on, we need some way to exit the input loop, and I
550 # With autoindent on, we need some way to exit the input loop, and I
548 # don't want to force the user to have to backspace all the way to
551 # don't want to force the user to have to backspace all the way to
549 # clear the line. The rule will be in this case, that either two
552 # clear the line. The rule will be in this case, that either two
550 # lines of pure whitespace in a row, or a line of pure whitespace but
553 # lines of pure whitespace in a row, or a line of pure whitespace but
551 # of a size different to the indent level, will exit the input loop.
554 # of a size different to the indent level, will exit the input loop.
552 line = line_info.line
555 line = line_info.line
553 continue_prompt = line_info.continue_prompt
556 continue_prompt = line_info.continue_prompt
554
557
555 if (continue_prompt and
558 if (continue_prompt and
556 self.shell.autoindent and
559 self.shell.autoindent and
557 line.isspace() and
560 line.isspace() and
558 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
561 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
559 line = ''
562 line = ''
560
563
561 return line
564 return line
562
565
563 def __str__(self):
566 def __str__(self):
564 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
567 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
565
568
566
569
567 class MacroHandler(PrefilterHandler):
570 class MacroHandler(PrefilterHandler):
568 handler_name = Unicode("macro")
571 handler_name = Unicode("macro")
569
572
570 def handle(self, line_info):
573 def handle(self, line_info):
571 obj = self.shell.user_ns.get(line_info.ifun)
574 obj = self.shell.user_ns.get(line_info.ifun)
572 pre_space = line_info.pre_whitespace
575 pre_space = line_info.pre_whitespace
573 line_sep = "\n" + pre_space
576 line_sep = "\n" + pre_space
574 return pre_space + line_sep.join(obj.value.splitlines())
577 return pre_space + line_sep.join(obj.value.splitlines())
575
578
576
579
577 class MagicHandler(PrefilterHandler):
580 class MagicHandler(PrefilterHandler):
578
581
579 handler_name = Unicode('magic')
582 handler_name = Unicode('magic')
580 esc_strings = List([ESC_MAGIC])
583 esc_strings = List([ESC_MAGIC])
581
584
582 def handle(self, line_info):
585 def handle(self, line_info):
583 """Execute magic functions."""
586 """Execute magic functions."""
584 ifun = line_info.ifun
587 ifun = line_info.ifun
585 the_rest = line_info.the_rest
588 the_rest = line_info.the_rest
586 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
589 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
587 t_arg_s = ifun + " " + the_rest
590 t_arg_s = ifun + " " + the_rest
588 t_magic_name, _, t_magic_arg_s = t_arg_s.partition(' ')
591 t_magic_name, _, t_magic_arg_s = t_arg_s.partition(' ')
589 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
592 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
590 cmd = '%sget_ipython().run_line_magic(%r, %r)' % (line_info.pre_whitespace, t_magic_name, t_magic_arg_s)
593 cmd = '%sget_ipython().run_line_magic(%r, %r)' % (line_info.pre_whitespace, t_magic_name, t_magic_arg_s)
591 return cmd
594 return cmd
592
595
593
596
594 class AutoHandler(PrefilterHandler):
597 class AutoHandler(PrefilterHandler):
595
598
596 handler_name = Unicode('auto')
599 handler_name = Unicode('auto')
597 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
600 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
598
601
599 def handle(self, line_info):
602 def handle(self, line_info):
600 """Handle lines which can be auto-executed, quoting if requested."""
603 """Handle lines which can be auto-executed, quoting if requested."""
601 line = line_info.line
604 line = line_info.line
602 ifun = line_info.ifun
605 ifun = line_info.ifun
603 the_rest = line_info.the_rest
606 the_rest = line_info.the_rest
604 esc = line_info.esc
607 esc = line_info.esc
605 continue_prompt = line_info.continue_prompt
608 continue_prompt = line_info.continue_prompt
606 obj = line_info.ofind(self.shell).obj
609 obj = line_info.ofind(self.shell).obj
607
610
608 # This should only be active for single-line input!
611 # This should only be active for single-line input!
609 if continue_prompt:
612 if continue_prompt:
610 return line
613 return line
611
614
612 force_auto = isinstance(obj, IPyAutocall)
615 force_auto = isinstance(obj, IPyAutocall)
613
616
614 # User objects sometimes raise exceptions on attribute access other
617 # User objects sometimes raise exceptions on attribute access other
615 # than AttributeError (we've seen it in the past), so it's safest to be
618 # than AttributeError (we've seen it in the past), so it's safest to be
616 # ultra-conservative here and catch all.
619 # ultra-conservative here and catch all.
617 try:
620 try:
618 auto_rewrite = obj.rewrite
621 auto_rewrite = obj.rewrite
619 except Exception:
622 except Exception:
620 auto_rewrite = True
623 auto_rewrite = True
621
624
622 if esc == ESC_QUOTE:
625 if esc == ESC_QUOTE:
623 # Auto-quote splitting on whitespace
626 # Auto-quote splitting on whitespace
624 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
627 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
625 elif esc == ESC_QUOTE2:
628 elif esc == ESC_QUOTE2:
626 # Auto-quote whole string
629 # Auto-quote whole string
627 newcmd = '%s("%s")' % (ifun,the_rest)
630 newcmd = '%s("%s")' % (ifun,the_rest)
628 elif esc == ESC_PAREN:
631 elif esc == ESC_PAREN:
629 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
632 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
630 else:
633 else:
631 # Auto-paren.
634 # Auto-paren.
632 if force_auto:
635 if force_auto:
633 # Don't rewrite if it is already a call.
636 # Don't rewrite if it is already a call.
634 do_rewrite = not the_rest.startswith('(')
637 do_rewrite = not the_rest.startswith('(')
635 else:
638 else:
636 if not the_rest:
639 if not the_rest:
637 # We only apply it to argument-less calls if the autocall
640 # We only apply it to argument-less calls if the autocall
638 # parameter is set to 2.
641 # parameter is set to 2.
639 do_rewrite = (self.shell.autocall >= 2)
642 do_rewrite = (self.shell.autocall >= 2)
640 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
643 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
641 # Don't autocall in this case: item access for an object
644 # Don't autocall in this case: item access for an object
642 # which is BOTH callable and implements __getitem__.
645 # which is BOTH callable and implements __getitem__.
643 do_rewrite = False
646 do_rewrite = False
644 else:
647 else:
645 do_rewrite = True
648 do_rewrite = True
646
649
647 # Figure out the rewritten command
650 # Figure out the rewritten command
648 if do_rewrite:
651 if do_rewrite:
649 if the_rest.endswith(';'):
652 if the_rest.endswith(';'):
650 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
653 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
651 else:
654 else:
652 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
655 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
653 else:
656 else:
654 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
657 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
655 return normal_handler.handle(line_info)
658 return normal_handler.handle(line_info)
656
659
657 # Display the rewritten call
660 # Display the rewritten call
658 if auto_rewrite:
661 if auto_rewrite:
659 self.shell.auto_rewrite_input(newcmd)
662 self.shell.auto_rewrite_input(newcmd)
660
663
661 return newcmd
664 return newcmd
662
665
663
666
664 class EmacsHandler(PrefilterHandler):
667 class EmacsHandler(PrefilterHandler):
665
668
666 handler_name = Unicode('emacs')
669 handler_name = Unicode('emacs')
667 esc_strings = List([])
670 esc_strings = List([])
668
671
669 def handle(self, line_info):
672 def handle(self, line_info):
670 """Handle input lines marked by python-mode."""
673 """Handle input lines marked by python-mode."""
671
674
672 # Currently, nothing is done. Later more functionality can be added
675 # Currently, nothing is done. Later more functionality can be added
673 # here if needed.
676 # here if needed.
674
677
675 # The input cache shouldn't be updated
678 # The input cache shouldn't be updated
676 return line_info.line
679 return line_info.line
677
680
678
681
679 #-----------------------------------------------------------------------------
682 #-----------------------------------------------------------------------------
680 # Defaults
683 # Defaults
681 #-----------------------------------------------------------------------------
684 #-----------------------------------------------------------------------------
682
685
683
686
684 _default_checkers = [
687 _default_checkers = [
685 EmacsChecker,
688 EmacsChecker,
686 MacroChecker,
689 MacroChecker,
687 IPyAutocallChecker,
690 IPyAutocallChecker,
688 AssignmentChecker,
691 AssignmentChecker,
689 AutoMagicChecker,
692 AutoMagicChecker,
690 PythonOpsChecker,
693 PythonOpsChecker,
691 AutocallChecker
694 AutocallChecker
692 ]
695 ]
693
696
694 _default_handlers = [
697 _default_handlers = [
695 PrefilterHandler,
698 PrefilterHandler,
696 MacroHandler,
699 MacroHandler,
697 MagicHandler,
700 MagicHandler,
698 AutoHandler,
701 AutoHandler,
699 EmacsHandler
702 EmacsHandler
700 ]
703 ]
General Comments 0
You need to be logged in to leave comments. Login now