##// END OF EJS Templates
Neater naming...
Corentin Cadiou -
Show More
@@ -1,2254 +1,2252 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 `<tab>` to expand it to its latex form.
53 and press `<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 ``Completer.backslash_combining_completions`` option to ``False``.
62 ``Completer.backslash_combining_completions`` option to ``False``.
63
63
64
64
65 Experimental
65 Experimental
66 ============
66 ============
67
67
68 Starting with IPython 6.0, this module can make use of the Jedi library to
68 Starting with IPython 6.0, this module can make use of the Jedi library to
69 generate completions both using static analysis of the code, and dynamically
69 generate completions both using static analysis of the code, and dynamically
70 inspecting multiple namespaces. Jedi is an autocompletion and static analysis
70 inspecting multiple namespaces. Jedi is an autocompletion and static analysis
71 for Python. The APIs attached to this new mechanism is unstable and will
71 for Python. The APIs attached to this new mechanism is unstable and will
72 raise unless use in an :any:`provisionalcompleter` context manager.
72 raise unless use in an :any:`provisionalcompleter` context manager.
73
73
74 You will find that the following are experimental:
74 You will find that the following are experimental:
75
75
76 - :any:`provisionalcompleter`
76 - :any:`provisionalcompleter`
77 - :any:`IPCompleter.completions`
77 - :any:`IPCompleter.completions`
78 - :any:`Completion`
78 - :any:`Completion`
79 - :any:`rectify_completions`
79 - :any:`rectify_completions`
80
80
81 .. note::
81 .. note::
82
82
83 better name for :any:`rectify_completions` ?
83 better name for :any:`rectify_completions` ?
84
84
85 We welcome any feedback on these new API, and we also encourage you to try this
85 We welcome any feedback on these new API, and we also encourage you to try this
86 module in debug mode (start IPython with ``--Completer.debug=True``) in order
86 module in debug mode (start IPython with ``--Completer.debug=True``) in order
87 to have extra logging information if :any:`jedi` is crashing, or if current
87 to have extra logging information if :any:`jedi` is crashing, or if current
88 IPython completer pending deprecations are returning results not yet handled
88 IPython completer pending deprecations are returning results not yet handled
89 by :any:`jedi`
89 by :any:`jedi`
90
90
91 Using Jedi for tab completion allow snippets like the following to work without
91 Using Jedi for tab completion allow snippets like the following to work without
92 having to execute any code:
92 having to execute any code:
93
93
94 >>> myvar = ['hello', 42]
94 >>> myvar = ['hello', 42]
95 ... myvar[1].bi<tab>
95 ... myvar[1].bi<tab>
96
96
97 Tab completion will be able to infer that ``myvar[1]`` is a real number without
97 Tab completion will be able to infer that ``myvar[1]`` is a real number without
98 executing any code unlike the previously available ``IPCompleter.greedy``
98 executing any code unlike the previously available ``IPCompleter.greedy``
99 option.
99 option.
100
100
101 Be sure to update :any:`jedi` to the latest stable version or to try the
101 Be sure to update :any:`jedi` to the latest stable version or to try the
102 current development version to get better completions.
102 current development version to get better completions.
103 """
103 """
104
104
105
105
106 # Copyright (c) IPython Development Team.
106 # Copyright (c) IPython Development Team.
107 # Distributed under the terms of the Modified BSD License.
107 # Distributed under the terms of the Modified BSD License.
108 #
108 #
109 # Some of this code originated from rlcompleter in the Python standard library
109 # Some of this code originated from rlcompleter in the Python standard library
110 # Copyright (C) 2001 Python Software Foundation, www.python.org
110 # Copyright (C) 2001 Python Software Foundation, www.python.org
111
111
112
112
113 import builtins as builtin_mod
113 import builtins as builtin_mod
114 import glob
114 import glob
115 import inspect
115 import inspect
116 import itertools
116 import itertools
117 import keyword
117 import keyword
118 import os
118 import os
119 import re
119 import re
120 import string
120 import string
121 import sys
121 import sys
122 import time
122 import time
123 import unicodedata
123 import unicodedata
124 import uuid
124 import uuid
125 import warnings
125 import warnings
126 from contextlib import contextmanager
126 from contextlib import contextmanager
127 from importlib import import_module
127 from importlib import import_module
128 from types import SimpleNamespace
128 from types import SimpleNamespace
129 from typing import Iterable, Iterator, List, Tuple, Union, Any, Sequence, Dict, NamedTuple, Pattern, Optional
129 from typing import Iterable, Iterator, List, Tuple, Union, Any, Sequence, Dict, NamedTuple, Pattern, Optional
130
130
131 from IPython.core.error import TryNext
131 from IPython.core.error import TryNext
132 from IPython.core.inputtransformer2 import ESC_MAGIC
132 from IPython.core.inputtransformer2 import ESC_MAGIC
133 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
133 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
134 from IPython.core.oinspect import InspectColors
134 from IPython.core.oinspect import InspectColors
135 from IPython.utils import generics
135 from IPython.utils import generics
136 from IPython.utils.dir2 import dir2, get_real_method
136 from IPython.utils.dir2 import dir2, get_real_method
137 from IPython.utils.path import ensure_dir_exists
137 from IPython.utils.path import ensure_dir_exists
138 from IPython.utils.process import arg_split
138 from IPython.utils.process import arg_split
139 from traitlets import Bool, Enum, Int, List as ListTrait, Unicode, default, observe
139 from traitlets import Bool, Enum, Int, List as ListTrait, Unicode, default, observe
140 from traitlets.config.configurable import Configurable
140 from traitlets.config.configurable import Configurable
141
141
142 import __main__
142 import __main__
143
143
144 # skip module docstests
144 # skip module docstests
145 skip_doctest = True
145 skip_doctest = True
146
146
147 try:
147 try:
148 import jedi
148 import jedi
149 jedi.settings.case_insensitive_completion = False
149 jedi.settings.case_insensitive_completion = False
150 import jedi.api.helpers
150 import jedi.api.helpers
151 import jedi.api.classes
151 import jedi.api.classes
152 JEDI_INSTALLED = True
152 JEDI_INSTALLED = True
153 except ImportError:
153 except ImportError:
154 JEDI_INSTALLED = False
154 JEDI_INSTALLED = False
155 #-----------------------------------------------------------------------------
155 #-----------------------------------------------------------------------------
156 # Globals
156 # Globals
157 #-----------------------------------------------------------------------------
157 #-----------------------------------------------------------------------------
158
158
159 # ranges where we have most of the valid unicode names. We could be more finer
159 # ranges where we have most of the valid unicode names. We could be more finer
160 # grained but is it worth it for performace While unicode have character in the
160 # grained but is it worth it for performace While unicode have character in the
161 # rage 0, 0x110000, we seem to have name for about 10% of those. (131808 as I
161 # rage 0, 0x110000, we seem to have name for about 10% of those. (131808 as I
162 # write this). With below range we cover them all, with a density of ~67%
162 # write this). With below range we cover them all, with a density of ~67%
163 # biggest next gap we consider only adds up about 1% density and there are 600
163 # biggest next gap we consider only adds up about 1% density and there are 600
164 # gaps that would need hard coding.
164 # gaps that would need hard coding.
165 _UNICODE_RANGES = [(32, 0x3134b), (0xe0001, 0xe01f0)]
165 _UNICODE_RANGES = [(32, 0x3134b), (0xe0001, 0xe01f0)]
166
166
167 # Public API
167 # Public API
168 __all__ = ['Completer','IPCompleter']
168 __all__ = ['Completer','IPCompleter']
169
169
170 if sys.platform == 'win32':
170 if sys.platform == 'win32':
171 PROTECTABLES = ' '
171 PROTECTABLES = ' '
172 else:
172 else:
173 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
173 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
174
174
175 # Protect against returning an enormous number of completions which the frontend
175 # Protect against returning an enormous number of completions which the frontend
176 # may have trouble processing.
176 # may have trouble processing.
177 MATCHES_LIMIT = 500
177 MATCHES_LIMIT = 500
178
178
179 _deprecation_readline_sentinel = object()
179 _deprecation_readline_sentinel = object()
180
180
181
181
182 class ProvisionalCompleterWarning(FutureWarning):
182 class ProvisionalCompleterWarning(FutureWarning):
183 """
183 """
184 Exception raise by an experimental feature in this module.
184 Exception raise by an experimental feature in this module.
185
185
186 Wrap code in :any:`provisionalcompleter` context manager if you
186 Wrap code in :any:`provisionalcompleter` context manager if you
187 are certain you want to use an unstable feature.
187 are certain you want to use an unstable feature.
188 """
188 """
189 pass
189 pass
190
190
191 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
191 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
192
192
193 @contextmanager
193 @contextmanager
194 def provisionalcompleter(action='ignore'):
194 def provisionalcompleter(action='ignore'):
195 """
195 """
196
196
197
197
198 This context manager has to be used in any place where unstable completer
198 This context manager has to be used in any place where unstable completer
199 behavior and API may be called.
199 behavior and API may be called.
200
200
201 >>> with provisionalcompleter():
201 >>> with provisionalcompleter():
202 ... completer.do_experimental_things() # works
202 ... completer.do_experimental_things() # works
203
203
204 >>> completer.do_experimental_things() # raises.
204 >>> completer.do_experimental_things() # raises.
205
205
206 .. note:: Unstable
206 .. note:: Unstable
207
207
208 By using this context manager you agree that the API in use may change
208 By using this context manager you agree that the API in use may change
209 without warning, and that you won't complain if they do so.
209 without warning, and that you won't complain if they do so.
210
210
211 You also understand that, if the API is not to your liking, you should report
211 You also understand that, if the API is not to your liking, you should report
212 a bug to explain your use case upstream.
212 a bug to explain your use case upstream.
213
213
214 We'll be happy to get your feedback, feature requests, and improvements on
214 We'll be happy to get your feedback, feature requests, and improvements on
215 any of the unstable APIs!
215 any of the unstable APIs!
216 """
216 """
217 with warnings.catch_warnings():
217 with warnings.catch_warnings():
218 warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
218 warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
219 yield
219 yield
220
220
221
221
222 def has_open_quotes(s):
222 def has_open_quotes(s):
223 """Return whether a string has open quotes.
223 """Return whether a string has open quotes.
224
224
225 This simply counts whether the number of quote characters of either type in
225 This simply counts whether the number of quote characters of either type in
226 the string is odd.
226 the string is odd.
227
227
228 Returns
228 Returns
229 -------
229 -------
230 If there is an open quote, the quote character is returned. Else, return
230 If there is an open quote, the quote character is returned. Else, return
231 False.
231 False.
232 """
232 """
233 # We check " first, then ', so complex cases with nested quotes will get
233 # We check " first, then ', so complex cases with nested quotes will get
234 # the " to take precedence.
234 # the " to take precedence.
235 if s.count('"') % 2:
235 if s.count('"') % 2:
236 return '"'
236 return '"'
237 elif s.count("'") % 2:
237 elif s.count("'") % 2:
238 return "'"
238 return "'"
239 else:
239 else:
240 return False
240 return False
241
241
242
242
243 def protect_filename(s, protectables=PROTECTABLES):
243 def protect_filename(s, protectables=PROTECTABLES):
244 """Escape a string to protect certain characters."""
244 """Escape a string to protect certain characters."""
245 if set(s) & set(protectables):
245 if set(s) & set(protectables):
246 if sys.platform == "win32":
246 if sys.platform == "win32":
247 return '"' + s + '"'
247 return '"' + s + '"'
248 else:
248 else:
249 return "".join(("\\" + c if c in protectables else c) for c in s)
249 return "".join(("\\" + c if c in protectables else c) for c in s)
250 else:
250 else:
251 return s
251 return s
252
252
253
253
254 def expand_user(path:str) -> Tuple[str, bool, str]:
254 def expand_user(path:str) -> Tuple[str, bool, str]:
255 """Expand ``~``-style usernames in strings.
255 """Expand ``~``-style usernames in strings.
256
256
257 This is similar to :func:`os.path.expanduser`, but it computes and returns
257 This is similar to :func:`os.path.expanduser`, but it computes and returns
258 extra information that will be useful if the input was being used in
258 extra information that will be useful if the input was being used in
259 computing completions, and you wish to return the completions with the
259 computing completions, and you wish to return the completions with the
260 original '~' instead of its expanded value.
260 original '~' instead of its expanded value.
261
261
262 Parameters
262 Parameters
263 ----------
263 ----------
264 path : str
264 path : str
265 String to be expanded. If no ~ is present, the output is the same as the
265 String to be expanded. If no ~ is present, the output is the same as the
266 input.
266 input.
267
267
268 Returns
268 Returns
269 -------
269 -------
270 newpath : str
270 newpath : str
271 Result of ~ expansion in the input path.
271 Result of ~ expansion in the input path.
272 tilde_expand : bool
272 tilde_expand : bool
273 Whether any expansion was performed or not.
273 Whether any expansion was performed or not.
274 tilde_val : str
274 tilde_val : str
275 The value that ~ was replaced with.
275 The value that ~ was replaced with.
276 """
276 """
277 # Default values
277 # Default values
278 tilde_expand = False
278 tilde_expand = False
279 tilde_val = ''
279 tilde_val = ''
280 newpath = path
280 newpath = path
281
281
282 if path.startswith('~'):
282 if path.startswith('~'):
283 tilde_expand = True
283 tilde_expand = True
284 rest = len(path)-1
284 rest = len(path)-1
285 newpath = os.path.expanduser(path)
285 newpath = os.path.expanduser(path)
286 if rest:
286 if rest:
287 tilde_val = newpath[:-rest]
287 tilde_val = newpath[:-rest]
288 else:
288 else:
289 tilde_val = newpath
289 tilde_val = newpath
290
290
291 return newpath, tilde_expand, tilde_val
291 return newpath, tilde_expand, tilde_val
292
292
293
293
294 def compress_user(path:str, tilde_expand:bool, tilde_val:str) -> str:
294 def compress_user(path:str, tilde_expand:bool, tilde_val:str) -> str:
295 """Does the opposite of expand_user, with its outputs.
295 """Does the opposite of expand_user, with its outputs.
296 """
296 """
297 if tilde_expand:
297 if tilde_expand:
298 return path.replace(tilde_val, '~')
298 return path.replace(tilde_val, '~')
299 else:
299 else:
300 return path
300 return path
301
301
302
302
303 def completions_sorting_key(word):
303 def completions_sorting_key(word):
304 """key for sorting completions
304 """key for sorting completions
305
305
306 This does several things:
306 This does several things:
307
307
308 - Demote any completions starting with underscores to the end
308 - Demote any completions starting with underscores to the end
309 - Insert any %magic and %%cellmagic completions in the alphabetical order
309 - Insert any %magic and %%cellmagic completions in the alphabetical order
310 by their name
310 by their name
311 """
311 """
312 prio1, prio2 = 0, 0
312 prio1, prio2 = 0, 0
313
313
314 if word.startswith('__'):
314 if word.startswith('__'):
315 prio1 = 2
315 prio1 = 2
316 elif word.startswith('_'):
316 elif word.startswith('_'):
317 prio1 = 1
317 prio1 = 1
318
318
319 if word.endswith('='):
319 if word.endswith('='):
320 prio1 = -1
320 prio1 = -1
321
321
322 if word.startswith('%%'):
322 if word.startswith('%%'):
323 # If there's another % in there, this is something else, so leave it alone
323 # If there's another % in there, this is something else, so leave it alone
324 if not "%" in word[2:]:
324 if not "%" in word[2:]:
325 word = word[2:]
325 word = word[2:]
326 prio2 = 2
326 prio2 = 2
327 elif word.startswith('%'):
327 elif word.startswith('%'):
328 if not "%" in word[1:]:
328 if not "%" in word[1:]:
329 word = word[1:]
329 word = word[1:]
330 prio2 = 1
330 prio2 = 1
331
331
332 return prio1, word, prio2
332 return prio1, word, prio2
333
333
334
334
335 class _FakeJediCompletion:
335 class _FakeJediCompletion:
336 """
336 """
337 This is a workaround to communicate to the UI that Jedi has crashed and to
337 This is a workaround to communicate to the UI that Jedi has crashed and to
338 report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
338 report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
339
339
340 Added in IPython 6.0 so should likely be removed for 7.0
340 Added in IPython 6.0 so should likely be removed for 7.0
341
341
342 """
342 """
343
343
344 def __init__(self, name):
344 def __init__(self, name):
345
345
346 self.name = name
346 self.name = name
347 self.complete = name
347 self.complete = name
348 self.type = 'crashed'
348 self.type = 'crashed'
349 self.name_with_symbols = name
349 self.name_with_symbols = name
350 self.signature = ''
350 self.signature = ''
351 self._origin = 'fake'
351 self._origin = 'fake'
352
352
353 def __repr__(self):
353 def __repr__(self):
354 return '<Fake completion object jedi has crashed>'
354 return '<Fake completion object jedi has crashed>'
355
355
356
356
357 class Completion:
357 class Completion:
358 """
358 """
359 Completion object used and return by IPython completers.
359 Completion object used and return by IPython completers.
360
360
361 .. warning:: Unstable
361 .. warning:: Unstable
362
362
363 This function is unstable, API may change without warning.
363 This function is unstable, API may change without warning.
364 It will also raise unless use in proper context manager.
364 It will also raise unless use in proper context manager.
365
365
366 This act as a middle ground :any:`Completion` object between the
366 This act as a middle ground :any:`Completion` object between the
367 :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
367 :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
368 object. While Jedi need a lot of information about evaluator and how the
368 object. While Jedi need a lot of information about evaluator and how the
369 code should be ran/inspected, PromptToolkit (and other frontend) mostly
369 code should be ran/inspected, PromptToolkit (and other frontend) mostly
370 need user facing information.
370 need user facing information.
371
371
372 - Which range should be replaced replaced by what.
372 - Which range should be replaced replaced by what.
373 - Some metadata (like completion type), or meta information to displayed to
373 - Some metadata (like completion type), or meta information to displayed to
374 the use user.
374 the use user.
375
375
376 For debugging purpose we can also store the origin of the completion (``jedi``,
376 For debugging purpose we can also store the origin of the completion (``jedi``,
377 ``IPython.python_matches``, ``IPython.magics_matches``...).
377 ``IPython.python_matches``, ``IPython.magics_matches``...).
378 """
378 """
379
379
380 __slots__ = ['start', 'end', 'text', 'type', 'signature', '_origin']
380 __slots__ = ['start', 'end', 'text', 'type', 'signature', '_origin']
381
381
382 def __init__(self, start: int, end: int, text: str, *, type: str=None, _origin='', signature='') -> None:
382 def __init__(self, start: int, end: int, text: str, *, type: str=None, _origin='', signature='') -> None:
383 warnings.warn("``Completion`` is a provisional API (as of IPython 6.0). "
383 warnings.warn("``Completion`` is a provisional API (as of IPython 6.0). "
384 "It may change without warnings. "
384 "It may change without warnings. "
385 "Use in corresponding context manager.",
385 "Use in corresponding context manager.",
386 category=ProvisionalCompleterWarning, stacklevel=2)
386 category=ProvisionalCompleterWarning, stacklevel=2)
387
387
388 self.start = start
388 self.start = start
389 self.end = end
389 self.end = end
390 self.text = text
390 self.text = text
391 self.type = type
391 self.type = type
392 self.signature = signature
392 self.signature = signature
393 self._origin = _origin
393 self._origin = _origin
394
394
395 def __repr__(self):
395 def __repr__(self):
396 return '<Completion start=%s end=%s text=%r type=%r, signature=%r,>' % \
396 return '<Completion start=%s end=%s text=%r type=%r, signature=%r,>' % \
397 (self.start, self.end, self.text, self.type or '?', self.signature or '?')
397 (self.start, self.end, self.text, self.type or '?', self.signature or '?')
398
398
399 def __eq__(self, other)->Bool:
399 def __eq__(self, other)->Bool:
400 """
400 """
401 Equality and hash do not hash the type (as some completer may not be
401 Equality and hash do not hash the type (as some completer may not be
402 able to infer the type), but are use to (partially) de-duplicate
402 able to infer the type), but are use to (partially) de-duplicate
403 completion.
403 completion.
404
404
405 Completely de-duplicating completion is a bit tricker that just
405 Completely de-duplicating completion is a bit tricker that just
406 comparing as it depends on surrounding text, which Completions are not
406 comparing as it depends on surrounding text, which Completions are not
407 aware of.
407 aware of.
408 """
408 """
409 return self.start == other.start and \
409 return self.start == other.start and \
410 self.end == other.end and \
410 self.end == other.end and \
411 self.text == other.text
411 self.text == other.text
412
412
413 def __hash__(self):
413 def __hash__(self):
414 return hash((self.start, self.end, self.text))
414 return hash((self.start, self.end, self.text))
415
415
416
416
417 _IC = Iterable[Completion]
417 _IC = Iterable[Completion]
418
418
419
419
420 def _deduplicate_completions(text: str, completions: _IC)-> _IC:
420 def _deduplicate_completions(text: str, completions: _IC)-> _IC:
421 """
421 """
422 Deduplicate a set of completions.
422 Deduplicate a set of completions.
423
423
424 .. warning:: Unstable
424 .. warning:: Unstable
425
425
426 This function is unstable, API may change without warning.
426 This function is unstable, API may change without warning.
427
427
428 Parameters
428 Parameters
429 ----------
429 ----------
430 text: str
430 text: str
431 text that should be completed.
431 text that should be completed.
432 completions: Iterator[Completion]
432 completions: Iterator[Completion]
433 iterator over the completions to deduplicate
433 iterator over the completions to deduplicate
434
434
435 Yields
435 Yields
436 ------
436 ------
437 `Completions` objects
437 `Completions` objects
438
438
439
439
440 Completions coming from multiple sources, may be different but end up having
440 Completions coming from multiple sources, may be different but end up having
441 the same effect when applied to ``text``. If this is the case, this will
441 the same effect when applied to ``text``. If this is the case, this will
442 consider completions as equal and only emit the first encountered.
442 consider completions as equal and only emit the first encountered.
443
443
444 Not folded in `completions()` yet for debugging purpose, and to detect when
444 Not folded in `completions()` yet for debugging purpose, and to detect when
445 the IPython completer does return things that Jedi does not, but should be
445 the IPython completer does return things that Jedi does not, but should be
446 at some point.
446 at some point.
447 """
447 """
448 completions = list(completions)
448 completions = list(completions)
449 if not completions:
449 if not completions:
450 return
450 return
451
451
452 new_start = min(c.start for c in completions)
452 new_start = min(c.start for c in completions)
453 new_end = max(c.end for c in completions)
453 new_end = max(c.end for c in completions)
454
454
455 seen = set()
455 seen = set()
456 for c in completions:
456 for c in completions:
457 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
457 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
458 if new_text not in seen:
458 if new_text not in seen:
459 yield c
459 yield c
460 seen.add(new_text)
460 seen.add(new_text)
461
461
462
462
463 def rectify_completions(text: str, completions: _IC, *, _debug=False)->_IC:
463 def rectify_completions(text: str, completions: _IC, *, _debug=False)->_IC:
464 """
464 """
465 Rectify a set of completions to all have the same ``start`` and ``end``
465 Rectify a set of completions to all have the same ``start`` and ``end``
466
466
467 .. warning:: Unstable
467 .. warning:: Unstable
468
468
469 This function is unstable, API may change without warning.
469 This function is unstable, API may change without warning.
470 It will also raise unless use in proper context manager.
470 It will also raise unless use in proper context manager.
471
471
472 Parameters
472 Parameters
473 ----------
473 ----------
474 text: str
474 text: str
475 text that should be completed.
475 text that should be completed.
476 completions: Iterator[Completion]
476 completions: Iterator[Completion]
477 iterator over the completions to rectify
477 iterator over the completions to rectify
478
478
479
479
480 :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
480 :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
481 the Jupyter Protocol requires them to behave like so. This will readjust
481 the Jupyter Protocol requires them to behave like so. This will readjust
482 the completion to have the same ``start`` and ``end`` by padding both
482 the completion to have the same ``start`` and ``end`` by padding both
483 extremities with surrounding text.
483 extremities with surrounding text.
484
484
485 During stabilisation should support a ``_debug`` option to log which
485 During stabilisation should support a ``_debug`` option to log which
486 completion are return by the IPython completer and not found in Jedi in
486 completion are return by the IPython completer and not found in Jedi in
487 order to make upstream bug report.
487 order to make upstream bug report.
488 """
488 """
489 warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
489 warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
490 "It may change without warnings. "
490 "It may change without warnings. "
491 "Use in corresponding context manager.",
491 "Use in corresponding context manager.",
492 category=ProvisionalCompleterWarning, stacklevel=2)
492 category=ProvisionalCompleterWarning, stacklevel=2)
493
493
494 completions = list(completions)
494 completions = list(completions)
495 if not completions:
495 if not completions:
496 return
496 return
497 starts = (c.start for c in completions)
497 starts = (c.start for c in completions)
498 ends = (c.end for c in completions)
498 ends = (c.end for c in completions)
499
499
500 new_start = min(starts)
500 new_start = min(starts)
501 new_end = max(ends)
501 new_end = max(ends)
502
502
503 seen_jedi = set()
503 seen_jedi = set()
504 seen_python_matches = set()
504 seen_python_matches = set()
505 for c in completions:
505 for c in completions:
506 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
506 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
507 if c._origin == 'jedi':
507 if c._origin == 'jedi':
508 seen_jedi.add(new_text)
508 seen_jedi.add(new_text)
509 elif c._origin == 'IPCompleter.python_matches':
509 elif c._origin == 'IPCompleter.python_matches':
510 seen_python_matches.add(new_text)
510 seen_python_matches.add(new_text)
511 yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin, signature=c.signature)
511 yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin, signature=c.signature)
512 diff = seen_python_matches.difference(seen_jedi)
512 diff = seen_python_matches.difference(seen_jedi)
513 if diff and _debug:
513 if diff and _debug:
514 print('IPython.python matches have extras:', diff)
514 print('IPython.python matches have extras:', diff)
515
515
516
516
517 if sys.platform == 'win32':
517 if sys.platform == 'win32':
518 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
518 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
519 else:
519 else:
520 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
520 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
521
521
522 GREEDY_DELIMS = ' =\r\n'
522 GREEDY_DELIMS = ' =\r\n'
523
523
524
524
525 class CompletionSplitter(object):
525 class CompletionSplitter(object):
526 """An object to split an input line in a manner similar to readline.
526 """An object to split an input line in a manner similar to readline.
527
527
528 By having our own implementation, we can expose readline-like completion in
528 By having our own implementation, we can expose readline-like completion in
529 a uniform manner to all frontends. This object only needs to be given the
529 a uniform manner to all frontends. This object only needs to be given the
530 line of text to be split and the cursor position on said line, and it
530 line of text to be split and the cursor position on said line, and it
531 returns the 'word' to be completed on at the cursor after splitting the
531 returns the 'word' to be completed on at the cursor after splitting the
532 entire line.
532 entire line.
533
533
534 What characters are used as splitting delimiters can be controlled by
534 What characters are used as splitting delimiters can be controlled by
535 setting the ``delims`` attribute (this is a property that internally
535 setting the ``delims`` attribute (this is a property that internally
536 automatically builds the necessary regular expression)"""
536 automatically builds the necessary regular expression)"""
537
537
538 # Private interface
538 # Private interface
539
539
540 # A string of delimiter characters. The default value makes sense for
540 # A string of delimiter characters. The default value makes sense for
541 # IPython's most typical usage patterns.
541 # IPython's most typical usage patterns.
542 _delims = DELIMS
542 _delims = DELIMS
543
543
544 # The expression (a normal string) to be compiled into a regular expression
544 # The expression (a normal string) to be compiled into a regular expression
545 # for actual splitting. We store it as an attribute mostly for ease of
545 # for actual splitting. We store it as an attribute mostly for ease of
546 # debugging, since this type of code can be so tricky to debug.
546 # debugging, since this type of code can be so tricky to debug.
547 _delim_expr = None
547 _delim_expr = None
548
548
549 # The regular expression that does the actual splitting
549 # The regular expression that does the actual splitting
550 _delim_re = None
550 _delim_re = None
551
551
552 def __init__(self, delims=None):
552 def __init__(self, delims=None):
553 delims = CompletionSplitter._delims if delims is None else delims
553 delims = CompletionSplitter._delims if delims is None else delims
554 self.delims = delims
554 self.delims = delims
555
555
556 @property
556 @property
557 def delims(self):
557 def delims(self):
558 """Return the string of delimiter characters."""
558 """Return the string of delimiter characters."""
559 return self._delims
559 return self._delims
560
560
561 @delims.setter
561 @delims.setter
562 def delims(self, delims):
562 def delims(self, delims):
563 """Set the delimiters for line splitting."""
563 """Set the delimiters for line splitting."""
564 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
564 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
565 self._delim_re = re.compile(expr)
565 self._delim_re = re.compile(expr)
566 self._delims = delims
566 self._delims = delims
567 self._delim_expr = expr
567 self._delim_expr = expr
568
568
569 def split_line(self, line, cursor_pos=None):
569 def split_line(self, line, cursor_pos=None):
570 """Split a line of text with a cursor at the given position.
570 """Split a line of text with a cursor at the given position.
571 """
571 """
572 l = line if cursor_pos is None else line[:cursor_pos]
572 l = line if cursor_pos is None else line[:cursor_pos]
573 return self._delim_re.split(l)[-1]
573 return self._delim_re.split(l)[-1]
574
574
575
575
576
576
577 class Completer(Configurable):
577 class Completer(Configurable):
578
578
579 greedy = Bool(False,
579 greedy = Bool(False,
580 help="""Activate greedy completion
580 help="""Activate greedy completion
581 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
581 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
582
582
583 This will enable completion on elements of lists, results of function calls, etc.,
583 This will enable completion on elements of lists, results of function calls, etc.,
584 but can be unsafe because the code is actually evaluated on TAB.
584 but can be unsafe because the code is actually evaluated on TAB.
585 """
585 """
586 ).tag(config=True)
586 ).tag(config=True)
587
587
588 use_jedi = Bool(default_value=JEDI_INSTALLED,
588 use_jedi = Bool(default_value=JEDI_INSTALLED,
589 help="Experimental: Use Jedi to generate autocompletions. "
589 help="Experimental: Use Jedi to generate autocompletions. "
590 "Default to True if jedi is installed.").tag(config=True)
590 "Default to True if jedi is installed.").tag(config=True)
591
591
592 jedi_compute_type_timeout = Int(default_value=400,
592 jedi_compute_type_timeout = Int(default_value=400,
593 help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types.
593 help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types.
594 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
594 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
595 performance by preventing jedi to build its cache.
595 performance by preventing jedi to build its cache.
596 """).tag(config=True)
596 """).tag(config=True)
597
597
598 debug = Bool(default_value=False,
598 debug = Bool(default_value=False,
599 help='Enable debug for the Completer. Mostly print extra '
599 help='Enable debug for the Completer. Mostly print extra '
600 'information for experimental jedi integration.')\
600 'information for experimental jedi integration.')\
601 .tag(config=True)
601 .tag(config=True)
602
602
603 backslash_combining_completions = Bool(True,
603 backslash_combining_completions = Bool(True,
604 help="Enable unicode completions, e.g. \\alpha<tab> . "
604 help="Enable unicode completions, e.g. \\alpha<tab> . "
605 "Includes completion of latex commands, unicode names, and expanding "
605 "Includes completion of latex commands, unicode names, and expanding "
606 "unicode characters back to latex commands.").tag(config=True)
606 "unicode characters back to latex commands.").tag(config=True)
607
607
608
608
609
609
610 def __init__(self, namespace=None, global_namespace=None, **kwargs):
610 def __init__(self, namespace=None, global_namespace=None, **kwargs):
611 """Create a new completer for the command line.
611 """Create a new completer for the command line.
612
612
613 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
613 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
614
614
615 If unspecified, the default namespace where completions are performed
615 If unspecified, the default namespace where completions are performed
616 is __main__ (technically, __main__.__dict__). Namespaces should be
616 is __main__ (technically, __main__.__dict__). Namespaces should be
617 given as dictionaries.
617 given as dictionaries.
618
618
619 An optional second namespace can be given. This allows the completer
619 An optional second namespace can be given. This allows the completer
620 to handle cases where both the local and global scopes need to be
620 to handle cases where both the local and global scopes need to be
621 distinguished.
621 distinguished.
622 """
622 """
623
623
624 # Don't bind to namespace quite yet, but flag whether the user wants a
624 # Don't bind to namespace quite yet, but flag whether the user wants a
625 # specific namespace or to use __main__.__dict__. This will allow us
625 # specific namespace or to use __main__.__dict__. This will allow us
626 # to bind to __main__.__dict__ at completion time, not now.
626 # to bind to __main__.__dict__ at completion time, not now.
627 if namespace is None:
627 if namespace is None:
628 self.use_main_ns = True
628 self.use_main_ns = True
629 else:
629 else:
630 self.use_main_ns = False
630 self.use_main_ns = False
631 self.namespace = namespace
631 self.namespace = namespace
632
632
633 # The global namespace, if given, can be bound directly
633 # The global namespace, if given, can be bound directly
634 if global_namespace is None:
634 if global_namespace is None:
635 self.global_namespace = {}
635 self.global_namespace = {}
636 else:
636 else:
637 self.global_namespace = global_namespace
637 self.global_namespace = global_namespace
638
638
639 self.custom_matchers = []
639 self.custom_matchers = []
640
640
641 super(Completer, self).__init__(**kwargs)
641 super(Completer, self).__init__(**kwargs)
642
642
643 def complete(self, text, state):
643 def complete(self, text, state):
644 """Return the next possible completion for 'text'.
644 """Return the next possible completion for 'text'.
645
645
646 This is called successively with state == 0, 1, 2, ... until it
646 This is called successively with state == 0, 1, 2, ... until it
647 returns None. The completion should begin with 'text'.
647 returns None. The completion should begin with 'text'.
648
648
649 """
649 """
650 if self.use_main_ns:
650 if self.use_main_ns:
651 self.namespace = __main__.__dict__
651 self.namespace = __main__.__dict__
652
652
653 if state == 0:
653 if state == 0:
654 if "." in text:
654 if "." in text:
655 self.matches = self.attr_matches(text)
655 self.matches = self.attr_matches(text)
656 else:
656 else:
657 self.matches = self.global_matches(text)
657 self.matches = self.global_matches(text)
658 try:
658 try:
659 return self.matches[state]
659 return self.matches[state]
660 except IndexError:
660 except IndexError:
661 return None
661 return None
662
662
663 def global_matches(self, text):
663 def global_matches(self, text):
664 """Compute matches when text is a simple name.
664 """Compute matches when text is a simple name.
665
665
666 Return a list of all keywords, built-in functions and names currently
666 Return a list of all keywords, built-in functions and names currently
667 defined in self.namespace or self.global_namespace that match.
667 defined in self.namespace or self.global_namespace that match.
668
668
669 """
669 """
670 matches = []
670 matches = []
671 match_append = matches.append
671 match_append = matches.append
672 n = len(text)
672 n = len(text)
673 for lst in [keyword.kwlist,
673 for lst in [keyword.kwlist,
674 builtin_mod.__dict__.keys(),
674 builtin_mod.__dict__.keys(),
675 self.namespace.keys(),
675 self.namespace.keys(),
676 self.global_namespace.keys()]:
676 self.global_namespace.keys()]:
677 for word in lst:
677 for word in lst:
678 if word[:n] == text and word != "__builtins__":
678 if word[:n] == text and word != "__builtins__":
679 match_append(word)
679 match_append(word)
680
680
681 snake_case_re = re.compile(r"[^_]+(_[^_]+)+?\Z")
681 snake_case_re = re.compile(r"[^_]+(_[^_]+)+?\Z")
682 for lst in [self.namespace.keys(),
682 for lst in [self.namespace.keys(),
683 self.global_namespace.keys()]:
683 self.global_namespace.keys()]:
684 shortened = {"_".join([sub[0] for sub in word.split('_')]) : word
684 shortened = {"_".join([sub[0] for sub in word.split('_')]) : word
685 for word in lst if snake_case_re.match(word)}
685 for word in lst if snake_case_re.match(word)}
686 for word in shortened.keys():
686 for word in shortened.keys():
687 if word[:n] == text and word != "__builtins__":
687 if word[:n] == text and word != "__builtins__":
688 match_append(shortened[word])
688 match_append(shortened[word])
689 return matches
689 return matches
690
690
691 def attr_matches(self, text):
691 def attr_matches(self, text):
692 """Compute matches when text contains a dot.
692 """Compute matches when text contains a dot.
693
693
694 Assuming the text is of the form NAME.NAME....[NAME], and is
694 Assuming the text is of the form NAME.NAME....[NAME], and is
695 evaluatable in self.namespace or self.global_namespace, it will be
695 evaluatable in self.namespace or self.global_namespace, it will be
696 evaluated and its attributes (as revealed by dir()) are used as
696 evaluated and its attributes (as revealed by dir()) are used as
697 possible completions. (For class instances, class members are
697 possible completions. (For class instances, class members are
698 also considered.)
698 also considered.)
699
699
700 WARNING: this can still invoke arbitrary C code, if an object
700 WARNING: this can still invoke arbitrary C code, if an object
701 with a __getattr__ hook is evaluated.
701 with a __getattr__ hook is evaluated.
702
702
703 """
703 """
704
704
705 # Another option, seems to work great. Catches things like ''.<tab>
705 # Another option, seems to work great. Catches things like ''.<tab>
706 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
706 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
707
707
708 if m:
708 if m:
709 expr, attr = m.group(1, 3)
709 expr, attr = m.group(1, 3)
710 elif self.greedy:
710 elif self.greedy:
711 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
711 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
712 if not m2:
712 if not m2:
713 return []
713 return []
714 expr, attr = m2.group(1,2)
714 expr, attr = m2.group(1,2)
715 else:
715 else:
716 return []
716 return []
717
717
718 try:
718 try:
719 obj = eval(expr, self.namespace)
719 obj = eval(expr, self.namespace)
720 except:
720 except:
721 try:
721 try:
722 obj = eval(expr, self.global_namespace)
722 obj = eval(expr, self.global_namespace)
723 except:
723 except:
724 return []
724 return []
725
725
726 if self.limit_to__all__ and hasattr(obj, '__all__'):
726 if self.limit_to__all__ and hasattr(obj, '__all__'):
727 words = get__all__entries(obj)
727 words = get__all__entries(obj)
728 else:
728 else:
729 words = dir2(obj)
729 words = dir2(obj)
730
730
731 try:
731 try:
732 words = generics.complete_object(obj, words)
732 words = generics.complete_object(obj, words)
733 except TryNext:
733 except TryNext:
734 pass
734 pass
735 except AssertionError:
735 except AssertionError:
736 raise
736 raise
737 except Exception:
737 except Exception:
738 # Silence errors from completion function
738 # Silence errors from completion function
739 #raise # dbg
739 #raise # dbg
740 pass
740 pass
741 # Build match list to return
741 # Build match list to return
742 n = len(attr)
742 n = len(attr)
743 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
743 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
744
744
745
745
746 def get__all__entries(obj):
746 def get__all__entries(obj):
747 """returns the strings in the __all__ attribute"""
747 """returns the strings in the __all__ attribute"""
748 try:
748 try:
749 words = getattr(obj, '__all__')
749 words = getattr(obj, '__all__')
750 except:
750 except:
751 return []
751 return []
752
752
753 return [w for w in words if isinstance(w, str)]
753 return [w for w in words if isinstance(w, str)]
754
754
755
755
756 def match_dict_keys(keys: List[Union[str, bytes, Tuple[Union[str, bytes]]]], prefix: str, delims: str,
756 def match_dict_keys(keys: List[Union[str, bytes, Tuple[Union[str, bytes]]]], prefix: str, delims: str,
757 prefix_tuple: Tuple[str, bytes]=()) -> Tuple[str, int, List[str]]:
757 extra_prefix: Optional[Tuple[str, bytes]]=None) -> Tuple[str, int, List[str]]:
758 """Used by dict_key_matches, matching the prefix to a list of keys
758 """Used by dict_key_matches, matching the prefix to a list of keys
759
759
760 Parameters
760 Parameters
761 ==========
761 ==========
762 keys:
762 keys:
763 list of keys in dictionary currently being completed.
763 list of keys in dictionary currently being completed.
764 prefix:
764 prefix:
765 Part of the text already typed by the user. E.g. `mydict[b'fo`
765 Part of the text already typed by the user. E.g. `mydict[b'fo`
766 delims:
766 delims:
767 String of delimiters to consider when finding the current key.
767 String of delimiters to consider when finding the current key.
768 prefix_tuple: optional
768 extra_prefix: optional
769 Part of the text already typed in multi-key index cases. E.g. for
769 Part of the text already typed in multi-key index cases. E.g. for
770 `mydict['foo', "bar", 'b`, this would be `('foo', 'bar')`.
770 `mydict['foo', "bar", 'b`, this would be `('foo', 'bar')`.
771
771
772 Returns
772 Returns
773 =======
773 =======
774
774
775 A tuple of three elements: ``quote``, ``token_start``, ``matched``, with
775 A tuple of three elements: ``quote``, ``token_start``, ``matched``, with
776 ``quote`` being the quote that need to be used to close current string.
776 ``quote`` being the quote that need to be used to close current string.
777 ``token_start`` the position where the replacement should start occurring,
777 ``token_start`` the position where the replacement should start occurring,
778 ``matches`` a list of replacement/completion
778 ``matches`` a list of replacement/completion
779
779
780 """
780 """
781 prefix_tuple = extra_prefix if extra_prefix else ()
781 Nprefix = len(prefix_tuple)
782 Nprefix = len(prefix_tuple)
782 def filter_by_prefix_tuple(key):
783 def filter_by_prefix_tuple(key):
783 if len(key) < Nprefix:
784 if len(key) < Nprefix:
784 return False
785 return False
785 for k, pt in zip(key, prefix_tuple):
786 for k, pt in zip(key, prefix_tuple):
786 if k != pt:
787 if k != pt:
787 return False
788 return False
788 return True
789 return True
789
790
790 new_keys = []
791 new_keys = []
791 for k in keys:
792 for k in keys:
792 if isinstance(k, (str, bytes)):
793 if isinstance(k, (str, bytes)):
793 new_keys.append(k)
794 new_keys.append(k)
794 elif isinstance(k, tuple) and filter_by_prefix_tuple(k):
795 elif isinstance(k, tuple) and filter_by_prefix_tuple(k):
795 new_keys.append(k[Nprefix])
796 new_keys.append(k[Nprefix])
796
797
797 keys = new_keys
798 keys = new_keys
798 if not prefix:
799 if not prefix:
799 return '', 0, [repr(k) for k in keys
800 return '', 0, [repr(k) for k in keys
800 if isinstance(k, (str, bytes))]
801 if isinstance(k, (str, bytes))]
801 quote_match = re.search('["\']', prefix)
802 quote_match = re.search('["\']', prefix)
802 assert quote_match is not None # silence mypy
803 assert quote_match is not None # silence mypy
803 quote = quote_match.group()
804 quote = quote_match.group()
804 try:
805 try:
805 prefix_str = eval(prefix + quote, {})
806 prefix_str = eval(prefix + quote, {})
806 except Exception:
807 except Exception:
807 return '', 0, []
808 return '', 0, []
808
809
809 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
810 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
810 token_match = re.search(pattern, prefix, re.UNICODE)
811 token_match = re.search(pattern, prefix, re.UNICODE)
811 assert token_match is not None # silence mypy
812 assert token_match is not None # silence mypy
812 token_start = token_match.start()
813 token_start = token_match.start()
813 token_prefix = token_match.group()
814 token_prefix = token_match.group()
814
815
815 matched:List[str] = []
816 matched:List[str] = []
816 for key in keys:
817 for key in keys:
817 try:
818 try:
818 if not key.startswith(prefix_str):
819 if not key.startswith(prefix_str):
819 continue
820 continue
820 except (AttributeError, TypeError, UnicodeError):
821 except (AttributeError, TypeError, UnicodeError):
821 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
822 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
822 continue
823 continue
823
824
824 # reformat remainder of key to begin with prefix
825 # reformat remainder of key to begin with prefix
825 rem = key[len(prefix_str):]
826 rem = key[len(prefix_str):]
826 # force repr wrapped in '
827 # force repr wrapped in '
827 rem_repr = repr(rem + '"') if isinstance(rem, str) else repr(rem + b'"')
828 rem_repr = repr(rem + '"') if isinstance(rem, str) else repr(rem + b'"')
828 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
829 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
829 if quote == '"':
830 if quote == '"':
830 # The entered prefix is quoted with ",
831 # The entered prefix is quoted with ",
831 # but the match is quoted with '.
832 # but the match is quoted with '.
832 # A contained " hence needs escaping for comparison:
833 # A contained " hence needs escaping for comparison:
833 rem_repr = rem_repr.replace('"', '\\"')
834 rem_repr = rem_repr.replace('"', '\\"')
834
835
835 # then reinsert prefix from start of token
836 # then reinsert prefix from start of token
836 matched.append('%s%s' % (token_prefix, rem_repr))
837 matched.append('%s%s' % (token_prefix, rem_repr))
837 return quote, token_start, matched
838 return quote, token_start, matched
838
839
839
840
840 def cursor_to_position(text:str, line:int, column:int)->int:
841 def cursor_to_position(text:str, line:int, column:int)->int:
841 """
842 """
842
843
843 Convert the (line,column) position of the cursor in text to an offset in a
844 Convert the (line,column) position of the cursor in text to an offset in a
844 string.
845 string.
845
846
846 Parameters
847 Parameters
847 ----------
848 ----------
848
849
849 text : str
850 text : str
850 The text in which to calculate the cursor offset
851 The text in which to calculate the cursor offset
851 line : int
852 line : int
852 Line of the cursor; 0-indexed
853 Line of the cursor; 0-indexed
853 column : int
854 column : int
854 Column of the cursor 0-indexed
855 Column of the cursor 0-indexed
855
856
856 Return
857 Return
857 ------
858 ------
858 Position of the cursor in ``text``, 0-indexed.
859 Position of the cursor in ``text``, 0-indexed.
859
860
860 See Also
861 See Also
861 --------
862 --------
862 position_to_cursor: reciprocal of this function
863 position_to_cursor: reciprocal of this function
863
864
864 """
865 """
865 lines = text.split('\n')
866 lines = text.split('\n')
866 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
867 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
867
868
868 return sum(len(l) + 1 for l in lines[:line]) + column
869 return sum(len(l) + 1 for l in lines[:line]) + column
869
870
870 def position_to_cursor(text:str, offset:int)->Tuple[int, int]:
871 def position_to_cursor(text:str, offset:int)->Tuple[int, int]:
871 """
872 """
872 Convert the position of the cursor in text (0 indexed) to a line
873 Convert the position of the cursor in text (0 indexed) to a line
873 number(0-indexed) and a column number (0-indexed) pair
874 number(0-indexed) and a column number (0-indexed) pair
874
875
875 Position should be a valid position in ``text``.
876 Position should be a valid position in ``text``.
876
877
877 Parameters
878 Parameters
878 ----------
879 ----------
879
880
880 text : str
881 text : str
881 The text in which to calculate the cursor offset
882 The text in which to calculate the cursor offset
882 offset : int
883 offset : int
883 Position of the cursor in ``text``, 0-indexed.
884 Position of the cursor in ``text``, 0-indexed.
884
885
885 Return
886 Return
886 ------
887 ------
887 (line, column) : (int, int)
888 (line, column) : (int, int)
888 Line of the cursor; 0-indexed, column of the cursor 0-indexed
889 Line of the cursor; 0-indexed, column of the cursor 0-indexed
889
890
890
891
891 See Also
892 See Also
892 --------
893 --------
893 cursor_to_position : reciprocal of this function
894 cursor_to_position : reciprocal of this function
894
895
895
896
896 """
897 """
897
898
898 assert 0 <= offset <= len(text) , "0 <= %s <= %s" % (offset , len(text))
899 assert 0 <= offset <= len(text) , "0 <= %s <= %s" % (offset , len(text))
899
900
900 before = text[:offset]
901 before = text[:offset]
901 blines = before.split('\n') # ! splitnes trim trailing \n
902 blines = before.split('\n') # ! splitnes trim trailing \n
902 line = before.count('\n')
903 line = before.count('\n')
903 col = len(blines[-1])
904 col = len(blines[-1])
904 return line, col
905 return line, col
905
906
906
907
907 def _safe_isinstance(obj, module, class_name):
908 def _safe_isinstance(obj, module, class_name):
908 """Checks if obj is an instance of module.class_name if loaded
909 """Checks if obj is an instance of module.class_name if loaded
909 """
910 """
910 return (module in sys.modules and
911 return (module in sys.modules and
911 isinstance(obj, getattr(import_module(module), class_name)))
912 isinstance(obj, getattr(import_module(module), class_name)))
912
913
913 def back_unicode_name_matches(text:str) -> Tuple[str, Sequence[str]]:
914 def back_unicode_name_matches(text:str) -> Tuple[str, Sequence[str]]:
914 """Match Unicode characters back to Unicode name
915 """Match Unicode characters back to Unicode name
915
916
916 This does ``β˜ƒ`` -> ``\\snowman``
917 This does ``β˜ƒ`` -> ``\\snowman``
917
918
918 Note that snowman is not a valid python3 combining character but will be expanded.
919 Note that snowman is not a valid python3 combining character but will be expanded.
919 Though it will not recombine back to the snowman character by the completion machinery.
920 Though it will not recombine back to the snowman character by the completion machinery.
920
921
921 This will not either back-complete standard sequences like \\n, \\b ...
922 This will not either back-complete standard sequences like \\n, \\b ...
922
923
923 Returns
924 Returns
924 =======
925 =======
925
926
926 Return a tuple with two elements:
927 Return a tuple with two elements:
927
928
928 - The Unicode character that was matched (preceded with a backslash), or
929 - The Unicode character that was matched (preceded with a backslash), or
929 empty string,
930 empty string,
930 - a sequence (of 1), name for the match Unicode character, preceded by
931 - a sequence (of 1), name for the match Unicode character, preceded by
931 backslash, or empty if no match.
932 backslash, or empty if no match.
932
933
933 """
934 """
934 if len(text)<2:
935 if len(text)<2:
935 return '', ()
936 return '', ()
936 maybe_slash = text[-2]
937 maybe_slash = text[-2]
937 if maybe_slash != '\\':
938 if maybe_slash != '\\':
938 return '', ()
939 return '', ()
939
940
940 char = text[-1]
941 char = text[-1]
941 # no expand on quote for completion in strings.
942 # no expand on quote for completion in strings.
942 # nor backcomplete standard ascii keys
943 # nor backcomplete standard ascii keys
943 if char in string.ascii_letters or char in ('"',"'"):
944 if char in string.ascii_letters or char in ('"',"'"):
944 return '', ()
945 return '', ()
945 try :
946 try :
946 unic = unicodedata.name(char)
947 unic = unicodedata.name(char)
947 return '\\'+char,('\\'+unic,)
948 return '\\'+char,('\\'+unic,)
948 except KeyError:
949 except KeyError:
949 pass
950 pass
950 return '', ()
951 return '', ()
951
952
952 def back_latex_name_matches(text:str) -> Tuple[str, Sequence[str]] :
953 def back_latex_name_matches(text:str) -> Tuple[str, Sequence[str]] :
953 """Match latex characters back to unicode name
954 """Match latex characters back to unicode name
954
955
955 This does ``\\β„΅`` -> ``\\aleph``
956 This does ``\\β„΅`` -> ``\\aleph``
956
957
957 """
958 """
958 if len(text)<2:
959 if len(text)<2:
959 return '', ()
960 return '', ()
960 maybe_slash = text[-2]
961 maybe_slash = text[-2]
961 if maybe_slash != '\\':
962 if maybe_slash != '\\':
962 return '', ()
963 return '', ()
963
964
964
965
965 char = text[-1]
966 char = text[-1]
966 # no expand on quote for completion in strings.
967 # no expand on quote for completion in strings.
967 # nor backcomplete standard ascii keys
968 # nor backcomplete standard ascii keys
968 if char in string.ascii_letters or char in ('"',"'"):
969 if char in string.ascii_letters or char in ('"',"'"):
969 return '', ()
970 return '', ()
970 try :
971 try :
971 latex = reverse_latex_symbol[char]
972 latex = reverse_latex_symbol[char]
972 # '\\' replace the \ as well
973 # '\\' replace the \ as well
973 return '\\'+char,[latex]
974 return '\\'+char,[latex]
974 except KeyError:
975 except KeyError:
975 pass
976 pass
976 return '', ()
977 return '', ()
977
978
978
979
979 def _formatparamchildren(parameter) -> str:
980 def _formatparamchildren(parameter) -> str:
980 """
981 """
981 Get parameter name and value from Jedi Private API
982 Get parameter name and value from Jedi Private API
982
983
983 Jedi does not expose a simple way to get `param=value` from its API.
984 Jedi does not expose a simple way to get `param=value` from its API.
984
985
985 Parameter
986 Parameter
986 =========
987 =========
987
988
988 parameter:
989 parameter:
989 Jedi's function `Param`
990 Jedi's function `Param`
990
991
991 Returns
992 Returns
992 =======
993 =======
993
994
994 A string like 'a', 'b=1', '*args', '**kwargs'
995 A string like 'a', 'b=1', '*args', '**kwargs'
995
996
996
997
997 """
998 """
998 description = parameter.description
999 description = parameter.description
999 if not description.startswith('param '):
1000 if not description.startswith('param '):
1000 raise ValueError('Jedi function parameter description have change format.'
1001 raise ValueError('Jedi function parameter description have change format.'
1001 'Expected "param ...", found %r".' % description)
1002 'Expected "param ...", found %r".' % description)
1002 return description[6:]
1003 return description[6:]
1003
1004
1004 def _make_signature(completion)-> str:
1005 def _make_signature(completion)-> str:
1005 """
1006 """
1006 Make the signature from a jedi completion
1007 Make the signature from a jedi completion
1007
1008
1008 Parameter
1009 Parameter
1009 =========
1010 =========
1010
1011
1011 completion: jedi.Completion
1012 completion: jedi.Completion
1012 object does not complete a function type
1013 object does not complete a function type
1013
1014
1014 Returns
1015 Returns
1015 =======
1016 =======
1016
1017
1017 a string consisting of the function signature, with the parenthesis but
1018 a string consisting of the function signature, with the parenthesis but
1018 without the function name. example:
1019 without the function name. example:
1019 `(a, *args, b=1, **kwargs)`
1020 `(a, *args, b=1, **kwargs)`
1020
1021
1021 """
1022 """
1022
1023
1023 # it looks like this might work on jedi 0.17
1024 # it looks like this might work on jedi 0.17
1024 if hasattr(completion, 'get_signatures'):
1025 if hasattr(completion, 'get_signatures'):
1025 signatures = completion.get_signatures()
1026 signatures = completion.get_signatures()
1026 if not signatures:
1027 if not signatures:
1027 return '(?)'
1028 return '(?)'
1028
1029
1029 c0 = completion.get_signatures()[0]
1030 c0 = completion.get_signatures()[0]
1030 return '('+c0.to_string().split('(', maxsplit=1)[1]
1031 return '('+c0.to_string().split('(', maxsplit=1)[1]
1031
1032
1032 return '(%s)'% ', '.join([f for f in (_formatparamchildren(p) for signature in completion.get_signatures()
1033 return '(%s)'% ', '.join([f for f in (_formatparamchildren(p) for signature in completion.get_signatures()
1033 for p in signature.defined_names()) if f])
1034 for p in signature.defined_names()) if f])
1034
1035
1035
1036
1036 class _CompleteResult(NamedTuple):
1037 class _CompleteResult(NamedTuple):
1037 matched_text : str
1038 matched_text : str
1038 matches: Sequence[str]
1039 matches: Sequence[str]
1039 matches_origin: Sequence[str]
1040 matches_origin: Sequence[str]
1040 jedi_matches: Any
1041 jedi_matches: Any
1041
1042
1042
1043
1043 class IPCompleter(Completer):
1044 class IPCompleter(Completer):
1044 """Extension of the completer class with IPython-specific features"""
1045 """Extension of the completer class with IPython-specific features"""
1045
1046
1046 __dict_key_regexps: Optional[Dict[bool,Pattern]] = None
1047 __dict_key_regexps: Optional[Dict[bool,Pattern]] = None
1047
1048
1048 @observe('greedy')
1049 @observe('greedy')
1049 def _greedy_changed(self, change):
1050 def _greedy_changed(self, change):
1050 """update the splitter and readline delims when greedy is changed"""
1051 """update the splitter and readline delims when greedy is changed"""
1051 if change['new']:
1052 if change['new']:
1052 self.splitter.delims = GREEDY_DELIMS
1053 self.splitter.delims = GREEDY_DELIMS
1053 else:
1054 else:
1054 self.splitter.delims = DELIMS
1055 self.splitter.delims = DELIMS
1055
1056
1056 dict_keys_only = Bool(False,
1057 dict_keys_only = Bool(False,
1057 help="""Whether to show dict key matches only""")
1058 help="""Whether to show dict key matches only""")
1058
1059
1059 merge_completions = Bool(True,
1060 merge_completions = Bool(True,
1060 help="""Whether to merge completion results into a single list
1061 help="""Whether to merge completion results into a single list
1061
1062
1062 If False, only the completion results from the first non-empty
1063 If False, only the completion results from the first non-empty
1063 completer will be returned.
1064 completer will be returned.
1064 """
1065 """
1065 ).tag(config=True)
1066 ).tag(config=True)
1066 omit__names = Enum((0,1,2), default_value=2,
1067 omit__names = Enum((0,1,2), default_value=2,
1067 help="""Instruct the completer to omit private method names
1068 help="""Instruct the completer to omit private method names
1068
1069
1069 Specifically, when completing on ``object.<tab>``.
1070 Specifically, when completing on ``object.<tab>``.
1070
1071
1071 When 2 [default]: all names that start with '_' will be excluded.
1072 When 2 [default]: all names that start with '_' will be excluded.
1072
1073
1073 When 1: all 'magic' names (``__foo__``) will be excluded.
1074 When 1: all 'magic' names (``__foo__``) will be excluded.
1074
1075
1075 When 0: nothing will be excluded.
1076 When 0: nothing will be excluded.
1076 """
1077 """
1077 ).tag(config=True)
1078 ).tag(config=True)
1078 limit_to__all__ = Bool(False,
1079 limit_to__all__ = Bool(False,
1079 help="""
1080 help="""
1080 DEPRECATED as of version 5.0.
1081 DEPRECATED as of version 5.0.
1081
1082
1082 Instruct the completer to use __all__ for the completion
1083 Instruct the completer to use __all__ for the completion
1083
1084
1084 Specifically, when completing on ``object.<tab>``.
1085 Specifically, when completing on ``object.<tab>``.
1085
1086
1086 When True: only those names in obj.__all__ will be included.
1087 When True: only those names in obj.__all__ will be included.
1087
1088
1088 When False [default]: the __all__ attribute is ignored
1089 When False [default]: the __all__ attribute is ignored
1089 """,
1090 """,
1090 ).tag(config=True)
1091 ).tag(config=True)
1091
1092
1092 profile_completions = Bool(
1093 profile_completions = Bool(
1093 default_value=False,
1094 default_value=False,
1094 help="If True, emit profiling data for completion subsystem using cProfile."
1095 help="If True, emit profiling data for completion subsystem using cProfile."
1095 ).tag(config=True)
1096 ).tag(config=True)
1096
1097
1097 profiler_output_dir = Unicode(
1098 profiler_output_dir = Unicode(
1098 default_value=".completion_profiles",
1099 default_value=".completion_profiles",
1099 help="Template for path at which to output profile data for completions."
1100 help="Template for path at which to output profile data for completions."
1100 ).tag(config=True)
1101 ).tag(config=True)
1101
1102
1102 @observe('limit_to__all__')
1103 @observe('limit_to__all__')
1103 def _limit_to_all_changed(self, change):
1104 def _limit_to_all_changed(self, change):
1104 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
1105 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
1105 'value has been deprecated since IPython 5.0, will be made to have '
1106 'value has been deprecated since IPython 5.0, will be made to have '
1106 'no effects and then removed in future version of IPython.',
1107 'no effects and then removed in future version of IPython.',
1107 UserWarning)
1108 UserWarning)
1108
1109
1109 def __init__(self, shell=None, namespace=None, global_namespace=None,
1110 def __init__(self, shell=None, namespace=None, global_namespace=None,
1110 use_readline=_deprecation_readline_sentinel, config=None, **kwargs):
1111 use_readline=_deprecation_readline_sentinel, config=None, **kwargs):
1111 """IPCompleter() -> completer
1112 """IPCompleter() -> completer
1112
1113
1113 Return a completer object.
1114 Return a completer object.
1114
1115
1115 Parameters
1116 Parameters
1116 ----------
1117 ----------
1117
1118
1118 shell
1119 shell
1119 a pointer to the ipython shell itself. This is needed
1120 a pointer to the ipython shell itself. This is needed
1120 because this completer knows about magic functions, and those can
1121 because this completer knows about magic functions, and those can
1121 only be accessed via the ipython instance.
1122 only be accessed via the ipython instance.
1122
1123
1123 namespace : dict, optional
1124 namespace : dict, optional
1124 an optional dict where completions are performed.
1125 an optional dict where completions are performed.
1125
1126
1126 global_namespace : dict, optional
1127 global_namespace : dict, optional
1127 secondary optional dict for completions, to
1128 secondary optional dict for completions, to
1128 handle cases (such as IPython embedded inside functions) where
1129 handle cases (such as IPython embedded inside functions) where
1129 both Python scopes are visible.
1130 both Python scopes are visible.
1130
1131
1131 use_readline : bool, optional
1132 use_readline : bool, optional
1132 DEPRECATED, ignored since IPython 6.0, will have no effects
1133 DEPRECATED, ignored since IPython 6.0, will have no effects
1133 """
1134 """
1134
1135
1135 self.magic_escape = ESC_MAGIC
1136 self.magic_escape = ESC_MAGIC
1136 self.splitter = CompletionSplitter()
1137 self.splitter = CompletionSplitter()
1137
1138
1138 if use_readline is not _deprecation_readline_sentinel:
1139 if use_readline is not _deprecation_readline_sentinel:
1139 warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.',
1140 warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.',
1140 DeprecationWarning, stacklevel=2)
1141 DeprecationWarning, stacklevel=2)
1141
1142
1142 # _greedy_changed() depends on splitter and readline being defined:
1143 # _greedy_changed() depends on splitter and readline being defined:
1143 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
1144 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
1144 config=config, **kwargs)
1145 config=config, **kwargs)
1145
1146
1146 # List where completion matches will be stored
1147 # List where completion matches will be stored
1147 self.matches = []
1148 self.matches = []
1148 self.shell = shell
1149 self.shell = shell
1149 # Regexp to split filenames with spaces in them
1150 # Regexp to split filenames with spaces in them
1150 self.space_name_re = re.compile(r'([^\\] )')
1151 self.space_name_re = re.compile(r'([^\\] )')
1151 # Hold a local ref. to glob.glob for speed
1152 # Hold a local ref. to glob.glob for speed
1152 self.glob = glob.glob
1153 self.glob = glob.glob
1153
1154
1154 # Determine if we are running on 'dumb' terminals, like (X)Emacs
1155 # Determine if we are running on 'dumb' terminals, like (X)Emacs
1155 # buffers, to avoid completion problems.
1156 # buffers, to avoid completion problems.
1156 term = os.environ.get('TERM','xterm')
1157 term = os.environ.get('TERM','xterm')
1157 self.dumb_terminal = term in ['dumb','emacs']
1158 self.dumb_terminal = term in ['dumb','emacs']
1158
1159
1159 # Special handling of backslashes needed in win32 platforms
1160 # Special handling of backslashes needed in win32 platforms
1160 if sys.platform == "win32":
1161 if sys.platform == "win32":
1161 self.clean_glob = self._clean_glob_win32
1162 self.clean_glob = self._clean_glob_win32
1162 else:
1163 else:
1163 self.clean_glob = self._clean_glob
1164 self.clean_glob = self._clean_glob
1164
1165
1165 #regexp to parse docstring for function signature
1166 #regexp to parse docstring for function signature
1166 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1167 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1167 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1168 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1168 #use this if positional argument name is also needed
1169 #use this if positional argument name is also needed
1169 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
1170 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
1170
1171
1171 self.magic_arg_matchers = [
1172 self.magic_arg_matchers = [
1172 self.magic_config_matches,
1173 self.magic_config_matches,
1173 self.magic_color_matches,
1174 self.magic_color_matches,
1174 ]
1175 ]
1175
1176
1176 # This is set externally by InteractiveShell
1177 # This is set externally by InteractiveShell
1177 self.custom_completers = None
1178 self.custom_completers = None
1178
1179
1179 # This is a list of names of unicode characters that can be completed
1180 # This is a list of names of unicode characters that can be completed
1180 # into their corresponding unicode value. The list is large, so we
1181 # into their corresponding unicode value. The list is large, so we
1181 # laziliy initialize it on first use. Consuming code should access this
1182 # laziliy initialize it on first use. Consuming code should access this
1182 # attribute through the `@unicode_names` property.
1183 # attribute through the `@unicode_names` property.
1183 self._unicode_names = None
1184 self._unicode_names = None
1184
1185
1185 @property
1186 @property
1186 def matchers(self) -> List[Any]:
1187 def matchers(self) -> List[Any]:
1187 """All active matcher routines for completion"""
1188 """All active matcher routines for completion"""
1188 if self.dict_keys_only:
1189 if self.dict_keys_only:
1189 return [self.dict_key_matches]
1190 return [self.dict_key_matches]
1190
1191
1191 if self.use_jedi:
1192 if self.use_jedi:
1192 return [
1193 return [
1193 *self.custom_matchers,
1194 *self.custom_matchers,
1194 self.file_matches,
1195 self.file_matches,
1195 self.magic_matches,
1196 self.magic_matches,
1196 self.dict_key_matches,
1197 self.dict_key_matches,
1197 ]
1198 ]
1198 else:
1199 else:
1199 return [
1200 return [
1200 *self.custom_matchers,
1201 *self.custom_matchers,
1201 self.python_matches,
1202 self.python_matches,
1202 self.file_matches,
1203 self.file_matches,
1203 self.magic_matches,
1204 self.magic_matches,
1204 self.python_func_kw_matches,
1205 self.python_func_kw_matches,
1205 self.dict_key_matches,
1206 self.dict_key_matches,
1206 ]
1207 ]
1207
1208
1208 def all_completions(self, text:str) -> List[str]:
1209 def all_completions(self, text:str) -> List[str]:
1209 """
1210 """
1210 Wrapper around the completion methods for the benefit of emacs.
1211 Wrapper around the completion methods for the benefit of emacs.
1211 """
1212 """
1212 prefix = text.rpartition('.')[0]
1213 prefix = text.rpartition('.')[0]
1213 with provisionalcompleter():
1214 with provisionalcompleter():
1214 return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text
1215 return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text
1215 for c in self.completions(text, len(text))]
1216 for c in self.completions(text, len(text))]
1216
1217
1217 return self.complete(text)[1]
1218 return self.complete(text)[1]
1218
1219
1219 def _clean_glob(self, text:str):
1220 def _clean_glob(self, text:str):
1220 return self.glob("%s*" % text)
1221 return self.glob("%s*" % text)
1221
1222
1222 def _clean_glob_win32(self, text:str):
1223 def _clean_glob_win32(self, text:str):
1223 return [f.replace("\\","/")
1224 return [f.replace("\\","/")
1224 for f in self.glob("%s*" % text)]
1225 for f in self.glob("%s*" % text)]
1225
1226
1226 def file_matches(self, text:str)->List[str]:
1227 def file_matches(self, text:str)->List[str]:
1227 """Match filenames, expanding ~USER type strings.
1228 """Match filenames, expanding ~USER type strings.
1228
1229
1229 Most of the seemingly convoluted logic in this completer is an
1230 Most of the seemingly convoluted logic in this completer is an
1230 attempt to handle filenames with spaces in them. And yet it's not
1231 attempt to handle filenames with spaces in them. And yet it's not
1231 quite perfect, because Python's readline doesn't expose all of the
1232 quite perfect, because Python's readline doesn't expose all of the
1232 GNU readline details needed for this to be done correctly.
1233 GNU readline details needed for this to be done correctly.
1233
1234
1234 For a filename with a space in it, the printed completions will be
1235 For a filename with a space in it, the printed completions will be
1235 only the parts after what's already been typed (instead of the
1236 only the parts after what's already been typed (instead of the
1236 full completions, as is normally done). I don't think with the
1237 full completions, as is normally done). I don't think with the
1237 current (as of Python 2.3) Python readline it's possible to do
1238 current (as of Python 2.3) Python readline it's possible to do
1238 better."""
1239 better."""
1239
1240
1240 # chars that require escaping with backslash - i.e. chars
1241 # chars that require escaping with backslash - i.e. chars
1241 # that readline treats incorrectly as delimiters, but we
1242 # that readline treats incorrectly as delimiters, but we
1242 # don't want to treat as delimiters in filename matching
1243 # don't want to treat as delimiters in filename matching
1243 # when escaped with backslash
1244 # when escaped with backslash
1244 if text.startswith('!'):
1245 if text.startswith('!'):
1245 text = text[1:]
1246 text = text[1:]
1246 text_prefix = u'!'
1247 text_prefix = u'!'
1247 else:
1248 else:
1248 text_prefix = u''
1249 text_prefix = u''
1249
1250
1250 text_until_cursor = self.text_until_cursor
1251 text_until_cursor = self.text_until_cursor
1251 # track strings with open quotes
1252 # track strings with open quotes
1252 open_quotes = has_open_quotes(text_until_cursor)
1253 open_quotes = has_open_quotes(text_until_cursor)
1253
1254
1254 if '(' in text_until_cursor or '[' in text_until_cursor:
1255 if '(' in text_until_cursor or '[' in text_until_cursor:
1255 lsplit = text
1256 lsplit = text
1256 else:
1257 else:
1257 try:
1258 try:
1258 # arg_split ~ shlex.split, but with unicode bugs fixed by us
1259 # arg_split ~ shlex.split, but with unicode bugs fixed by us
1259 lsplit = arg_split(text_until_cursor)[-1]
1260 lsplit = arg_split(text_until_cursor)[-1]
1260 except ValueError:
1261 except ValueError:
1261 # typically an unmatched ", or backslash without escaped char.
1262 # typically an unmatched ", or backslash without escaped char.
1262 if open_quotes:
1263 if open_quotes:
1263 lsplit = text_until_cursor.split(open_quotes)[-1]
1264 lsplit = text_until_cursor.split(open_quotes)[-1]
1264 else:
1265 else:
1265 return []
1266 return []
1266 except IndexError:
1267 except IndexError:
1267 # tab pressed on empty line
1268 # tab pressed on empty line
1268 lsplit = ""
1269 lsplit = ""
1269
1270
1270 if not open_quotes and lsplit != protect_filename(lsplit):
1271 if not open_quotes and lsplit != protect_filename(lsplit):
1271 # if protectables are found, do matching on the whole escaped name
1272 # if protectables are found, do matching on the whole escaped name
1272 has_protectables = True
1273 has_protectables = True
1273 text0,text = text,lsplit
1274 text0,text = text,lsplit
1274 else:
1275 else:
1275 has_protectables = False
1276 has_protectables = False
1276 text = os.path.expanduser(text)
1277 text = os.path.expanduser(text)
1277
1278
1278 if text == "":
1279 if text == "":
1279 return [text_prefix + protect_filename(f) for f in self.glob("*")]
1280 return [text_prefix + protect_filename(f) for f in self.glob("*")]
1280
1281
1281 # Compute the matches from the filesystem
1282 # Compute the matches from the filesystem
1282 if sys.platform == 'win32':
1283 if sys.platform == 'win32':
1283 m0 = self.clean_glob(text)
1284 m0 = self.clean_glob(text)
1284 else:
1285 else:
1285 m0 = self.clean_glob(text.replace('\\', ''))
1286 m0 = self.clean_glob(text.replace('\\', ''))
1286
1287
1287 if has_protectables:
1288 if has_protectables:
1288 # If we had protectables, we need to revert our changes to the
1289 # If we had protectables, we need to revert our changes to the
1289 # beginning of filename so that we don't double-write the part
1290 # beginning of filename so that we don't double-write the part
1290 # of the filename we have so far
1291 # of the filename we have so far
1291 len_lsplit = len(lsplit)
1292 len_lsplit = len(lsplit)
1292 matches = [text_prefix + text0 +
1293 matches = [text_prefix + text0 +
1293 protect_filename(f[len_lsplit:]) for f in m0]
1294 protect_filename(f[len_lsplit:]) for f in m0]
1294 else:
1295 else:
1295 if open_quotes:
1296 if open_quotes:
1296 # if we have a string with an open quote, we don't need to
1297 # if we have a string with an open quote, we don't need to
1297 # protect the names beyond the quote (and we _shouldn't_, as
1298 # protect the names beyond the quote (and we _shouldn't_, as
1298 # it would cause bugs when the filesystem call is made).
1299 # it would cause bugs when the filesystem call is made).
1299 matches = m0 if sys.platform == "win32" else\
1300 matches = m0 if sys.platform == "win32" else\
1300 [protect_filename(f, open_quotes) for f in m0]
1301 [protect_filename(f, open_quotes) for f in m0]
1301 else:
1302 else:
1302 matches = [text_prefix +
1303 matches = [text_prefix +
1303 protect_filename(f) for f in m0]
1304 protect_filename(f) for f in m0]
1304
1305
1305 # Mark directories in input list by appending '/' to their names.
1306 # Mark directories in input list by appending '/' to their names.
1306 return [x+'/' if os.path.isdir(x) else x for x in matches]
1307 return [x+'/' if os.path.isdir(x) else x for x in matches]
1307
1308
1308 def magic_matches(self, text:str):
1309 def magic_matches(self, text:str):
1309 """Match magics"""
1310 """Match magics"""
1310 # Get all shell magics now rather than statically, so magics loaded at
1311 # Get all shell magics now rather than statically, so magics loaded at
1311 # runtime show up too.
1312 # runtime show up too.
1312 lsm = self.shell.magics_manager.lsmagic()
1313 lsm = self.shell.magics_manager.lsmagic()
1313 line_magics = lsm['line']
1314 line_magics = lsm['line']
1314 cell_magics = lsm['cell']
1315 cell_magics = lsm['cell']
1315 pre = self.magic_escape
1316 pre = self.magic_escape
1316 pre2 = pre+pre
1317 pre2 = pre+pre
1317
1318
1318 explicit_magic = text.startswith(pre)
1319 explicit_magic = text.startswith(pre)
1319
1320
1320 # Completion logic:
1321 # Completion logic:
1321 # - user gives %%: only do cell magics
1322 # - user gives %%: only do cell magics
1322 # - user gives %: do both line and cell magics
1323 # - user gives %: do both line and cell magics
1323 # - no prefix: do both
1324 # - no prefix: do both
1324 # In other words, line magics are skipped if the user gives %% explicitly
1325 # In other words, line magics are skipped if the user gives %% explicitly
1325 #
1326 #
1326 # We also exclude magics that match any currently visible names:
1327 # We also exclude magics that match any currently visible names:
1327 # https://github.com/ipython/ipython/issues/4877, unless the user has
1328 # https://github.com/ipython/ipython/issues/4877, unless the user has
1328 # typed a %:
1329 # typed a %:
1329 # https://github.com/ipython/ipython/issues/10754
1330 # https://github.com/ipython/ipython/issues/10754
1330 bare_text = text.lstrip(pre)
1331 bare_text = text.lstrip(pre)
1331 global_matches = self.global_matches(bare_text)
1332 global_matches = self.global_matches(bare_text)
1332 if not explicit_magic:
1333 if not explicit_magic:
1333 def matches(magic):
1334 def matches(magic):
1334 """
1335 """
1335 Filter magics, in particular remove magics that match
1336 Filter magics, in particular remove magics that match
1336 a name present in global namespace.
1337 a name present in global namespace.
1337 """
1338 """
1338 return ( magic.startswith(bare_text) and
1339 return ( magic.startswith(bare_text) and
1339 magic not in global_matches )
1340 magic not in global_matches )
1340 else:
1341 else:
1341 def matches(magic):
1342 def matches(magic):
1342 return magic.startswith(bare_text)
1343 return magic.startswith(bare_text)
1343
1344
1344 comp = [ pre2+m for m in cell_magics if matches(m)]
1345 comp = [ pre2+m for m in cell_magics if matches(m)]
1345 if not text.startswith(pre2):
1346 if not text.startswith(pre2):
1346 comp += [ pre+m for m in line_magics if matches(m)]
1347 comp += [ pre+m for m in line_magics if matches(m)]
1347
1348
1348 return comp
1349 return comp
1349
1350
1350 def magic_config_matches(self, text:str) -> List[str]:
1351 def magic_config_matches(self, text:str) -> List[str]:
1351 """ Match class names and attributes for %config magic """
1352 """ Match class names and attributes for %config magic """
1352 texts = text.strip().split()
1353 texts = text.strip().split()
1353
1354
1354 if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'):
1355 if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'):
1355 # get all configuration classes
1356 # get all configuration classes
1356 classes = sorted(set([ c for c in self.shell.configurables
1357 classes = sorted(set([ c for c in self.shell.configurables
1357 if c.__class__.class_traits(config=True)
1358 if c.__class__.class_traits(config=True)
1358 ]), key=lambda x: x.__class__.__name__)
1359 ]), key=lambda x: x.__class__.__name__)
1359 classnames = [ c.__class__.__name__ for c in classes ]
1360 classnames = [ c.__class__.__name__ for c in classes ]
1360
1361
1361 # return all classnames if config or %config is given
1362 # return all classnames if config or %config is given
1362 if len(texts) == 1:
1363 if len(texts) == 1:
1363 return classnames
1364 return classnames
1364
1365
1365 # match classname
1366 # match classname
1366 classname_texts = texts[1].split('.')
1367 classname_texts = texts[1].split('.')
1367 classname = classname_texts[0]
1368 classname = classname_texts[0]
1368 classname_matches = [ c for c in classnames
1369 classname_matches = [ c for c in classnames
1369 if c.startswith(classname) ]
1370 if c.startswith(classname) ]
1370
1371
1371 # return matched classes or the matched class with attributes
1372 # return matched classes or the matched class with attributes
1372 if texts[1].find('.') < 0:
1373 if texts[1].find('.') < 0:
1373 return classname_matches
1374 return classname_matches
1374 elif len(classname_matches) == 1 and \
1375 elif len(classname_matches) == 1 and \
1375 classname_matches[0] == classname:
1376 classname_matches[0] == classname:
1376 cls = classes[classnames.index(classname)].__class__
1377 cls = classes[classnames.index(classname)].__class__
1377 help = cls.class_get_help()
1378 help = cls.class_get_help()
1378 # strip leading '--' from cl-args:
1379 # strip leading '--' from cl-args:
1379 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
1380 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
1380 return [ attr.split('=')[0]
1381 return [ attr.split('=')[0]
1381 for attr in help.strip().splitlines()
1382 for attr in help.strip().splitlines()
1382 if attr.startswith(texts[1]) ]
1383 if attr.startswith(texts[1]) ]
1383 return []
1384 return []
1384
1385
1385 def magic_color_matches(self, text:str) -> List[str] :
1386 def magic_color_matches(self, text:str) -> List[str] :
1386 """ Match color schemes for %colors magic"""
1387 """ Match color schemes for %colors magic"""
1387 texts = text.split()
1388 texts = text.split()
1388 if text.endswith(' '):
1389 if text.endswith(' '):
1389 # .split() strips off the trailing whitespace. Add '' back
1390 # .split() strips off the trailing whitespace. Add '' back
1390 # so that: '%colors ' -> ['%colors', '']
1391 # so that: '%colors ' -> ['%colors', '']
1391 texts.append('')
1392 texts.append('')
1392
1393
1393 if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'):
1394 if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'):
1394 prefix = texts[1]
1395 prefix = texts[1]
1395 return [ color for color in InspectColors.keys()
1396 return [ color for color in InspectColors.keys()
1396 if color.startswith(prefix) ]
1397 if color.startswith(prefix) ]
1397 return []
1398 return []
1398
1399
1399 def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str) -> Iterable[Any]:
1400 def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str) -> Iterable[Any]:
1400 """
1401 """
1401
1402
1402 Return a list of :any:`jedi.api.Completions` object from a ``text`` and
1403 Return a list of :any:`jedi.api.Completions` object from a ``text`` and
1403 cursor position.
1404 cursor position.
1404
1405
1405 Parameters
1406 Parameters
1406 ----------
1407 ----------
1407 cursor_column : int
1408 cursor_column : int
1408 column position of the cursor in ``text``, 0-indexed.
1409 column position of the cursor in ``text``, 0-indexed.
1409 cursor_line : int
1410 cursor_line : int
1410 line position of the cursor in ``text``, 0-indexed
1411 line position of the cursor in ``text``, 0-indexed
1411 text : str
1412 text : str
1412 text to complete
1413 text to complete
1413
1414
1414 Debugging
1415 Debugging
1415 ---------
1416 ---------
1416
1417
1417 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
1418 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
1418 object containing a string with the Jedi debug information attached.
1419 object containing a string with the Jedi debug information attached.
1419 """
1420 """
1420 namespaces = [self.namespace]
1421 namespaces = [self.namespace]
1421 if self.global_namespace is not None:
1422 if self.global_namespace is not None:
1422 namespaces.append(self.global_namespace)
1423 namespaces.append(self.global_namespace)
1423
1424
1424 completion_filter = lambda x:x
1425 completion_filter = lambda x:x
1425 offset = cursor_to_position(text, cursor_line, cursor_column)
1426 offset = cursor_to_position(text, cursor_line, cursor_column)
1426 # filter output if we are completing for object members
1427 # filter output if we are completing for object members
1427 if offset:
1428 if offset:
1428 pre = text[offset-1]
1429 pre = text[offset-1]
1429 if pre == '.':
1430 if pre == '.':
1430 if self.omit__names == 2:
1431 if self.omit__names == 2:
1431 completion_filter = lambda c:not c.name.startswith('_')
1432 completion_filter = lambda c:not c.name.startswith('_')
1432 elif self.omit__names == 1:
1433 elif self.omit__names == 1:
1433 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
1434 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
1434 elif self.omit__names == 0:
1435 elif self.omit__names == 0:
1435 completion_filter = lambda x:x
1436 completion_filter = lambda x:x
1436 else:
1437 else:
1437 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
1438 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
1438
1439
1439 interpreter = jedi.Interpreter(text[:offset], namespaces)
1440 interpreter = jedi.Interpreter(text[:offset], namespaces)
1440 try_jedi = True
1441 try_jedi = True
1441
1442
1442 try:
1443 try:
1443 # find the first token in the current tree -- if it is a ' or " then we are in a string
1444 # find the first token in the current tree -- if it is a ' or " then we are in a string
1444 completing_string = False
1445 completing_string = False
1445 try:
1446 try:
1446 first_child = next(c for c in interpreter._get_module().tree_node.children if hasattr(c, 'value'))
1447 first_child = next(c for c in interpreter._get_module().tree_node.children if hasattr(c, 'value'))
1447 except StopIteration:
1448 except StopIteration:
1448 pass
1449 pass
1449 else:
1450 else:
1450 # note the value may be ', ", or it may also be ''' or """, or
1451 # note the value may be ', ", or it may also be ''' or """, or
1451 # in some cases, """what/you/typed..., but all of these are
1452 # in some cases, """what/you/typed..., but all of these are
1452 # strings.
1453 # strings.
1453 completing_string = len(first_child.value) > 0 and first_child.value[0] in {"'", '"'}
1454 completing_string = len(first_child.value) > 0 and first_child.value[0] in {"'", '"'}
1454
1455
1455 # if we are in a string jedi is likely not the right candidate for
1456 # if we are in a string jedi is likely not the right candidate for
1456 # now. Skip it.
1457 # now. Skip it.
1457 try_jedi = not completing_string
1458 try_jedi = not completing_string
1458 except Exception as e:
1459 except Exception as e:
1459 # many of things can go wrong, we are using private API just don't crash.
1460 # many of things can go wrong, we are using private API just don't crash.
1460 if self.debug:
1461 if self.debug:
1461 print("Error detecting if completing a non-finished string :", e, '|')
1462 print("Error detecting if completing a non-finished string :", e, '|')
1462
1463
1463 if not try_jedi:
1464 if not try_jedi:
1464 return []
1465 return []
1465 try:
1466 try:
1466 return filter(completion_filter, interpreter.complete(column=cursor_column, line=cursor_line + 1))
1467 return filter(completion_filter, interpreter.complete(column=cursor_column, line=cursor_line + 1))
1467 except Exception as e:
1468 except Exception as e:
1468 if self.debug:
1469 if self.debug:
1469 return [_FakeJediCompletion('Oops Jedi has crashed, please report a bug with the following:\n"""\n%s\ns"""' % (e))]
1470 return [_FakeJediCompletion('Oops Jedi has crashed, please report a bug with the following:\n"""\n%s\ns"""' % (e))]
1470 else:
1471 else:
1471 return []
1472 return []
1472
1473
1473 def python_matches(self, text:str)->List[str]:
1474 def python_matches(self, text:str)->List[str]:
1474 """Match attributes or global python names"""
1475 """Match attributes or global python names"""
1475 if "." in text:
1476 if "." in text:
1476 try:
1477 try:
1477 matches = self.attr_matches(text)
1478 matches = self.attr_matches(text)
1478 if text.endswith('.') and self.omit__names:
1479 if text.endswith('.') and self.omit__names:
1479 if self.omit__names == 1:
1480 if self.omit__names == 1:
1480 # true if txt is _not_ a __ name, false otherwise:
1481 # true if txt is _not_ a __ name, false otherwise:
1481 no__name = (lambda txt:
1482 no__name = (lambda txt:
1482 re.match(r'.*\.__.*?__',txt) is None)
1483 re.match(r'.*\.__.*?__',txt) is None)
1483 else:
1484 else:
1484 # true if txt is _not_ a _ name, false otherwise:
1485 # true if txt is _not_ a _ name, false otherwise:
1485 no__name = (lambda txt:
1486 no__name = (lambda txt:
1486 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
1487 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
1487 matches = filter(no__name, matches)
1488 matches = filter(no__name, matches)
1488 except NameError:
1489 except NameError:
1489 # catches <undefined attributes>.<tab>
1490 # catches <undefined attributes>.<tab>
1490 matches = []
1491 matches = []
1491 else:
1492 else:
1492 matches = self.global_matches(text)
1493 matches = self.global_matches(text)
1493 return matches
1494 return matches
1494
1495
1495 def _default_arguments_from_docstring(self, doc):
1496 def _default_arguments_from_docstring(self, doc):
1496 """Parse the first line of docstring for call signature.
1497 """Parse the first line of docstring for call signature.
1497
1498
1498 Docstring should be of the form 'min(iterable[, key=func])\n'.
1499 Docstring should be of the form 'min(iterable[, key=func])\n'.
1499 It can also parse cython docstring of the form
1500 It can also parse cython docstring of the form
1500 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
1501 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
1501 """
1502 """
1502 if doc is None:
1503 if doc is None:
1503 return []
1504 return []
1504
1505
1505 #care only the firstline
1506 #care only the firstline
1506 line = doc.lstrip().splitlines()[0]
1507 line = doc.lstrip().splitlines()[0]
1507
1508
1508 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1509 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1509 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
1510 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
1510 sig = self.docstring_sig_re.search(line)
1511 sig = self.docstring_sig_re.search(line)
1511 if sig is None:
1512 if sig is None:
1512 return []
1513 return []
1513 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
1514 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
1514 sig = sig.groups()[0].split(',')
1515 sig = sig.groups()[0].split(',')
1515 ret = []
1516 ret = []
1516 for s in sig:
1517 for s in sig:
1517 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1518 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1518 ret += self.docstring_kwd_re.findall(s)
1519 ret += self.docstring_kwd_re.findall(s)
1519 return ret
1520 return ret
1520
1521
1521 def _default_arguments(self, obj):
1522 def _default_arguments(self, obj):
1522 """Return the list of default arguments of obj if it is callable,
1523 """Return the list of default arguments of obj if it is callable,
1523 or empty list otherwise."""
1524 or empty list otherwise."""
1524 call_obj = obj
1525 call_obj = obj
1525 ret = []
1526 ret = []
1526 if inspect.isbuiltin(obj):
1527 if inspect.isbuiltin(obj):
1527 pass
1528 pass
1528 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
1529 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
1529 if inspect.isclass(obj):
1530 if inspect.isclass(obj):
1530 #for cython embedsignature=True the constructor docstring
1531 #for cython embedsignature=True the constructor docstring
1531 #belongs to the object itself not __init__
1532 #belongs to the object itself not __init__
1532 ret += self._default_arguments_from_docstring(
1533 ret += self._default_arguments_from_docstring(
1533 getattr(obj, '__doc__', ''))
1534 getattr(obj, '__doc__', ''))
1534 # for classes, check for __init__,__new__
1535 # for classes, check for __init__,__new__
1535 call_obj = (getattr(obj, '__init__', None) or
1536 call_obj = (getattr(obj, '__init__', None) or
1536 getattr(obj, '__new__', None))
1537 getattr(obj, '__new__', None))
1537 # for all others, check if they are __call__able
1538 # for all others, check if they are __call__able
1538 elif hasattr(obj, '__call__'):
1539 elif hasattr(obj, '__call__'):
1539 call_obj = obj.__call__
1540 call_obj = obj.__call__
1540 ret += self._default_arguments_from_docstring(
1541 ret += self._default_arguments_from_docstring(
1541 getattr(call_obj, '__doc__', ''))
1542 getattr(call_obj, '__doc__', ''))
1542
1543
1543 _keeps = (inspect.Parameter.KEYWORD_ONLY,
1544 _keeps = (inspect.Parameter.KEYWORD_ONLY,
1544 inspect.Parameter.POSITIONAL_OR_KEYWORD)
1545 inspect.Parameter.POSITIONAL_OR_KEYWORD)
1545
1546
1546 try:
1547 try:
1547 sig = inspect.signature(call_obj)
1548 sig = inspect.signature(call_obj)
1548 ret.extend(k for k, v in sig.parameters.items() if
1549 ret.extend(k for k, v in sig.parameters.items() if
1549 v.kind in _keeps)
1550 v.kind in _keeps)
1550 except ValueError:
1551 except ValueError:
1551 pass
1552 pass
1552
1553
1553 return list(set(ret))
1554 return list(set(ret))
1554
1555
1555 def python_func_kw_matches(self, text):
1556 def python_func_kw_matches(self, text):
1556 """Match named parameters (kwargs) of the last open function"""
1557 """Match named parameters (kwargs) of the last open function"""
1557
1558
1558 if "." in text: # a parameter cannot be dotted
1559 if "." in text: # a parameter cannot be dotted
1559 return []
1560 return []
1560 try: regexp = self.__funcParamsRegex
1561 try: regexp = self.__funcParamsRegex
1561 except AttributeError:
1562 except AttributeError:
1562 regexp = self.__funcParamsRegex = re.compile(r'''
1563 regexp = self.__funcParamsRegex = re.compile(r'''
1563 '.*?(?<!\\)' | # single quoted strings or
1564 '.*?(?<!\\)' | # single quoted strings or
1564 ".*?(?<!\\)" | # double quoted strings or
1565 ".*?(?<!\\)" | # double quoted strings or
1565 \w+ | # identifier
1566 \w+ | # identifier
1566 \S # other characters
1567 \S # other characters
1567 ''', re.VERBOSE | re.DOTALL)
1568 ''', re.VERBOSE | re.DOTALL)
1568 # 1. find the nearest identifier that comes before an unclosed
1569 # 1. find the nearest identifier that comes before an unclosed
1569 # parenthesis before the cursor
1570 # parenthesis before the cursor
1570 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
1571 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
1571 tokens = regexp.findall(self.text_until_cursor)
1572 tokens = regexp.findall(self.text_until_cursor)
1572 iterTokens = reversed(tokens); openPar = 0
1573 iterTokens = reversed(tokens); openPar = 0
1573
1574
1574 for token in iterTokens:
1575 for token in iterTokens:
1575 if token == ')':
1576 if token == ')':
1576 openPar -= 1
1577 openPar -= 1
1577 elif token == '(':
1578 elif token == '(':
1578 openPar += 1
1579 openPar += 1
1579 if openPar > 0:
1580 if openPar > 0:
1580 # found the last unclosed parenthesis
1581 # found the last unclosed parenthesis
1581 break
1582 break
1582 else:
1583 else:
1583 return []
1584 return []
1584 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
1585 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
1585 ids = []
1586 ids = []
1586 isId = re.compile(r'\w+$').match
1587 isId = re.compile(r'\w+$').match
1587
1588
1588 while True:
1589 while True:
1589 try:
1590 try:
1590 ids.append(next(iterTokens))
1591 ids.append(next(iterTokens))
1591 if not isId(ids[-1]):
1592 if not isId(ids[-1]):
1592 ids.pop(); break
1593 ids.pop(); break
1593 if not next(iterTokens) == '.':
1594 if not next(iterTokens) == '.':
1594 break
1595 break
1595 except StopIteration:
1596 except StopIteration:
1596 break
1597 break
1597
1598
1598 # Find all named arguments already assigned to, as to avoid suggesting
1599 # Find all named arguments already assigned to, as to avoid suggesting
1599 # them again
1600 # them again
1600 usedNamedArgs = set()
1601 usedNamedArgs = set()
1601 par_level = -1
1602 par_level = -1
1602 for token, next_token in zip(tokens, tokens[1:]):
1603 for token, next_token in zip(tokens, tokens[1:]):
1603 if token == '(':
1604 if token == '(':
1604 par_level += 1
1605 par_level += 1
1605 elif token == ')':
1606 elif token == ')':
1606 par_level -= 1
1607 par_level -= 1
1607
1608
1608 if par_level != 0:
1609 if par_level != 0:
1609 continue
1610 continue
1610
1611
1611 if next_token != '=':
1612 if next_token != '=':
1612 continue
1613 continue
1613
1614
1614 usedNamedArgs.add(token)
1615 usedNamedArgs.add(token)
1615
1616
1616 argMatches = []
1617 argMatches = []
1617 try:
1618 try:
1618 callableObj = '.'.join(ids[::-1])
1619 callableObj = '.'.join(ids[::-1])
1619 namedArgs = self._default_arguments(eval(callableObj,
1620 namedArgs = self._default_arguments(eval(callableObj,
1620 self.namespace))
1621 self.namespace))
1621
1622
1622 # Remove used named arguments from the list, no need to show twice
1623 # Remove used named arguments from the list, no need to show twice
1623 for namedArg in set(namedArgs) - usedNamedArgs:
1624 for namedArg in set(namedArgs) - usedNamedArgs:
1624 if namedArg.startswith(text):
1625 if namedArg.startswith(text):
1625 argMatches.append("%s=" %namedArg)
1626 argMatches.append("%s=" %namedArg)
1626 except:
1627 except:
1627 pass
1628 pass
1628
1629
1629 return argMatches
1630 return argMatches
1630
1631
1631 @staticmethod
1632 @staticmethod
1632 def _get_keys(obj: Any) -> List[Any]:
1633 def _get_keys(obj: Any) -> List[Any]:
1633 # Objects can define their own completions by defining an
1634 # Objects can define their own completions by defining an
1634 # _ipy_key_completions_() method.
1635 # _ipy_key_completions_() method.
1635 method = get_real_method(obj, '_ipython_key_completions_')
1636 method = get_real_method(obj, '_ipython_key_completions_')
1636 if method is not None:
1637 if method is not None:
1637 return method()
1638 return method()
1638
1639
1639 # Special case some common in-memory dict-like types
1640 # Special case some common in-memory dict-like types
1640 if isinstance(obj, dict) or\
1641 if isinstance(obj, dict) or\
1641 _safe_isinstance(obj, 'pandas', 'DataFrame'):
1642 _safe_isinstance(obj, 'pandas', 'DataFrame'):
1642 try:
1643 try:
1643 return list(obj.keys())
1644 return list(obj.keys())
1644 except Exception:
1645 except Exception:
1645 return []
1646 return []
1646 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
1647 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
1647 _safe_isinstance(obj, 'numpy', 'void'):
1648 _safe_isinstance(obj, 'numpy', 'void'):
1648 return obj.dtype.names or []
1649 return obj.dtype.names or []
1649 return []
1650 return []
1650
1651
1651 def dict_key_matches(self, text:str) -> List[str]:
1652 def dict_key_matches(self, text:str) -> List[str]:
1652 "Match string keys in a dictionary, after e.g. 'foo[' "
1653 "Match string keys in a dictionary, after e.g. 'foo[' "
1653
1654
1654
1655
1655 if self.__dict_key_regexps is not None:
1656 if self.__dict_key_regexps is not None:
1656 regexps = self.__dict_key_regexps
1657 regexps = self.__dict_key_regexps
1657 else:
1658 else:
1658 dict_key_re_fmt = r'''(?x)
1659 dict_key_re_fmt = r'''(?x)
1659 ( # match dict-referring expression wrt greedy setting
1660 ( # match dict-referring expression wrt greedy setting
1660 %s
1661 %s
1661 )
1662 )
1662 \[ # open bracket
1663 \[ # open bracket
1663 \s* # and optional whitespace
1664 \s* # and optional whitespace
1664 # Capture any number of str-like objects (e.g. "a", "b", 'c')
1665 # Capture any number of str-like objects (e.g. "a", "b", 'c')
1665 ((?:[uUbB]? # string prefix (r not handled)
1666 ((?:[uUbB]? # string prefix (r not handled)
1666 (?:
1667 (?:
1667 '(?:[^']|(?<!\\)\\')*'
1668 '(?:[^']|(?<!\\)\\')*'
1668 |
1669 |
1669 "(?:[^"]|(?<!\\)\\")*"
1670 "(?:[^"]|(?<!\\)\\")*"
1670 )
1671 )
1671 \s*,\s*
1672 \s*,\s*
1672 )*)
1673 )*)
1673 ([uUbB]? # string prefix (r not handled)
1674 ([uUbB]? # string prefix (r not handled)
1674 (?: # unclosed string
1675 (?: # unclosed string
1675 '(?:[^']|(?<!\\)\\')*
1676 '(?:[^']|(?<!\\)\\')*
1676 |
1677 |
1677 "(?:[^"]|(?<!\\)\\")*
1678 "(?:[^"]|(?<!\\)\\")*
1678 )
1679 )
1679 )?
1680 )?
1680 $
1681 $
1681 '''
1682 '''
1682 regexps = self.__dict_key_regexps = {
1683 regexps = self.__dict_key_regexps = {
1683 False: re.compile(dict_key_re_fmt % r'''
1684 False: re.compile(dict_key_re_fmt % r'''
1684 # identifiers separated by .
1685 # identifiers separated by .
1685 (?!\d)\w+
1686 (?!\d)\w+
1686 (?:\.(?!\d)\w+)*
1687 (?:\.(?!\d)\w+)*
1687 '''),
1688 '''),
1688 True: re.compile(dict_key_re_fmt % '''
1689 True: re.compile(dict_key_re_fmt % '''
1689 .+
1690 .+
1690 ''')
1691 ''')
1691 }
1692 }
1692
1693
1693 match = regexps[self.greedy].search(self.text_until_cursor)
1694 match = regexps[self.greedy].search(self.text_until_cursor)
1694
1695
1695 if match is None:
1696 if match is None:
1696 return []
1697 return []
1697
1698
1698 expr, prefix0, prefix = match.groups()
1699 expr, prefix0, prefix = match.groups()
1699 try:
1700 try:
1700 obj = eval(expr, self.namespace)
1701 obj = eval(expr, self.namespace)
1701 except Exception:
1702 except Exception:
1702 try:
1703 try:
1703 obj = eval(expr, self.global_namespace)
1704 obj = eval(expr, self.global_namespace)
1704 except Exception:
1705 except Exception:
1705 return []
1706 return []
1706
1707
1707 keys = self._get_keys(obj)
1708 keys = self._get_keys(obj)
1708 if not keys:
1709 if not keys:
1709 return keys
1710 return keys
1710
1711
1711 if prefix0 != '':
1712 extra_prefix = eval(prefix0) if prefix0 != '' else None
1712 tuple_prefix = eval(prefix0)
1713 else:
1714 tuple_prefix = tuple()
1715
1713
1716 closing_quote, token_offset, matches = match_dict_keys(keys, tuple_prefix, prefix, self.splitter.delims)
1714 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims, extra_prefix=extra_prefix)
1717 if not matches:
1715 if not matches:
1718 return matches
1716 return matches
1719
1717
1720 # get the cursor position of
1718 # get the cursor position of
1721 # - the text being completed
1719 # - the text being completed
1722 # - the start of the key text
1720 # - the start of the key text
1723 # - the start of the completion
1721 # - the start of the completion
1724 text_start = len(self.text_until_cursor) - len(text)
1722 text_start = len(self.text_until_cursor) - len(text)
1725 if prefix:
1723 if prefix:
1726 key_start = match.start(3)
1724 key_start = match.start(3)
1727 completion_start = key_start + token_offset
1725 completion_start = key_start + token_offset
1728 else:
1726 else:
1729 key_start = completion_start = match.end()
1727 key_start = completion_start = match.end()
1730
1728
1731 # grab the leading prefix, to make sure all completions start with `text`
1729 # grab the leading prefix, to make sure all completions start with `text`
1732 if text_start > key_start:
1730 if text_start > key_start:
1733 leading = ''
1731 leading = ''
1734 else:
1732 else:
1735 leading = text[text_start:completion_start]
1733 leading = text[text_start:completion_start]
1736
1734
1737 # the index of the `[` character
1735 # the index of the `[` character
1738 bracket_idx = match.end(1)
1736 bracket_idx = match.end(1)
1739
1737
1740 # append closing quote and bracket as appropriate
1738 # append closing quote and bracket as appropriate
1741 # this is *not* appropriate if the opening quote or bracket is outside
1739 # this is *not* appropriate if the opening quote or bracket is outside
1742 # the text given to this method
1740 # the text given to this method
1743 suf = ''
1741 suf = ''
1744 continuation = self.line_buffer[len(self.text_until_cursor):]
1742 continuation = self.line_buffer[len(self.text_until_cursor):]
1745 if key_start > text_start and closing_quote:
1743 if key_start > text_start and closing_quote:
1746 # quotes were opened inside text, maybe close them
1744 # quotes were opened inside text, maybe close them
1747 if continuation.startswith(closing_quote):
1745 if continuation.startswith(closing_quote):
1748 continuation = continuation[len(closing_quote):]
1746 continuation = continuation[len(closing_quote):]
1749 else:
1747 else:
1750 suf += closing_quote
1748 suf += closing_quote
1751 if bracket_idx > text_start:
1749 if bracket_idx > text_start:
1752 # brackets were opened inside text, maybe close them
1750 # brackets were opened inside text, maybe close them
1753 if not continuation.startswith(']'):
1751 if not continuation.startswith(']'):
1754 suf += ']'
1752 suf += ']'
1755
1753
1756 return [leading + k + suf for k in matches]
1754 return [leading + k + suf for k in matches]
1757
1755
1758 @staticmethod
1756 @staticmethod
1759 def unicode_name_matches(text:str) -> Tuple[str, List[str]] :
1757 def unicode_name_matches(text:str) -> Tuple[str, List[str]] :
1760 """Match Latex-like syntax for unicode characters base
1758 """Match Latex-like syntax for unicode characters base
1761 on the name of the character.
1759 on the name of the character.
1762
1760
1763 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
1761 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
1764
1762
1765 Works only on valid python 3 identifier, or on combining characters that
1763 Works only on valid python 3 identifier, or on combining characters that
1766 will combine to form a valid identifier.
1764 will combine to form a valid identifier.
1767 """
1765 """
1768 slashpos = text.rfind('\\')
1766 slashpos = text.rfind('\\')
1769 if slashpos > -1:
1767 if slashpos > -1:
1770 s = text[slashpos+1:]
1768 s = text[slashpos+1:]
1771 try :
1769 try :
1772 unic = unicodedata.lookup(s)
1770 unic = unicodedata.lookup(s)
1773 # allow combining chars
1771 # allow combining chars
1774 if ('a'+unic).isidentifier():
1772 if ('a'+unic).isidentifier():
1775 return '\\'+s,[unic]
1773 return '\\'+s,[unic]
1776 except KeyError:
1774 except KeyError:
1777 pass
1775 pass
1778 return '', []
1776 return '', []
1779
1777
1780
1778
1781 def latex_matches(self, text:str) -> Tuple[str, Sequence[str]]:
1779 def latex_matches(self, text:str) -> Tuple[str, Sequence[str]]:
1782 """Match Latex syntax for unicode characters.
1780 """Match Latex syntax for unicode characters.
1783
1781
1784 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
1782 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
1785 """
1783 """
1786 slashpos = text.rfind('\\')
1784 slashpos = text.rfind('\\')
1787 if slashpos > -1:
1785 if slashpos > -1:
1788 s = text[slashpos:]
1786 s = text[slashpos:]
1789 if s in latex_symbols:
1787 if s in latex_symbols:
1790 # Try to complete a full latex symbol to unicode
1788 # Try to complete a full latex symbol to unicode
1791 # \\alpha -> Ξ±
1789 # \\alpha -> Ξ±
1792 return s, [latex_symbols[s]]
1790 return s, [latex_symbols[s]]
1793 else:
1791 else:
1794 # If a user has partially typed a latex symbol, give them
1792 # If a user has partially typed a latex symbol, give them
1795 # a full list of options \al -> [\aleph, \alpha]
1793 # a full list of options \al -> [\aleph, \alpha]
1796 matches = [k for k in latex_symbols if k.startswith(s)]
1794 matches = [k for k in latex_symbols if k.startswith(s)]
1797 if matches:
1795 if matches:
1798 return s, matches
1796 return s, matches
1799 return '', ()
1797 return '', ()
1800
1798
1801 def dispatch_custom_completer(self, text):
1799 def dispatch_custom_completer(self, text):
1802 if not self.custom_completers:
1800 if not self.custom_completers:
1803 return
1801 return
1804
1802
1805 line = self.line_buffer
1803 line = self.line_buffer
1806 if not line.strip():
1804 if not line.strip():
1807 return None
1805 return None
1808
1806
1809 # Create a little structure to pass all the relevant information about
1807 # Create a little structure to pass all the relevant information about
1810 # the current completion to any custom completer.
1808 # the current completion to any custom completer.
1811 event = SimpleNamespace()
1809 event = SimpleNamespace()
1812 event.line = line
1810 event.line = line
1813 event.symbol = text
1811 event.symbol = text
1814 cmd = line.split(None,1)[0]
1812 cmd = line.split(None,1)[0]
1815 event.command = cmd
1813 event.command = cmd
1816 event.text_until_cursor = self.text_until_cursor
1814 event.text_until_cursor = self.text_until_cursor
1817
1815
1818 # for foo etc, try also to find completer for %foo
1816 # for foo etc, try also to find completer for %foo
1819 if not cmd.startswith(self.magic_escape):
1817 if not cmd.startswith(self.magic_escape):
1820 try_magic = self.custom_completers.s_matches(
1818 try_magic = self.custom_completers.s_matches(
1821 self.magic_escape + cmd)
1819 self.magic_escape + cmd)
1822 else:
1820 else:
1823 try_magic = []
1821 try_magic = []
1824
1822
1825 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1823 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1826 try_magic,
1824 try_magic,
1827 self.custom_completers.flat_matches(self.text_until_cursor)):
1825 self.custom_completers.flat_matches(self.text_until_cursor)):
1828 try:
1826 try:
1829 res = c(event)
1827 res = c(event)
1830 if res:
1828 if res:
1831 # first, try case sensitive match
1829 # first, try case sensitive match
1832 withcase = [r for r in res if r.startswith(text)]
1830 withcase = [r for r in res if r.startswith(text)]
1833 if withcase:
1831 if withcase:
1834 return withcase
1832 return withcase
1835 # if none, then case insensitive ones are ok too
1833 # if none, then case insensitive ones are ok too
1836 text_low = text.lower()
1834 text_low = text.lower()
1837 return [r for r in res if r.lower().startswith(text_low)]
1835 return [r for r in res if r.lower().startswith(text_low)]
1838 except TryNext:
1836 except TryNext:
1839 pass
1837 pass
1840 except KeyboardInterrupt:
1838 except KeyboardInterrupt:
1841 """
1839 """
1842 If custom completer take too long,
1840 If custom completer take too long,
1843 let keyboard interrupt abort and return nothing.
1841 let keyboard interrupt abort and return nothing.
1844 """
1842 """
1845 break
1843 break
1846
1844
1847 return None
1845 return None
1848
1846
1849 def completions(self, text: str, offset: int)->Iterator[Completion]:
1847 def completions(self, text: str, offset: int)->Iterator[Completion]:
1850 """
1848 """
1851 Returns an iterator over the possible completions
1849 Returns an iterator over the possible completions
1852
1850
1853 .. warning:: Unstable
1851 .. warning:: Unstable
1854
1852
1855 This function is unstable, API may change without warning.
1853 This function is unstable, API may change without warning.
1856 It will also raise unless use in proper context manager.
1854 It will also raise unless use in proper context manager.
1857
1855
1858 Parameters
1856 Parameters
1859 ----------
1857 ----------
1860
1858
1861 text:str
1859 text:str
1862 Full text of the current input, multi line string.
1860 Full text of the current input, multi line string.
1863 offset:int
1861 offset:int
1864 Integer representing the position of the cursor in ``text``. Offset
1862 Integer representing the position of the cursor in ``text``. Offset
1865 is 0-based indexed.
1863 is 0-based indexed.
1866
1864
1867 Yields
1865 Yields
1868 ------
1866 ------
1869 :any:`Completion` object
1867 :any:`Completion` object
1870
1868
1871
1869
1872 The cursor on a text can either be seen as being "in between"
1870 The cursor on a text can either be seen as being "in between"
1873 characters or "On" a character depending on the interface visible to
1871 characters or "On" a character depending on the interface visible to
1874 the user. For consistency the cursor being on "in between" characters X
1872 the user. For consistency the cursor being on "in between" characters X
1875 and Y is equivalent to the cursor being "on" character Y, that is to say
1873 and Y is equivalent to the cursor being "on" character Y, that is to say
1876 the character the cursor is on is considered as being after the cursor.
1874 the character the cursor is on is considered as being after the cursor.
1877
1875
1878 Combining characters may span more that one position in the
1876 Combining characters may span more that one position in the
1879 text.
1877 text.
1880
1878
1881
1879
1882 .. note::
1880 .. note::
1883
1881
1884 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
1882 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
1885 fake Completion token to distinguish completion returned by Jedi
1883 fake Completion token to distinguish completion returned by Jedi
1886 and usual IPython completion.
1884 and usual IPython completion.
1887
1885
1888 .. note::
1886 .. note::
1889
1887
1890 Completions are not completely deduplicated yet. If identical
1888 Completions are not completely deduplicated yet. If identical
1891 completions are coming from different sources this function does not
1889 completions are coming from different sources this function does not
1892 ensure that each completion object will only be present once.
1890 ensure that each completion object will only be present once.
1893 """
1891 """
1894 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
1892 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
1895 "It may change without warnings. "
1893 "It may change without warnings. "
1896 "Use in corresponding context manager.",
1894 "Use in corresponding context manager.",
1897 category=ProvisionalCompleterWarning, stacklevel=2)
1895 category=ProvisionalCompleterWarning, stacklevel=2)
1898
1896
1899 seen = set()
1897 seen = set()
1900 profiler:Optional[cProfile.Profile]
1898 profiler:Optional[cProfile.Profile]
1901 try:
1899 try:
1902 if self.profile_completions:
1900 if self.profile_completions:
1903 import cProfile
1901 import cProfile
1904 profiler = cProfile.Profile()
1902 profiler = cProfile.Profile()
1905 profiler.enable()
1903 profiler.enable()
1906 else:
1904 else:
1907 profiler = None
1905 profiler = None
1908
1906
1909 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
1907 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
1910 if c and (c in seen):
1908 if c and (c in seen):
1911 continue
1909 continue
1912 yield c
1910 yield c
1913 seen.add(c)
1911 seen.add(c)
1914 except KeyboardInterrupt:
1912 except KeyboardInterrupt:
1915 """if completions take too long and users send keyboard interrupt,
1913 """if completions take too long and users send keyboard interrupt,
1916 do not crash and return ASAP. """
1914 do not crash and return ASAP. """
1917 pass
1915 pass
1918 finally:
1916 finally:
1919 if profiler is not None:
1917 if profiler is not None:
1920 profiler.disable()
1918 profiler.disable()
1921 ensure_dir_exists(self.profiler_output_dir)
1919 ensure_dir_exists(self.profiler_output_dir)
1922 output_path = os.path.join(self.profiler_output_dir, str(uuid.uuid4()))
1920 output_path = os.path.join(self.profiler_output_dir, str(uuid.uuid4()))
1923 print("Writing profiler output to", output_path)
1921 print("Writing profiler output to", output_path)
1924 profiler.dump_stats(output_path)
1922 profiler.dump_stats(output_path)
1925
1923
1926 def _completions(self, full_text: str, offset: int, *, _timeout) -> Iterator[Completion]:
1924 def _completions(self, full_text: str, offset: int, *, _timeout) -> Iterator[Completion]:
1927 """
1925 """
1928 Core completion module.Same signature as :any:`completions`, with the
1926 Core completion module.Same signature as :any:`completions`, with the
1929 extra `timeout` parameter (in seconds).
1927 extra `timeout` parameter (in seconds).
1930
1928
1931
1929
1932 Computing jedi's completion ``.type`` can be quite expensive (it is a
1930 Computing jedi's completion ``.type`` can be quite expensive (it is a
1933 lazy property) and can require some warm-up, more warm up than just
1931 lazy property) and can require some warm-up, more warm up than just
1934 computing the ``name`` of a completion. The warm-up can be :
1932 computing the ``name`` of a completion. The warm-up can be :
1935
1933
1936 - Long warm-up the first time a module is encountered after
1934 - Long warm-up the first time a module is encountered after
1937 install/update: actually build parse/inference tree.
1935 install/update: actually build parse/inference tree.
1938
1936
1939 - first time the module is encountered in a session: load tree from
1937 - first time the module is encountered in a session: load tree from
1940 disk.
1938 disk.
1941
1939
1942 We don't want to block completions for tens of seconds so we give the
1940 We don't want to block completions for tens of seconds so we give the
1943 completer a "budget" of ``_timeout`` seconds per invocation to compute
1941 completer a "budget" of ``_timeout`` seconds per invocation to compute
1944 completions types, the completions that have not yet been computed will
1942 completions types, the completions that have not yet been computed will
1945 be marked as "unknown" an will have a chance to be computed next round
1943 be marked as "unknown" an will have a chance to be computed next round
1946 are things get cached.
1944 are things get cached.
1947
1945
1948 Keep in mind that Jedi is not the only thing treating the completion so
1946 Keep in mind that Jedi is not the only thing treating the completion so
1949 keep the timeout short-ish as if we take more than 0.3 second we still
1947 keep the timeout short-ish as if we take more than 0.3 second we still
1950 have lots of processing to do.
1948 have lots of processing to do.
1951
1949
1952 """
1950 """
1953 deadline = time.monotonic() + _timeout
1951 deadline = time.monotonic() + _timeout
1954
1952
1955
1953
1956 before = full_text[:offset]
1954 before = full_text[:offset]
1957 cursor_line, cursor_column = position_to_cursor(full_text, offset)
1955 cursor_line, cursor_column = position_to_cursor(full_text, offset)
1958
1956
1959 matched_text, matches, matches_origin, jedi_matches = self._complete(
1957 matched_text, matches, matches_origin, jedi_matches = self._complete(
1960 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column)
1958 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column)
1961
1959
1962 iter_jm = iter(jedi_matches)
1960 iter_jm = iter(jedi_matches)
1963 if _timeout:
1961 if _timeout:
1964 for jm in iter_jm:
1962 for jm in iter_jm:
1965 try:
1963 try:
1966 type_ = jm.type
1964 type_ = jm.type
1967 except Exception:
1965 except Exception:
1968 if self.debug:
1966 if self.debug:
1969 print("Error in Jedi getting type of ", jm)
1967 print("Error in Jedi getting type of ", jm)
1970 type_ = None
1968 type_ = None
1971 delta = len(jm.name_with_symbols) - len(jm.complete)
1969 delta = len(jm.name_with_symbols) - len(jm.complete)
1972 if type_ == 'function':
1970 if type_ == 'function':
1973 signature = _make_signature(jm)
1971 signature = _make_signature(jm)
1974 else:
1972 else:
1975 signature = ''
1973 signature = ''
1976 yield Completion(start=offset - delta,
1974 yield Completion(start=offset - delta,
1977 end=offset,
1975 end=offset,
1978 text=jm.name_with_symbols,
1976 text=jm.name_with_symbols,
1979 type=type_,
1977 type=type_,
1980 signature=signature,
1978 signature=signature,
1981 _origin='jedi')
1979 _origin='jedi')
1982
1980
1983 if time.monotonic() > deadline:
1981 if time.monotonic() > deadline:
1984 break
1982 break
1985
1983
1986 for jm in iter_jm:
1984 for jm in iter_jm:
1987 delta = len(jm.name_with_symbols) - len(jm.complete)
1985 delta = len(jm.name_with_symbols) - len(jm.complete)
1988 yield Completion(start=offset - delta,
1986 yield Completion(start=offset - delta,
1989 end=offset,
1987 end=offset,
1990 text=jm.name_with_symbols,
1988 text=jm.name_with_symbols,
1991 type='<unknown>', # don't compute type for speed
1989 type='<unknown>', # don't compute type for speed
1992 _origin='jedi',
1990 _origin='jedi',
1993 signature='')
1991 signature='')
1994
1992
1995
1993
1996 start_offset = before.rfind(matched_text)
1994 start_offset = before.rfind(matched_text)
1997
1995
1998 # TODO:
1996 # TODO:
1999 # Suppress this, right now just for debug.
1997 # Suppress this, right now just for debug.
2000 if jedi_matches and matches and self.debug:
1998 if jedi_matches and matches and self.debug:
2001 yield Completion(start=start_offset, end=offset, text='--jedi/ipython--',
1999 yield Completion(start=start_offset, end=offset, text='--jedi/ipython--',
2002 _origin='debug', type='none', signature='')
2000 _origin='debug', type='none', signature='')
2003
2001
2004 # I'm unsure if this is always true, so let's assert and see if it
2002 # I'm unsure if this is always true, so let's assert and see if it
2005 # crash
2003 # crash
2006 assert before.endswith(matched_text)
2004 assert before.endswith(matched_text)
2007 for m, t in zip(matches, matches_origin):
2005 for m, t in zip(matches, matches_origin):
2008 yield Completion(start=start_offset, end=offset, text=m, _origin=t, signature='', type='<unknown>')
2006 yield Completion(start=start_offset, end=offset, text=m, _origin=t, signature='', type='<unknown>')
2009
2007
2010
2008
2011 def complete(self, text=None, line_buffer=None, cursor_pos=None) -> Tuple[str, Sequence[str]]:
2009 def complete(self, text=None, line_buffer=None, cursor_pos=None) -> Tuple[str, Sequence[str]]:
2012 """Find completions for the given text and line context.
2010 """Find completions for the given text and line context.
2013
2011
2014 Note that both the text and the line_buffer are optional, but at least
2012 Note that both the text and the line_buffer are optional, but at least
2015 one of them must be given.
2013 one of them must be given.
2016
2014
2017 Parameters
2015 Parameters
2018 ----------
2016 ----------
2019 text : string, optional
2017 text : string, optional
2020 Text to perform the completion on. If not given, the line buffer
2018 Text to perform the completion on. If not given, the line buffer
2021 is split using the instance's CompletionSplitter object.
2019 is split using the instance's CompletionSplitter object.
2022
2020
2023 line_buffer : string, optional
2021 line_buffer : string, optional
2024 If not given, the completer attempts to obtain the current line
2022 If not given, the completer attempts to obtain the current line
2025 buffer via readline. This keyword allows clients which are
2023 buffer via readline. This keyword allows clients which are
2026 requesting for text completions in non-readline contexts to inform
2024 requesting for text completions in non-readline contexts to inform
2027 the completer of the entire text.
2025 the completer of the entire text.
2028
2026
2029 cursor_pos : int, optional
2027 cursor_pos : int, optional
2030 Index of the cursor in the full line buffer. Should be provided by
2028 Index of the cursor in the full line buffer. Should be provided by
2031 remote frontends where kernel has no access to frontend state.
2029 remote frontends where kernel has no access to frontend state.
2032
2030
2033 Returns
2031 Returns
2034 -------
2032 -------
2035 Tuple of two items:
2033 Tuple of two items:
2036 text : str
2034 text : str
2037 Text that was actually used in the completion.
2035 Text that was actually used in the completion.
2038 matches : list
2036 matches : list
2039 A list of completion matches.
2037 A list of completion matches.
2040
2038
2041
2039
2042 .. note::
2040 .. note::
2043
2041
2044 This API is likely to be deprecated and replaced by
2042 This API is likely to be deprecated and replaced by
2045 :any:`IPCompleter.completions` in the future.
2043 :any:`IPCompleter.completions` in the future.
2046
2044
2047
2045
2048 """
2046 """
2049 warnings.warn('`Completer.complete` is pending deprecation since '
2047 warnings.warn('`Completer.complete` is pending deprecation since '
2050 'IPython 6.0 and will be replaced by `Completer.completions`.',
2048 'IPython 6.0 and will be replaced by `Completer.completions`.',
2051 PendingDeprecationWarning)
2049 PendingDeprecationWarning)
2052 # potential todo, FOLD the 3rd throw away argument of _complete
2050 # potential todo, FOLD the 3rd throw away argument of _complete
2053 # into the first 2 one.
2051 # into the first 2 one.
2054 return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2]
2052 return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2]
2055
2053
2056 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
2054 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
2057 full_text=None) -> _CompleteResult:
2055 full_text=None) -> _CompleteResult:
2058 """
2056 """
2059
2057
2060 Like complete but can also returns raw jedi completions as well as the
2058 Like complete but can also returns raw jedi completions as well as the
2061 origin of the completion text. This could (and should) be made much
2059 origin of the completion text. This could (and should) be made much
2062 cleaner but that will be simpler once we drop the old (and stateful)
2060 cleaner but that will be simpler once we drop the old (and stateful)
2063 :any:`complete` API.
2061 :any:`complete` API.
2064
2062
2065
2063
2066 With current provisional API, cursor_pos act both (depending on the
2064 With current provisional API, cursor_pos act both (depending on the
2067 caller) as the offset in the ``text`` or ``line_buffer``, or as the
2065 caller) as the offset in the ``text`` or ``line_buffer``, or as the
2068 ``column`` when passing multiline strings this could/should be renamed
2066 ``column`` when passing multiline strings this could/should be renamed
2069 but would add extra noise.
2067 but would add extra noise.
2070
2068
2071 Return
2069 Return
2072 ======
2070 ======
2073
2071
2074 A tuple of N elements which are (likely):
2072 A tuple of N elements which are (likely):
2075
2073
2076 matched_text: ? the text that the complete matched
2074 matched_text: ? the text that the complete matched
2077 matches: list of completions ?
2075 matches: list of completions ?
2078 matches_origin: ? list same lenght as matches, and where each completion came from
2076 matches_origin: ? list same lenght as matches, and where each completion came from
2079 jedi_matches: list of Jedi matches, have it's own structure.
2077 jedi_matches: list of Jedi matches, have it's own structure.
2080 """
2078 """
2081
2079
2082
2080
2083 # if the cursor position isn't given, the only sane assumption we can
2081 # if the cursor position isn't given, the only sane assumption we can
2084 # make is that it's at the end of the line (the common case)
2082 # make is that it's at the end of the line (the common case)
2085 if cursor_pos is None:
2083 if cursor_pos is None:
2086 cursor_pos = len(line_buffer) if text is None else len(text)
2084 cursor_pos = len(line_buffer) if text is None else len(text)
2087
2085
2088 if self.use_main_ns:
2086 if self.use_main_ns:
2089 self.namespace = __main__.__dict__
2087 self.namespace = __main__.__dict__
2090
2088
2091 # if text is either None or an empty string, rely on the line buffer
2089 # if text is either None or an empty string, rely on the line buffer
2092 if (not line_buffer) and full_text:
2090 if (not line_buffer) and full_text:
2093 line_buffer = full_text.split('\n')[cursor_line]
2091 line_buffer = full_text.split('\n')[cursor_line]
2094 if not text: # issue #11508: check line_buffer before calling split_line
2092 if not text: # issue #11508: check line_buffer before calling split_line
2095 text = self.splitter.split_line(line_buffer, cursor_pos) if line_buffer else ''
2093 text = self.splitter.split_line(line_buffer, cursor_pos) if line_buffer else ''
2096
2094
2097 if self.backslash_combining_completions:
2095 if self.backslash_combining_completions:
2098 # allow deactivation of these on windows.
2096 # allow deactivation of these on windows.
2099 base_text = text if not line_buffer else line_buffer[:cursor_pos]
2097 base_text = text if not line_buffer else line_buffer[:cursor_pos]
2100
2098
2101 for meth in (self.latex_matches,
2099 for meth in (self.latex_matches,
2102 self.unicode_name_matches,
2100 self.unicode_name_matches,
2103 back_latex_name_matches,
2101 back_latex_name_matches,
2104 back_unicode_name_matches,
2102 back_unicode_name_matches,
2105 self.fwd_unicode_match):
2103 self.fwd_unicode_match):
2106 name_text, name_matches = meth(base_text)
2104 name_text, name_matches = meth(base_text)
2107 if name_text:
2105 if name_text:
2108 return _CompleteResult(name_text, name_matches[:MATCHES_LIMIT], \
2106 return _CompleteResult(name_text, name_matches[:MATCHES_LIMIT], \
2109 [meth.__qualname__]*min(len(name_matches), MATCHES_LIMIT), ())
2107 [meth.__qualname__]*min(len(name_matches), MATCHES_LIMIT), ())
2110
2108
2111
2109
2112 # If no line buffer is given, assume the input text is all there was
2110 # If no line buffer is given, assume the input text is all there was
2113 if line_buffer is None:
2111 if line_buffer is None:
2114 line_buffer = text
2112 line_buffer = text
2115
2113
2116 self.line_buffer = line_buffer
2114 self.line_buffer = line_buffer
2117 self.text_until_cursor = self.line_buffer[:cursor_pos]
2115 self.text_until_cursor = self.line_buffer[:cursor_pos]
2118
2116
2119 # Do magic arg matches
2117 # Do magic arg matches
2120 for matcher in self.magic_arg_matchers:
2118 for matcher in self.magic_arg_matchers:
2121 matches = list(matcher(line_buffer))[:MATCHES_LIMIT]
2119 matches = list(matcher(line_buffer))[:MATCHES_LIMIT]
2122 if matches:
2120 if matches:
2123 origins = [matcher.__qualname__] * len(matches)
2121 origins = [matcher.__qualname__] * len(matches)
2124 return _CompleteResult(text, matches, origins, ())
2122 return _CompleteResult(text, matches, origins, ())
2125
2123
2126 # Start with a clean slate of completions
2124 # Start with a clean slate of completions
2127 matches = []
2125 matches = []
2128
2126
2129 # FIXME: we should extend our api to return a dict with completions for
2127 # FIXME: we should extend our api to return a dict with completions for
2130 # different types of objects. The rlcomplete() method could then
2128 # different types of objects. The rlcomplete() method could then
2131 # simply collapse the dict into a list for readline, but we'd have
2129 # simply collapse the dict into a list for readline, but we'd have
2132 # richer completion semantics in other environments.
2130 # richer completion semantics in other environments.
2133 completions:Iterable[Any] = []
2131 completions:Iterable[Any] = []
2134 if self.use_jedi:
2132 if self.use_jedi:
2135 if not full_text:
2133 if not full_text:
2136 full_text = line_buffer
2134 full_text = line_buffer
2137 completions = self._jedi_matches(
2135 completions = self._jedi_matches(
2138 cursor_pos, cursor_line, full_text)
2136 cursor_pos, cursor_line, full_text)
2139
2137
2140 if self.merge_completions:
2138 if self.merge_completions:
2141 matches = []
2139 matches = []
2142 for matcher in self.matchers:
2140 for matcher in self.matchers:
2143 try:
2141 try:
2144 matches.extend([(m, matcher.__qualname__)
2142 matches.extend([(m, matcher.__qualname__)
2145 for m in matcher(text)])
2143 for m in matcher(text)])
2146 except:
2144 except:
2147 # Show the ugly traceback if the matcher causes an
2145 # Show the ugly traceback if the matcher causes an
2148 # exception, but do NOT crash the kernel!
2146 # exception, but do NOT crash the kernel!
2149 sys.excepthook(*sys.exc_info())
2147 sys.excepthook(*sys.exc_info())
2150 else:
2148 else:
2151 for matcher in self.matchers:
2149 for matcher in self.matchers:
2152 matches = [(m, matcher.__qualname__)
2150 matches = [(m, matcher.__qualname__)
2153 for m in matcher(text)]
2151 for m in matcher(text)]
2154 if matches:
2152 if matches:
2155 break
2153 break
2156
2154
2157 seen = set()
2155 seen = set()
2158 filtered_matches = set()
2156 filtered_matches = set()
2159 for m in matches:
2157 for m in matches:
2160 t, c = m
2158 t, c = m
2161 if t not in seen:
2159 if t not in seen:
2162 filtered_matches.add(m)
2160 filtered_matches.add(m)
2163 seen.add(t)
2161 seen.add(t)
2164
2162
2165 _filtered_matches = sorted(filtered_matches, key=lambda x: completions_sorting_key(x[0]))
2163 _filtered_matches = sorted(filtered_matches, key=lambda x: completions_sorting_key(x[0]))
2166
2164
2167 custom_res = [(m, 'custom') for m in self.dispatch_custom_completer(text) or []]
2165 custom_res = [(m, 'custom') for m in self.dispatch_custom_completer(text) or []]
2168
2166
2169 _filtered_matches = custom_res or _filtered_matches
2167 _filtered_matches = custom_res or _filtered_matches
2170
2168
2171 _filtered_matches = _filtered_matches[:MATCHES_LIMIT]
2169 _filtered_matches = _filtered_matches[:MATCHES_LIMIT]
2172 _matches = [m[0] for m in _filtered_matches]
2170 _matches = [m[0] for m in _filtered_matches]
2173 origins = [m[1] for m in _filtered_matches]
2171 origins = [m[1] for m in _filtered_matches]
2174
2172
2175 self.matches = _matches
2173 self.matches = _matches
2176
2174
2177 return _CompleteResult(text, _matches, origins, completions)
2175 return _CompleteResult(text, _matches, origins, completions)
2178
2176
2179 def fwd_unicode_match(self, text:str) -> Tuple[str, Sequence[str]]:
2177 def fwd_unicode_match(self, text:str) -> Tuple[str, Sequence[str]]:
2180 """
2178 """
2181
2179
2182 Forward match a string starting with a backslash with a list of
2180 Forward match a string starting with a backslash with a list of
2183 potential Unicode completions.
2181 potential Unicode completions.
2184
2182
2185 Will compute list list of Unicode character names on first call and cache it.
2183 Will compute list list of Unicode character names on first call and cache it.
2186
2184
2187 Return
2185 Return
2188 ======
2186 ======
2189
2187
2190 At tuple with:
2188 At tuple with:
2191 - matched text (empty if no matches)
2189 - matched text (empty if no matches)
2192 - list of potential completions, empty tuple otherwise)
2190 - list of potential completions, empty tuple otherwise)
2193 """
2191 """
2194 # TODO: self.unicode_names is here a list we traverse each time with ~100k elements.
2192 # TODO: self.unicode_names is here a list we traverse each time with ~100k elements.
2195 # We could do a faster match using a Trie.
2193 # We could do a faster match using a Trie.
2196
2194
2197 # Using pygtrie the follwing seem to work:
2195 # Using pygtrie the follwing seem to work:
2198
2196
2199 # s = PrefixSet()
2197 # s = PrefixSet()
2200
2198
2201 # for c in range(0,0x10FFFF + 1):
2199 # for c in range(0,0x10FFFF + 1):
2202 # try:
2200 # try:
2203 # s.add(unicodedata.name(chr(c)))
2201 # s.add(unicodedata.name(chr(c)))
2204 # except ValueError:
2202 # except ValueError:
2205 # pass
2203 # pass
2206 # [''.join(k) for k in s.iter(prefix)]
2204 # [''.join(k) for k in s.iter(prefix)]
2207
2205
2208 # But need to be timed and adds an extra dependency.
2206 # But need to be timed and adds an extra dependency.
2209
2207
2210 slashpos = text.rfind('\\')
2208 slashpos = text.rfind('\\')
2211 # if text starts with slash
2209 # if text starts with slash
2212 if slashpos > -1:
2210 if slashpos > -1:
2213 # PERF: It's important that we don't access self._unicode_names
2211 # PERF: It's important that we don't access self._unicode_names
2214 # until we're inside this if-block. _unicode_names is lazily
2212 # until we're inside this if-block. _unicode_names is lazily
2215 # initialized, and it takes a user-noticeable amount of time to
2213 # initialized, and it takes a user-noticeable amount of time to
2216 # initialize it, so we don't want to initialize it unless we're
2214 # initialize it, so we don't want to initialize it unless we're
2217 # actually going to use it.
2215 # actually going to use it.
2218 s = text[slashpos+1:]
2216 s = text[slashpos+1:]
2219 candidates = [x for x in self.unicode_names if x.startswith(s)]
2217 candidates = [x for x in self.unicode_names if x.startswith(s)]
2220 if candidates:
2218 if candidates:
2221 return s, candidates
2219 return s, candidates
2222 else:
2220 else:
2223 return '', ()
2221 return '', ()
2224
2222
2225 # if text does not start with slash
2223 # if text does not start with slash
2226 else:
2224 else:
2227 return '', ()
2225 return '', ()
2228
2226
2229 @property
2227 @property
2230 def unicode_names(self) -> List[str]:
2228 def unicode_names(self) -> List[str]:
2231 """List of names of unicode code points that can be completed.
2229 """List of names of unicode code points that can be completed.
2232
2230
2233 The list is lazily initialized on first access.
2231 The list is lazily initialized on first access.
2234 """
2232 """
2235 if self._unicode_names is None:
2233 if self._unicode_names is None:
2236 names = []
2234 names = []
2237 for c in range(0,0x10FFFF + 1):
2235 for c in range(0,0x10FFFF + 1):
2238 try:
2236 try:
2239 names.append(unicodedata.name(chr(c)))
2237 names.append(unicodedata.name(chr(c)))
2240 except ValueError:
2238 except ValueError:
2241 pass
2239 pass
2242 self._unicode_names = _unicode_name_compute(_UNICODE_RANGES)
2240 self._unicode_names = _unicode_name_compute(_UNICODE_RANGES)
2243
2241
2244 return self._unicode_names
2242 return self._unicode_names
2245
2243
2246 def _unicode_name_compute(ranges:List[Tuple[int,int]]) -> List[str]:
2244 def _unicode_name_compute(ranges:List[Tuple[int,int]]) -> List[str]:
2247 names = []
2245 names = []
2248 for start,stop in ranges:
2246 for start,stop in ranges:
2249 for c in range(start, stop) :
2247 for c in range(start, stop) :
2250 try:
2248 try:
2251 names.append(unicodedata.name(chr(c)))
2249 names.append(unicodedata.name(chr(c)))
2252 except ValueError:
2250 except ValueError:
2253 pass
2251 pass
2254 return names
2252 return names
General Comments 0
You need to be logged in to leave comments. Login now