##// END OF EJS Templates
Merge pull request #10244 from Carreau/protect-jedi...
Thomas Kluyver -
r23324:036091f9 merge
parent child Browse files
Show More
@@ -1,1736 +1,1742
1 # encoding: utf-8
1 # encoding: utf-8
2 """Completion for IPython.
2 """Completion for IPython.
3
3
4 This module started as fork of the rlcompleter module in the Python standard
4 This module started as fork of the rlcompleter module in the Python standard
5 library. The original enhancements made to rlcompleter have been sent
5 library. The original enhancements made to rlcompleter have been sent
6 upstream and were accepted as of Python 2.3,
6 upstream and were accepted as of Python 2.3,
7
7
8 This module now support a wide variety of completion mechanism both available
8 This module now support a wide variety of completion mechanism both available
9 for normal classic Python code, as well as completer for IPython specific
9 for normal classic Python code, as well as completer for IPython specific
10 Syntax like magics.
10 Syntax like magics.
11
11
12 Experimental
12 Experimental
13 ============
13 ============
14
14
15 Starting with IPython 6.0, this module can make use of the Jedi library to
15 Starting with IPython 6.0, this module can make use of the Jedi library to
16 generate completions both using static analysis of the code, and dynamically
16 generate completions both using static analysis of the code, and dynamically
17 inspecting multiple namespaces. The APIs attached to this new mechanism is
17 inspecting multiple namespaces. The APIs attached to this new mechanism is
18 unstable and will raise unless use in an :any:`provisionalcompleter` context
18 unstable and will raise unless use in an :any:`provisionalcompleter` context
19 manager.
19 manager.
20
20
21 You will find that the following are experimental:
21 You will find that the following are experimental:
22
22
23 - :any:`provisionalcompleter`
23 - :any:`provisionalcompleter`
24 - :any:`IPCompleter.completions`
24 - :any:`IPCompleter.completions`
25 - :any:`Completion`
25 - :any:`Completion`
26 - :any:`rectify_completions`
26 - :any:`rectify_completions`
27
27
28 .. note::
28 .. note::
29
29
30 better name for :any:`rectify_completions` ?
30 better name for :any:`rectify_completions` ?
31
31
32 We welcome any feedback on these new API, and we also encourage you to try this
32 We welcome any feedback on these new API, and we also encourage you to try this
33 module in debug mode (start IPython with ``--Completer.debug=True``) in order
33 module in debug mode (start IPython with ``--Completer.debug=True``) in order
34 to have extra logging information is :any:`jedi` is crashing, or if current
34 to have extra logging information is :any:`jedi` is crashing, or if current
35 IPython completer pending deprecations are returning results not yet handled
35 IPython completer pending deprecations are returning results not yet handled
36 by :any:`jedi`.
36 by :any:`jedi`.
37
37
38 Using Jedi for tab completion allow snippets like the following to work without
38 Using Jedi for tab completion allow snippets like the following to work without
39 having to execute any code:
39 having to execute any code:
40
40
41 >>> myvar = ['hello', 42]
41 >>> myvar = ['hello', 42]
42 ... myvar[1].bi<tab>
42 ... myvar[1].bi<tab>
43
43
44 Tab completion will be able to infer that ``myvar[1]`` is a real number without
44 Tab completion will be able to infer that ``myvar[1]`` is a real number without
45 executing any code unlike the previously available ``IPCompleter.greedy``
45 executing any code unlike the previously available ``IPCompleter.greedy``
46 option.
46 option.
47
47
48 Be sure to update :any:`jedi` to the latest stable version or to try the
48 Be sure to update :any:`jedi` to the latest stable version or to try the
49 current development version to get better completions.
49 current development version to get better completions.
50 """
50 """
51
51
52 # skip module docstests
52 # skip module docstests
53 skip_doctest = True
53 skip_doctest = True
54
54
55 # Copyright (c) IPython Development Team.
55 # Copyright (c) IPython Development Team.
56 # Distributed under the terms of the Modified BSD License.
56 # Distributed under the terms of the Modified BSD License.
57 #
57 #
58 # Some of this code originated from rlcompleter in the Python standard library
58 # Some of this code originated from rlcompleter in the Python standard library
59 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 # Copyright (C) 2001 Python Software Foundation, www.python.org
60
60
61
61
62 import __main__
62 import __main__
63 import builtins as builtin_mod
63 import builtins as builtin_mod
64 import glob
64 import glob
65 import time
65 import time
66 import inspect
66 import inspect
67 import itertools
67 import itertools
68 import keyword
68 import keyword
69 import os
69 import os
70 import re
70 import re
71 import sys
71 import sys
72 import unicodedata
72 import unicodedata
73 import string
73 import string
74 import warnings
74 import warnings
75
75
76 from contextlib import contextmanager
76 from contextlib import contextmanager
77 from importlib import import_module
77 from importlib import import_module
78 from typing import Iterator, List
78 from typing import Iterator, List
79 from types import SimpleNamespace
79 from types import SimpleNamespace
80
80
81 from traitlets.config.configurable import Configurable
81 from traitlets.config.configurable import Configurable
82 from IPython.core.error import TryNext
82 from IPython.core.error import TryNext
83 from IPython.core.inputsplitter import ESC_MAGIC
83 from IPython.core.inputsplitter import ESC_MAGIC
84 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
84 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
85 from IPython.utils import generics
85 from IPython.utils import generics
86 from IPython.utils.dir2 import dir2, get_real_method
86 from IPython.utils.dir2 import dir2, get_real_method
87 from IPython.utils.process import arg_split
87 from IPython.utils.process import arg_split
88 from IPython.utils.py3compat import cast_unicode_py2
88 from IPython.utils.py3compat import cast_unicode_py2
89 from traitlets import Bool, Enum, observe, Int
89 from traitlets import Bool, Enum, observe, Int
90
90
91 try:
91 try:
92 import jedi
92 import jedi
93 import jedi.api.helpers
93 import jedi.api.helpers
94 JEDI_INSTALLED = True
94 JEDI_INSTALLED = True
95 except ImportError:
95 except ImportError:
96 JEDI_INSTALLED = False
96 JEDI_INSTALLED = False
97 #-----------------------------------------------------------------------------
97 #-----------------------------------------------------------------------------
98 # Globals
98 # Globals
99 #-----------------------------------------------------------------------------
99 #-----------------------------------------------------------------------------
100
100
101 # Public API
101 # Public API
102 __all__ = ['Completer','IPCompleter']
102 __all__ = ['Completer','IPCompleter']
103
103
104 if sys.platform == 'win32':
104 if sys.platform == 'win32':
105 PROTECTABLES = ' '
105 PROTECTABLES = ' '
106 else:
106 else:
107 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
107 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
108
108
109
109
110 _deprecation_readline_sentinel = object()
110 _deprecation_readline_sentinel = object()
111
111
112
112
113 class ProvisionalCompleterWarning(FutureWarning):
113 class ProvisionalCompleterWarning(FutureWarning):
114 """
114 """
115 Exception raise by an experimental feature in this module.
115 Exception raise by an experimental feature in this module.
116
116
117 Wrap code in :any:`provisionalcompleter` context manager if you
117 Wrap code in :any:`provisionalcompleter` context manager if you
118 are certain you want to use an unstable feature.
118 are certain you want to use an unstable feature.
119 """
119 """
120 pass
120 pass
121
121
122 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
122 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
123
123
124 @contextmanager
124 @contextmanager
125 def provisionalcompleter(action='ignore'):
125 def provisionalcompleter(action='ignore'):
126 """
126 """
127
127
128
128
129 This contest manager has to be used in any place where unstable completer
129 This contest manager has to be used in any place where unstable completer
130 behavior and API may be called.
130 behavior and API may be called.
131
131
132 >>> with provisionalcompleter():
132 >>> with provisionalcompleter():
133 ... completer.do_experimetal_things() # works
133 ... completer.do_experimetal_things() # works
134
134
135 >>> completer.do_experimental_things() # raises.
135 >>> completer.do_experimental_things() # raises.
136
136
137 .. note:: Unstable
137 .. note:: Unstable
138
138
139 By using this context manager you agree that the API in use may change
139 By using this context manager you agree that the API in use may change
140 without warning, and that you won't complain if they do so.
140 without warning, and that you won't complain if they do so.
141
141
142 You also understand that if the API is not to you liking you should report
142 You also understand that if the API is not to you liking you should report
143 a bug to explain your use case upstream and improve the API and will loose
143 a bug to explain your use case upstream and improve the API and will loose
144 credibility if you complain after the API is make stable.
144 credibility if you complain after the API is make stable.
145
145
146 We'll be happy to get your feedback , feature request and improvement on
146 We'll be happy to get your feedback , feature request and improvement on
147 any of the unstable APIs !
147 any of the unstable APIs !
148 """
148 """
149 with warnings.catch_warnings():
149 with warnings.catch_warnings():
150 warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
150 warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
151 yield
151 yield
152
152
153
153
154 def has_open_quotes(s):
154 def has_open_quotes(s):
155 """Return whether a string has open quotes.
155 """Return whether a string has open quotes.
156
156
157 This simply counts whether the number of quote characters of either type in
157 This simply counts whether the number of quote characters of either type in
158 the string is odd.
158 the string is odd.
159
159
160 Returns
160 Returns
161 -------
161 -------
162 If there is an open quote, the quote character is returned. Else, return
162 If there is an open quote, the quote character is returned. Else, return
163 False.
163 False.
164 """
164 """
165 # We check " first, then ', so complex cases with nested quotes will get
165 # We check " first, then ', so complex cases with nested quotes will get
166 # the " to take precedence.
166 # the " to take precedence.
167 if s.count('"') % 2:
167 if s.count('"') % 2:
168 return '"'
168 return '"'
169 elif s.count("'") % 2:
169 elif s.count("'") % 2:
170 return "'"
170 return "'"
171 else:
171 else:
172 return False
172 return False
173
173
174
174
175 def protect_filename(s):
175 def protect_filename(s):
176 """Escape a string to protect certain characters."""
176 """Escape a string to protect certain characters."""
177 if set(s) & set(PROTECTABLES):
177 if set(s) & set(PROTECTABLES):
178 if sys.platform == "win32":
178 if sys.platform == "win32":
179 return '"' + s + '"'
179 return '"' + s + '"'
180 else:
180 else:
181 return "".join(("\\" + c if c in PROTECTABLES else c) for c in s)
181 return "".join(("\\" + c if c in PROTECTABLES else c) for c in s)
182 else:
182 else:
183 return s
183 return s
184
184
185
185
186 def expand_user(path):
186 def expand_user(path):
187 """Expand ``~``-style usernames in strings.
187 """Expand ``~``-style usernames in strings.
188
188
189 This is similar to :func:`os.path.expanduser`, but it computes and returns
189 This is similar to :func:`os.path.expanduser`, but it computes and returns
190 extra information that will be useful if the input was being used in
190 extra information that will be useful if the input was being used in
191 computing completions, and you wish to return the completions with the
191 computing completions, and you wish to return the completions with the
192 original '~' instead of its expanded value.
192 original '~' instead of its expanded value.
193
193
194 Parameters
194 Parameters
195 ----------
195 ----------
196 path : str
196 path : str
197 String to be expanded. If no ~ is present, the output is the same as the
197 String to be expanded. If no ~ is present, the output is the same as the
198 input.
198 input.
199
199
200 Returns
200 Returns
201 -------
201 -------
202 newpath : str
202 newpath : str
203 Result of ~ expansion in the input path.
203 Result of ~ expansion in the input path.
204 tilde_expand : bool
204 tilde_expand : bool
205 Whether any expansion was performed or not.
205 Whether any expansion was performed or not.
206 tilde_val : str
206 tilde_val : str
207 The value that ~ was replaced with.
207 The value that ~ was replaced with.
208 """
208 """
209 # Default values
209 # Default values
210 tilde_expand = False
210 tilde_expand = False
211 tilde_val = ''
211 tilde_val = ''
212 newpath = path
212 newpath = path
213
213
214 if path.startswith('~'):
214 if path.startswith('~'):
215 tilde_expand = True
215 tilde_expand = True
216 rest = len(path)-1
216 rest = len(path)-1
217 newpath = os.path.expanduser(path)
217 newpath = os.path.expanduser(path)
218 if rest:
218 if rest:
219 tilde_val = newpath[:-rest]
219 tilde_val = newpath[:-rest]
220 else:
220 else:
221 tilde_val = newpath
221 tilde_val = newpath
222
222
223 return newpath, tilde_expand, tilde_val
223 return newpath, tilde_expand, tilde_val
224
224
225
225
226 def compress_user(path, tilde_expand, tilde_val):
226 def compress_user(path, tilde_expand, tilde_val):
227 """Does the opposite of expand_user, with its outputs.
227 """Does the opposite of expand_user, with its outputs.
228 """
228 """
229 if tilde_expand:
229 if tilde_expand:
230 return path.replace(tilde_val, '~')
230 return path.replace(tilde_val, '~')
231 else:
231 else:
232 return path
232 return path
233
233
234
234
235 def completions_sorting_key(word):
235 def completions_sorting_key(word):
236 """key for sorting completions
236 """key for sorting completions
237
237
238 This does several things:
238 This does several things:
239
239
240 - Lowercase all completions, so they are sorted alphabetically with
240 - Lowercase all completions, so they are sorted alphabetically with
241 upper and lower case words mingled
241 upper and lower case words mingled
242 - Demote any completions starting with underscores to the end
242 - Demote any completions starting with underscores to the end
243 - Insert any %magic and %%cellmagic completions in the alphabetical order
243 - Insert any %magic and %%cellmagic completions in the alphabetical order
244 by their name
244 by their name
245 """
245 """
246 # Case insensitive sort
246 # Case insensitive sort
247 word = word.lower()
247 word = word.lower()
248
248
249 prio1, prio2 = 0, 0
249 prio1, prio2 = 0, 0
250
250
251 if word.startswith('__'):
251 if word.startswith('__'):
252 prio1 = 2
252 prio1 = 2
253 elif word.startswith('_'):
253 elif word.startswith('_'):
254 prio1 = 1
254 prio1 = 1
255
255
256 if word.endswith('='):
256 if word.endswith('='):
257 prio1 = -1
257 prio1 = -1
258
258
259 if word.startswith('%%'):
259 if word.startswith('%%'):
260 # If there's another % in there, this is something else, so leave it alone
260 # If there's another % in there, this is something else, so leave it alone
261 if not "%" in word[2:]:
261 if not "%" in word[2:]:
262 word = word[2:]
262 word = word[2:]
263 prio2 = 2
263 prio2 = 2
264 elif word.startswith('%'):
264 elif word.startswith('%'):
265 if not "%" in word[1:]:
265 if not "%" in word[1:]:
266 word = word[1:]
266 word = word[1:]
267 prio2 = 1
267 prio2 = 1
268
268
269 return prio1, word, prio2
269 return prio1, word, prio2
270
270
271
271
272 class _FakeJediCompletion:
272 class _FakeJediCompletion:
273 """
273 """
274 This is a workaround to communicate to the UI that Jedi has crashed and to
274 This is a workaround to communicate to the UI that Jedi has crashed and to
275 report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
275 report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
276
276
277 Added in IPython 6.0 so should likely be removed for 7.0
277 Added in IPython 6.0 so should likely be removed for 7.0
278
278
279 """
279 """
280
280
281 def __init__(self, name):
281 def __init__(self, name):
282
282
283 self.name = name
283 self.name = name
284 self.complete = name
284 self.complete = name
285 self.type = 'crashed'
285 self.type = 'crashed'
286 self.name_with_symbols = name
286 self.name_with_symbols = name
287
287
288 def __repr__(self):
288 def __repr__(self):
289 return '<Fake completion object jedi has crashed>'
289 return '<Fake completion object jedi has crashed>'
290
290
291
291
292 class Completion:
292 class Completion:
293 """
293 """
294 Completion object used and return by IPython completers.
294 Completion object used and return by IPython completers.
295
295
296 .. warning:: Unstable
296 .. warning:: Unstable
297
297
298 This function is unstable, API may change without warning.
298 This function is unstable, API may change without warning.
299 It will also raise unless use in proper context manager.
299 It will also raise unless use in proper context manager.
300
300
301 This act as a middle ground :any:`Completion` object between the
301 This act as a middle ground :any:`Completion` object between the
302 :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
302 :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
303 object. While Jedi need a lot of information about evaluator and how the
303 object. While Jedi need a lot of information about evaluator and how the
304 code should be ran/inspected, PromptToolkit (and other frontend) mostly
304 code should be ran/inspected, PromptToolkit (and other frontend) mostly
305 need user facing information.
305 need user facing information.
306
306
307 - Which range should be replaced replaced by what.
307 - Which range should be replaced replaced by what.
308 - Some metadata (like completion type), or meta informations to displayed to
308 - Some metadata (like completion type), or meta informations to displayed to
309 the use user.
309 the use user.
310
310
311 For debugging purpose we can also store the origin of the completion (``jedi``,
311 For debugging purpose we can also store the origin of the completion (``jedi``,
312 ``IPython.python_matches``, ``IPython.magics_matches``...).
312 ``IPython.python_matches``, ``IPython.magics_matches``...).
313 """
313 """
314
314
315 def __init__(self, start: int, end: int, text: str, *, type: str=None, _origin=''):
315 def __init__(self, start: int, end: int, text: str, *, type: str=None, _origin=''):
316 warnings.warn("``Completion`` is a provisional API (as of IPython 6.0). "
316 warnings.warn("``Completion`` is a provisional API (as of IPython 6.0). "
317 "It may change without warnings. "
317 "It may change without warnings. "
318 "Use in corresponding context manager.",
318 "Use in corresponding context manager.",
319 category=ProvisionalCompleterWarning, stacklevel=2)
319 category=ProvisionalCompleterWarning, stacklevel=2)
320
320
321 self.start = start
321 self.start = start
322 self.end = end
322 self.end = end
323 self.text = text
323 self.text = text
324 self.type = type
324 self.type = type
325 self._origin = _origin
325 self._origin = _origin
326
326
327 def __repr__(self):
327 def __repr__(self):
328 return '<Completion start=%s end=%s text=%r type=%r>' % (self.start, self.end, self.text, self.type or '?')
328 return '<Completion start=%s end=%s text=%r type=%r>' % (self.start, self.end, self.text, self.type or '?')
329
329
330 def __eq__(self, other)->Bool:
330 def __eq__(self, other)->Bool:
331 """
331 """
332 Equality and hash do not hash the type (as some completer may not be
332 Equality and hash do not hash the type (as some completer may not be
333 able to infer the type), but are use to (partially) de-duplicate
333 able to infer the type), but are use to (partially) de-duplicate
334 completion.
334 completion.
335
335
336 Completely de-duplicating completion is a bit tricker that just
336 Completely de-duplicating completion is a bit tricker that just
337 comparing as it depends on surrounding text, which Completions are not
337 comparing as it depends on surrounding text, which Completions are not
338 aware of.
338 aware of.
339 """
339 """
340 return self.start == other.start and \
340 return self.start == other.start and \
341 self.end == other.end and \
341 self.end == other.end and \
342 self.text == other.text
342 self.text == other.text
343
343
344 def __hash__(self):
344 def __hash__(self):
345 return hash((self.start, self.end, self.text))
345 return hash((self.start, self.end, self.text))
346
346
347 _IC = Iterator[Completion]
347 _IC = Iterator[Completion]
348
348
349 def rectify_completions(text:str, completion:_IC, *, _debug=False)->_IC:
349 def rectify_completions(text:str, completion:_IC, *, _debug=False)->_IC:
350 """
350 """
351 Rectify a set of completion to all have the same ``start`` and ``end``
351 Rectify a set of completion to all have the same ``start`` and ``end``
352
352
353 .. warning:: Unstable
353 .. warning:: Unstable
354
354
355 This function is unstable, API may change without warning.
355 This function is unstable, API may change without warning.
356 It will also raise unless use in proper context manager.
356 It will also raise unless use in proper context manager.
357
357
358 Parameters
358 Parameters
359 ----------
359 ----------
360 text: str
360 text: str
361 text that should be completed.
361 text that should be completed.
362 completion: Iterator[Completion]
362 completion: Iterator[Completion]
363 iterator over the completions to rectify
363 iterator over the completions to rectify
364
364
365
365
366 :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
366 :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
367 the Jupyter Protocol requires them to behave like so. This will readjust
367 the Jupyter Protocol requires them to behave like so. This will readjust
368 the completion to have the same ``start`` and ``end` by padding both
368 the completion to have the same ``start`` and ``end` by padding both
369 extremities with surrounding text.
369 extremities with surrounding text.
370
370
371 During stabilisation should support a ``_debug`` option to log which
371 During stabilisation should support a ``_debug`` option to log which
372 completion are return by the IPython completer and not found in Jedi in
372 completion are return by the IPython completer and not found in Jedi in
373 order to make upstream bug report.
373 order to make upstream bug report.
374 """
374 """
375 warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
375 warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
376 "It may change without warnings. "
376 "It may change without warnings. "
377 "Use in corresponding context manager.",
377 "Use in corresponding context manager.",
378 category=ProvisionalCompleterWarning, stacklevel=2)
378 category=ProvisionalCompleterWarning, stacklevel=2)
379
379
380 completions = list(completion)
380 completions = list(completion)
381 if not completions:
381 if not completions:
382 return
382 return
383 starts = (c.start for c in completions)
383 starts = (c.start for c in completions)
384 ends = (c.end for c in completions)
384 ends = (c.end for c in completions)
385
385
386 new_start = min(starts)
386 new_start = min(starts)
387 new_end = max(ends)
387 new_end = max(ends)
388
388
389 seen_jedi = set()
389 seen_jedi = set()
390 seen_python_matches = set()
390 seen_python_matches = set()
391 for c in completions:
391 for c in completions:
392 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
392 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
393 if c._origin == 'jedi':
393 if c._origin == 'jedi':
394 seen_jedi.add(new_text)
394 seen_jedi.add(new_text)
395 elif c._origin == 'IPCompleter.python_matches':
395 elif c._origin == 'IPCompleter.python_matches':
396 seen_python_matches.add(new_text)
396 seen_python_matches.add(new_text)
397 yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin)
397 yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin)
398 diff = seen_python_matches.difference(seen_jedi)
398 diff = seen_python_matches.difference(seen_jedi)
399 if diff and _debug:
399 if diff and _debug:
400 print('IPython.python matches have extras:', diff)
400 print('IPython.python matches have extras:', diff)
401
401
402
402
403 if sys.platform == 'win32':
403 if sys.platform == 'win32':
404 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
404 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
405 else:
405 else:
406 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
406 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
407
407
408 GREEDY_DELIMS = ' =\r\n'
408 GREEDY_DELIMS = ' =\r\n'
409
409
410
410
411 class CompletionSplitter(object):
411 class CompletionSplitter(object):
412 """An object to split an input line in a manner similar to readline.
412 """An object to split an input line in a manner similar to readline.
413
413
414 By having our own implementation, we can expose readline-like completion in
414 By having our own implementation, we can expose readline-like completion in
415 a uniform manner to all frontends. This object only needs to be given the
415 a uniform manner to all frontends. This object only needs to be given the
416 line of text to be split and the cursor position on said line, and it
416 line of text to be split and the cursor position on said line, and it
417 returns the 'word' to be completed on at the cursor after splitting the
417 returns the 'word' to be completed on at the cursor after splitting the
418 entire line.
418 entire line.
419
419
420 What characters are used as splitting delimiters can be controlled by
420 What characters are used as splitting delimiters can be controlled by
421 setting the ``delims`` attribute (this is a property that internally
421 setting the ``delims`` attribute (this is a property that internally
422 automatically builds the necessary regular expression)"""
422 automatically builds the necessary regular expression)"""
423
423
424 # Private interface
424 # Private interface
425
425
426 # A string of delimiter characters. The default value makes sense for
426 # A string of delimiter characters. The default value makes sense for
427 # IPython's most typical usage patterns.
427 # IPython's most typical usage patterns.
428 _delims = DELIMS
428 _delims = DELIMS
429
429
430 # The expression (a normal string) to be compiled into a regular expression
430 # The expression (a normal string) to be compiled into a regular expression
431 # for actual splitting. We store it as an attribute mostly for ease of
431 # for actual splitting. We store it as an attribute mostly for ease of
432 # debugging, since this type of code can be so tricky to debug.
432 # debugging, since this type of code can be so tricky to debug.
433 _delim_expr = None
433 _delim_expr = None
434
434
435 # The regular expression that does the actual splitting
435 # The regular expression that does the actual splitting
436 _delim_re = None
436 _delim_re = None
437
437
438 def __init__(self, delims=None):
438 def __init__(self, delims=None):
439 delims = CompletionSplitter._delims if delims is None else delims
439 delims = CompletionSplitter._delims if delims is None else delims
440 self.delims = delims
440 self.delims = delims
441
441
442 @property
442 @property
443 def delims(self):
443 def delims(self):
444 """Return the string of delimiter characters."""
444 """Return the string of delimiter characters."""
445 return self._delims
445 return self._delims
446
446
447 @delims.setter
447 @delims.setter
448 def delims(self, delims):
448 def delims(self, delims):
449 """Set the delimiters for line splitting."""
449 """Set the delimiters for line splitting."""
450 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
450 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
451 self._delim_re = re.compile(expr)
451 self._delim_re = re.compile(expr)
452 self._delims = delims
452 self._delims = delims
453 self._delim_expr = expr
453 self._delim_expr = expr
454
454
455 def split_line(self, line, cursor_pos=None):
455 def split_line(self, line, cursor_pos=None):
456 """Split a line of text with a cursor at the given position.
456 """Split a line of text with a cursor at the given position.
457 """
457 """
458 l = line if cursor_pos is None else line[:cursor_pos]
458 l = line if cursor_pos is None else line[:cursor_pos]
459 return self._delim_re.split(l)[-1]
459 return self._delim_re.split(l)[-1]
460
460
461
461
462
462
463 class Completer(Configurable):
463 class Completer(Configurable):
464
464
465 greedy = Bool(False,
465 greedy = Bool(False,
466 help="""Activate greedy completion
466 help="""Activate greedy completion
467 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
467 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
468
468
469 This will enable completion on elements of lists, results of function calls, etc.,
469 This will enable completion on elements of lists, results of function calls, etc.,
470 but can be unsafe because the code is actually evaluated on TAB.
470 but can be unsafe because the code is actually evaluated on TAB.
471 """
471 """
472 ).tag(config=True)
472 ).tag(config=True)
473
473
474 use_jedi = Bool(default_value=JEDI_INSTALLED,
474 use_jedi = Bool(default_value=JEDI_INSTALLED,
475 help="Experimental: Use Jedi to generate autocompletions. "
475 help="Experimental: Use Jedi to generate autocompletions. "
476 "Default to True if jedi is installed").tag(config=True)
476 "Default to True if jedi is installed").tag(config=True)
477
477
478 jedi_compute_type_timeout = Int(default_value=400,
478 jedi_compute_type_timeout = Int(default_value=400,
479 help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types.
479 help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types.
480 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
480 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
481 performance by preventing jedi to build its cache.
481 performance by preventing jedi to build its cache.
482 """).tag(config=True)
482 """).tag(config=True)
483
483
484 debug = Bool(default_value=False,
484 debug = Bool(default_value=False,
485 help='Enable debug for the Completer. Mostly print extra '
485 help='Enable debug for the Completer. Mostly print extra '
486 'information for experimental jedi integration.')\
486 'information for experimental jedi integration.')\
487 .tag(config=True)
487 .tag(config=True)
488
488
489
489
490 def __init__(self, namespace=None, global_namespace=None, **kwargs):
490 def __init__(self, namespace=None, global_namespace=None, **kwargs):
491 """Create a new completer for the command line.
491 """Create a new completer for the command line.
492
492
493 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
493 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
494
494
495 If unspecified, the default namespace where completions are performed
495 If unspecified, the default namespace where completions are performed
496 is __main__ (technically, __main__.__dict__). Namespaces should be
496 is __main__ (technically, __main__.__dict__). Namespaces should be
497 given as dictionaries.
497 given as dictionaries.
498
498
499 An optional second namespace can be given. This allows the completer
499 An optional second namespace can be given. This allows the completer
500 to handle cases where both the local and global scopes need to be
500 to handle cases where both the local and global scopes need to be
501 distinguished.
501 distinguished.
502 """
502 """
503
503
504 # Don't bind to namespace quite yet, but flag whether the user wants a
504 # Don't bind to namespace quite yet, but flag whether the user wants a
505 # specific namespace or to use __main__.__dict__. This will allow us
505 # specific namespace or to use __main__.__dict__. This will allow us
506 # to bind to __main__.__dict__ at completion time, not now.
506 # to bind to __main__.__dict__ at completion time, not now.
507 if namespace is None:
507 if namespace is None:
508 self.use_main_ns = True
508 self.use_main_ns = True
509 else:
509 else:
510 self.use_main_ns = False
510 self.use_main_ns = False
511 self.namespace = namespace
511 self.namespace = namespace
512
512
513 # The global namespace, if given, can be bound directly
513 # The global namespace, if given, can be bound directly
514 if global_namespace is None:
514 if global_namespace is None:
515 self.global_namespace = {}
515 self.global_namespace = {}
516 else:
516 else:
517 self.global_namespace = global_namespace
517 self.global_namespace = global_namespace
518
518
519 super(Completer, self).__init__(**kwargs)
519 super(Completer, self).__init__(**kwargs)
520
520
521 def complete(self, text, state):
521 def complete(self, text, state):
522 """Return the next possible completion for 'text'.
522 """Return the next possible completion for 'text'.
523
523
524 This is called successively with state == 0, 1, 2, ... until it
524 This is called successively with state == 0, 1, 2, ... until it
525 returns None. The completion should begin with 'text'.
525 returns None. The completion should begin with 'text'.
526
526
527 """
527 """
528 if self.use_main_ns:
528 if self.use_main_ns:
529 self.namespace = __main__.__dict__
529 self.namespace = __main__.__dict__
530
530
531 if state == 0:
531 if state == 0:
532 if "." in text:
532 if "." in text:
533 self.matches = self.attr_matches(text)
533 self.matches = self.attr_matches(text)
534 else:
534 else:
535 self.matches = self.global_matches(text)
535 self.matches = self.global_matches(text)
536 try:
536 try:
537 return self.matches[state]
537 return self.matches[state]
538 except IndexError:
538 except IndexError:
539 return None
539 return None
540
540
541 def global_matches(self, text):
541 def global_matches(self, text):
542 """Compute matches when text is a simple name.
542 """Compute matches when text is a simple name.
543
543
544 Return a list of all keywords, built-in functions and names currently
544 Return a list of all keywords, built-in functions and names currently
545 defined in self.namespace or self.global_namespace that match.
545 defined in self.namespace or self.global_namespace that match.
546
546
547 """
547 """
548 matches = []
548 matches = []
549 match_append = matches.append
549 match_append = matches.append
550 n = len(text)
550 n = len(text)
551 for lst in [keyword.kwlist,
551 for lst in [keyword.kwlist,
552 builtin_mod.__dict__.keys(),
552 builtin_mod.__dict__.keys(),
553 self.namespace.keys(),
553 self.namespace.keys(),
554 self.global_namespace.keys()]:
554 self.global_namespace.keys()]:
555 for word in lst:
555 for word in lst:
556 if word[:n] == text and word != "__builtins__":
556 if word[:n] == text and word != "__builtins__":
557 match_append(word)
557 match_append(word)
558 return [cast_unicode_py2(m) for m in matches]
558 return [cast_unicode_py2(m) for m in matches]
559
559
560 def attr_matches(self, text):
560 def attr_matches(self, text):
561 """Compute matches when text contains a dot.
561 """Compute matches when text contains a dot.
562
562
563 Assuming the text is of the form NAME.NAME....[NAME], and is
563 Assuming the text is of the form NAME.NAME....[NAME], and is
564 evaluatable in self.namespace or self.global_namespace, it will be
564 evaluatable in self.namespace or self.global_namespace, it will be
565 evaluated and its attributes (as revealed by dir()) are used as
565 evaluated and its attributes (as revealed by dir()) are used as
566 possible completions. (For class instances, class members are are
566 possible completions. (For class instances, class members are are
567 also considered.)
567 also considered.)
568
568
569 WARNING: this can still invoke arbitrary C code, if an object
569 WARNING: this can still invoke arbitrary C code, if an object
570 with a __getattr__ hook is evaluated.
570 with a __getattr__ hook is evaluated.
571
571
572 """
572 """
573
573
574 # Another option, seems to work great. Catches things like ''.<tab>
574 # Another option, seems to work great. Catches things like ''.<tab>
575 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
575 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
576
576
577 if m:
577 if m:
578 expr, attr = m.group(1, 3)
578 expr, attr = m.group(1, 3)
579 elif self.greedy:
579 elif self.greedy:
580 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
580 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
581 if not m2:
581 if not m2:
582 return []
582 return []
583 expr, attr = m2.group(1,2)
583 expr, attr = m2.group(1,2)
584 else:
584 else:
585 return []
585 return []
586
586
587 try:
587 try:
588 obj = eval(expr, self.namespace)
588 obj = eval(expr, self.namespace)
589 except:
589 except:
590 try:
590 try:
591 obj = eval(expr, self.global_namespace)
591 obj = eval(expr, self.global_namespace)
592 except:
592 except:
593 return []
593 return []
594
594
595 if self.limit_to__all__ and hasattr(obj, '__all__'):
595 if self.limit_to__all__ and hasattr(obj, '__all__'):
596 words = get__all__entries(obj)
596 words = get__all__entries(obj)
597 else:
597 else:
598 words = dir2(obj)
598 words = dir2(obj)
599
599
600 try:
600 try:
601 words = generics.complete_object(obj, words)
601 words = generics.complete_object(obj, words)
602 except TryNext:
602 except TryNext:
603 pass
603 pass
604 except AssertionError:
604 except AssertionError:
605 raise
605 raise
606 except Exception:
606 except Exception:
607 # Silence errors from completion function
607 # Silence errors from completion function
608 #raise # dbg
608 #raise # dbg
609 pass
609 pass
610 # Build match list to return
610 # Build match list to return
611 n = len(attr)
611 n = len(attr)
612 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
612 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
613
613
614
614
615 def get__all__entries(obj):
615 def get__all__entries(obj):
616 """returns the strings in the __all__ attribute"""
616 """returns the strings in the __all__ attribute"""
617 try:
617 try:
618 words = getattr(obj, '__all__')
618 words = getattr(obj, '__all__')
619 except:
619 except:
620 return []
620 return []
621
621
622 return [cast_unicode_py2(w) for w in words if isinstance(w, str)]
622 return [cast_unicode_py2(w) for w in words if isinstance(w, str)]
623
623
624
624
625 def match_dict_keys(keys, prefix, delims):
625 def match_dict_keys(keys, prefix, delims):
626 """Used by dict_key_matches, matching the prefix to a list of keys"""
626 """Used by dict_key_matches, matching the prefix to a list of keys"""
627 if not prefix:
627 if not prefix:
628 return None, 0, [repr(k) for k in keys
628 return None, 0, [repr(k) for k in keys
629 if isinstance(k, (str, bytes))]
629 if isinstance(k, (str, bytes))]
630 quote_match = re.search('["\']', prefix)
630 quote_match = re.search('["\']', prefix)
631 quote = quote_match.group()
631 quote = quote_match.group()
632 try:
632 try:
633 prefix_str = eval(prefix + quote, {})
633 prefix_str = eval(prefix + quote, {})
634 except Exception:
634 except Exception:
635 return None, 0, []
635 return None, 0, []
636
636
637 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
637 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
638 token_match = re.search(pattern, prefix, re.UNICODE)
638 token_match = re.search(pattern, prefix, re.UNICODE)
639 token_start = token_match.start()
639 token_start = token_match.start()
640 token_prefix = token_match.group()
640 token_prefix = token_match.group()
641
641
642 # TODO: support bytes in Py3k
642 # TODO: support bytes in Py3k
643 matched = []
643 matched = []
644 for key in keys:
644 for key in keys:
645 try:
645 try:
646 if not key.startswith(prefix_str):
646 if not key.startswith(prefix_str):
647 continue
647 continue
648 except (AttributeError, TypeError, UnicodeError):
648 except (AttributeError, TypeError, UnicodeError):
649 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
649 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
650 continue
650 continue
651
651
652 # reformat remainder of key to begin with prefix
652 # reformat remainder of key to begin with prefix
653 rem = key[len(prefix_str):]
653 rem = key[len(prefix_str):]
654 # force repr wrapped in '
654 # force repr wrapped in '
655 rem_repr = repr(rem + '"')
655 rem_repr = repr(rem + '"')
656 if rem_repr.startswith('u') and prefix[0] not in 'uU':
656 if rem_repr.startswith('u') and prefix[0] not in 'uU':
657 # Found key is unicode, but prefix is Py2 string.
657 # Found key is unicode, but prefix is Py2 string.
658 # Therefore attempt to interpret key as string.
658 # Therefore attempt to interpret key as string.
659 try:
659 try:
660 rem_repr = repr(rem.encode('ascii') + '"')
660 rem_repr = repr(rem.encode('ascii') + '"')
661 except UnicodeEncodeError:
661 except UnicodeEncodeError:
662 continue
662 continue
663
663
664 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
664 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
665 if quote == '"':
665 if quote == '"':
666 # The entered prefix is quoted with ",
666 # The entered prefix is quoted with ",
667 # but the match is quoted with '.
667 # but the match is quoted with '.
668 # A contained " hence needs escaping for comparison:
668 # A contained " hence needs escaping for comparison:
669 rem_repr = rem_repr.replace('"', '\\"')
669 rem_repr = rem_repr.replace('"', '\\"')
670
670
671 # then reinsert prefix from start of token
671 # then reinsert prefix from start of token
672 matched.append('%s%s' % (token_prefix, rem_repr))
672 matched.append('%s%s' % (token_prefix, rem_repr))
673 return quote, token_start, matched
673 return quote, token_start, matched
674
674
675
675
676 def cursor_to_position(text:int, line:int, column:int)->int:
676 def cursor_to_position(text:int, line:int, column:int)->int:
677 """
677 """
678
678
679 Convert the (line,column) position of the cursor in text to an offset in a
679 Convert the (line,column) position of the cursor in text to an offset in a
680 string.
680 string.
681
681
682 Parameter
682 Parameter
683 ---------
683 ---------
684
684
685 text : str
685 text : str
686 The text in which to calculate the cursor offset
686 The text in which to calculate the cursor offset
687 line : int
687 line : int
688 Line of the cursor; 0-indexed
688 Line of the cursor; 0-indexed
689 column : int
689 column : int
690 Column of the cursor 0-indexed
690 Column of the cursor 0-indexed
691
691
692 Return
692 Return
693 ------
693 ------
694 Position of the cursor in ``text``, 0-indexed.
694 Position of the cursor in ``text``, 0-indexed.
695
695
696 See Also
696 See Also
697 --------
697 --------
698 position_to_cursor: reciprocal of this function
698 position_to_cursor: reciprocal of this function
699
699
700 """
700 """
701 lines = text.split('\n')
701 lines = text.split('\n')
702 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
702 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
703
703
704 return sum(len(l) + 1 for l in lines[:line]) + column
704 return sum(len(l) + 1 for l in lines[:line]) + column
705
705
706 def position_to_cursor(text:str, offset:int)->(int, int):
706 def position_to_cursor(text:str, offset:int)->(int, int):
707 """
707 """
708 Convert the position of the cursor in text (0 indexed) to a line
708 Convert the position of the cursor in text (0 indexed) to a line
709 number(0-indexed) and a column number (0-indexed) pair
709 number(0-indexed) and a column number (0-indexed) pair
710
710
711 Position should be a valid position in ``text``.
711 Position should be a valid position in ``text``.
712
712
713 Parameter
713 Parameter
714 ---------
714 ---------
715
715
716 text : str
716 text : str
717 The text in which to calculate the cursor offset
717 The text in which to calculate the cursor offset
718 offset : int
718 offset : int
719 Position of the cursor in ``text``, 0-indexed.
719 Position of the cursor in ``text``, 0-indexed.
720
720
721 Return
721 Return
722 ------
722 ------
723 (line, column) : (int, int)
723 (line, column) : (int, int)
724 Line of the cursor; 0-indexed, column of the cursor 0-indexed
724 Line of the cursor; 0-indexed, column of the cursor 0-indexed
725
725
726
726
727 See Also
727 See Also
728 --------
728 --------
729 cursor_to_position : reciprocal of this function
729 cursor_to_position : reciprocal of this function
730
730
731
731
732 """
732 """
733
733
734 assert 0 < offset <= len(text) , "0 < %s <= %s" % (offset , len(text))
734 assert 0 < offset <= len(text) , "0 < %s <= %s" % (offset , len(text))
735
735
736 before = text[:offset]
736 before = text[:offset]
737 blines = before.split('\n') # ! splitnes trim trailing \n
737 blines = before.split('\n') # ! splitnes trim trailing \n
738 line = before.count('\n')
738 line = before.count('\n')
739 col = len(blines[-1])
739 col = len(blines[-1])
740 return line, col
740 return line, col
741
741
742
742
743 def _safe_isinstance(obj, module, class_name):
743 def _safe_isinstance(obj, module, class_name):
744 """Checks if obj is an instance of module.class_name if loaded
744 """Checks if obj is an instance of module.class_name if loaded
745 """
745 """
746 return (module in sys.modules and
746 return (module in sys.modules and
747 isinstance(obj, getattr(import_module(module), class_name)))
747 isinstance(obj, getattr(import_module(module), class_name)))
748
748
749
749
750 def back_unicode_name_matches(text):
750 def back_unicode_name_matches(text):
751 u"""Match unicode characters back to unicode name
751 u"""Match unicode characters back to unicode name
752
752
753 This does ``β˜ƒ`` -> ``\\snowman``
753 This does ``β˜ƒ`` -> ``\\snowman``
754
754
755 Note that snowman is not a valid python3 combining character but will be expanded.
755 Note that snowman is not a valid python3 combining character but will be expanded.
756 Though it will not recombine back to the snowman character by the completion machinery.
756 Though it will not recombine back to the snowman character by the completion machinery.
757
757
758 This will not either back-complete standard sequences like \\n, \\b ...
758 This will not either back-complete standard sequences like \\n, \\b ...
759
759
760 Used on Python 3 only.
760 Used on Python 3 only.
761 """
761 """
762 if len(text)<2:
762 if len(text)<2:
763 return u'', ()
763 return u'', ()
764 maybe_slash = text[-2]
764 maybe_slash = text[-2]
765 if maybe_slash != '\\':
765 if maybe_slash != '\\':
766 return u'', ()
766 return u'', ()
767
767
768 char = text[-1]
768 char = text[-1]
769 # no expand on quote for completion in strings.
769 # no expand on quote for completion in strings.
770 # nor backcomplete standard ascii keys
770 # nor backcomplete standard ascii keys
771 if char in string.ascii_letters or char in ['"',"'"]:
771 if char in string.ascii_letters or char in ['"',"'"]:
772 return u'', ()
772 return u'', ()
773 try :
773 try :
774 unic = unicodedata.name(char)
774 unic = unicodedata.name(char)
775 return '\\'+char,['\\'+unic]
775 return '\\'+char,['\\'+unic]
776 except KeyError:
776 except KeyError:
777 pass
777 pass
778 return u'', ()
778 return u'', ()
779
779
780 def back_latex_name_matches(text:str):
780 def back_latex_name_matches(text:str):
781 """Match latex characters back to unicode name
781 """Match latex characters back to unicode name
782
782
783 This does ``\\β„΅`` -> ``\\aleph``
783 This does ``\\β„΅`` -> ``\\aleph``
784
784
785 Used on Python 3 only.
785 Used on Python 3 only.
786 """
786 """
787 if len(text)<2:
787 if len(text)<2:
788 return u'', ()
788 return u'', ()
789 maybe_slash = text[-2]
789 maybe_slash = text[-2]
790 if maybe_slash != '\\':
790 if maybe_slash != '\\':
791 return u'', ()
791 return u'', ()
792
792
793
793
794 char = text[-1]
794 char = text[-1]
795 # no expand on quote for completion in strings.
795 # no expand on quote for completion in strings.
796 # nor backcomplete standard ascii keys
796 # nor backcomplete standard ascii keys
797 if char in string.ascii_letters or char in ['"',"'"]:
797 if char in string.ascii_letters or char in ['"',"'"]:
798 return u'', ()
798 return u'', ()
799 try :
799 try :
800 latex = reverse_latex_symbol[char]
800 latex = reverse_latex_symbol[char]
801 # '\\' replace the \ as well
801 # '\\' replace the \ as well
802 return '\\'+char,[latex]
802 return '\\'+char,[latex]
803 except KeyError:
803 except KeyError:
804 pass
804 pass
805 return u'', ()
805 return u'', ()
806
806
807
807
808 class IPCompleter(Completer):
808 class IPCompleter(Completer):
809 """Extension of the completer class with IPython-specific features"""
809 """Extension of the completer class with IPython-specific features"""
810
810
811 @observe('greedy')
811 @observe('greedy')
812 def _greedy_changed(self, change):
812 def _greedy_changed(self, change):
813 """update the splitter and readline delims when greedy is changed"""
813 """update the splitter and readline delims when greedy is changed"""
814 if change['new']:
814 if change['new']:
815 self.splitter.delims = GREEDY_DELIMS
815 self.splitter.delims = GREEDY_DELIMS
816 else:
816 else:
817 self.splitter.delims = DELIMS
817 self.splitter.delims = DELIMS
818
818
819 merge_completions = Bool(True,
819 merge_completions = Bool(True,
820 help="""Whether to merge completion results into a single list
820 help="""Whether to merge completion results into a single list
821
821
822 If False, only the completion results from the first non-empty
822 If False, only the completion results from the first non-empty
823 completer will be returned.
823 completer will be returned.
824 """
824 """
825 ).tag(config=True)
825 ).tag(config=True)
826 omit__names = Enum((0,1,2), default_value=2,
826 omit__names = Enum((0,1,2), default_value=2,
827 help="""Instruct the completer to omit private method names
827 help="""Instruct the completer to omit private method names
828
828
829 Specifically, when completing on ``object.<tab>``.
829 Specifically, when completing on ``object.<tab>``.
830
830
831 When 2 [default]: all names that start with '_' will be excluded.
831 When 2 [default]: all names that start with '_' will be excluded.
832
832
833 When 1: all 'magic' names (``__foo__``) will be excluded.
833 When 1: all 'magic' names (``__foo__``) will be excluded.
834
834
835 When 0: nothing will be excluded.
835 When 0: nothing will be excluded.
836 """
836 """
837 ).tag(config=True)
837 ).tag(config=True)
838 limit_to__all__ = Bool(False,
838 limit_to__all__ = Bool(False,
839 help="""
839 help="""
840 DEPRECATED as of version 5.0.
840 DEPRECATED as of version 5.0.
841
841
842 Instruct the completer to use __all__ for the completion
842 Instruct the completer to use __all__ for the completion
843
843
844 Specifically, when completing on ``object.<tab>``.
844 Specifically, when completing on ``object.<tab>``.
845
845
846 When True: only those names in obj.__all__ will be included.
846 When True: only those names in obj.__all__ will be included.
847
847
848 When False [default]: the __all__ attribute is ignored
848 When False [default]: the __all__ attribute is ignored
849 """,
849 """,
850 ).tag(config=True)
850 ).tag(config=True)
851
851
852 @observe('limit_to__all__')
852 @observe('limit_to__all__')
853 def _limit_to_all_changed(self, change):
853 def _limit_to_all_changed(self, change):
854 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
854 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
855 'value has been deprecated since IPython 5.0, will be made to have '
855 'value has been deprecated since IPython 5.0, will be made to have '
856 'no effects and then removed in future version of IPython.',
856 'no effects and then removed in future version of IPython.',
857 UserWarning)
857 UserWarning)
858
858
859 def __init__(self, shell=None, namespace=None, global_namespace=None,
859 def __init__(self, shell=None, namespace=None, global_namespace=None,
860 use_readline=_deprecation_readline_sentinel, config=None, **kwargs):
860 use_readline=_deprecation_readline_sentinel, config=None, **kwargs):
861 """IPCompleter() -> completer
861 """IPCompleter() -> completer
862
862
863 Return a completer object.
863 Return a completer object.
864
864
865 Parameters
865 Parameters
866 ----------
866 ----------
867
867
868 shell
868 shell
869 a pointer to the ipython shell itself. This is needed
869 a pointer to the ipython shell itself. This is needed
870 because this completer knows about magic functions, and those can
870 because this completer knows about magic functions, and those can
871 only be accessed via the ipython instance.
871 only be accessed via the ipython instance.
872
872
873 namespace : dict, optional
873 namespace : dict, optional
874 an optional dict where completions are performed.
874 an optional dict where completions are performed.
875
875
876 global_namespace : dict, optional
876 global_namespace : dict, optional
877 secondary optional dict for completions, to
877 secondary optional dict for completions, to
878 handle cases (such as IPython embedded inside functions) where
878 handle cases (such as IPython embedded inside functions) where
879 both Python scopes are visible.
879 both Python scopes are visible.
880
880
881 use_readline : bool, optional
881 use_readline : bool, optional
882 DEPRECATED, ignored since IPython 6.0, will have no effects
882 DEPRECATED, ignored since IPython 6.0, will have no effects
883 """
883 """
884
884
885 self.magic_escape = ESC_MAGIC
885 self.magic_escape = ESC_MAGIC
886 self.splitter = CompletionSplitter()
886 self.splitter = CompletionSplitter()
887
887
888 if use_readline is not _deprecation_readline_sentinel:
888 if use_readline is not _deprecation_readline_sentinel:
889 warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.',
889 warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.',
890 DeprecationWarning, stacklevel=2)
890 DeprecationWarning, stacklevel=2)
891
891
892 # _greedy_changed() depends on splitter and readline being defined:
892 # _greedy_changed() depends on splitter and readline being defined:
893 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
893 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
894 config=config, **kwargs)
894 config=config, **kwargs)
895
895
896 # List where completion matches will be stored
896 # List where completion matches will be stored
897 self.matches = []
897 self.matches = []
898 self.shell = shell
898 self.shell = shell
899 # Regexp to split filenames with spaces in them
899 # Regexp to split filenames with spaces in them
900 self.space_name_re = re.compile(r'([^\\] )')
900 self.space_name_re = re.compile(r'([^\\] )')
901 # Hold a local ref. to glob.glob for speed
901 # Hold a local ref. to glob.glob for speed
902 self.glob = glob.glob
902 self.glob = glob.glob
903
903
904 # Determine if we are running on 'dumb' terminals, like (X)Emacs
904 # Determine if we are running on 'dumb' terminals, like (X)Emacs
905 # buffers, to avoid completion problems.
905 # buffers, to avoid completion problems.
906 term = os.environ.get('TERM','xterm')
906 term = os.environ.get('TERM','xterm')
907 self.dumb_terminal = term in ['dumb','emacs']
907 self.dumb_terminal = term in ['dumb','emacs']
908
908
909 # Special handling of backslashes needed in win32 platforms
909 # Special handling of backslashes needed in win32 platforms
910 if sys.platform == "win32":
910 if sys.platform == "win32":
911 self.clean_glob = self._clean_glob_win32
911 self.clean_glob = self._clean_glob_win32
912 else:
912 else:
913 self.clean_glob = self._clean_glob
913 self.clean_glob = self._clean_glob
914
914
915 #regexp to parse docstring for function signature
915 #regexp to parse docstring for function signature
916 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
916 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
917 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
917 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
918 #use this if positional argument name is also needed
918 #use this if positional argument name is also needed
919 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
919 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
920
920
921 # All active matcher routines for completion
921 # All active matcher routines for completion
922 self.matchers = [
922 self.matchers = [
923 self.python_matches,
923 self.python_matches,
924 self.file_matches,
924 self.file_matches,
925 self.magic_matches,
925 self.magic_matches,
926 self.python_func_kw_matches,
926 self.python_func_kw_matches,
927 self.dict_key_matches,
927 self.dict_key_matches,
928 ]
928 ]
929
929
930 # This is set externally by InteractiveShell
930 # This is set externally by InteractiveShell
931 self.custom_completers = None
931 self.custom_completers = None
932
932
933 def all_completions(self, text):
933 def all_completions(self, text):
934 """
934 """
935 Wrapper around the complete method for the benefit of emacs.
935 Wrapper around the complete method for the benefit of emacs.
936 """
936 """
937 return self.complete(text)[1]
937 return self.complete(text)[1]
938
938
939 def _clean_glob(self, text):
939 def _clean_glob(self, text):
940 return self.glob("%s*" % text)
940 return self.glob("%s*" % text)
941
941
942 def _clean_glob_win32(self,text):
942 def _clean_glob_win32(self,text):
943 return [f.replace("\\","/")
943 return [f.replace("\\","/")
944 for f in self.glob("%s*" % text)]
944 for f in self.glob("%s*" % text)]
945
945
946 def file_matches(self, text):
946 def file_matches(self, text):
947 """Match filenames, expanding ~USER type strings.
947 """Match filenames, expanding ~USER type strings.
948
948
949 Most of the seemingly convoluted logic in this completer is an
949 Most of the seemingly convoluted logic in this completer is an
950 attempt to handle filenames with spaces in them. And yet it's not
950 attempt to handle filenames with spaces in them. And yet it's not
951 quite perfect, because Python's readline doesn't expose all of the
951 quite perfect, because Python's readline doesn't expose all of the
952 GNU readline details needed for this to be done correctly.
952 GNU readline details needed for this to be done correctly.
953
953
954 For a filename with a space in it, the printed completions will be
954 For a filename with a space in it, the printed completions will be
955 only the parts after what's already been typed (instead of the
955 only the parts after what's already been typed (instead of the
956 full completions, as is normally done). I don't think with the
956 full completions, as is normally done). I don't think with the
957 current (as of Python 2.3) Python readline it's possible to do
957 current (as of Python 2.3) Python readline it's possible to do
958 better."""
958 better."""
959
959
960 # chars that require escaping with backslash - i.e. chars
960 # chars that require escaping with backslash - i.e. chars
961 # that readline treats incorrectly as delimiters, but we
961 # that readline treats incorrectly as delimiters, but we
962 # don't want to treat as delimiters in filename matching
962 # don't want to treat as delimiters in filename matching
963 # when escaped with backslash
963 # when escaped with backslash
964 if text.startswith('!'):
964 if text.startswith('!'):
965 text = text[1:]
965 text = text[1:]
966 text_prefix = u'!'
966 text_prefix = u'!'
967 else:
967 else:
968 text_prefix = u''
968 text_prefix = u''
969
969
970 text_until_cursor = self.text_until_cursor
970 text_until_cursor = self.text_until_cursor
971 # track strings with open quotes
971 # track strings with open quotes
972 open_quotes = has_open_quotes(text_until_cursor)
972 open_quotes = has_open_quotes(text_until_cursor)
973
973
974 if '(' in text_until_cursor or '[' in text_until_cursor:
974 if '(' in text_until_cursor or '[' in text_until_cursor:
975 lsplit = text
975 lsplit = text
976 else:
976 else:
977 try:
977 try:
978 # arg_split ~ shlex.split, but with unicode bugs fixed by us
978 # arg_split ~ shlex.split, but with unicode bugs fixed by us
979 lsplit = arg_split(text_until_cursor)[-1]
979 lsplit = arg_split(text_until_cursor)[-1]
980 except ValueError:
980 except ValueError:
981 # typically an unmatched ", or backslash without escaped char.
981 # typically an unmatched ", or backslash without escaped char.
982 if open_quotes:
982 if open_quotes:
983 lsplit = text_until_cursor.split(open_quotes)[-1]
983 lsplit = text_until_cursor.split(open_quotes)[-1]
984 else:
984 else:
985 return []
985 return []
986 except IndexError:
986 except IndexError:
987 # tab pressed on empty line
987 # tab pressed on empty line
988 lsplit = ""
988 lsplit = ""
989
989
990 if not open_quotes and lsplit != protect_filename(lsplit):
990 if not open_quotes and lsplit != protect_filename(lsplit):
991 # if protectables are found, do matching on the whole escaped name
991 # if protectables are found, do matching on the whole escaped name
992 has_protectables = True
992 has_protectables = True
993 text0,text = text,lsplit
993 text0,text = text,lsplit
994 else:
994 else:
995 has_protectables = False
995 has_protectables = False
996 text = os.path.expanduser(text)
996 text = os.path.expanduser(text)
997
997
998 if text == "":
998 if text == "":
999 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
999 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
1000
1000
1001 # Compute the matches from the filesystem
1001 # Compute the matches from the filesystem
1002 if sys.platform == 'win32':
1002 if sys.platform == 'win32':
1003 m0 = self.clean_glob(text)
1003 m0 = self.clean_glob(text)
1004 else:
1004 else:
1005 m0 = self.clean_glob(text.replace('\\', ''))
1005 m0 = self.clean_glob(text.replace('\\', ''))
1006
1006
1007 if has_protectables:
1007 if has_protectables:
1008 # If we had protectables, we need to revert our changes to the
1008 # If we had protectables, we need to revert our changes to the
1009 # beginning of filename so that we don't double-write the part
1009 # beginning of filename so that we don't double-write the part
1010 # of the filename we have so far
1010 # of the filename we have so far
1011 len_lsplit = len(lsplit)
1011 len_lsplit = len(lsplit)
1012 matches = [text_prefix + text0 +
1012 matches = [text_prefix + text0 +
1013 protect_filename(f[len_lsplit:]) for f in m0]
1013 protect_filename(f[len_lsplit:]) for f in m0]
1014 else:
1014 else:
1015 if open_quotes:
1015 if open_quotes:
1016 # if we have a string with an open quote, we don't need to
1016 # if we have a string with an open quote, we don't need to
1017 # protect the names at all (and we _shouldn't_, as it
1017 # protect the names at all (and we _shouldn't_, as it
1018 # would cause bugs when the filesystem call is made).
1018 # would cause bugs when the filesystem call is made).
1019 matches = m0
1019 matches = m0
1020 else:
1020 else:
1021 matches = [text_prefix +
1021 matches = [text_prefix +
1022 protect_filename(f) for f in m0]
1022 protect_filename(f) for f in m0]
1023
1023
1024 # Mark directories in input list by appending '/' to their names.
1024 # Mark directories in input list by appending '/' to their names.
1025 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
1025 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
1026
1026
1027 def magic_matches(self, text):
1027 def magic_matches(self, text):
1028 """Match magics"""
1028 """Match magics"""
1029 # Get all shell magics now rather than statically, so magics loaded at
1029 # Get all shell magics now rather than statically, so magics loaded at
1030 # runtime show up too.
1030 # runtime show up too.
1031 lsm = self.shell.magics_manager.lsmagic()
1031 lsm = self.shell.magics_manager.lsmagic()
1032 line_magics = lsm['line']
1032 line_magics = lsm['line']
1033 cell_magics = lsm['cell']
1033 cell_magics = lsm['cell']
1034 pre = self.magic_escape
1034 pre = self.magic_escape
1035 pre2 = pre+pre
1035 pre2 = pre+pre
1036
1036
1037 # Completion logic:
1037 # Completion logic:
1038 # - user gives %%: only do cell magics
1038 # - user gives %%: only do cell magics
1039 # - user gives %: do both line and cell magics
1039 # - user gives %: do both line and cell magics
1040 # - no prefix: do both
1040 # - no prefix: do both
1041 # In other words, line magics are skipped if the user gives %% explicitly
1041 # In other words, line magics are skipped if the user gives %% explicitly
1042 bare_text = text.lstrip(pre)
1042 bare_text = text.lstrip(pre)
1043 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
1043 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
1044 if not text.startswith(pre2):
1044 if not text.startswith(pre2):
1045 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
1045 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
1046 return [cast_unicode_py2(c) for c in comp]
1046 return [cast_unicode_py2(c) for c in comp]
1047
1047
1048 def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str):
1048 def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str):
1049 """
1049 """
1050
1050
1051 Return a list of :any:`jedi.api.Completions` object from a ``text`` and
1051 Return a list of :any:`jedi.api.Completions` object from a ``text`` and
1052 cursor position.
1052 cursor position.
1053
1053
1054 Parameters
1054 Parameters
1055 ----------
1055 ----------
1056 cursor_column : int
1056 cursor_column : int
1057 column position of the cursor in ``text``, 0-indexed.
1057 column position of the cursor in ``text``, 0-indexed.
1058 cursor_line : int
1058 cursor_line : int
1059 line position of the cursor in ``text``, 0-indexed
1059 line position of the cursor in ``text``, 0-indexed
1060 text : str
1060 text : str
1061 text to complete
1061 text to complete
1062
1062
1063 Debugging
1063 Debugging
1064 ---------
1064 ---------
1065
1065
1066 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
1066 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
1067 object containing a string with the Jedi debug information attached.
1067 object containing a string with the Jedi debug information attached.
1068 """
1068 """
1069 namespaces = [self.namespace]
1069 namespaces = [self.namespace]
1070 if self.global_namespace is not None:
1070 if self.global_namespace is not None:
1071 namespaces.append(self.global_namespace)
1071 namespaces.append(self.global_namespace)
1072
1072
1073 # cursor_pos is an it, jedi wants line and column
1073 # cursor_pos is an it, jedi wants line and column
1074 offset = cursor_to_position(text, cursor_line, cursor_column)
1074 offset = cursor_to_position(text, cursor_line, cursor_column)
1075 if offset:
1075 if offset:
1076 pre = text[offset-1]
1076 pre = text[offset-1]
1077 completion_filter = lambda x:x
1077 completion_filter = lambda x:x
1078 if pre == '.':
1078 if pre == '.':
1079 if self.omit__names == 2:
1079 if self.omit__names == 2:
1080 completion_filter = lambda c:not c.name.startswith('_')
1080 completion_filter = lambda c:not c.name.startswith('_')
1081 elif self.omit__names == 1:
1081 elif self.omit__names == 1:
1082 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
1082 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
1083 elif self.omit__names == 0:
1083 elif self.omit__names == 0:
1084 completion_filter = lambda x:x
1084 completion_filter = lambda x:x
1085 else:
1085 else:
1086 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
1086 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
1087
1087
1088 interpreter = jedi.Interpreter(
1088 interpreter = jedi.Interpreter(
1089 text, namespaces, column=cursor_column, line=cursor_line + 1)
1089 text, namespaces, column=cursor_column, line=cursor_line + 1)
1090 try:
1090 try:
1091 return filter(completion_filter, interpreter.completions())
1091 return filter(completion_filter, interpreter.completions())
1092 except Exception as e:
1092 except Exception as e:
1093 if self.debug:
1093 if self.debug:
1094 return [_FakeJediCompletion('Opps Jedi has crash please report a bug with the following:\n"""\n%s\ns"""' % (e))]
1094 return [_FakeJediCompletion('Opps Jedi has crash please report a bug with the following:\n"""\n%s\ns"""' % (e))]
1095 else:
1095 else:
1096 return []
1096 return []
1097
1097
1098 def python_matches(self, text):
1098 def python_matches(self, text):
1099 """Match attributes or global python names"""
1099 """Match attributes or global python names"""
1100 if "." in text:
1100 if "." in text:
1101 try:
1101 try:
1102 matches = self.attr_matches(text)
1102 matches = self.attr_matches(text)
1103 if text.endswith('.') and self.omit__names:
1103 if text.endswith('.') and self.omit__names:
1104 if self.omit__names == 1:
1104 if self.omit__names == 1:
1105 # true if txt is _not_ a __ name, false otherwise:
1105 # true if txt is _not_ a __ name, false otherwise:
1106 no__name = (lambda txt:
1106 no__name = (lambda txt:
1107 re.match(r'.*\.__.*?__',txt) is None)
1107 re.match(r'.*\.__.*?__',txt) is None)
1108 else:
1108 else:
1109 # true if txt is _not_ a _ name, false otherwise:
1109 # true if txt is _not_ a _ name, false otherwise:
1110 no__name = (lambda txt:
1110 no__name = (lambda txt:
1111 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
1111 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
1112 matches = filter(no__name, matches)
1112 matches = filter(no__name, matches)
1113 except NameError:
1113 except NameError:
1114 # catches <undefined attributes>.<tab>
1114 # catches <undefined attributes>.<tab>
1115 matches = []
1115 matches = []
1116 else:
1116 else:
1117 matches = self.global_matches(text)
1117 matches = self.global_matches(text)
1118 return matches
1118 return matches
1119
1119
1120 def _default_arguments_from_docstring(self, doc):
1120 def _default_arguments_from_docstring(self, doc):
1121 """Parse the first line of docstring for call signature.
1121 """Parse the first line of docstring for call signature.
1122
1122
1123 Docstring should be of the form 'min(iterable[, key=func])\n'.
1123 Docstring should be of the form 'min(iterable[, key=func])\n'.
1124 It can also parse cython docstring of the form
1124 It can also parse cython docstring of the form
1125 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
1125 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
1126 """
1126 """
1127 if doc is None:
1127 if doc is None:
1128 return []
1128 return []
1129
1129
1130 #care only the firstline
1130 #care only the firstline
1131 line = doc.lstrip().splitlines()[0]
1131 line = doc.lstrip().splitlines()[0]
1132
1132
1133 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1133 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1134 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
1134 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
1135 sig = self.docstring_sig_re.search(line)
1135 sig = self.docstring_sig_re.search(line)
1136 if sig is None:
1136 if sig is None:
1137 return []
1137 return []
1138 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
1138 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
1139 sig = sig.groups()[0].split(',')
1139 sig = sig.groups()[0].split(',')
1140 ret = []
1140 ret = []
1141 for s in sig:
1141 for s in sig:
1142 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1142 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1143 ret += self.docstring_kwd_re.findall(s)
1143 ret += self.docstring_kwd_re.findall(s)
1144 return ret
1144 return ret
1145
1145
1146 def _default_arguments(self, obj):
1146 def _default_arguments(self, obj):
1147 """Return the list of default arguments of obj if it is callable,
1147 """Return the list of default arguments of obj if it is callable,
1148 or empty list otherwise."""
1148 or empty list otherwise."""
1149 call_obj = obj
1149 call_obj = obj
1150 ret = []
1150 ret = []
1151 if inspect.isbuiltin(obj):
1151 if inspect.isbuiltin(obj):
1152 pass
1152 pass
1153 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
1153 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
1154 if inspect.isclass(obj):
1154 if inspect.isclass(obj):
1155 #for cython embededsignature=True the constructor docstring
1155 #for cython embededsignature=True the constructor docstring
1156 #belongs to the object itself not __init__
1156 #belongs to the object itself not __init__
1157 ret += self._default_arguments_from_docstring(
1157 ret += self._default_arguments_from_docstring(
1158 getattr(obj, '__doc__', ''))
1158 getattr(obj, '__doc__', ''))
1159 # for classes, check for __init__,__new__
1159 # for classes, check for __init__,__new__
1160 call_obj = (getattr(obj, '__init__', None) or
1160 call_obj = (getattr(obj, '__init__', None) or
1161 getattr(obj, '__new__', None))
1161 getattr(obj, '__new__', None))
1162 # for all others, check if they are __call__able
1162 # for all others, check if they are __call__able
1163 elif hasattr(obj, '__call__'):
1163 elif hasattr(obj, '__call__'):
1164 call_obj = obj.__call__
1164 call_obj = obj.__call__
1165 ret += self._default_arguments_from_docstring(
1165 ret += self._default_arguments_from_docstring(
1166 getattr(call_obj, '__doc__', ''))
1166 getattr(call_obj, '__doc__', ''))
1167
1167
1168 _keeps = (inspect.Parameter.KEYWORD_ONLY,
1168 _keeps = (inspect.Parameter.KEYWORD_ONLY,
1169 inspect.Parameter.POSITIONAL_OR_KEYWORD)
1169 inspect.Parameter.POSITIONAL_OR_KEYWORD)
1170
1170
1171 try:
1171 try:
1172 sig = inspect.signature(call_obj)
1172 sig = inspect.signature(call_obj)
1173 ret.extend(k for k, v in sig.parameters.items() if
1173 ret.extend(k for k, v in sig.parameters.items() if
1174 v.kind in _keeps)
1174 v.kind in _keeps)
1175 except ValueError:
1175 except ValueError:
1176 pass
1176 pass
1177
1177
1178 return list(set(ret))
1178 return list(set(ret))
1179
1179
1180 def python_func_kw_matches(self,text):
1180 def python_func_kw_matches(self,text):
1181 """Match named parameters (kwargs) of the last open function"""
1181 """Match named parameters (kwargs) of the last open function"""
1182
1182
1183 if "." in text: # a parameter cannot be dotted
1183 if "." in text: # a parameter cannot be dotted
1184 return []
1184 return []
1185 try: regexp = self.__funcParamsRegex
1185 try: regexp = self.__funcParamsRegex
1186 except AttributeError:
1186 except AttributeError:
1187 regexp = self.__funcParamsRegex = re.compile(r'''
1187 regexp = self.__funcParamsRegex = re.compile(r'''
1188 '.*?(?<!\\)' | # single quoted strings or
1188 '.*?(?<!\\)' | # single quoted strings or
1189 ".*?(?<!\\)" | # double quoted strings or
1189 ".*?(?<!\\)" | # double quoted strings or
1190 \w+ | # identifier
1190 \w+ | # identifier
1191 \S # other characters
1191 \S # other characters
1192 ''', re.VERBOSE | re.DOTALL)
1192 ''', re.VERBOSE | re.DOTALL)
1193 # 1. find the nearest identifier that comes before an unclosed
1193 # 1. find the nearest identifier that comes before an unclosed
1194 # parenthesis before the cursor
1194 # parenthesis before the cursor
1195 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
1195 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
1196 tokens = regexp.findall(self.text_until_cursor)
1196 tokens = regexp.findall(self.text_until_cursor)
1197 iterTokens = reversed(tokens); openPar = 0
1197 iterTokens = reversed(tokens); openPar = 0
1198
1198
1199 for token in iterTokens:
1199 for token in iterTokens:
1200 if token == ')':
1200 if token == ')':
1201 openPar -= 1
1201 openPar -= 1
1202 elif token == '(':
1202 elif token == '(':
1203 openPar += 1
1203 openPar += 1
1204 if openPar > 0:
1204 if openPar > 0:
1205 # found the last unclosed parenthesis
1205 # found the last unclosed parenthesis
1206 break
1206 break
1207 else:
1207 else:
1208 return []
1208 return []
1209 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
1209 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
1210 ids = []
1210 ids = []
1211 isId = re.compile(r'\w+$').match
1211 isId = re.compile(r'\w+$').match
1212
1212
1213 while True:
1213 while True:
1214 try:
1214 try:
1215 ids.append(next(iterTokens))
1215 ids.append(next(iterTokens))
1216 if not isId(ids[-1]):
1216 if not isId(ids[-1]):
1217 ids.pop(); break
1217 ids.pop(); break
1218 if not next(iterTokens) == '.':
1218 if not next(iterTokens) == '.':
1219 break
1219 break
1220 except StopIteration:
1220 except StopIteration:
1221 break
1221 break
1222
1222
1223 # Find all named arguments already assigned to, as to avoid suggesting
1223 # Find all named arguments already assigned to, as to avoid suggesting
1224 # them again
1224 # them again
1225 usedNamedArgs = set()
1225 usedNamedArgs = set()
1226 par_level = -1
1226 par_level = -1
1227 for token, next_token in zip(tokens, tokens[1:]):
1227 for token, next_token in zip(tokens, tokens[1:]):
1228 if token == '(':
1228 if token == '(':
1229 par_level += 1
1229 par_level += 1
1230 elif token == ')':
1230 elif token == ')':
1231 par_level -= 1
1231 par_level -= 1
1232
1232
1233 if par_level != 0:
1233 if par_level != 0:
1234 continue
1234 continue
1235
1235
1236 if next_token != '=':
1236 if next_token != '=':
1237 continue
1237 continue
1238
1238
1239 usedNamedArgs.add(token)
1239 usedNamedArgs.add(token)
1240
1240
1241 # lookup the candidate callable matches either using global_matches
1241 # lookup the candidate callable matches either using global_matches
1242 # or attr_matches for dotted names
1242 # or attr_matches for dotted names
1243 if len(ids) == 1:
1243 if len(ids) == 1:
1244 callableMatches = self.global_matches(ids[0])
1244 callableMatches = self.global_matches(ids[0])
1245 else:
1245 else:
1246 callableMatches = self.attr_matches('.'.join(ids[::-1]))
1246 callableMatches = self.attr_matches('.'.join(ids[::-1]))
1247 argMatches = []
1247 argMatches = []
1248 for callableMatch in callableMatches:
1248 for callableMatch in callableMatches:
1249 try:
1249 try:
1250 namedArgs = self._default_arguments(eval(callableMatch,
1250 namedArgs = self._default_arguments(eval(callableMatch,
1251 self.namespace))
1251 self.namespace))
1252 except:
1252 except:
1253 continue
1253 continue
1254
1254
1255 # Remove used named arguments from the list, no need to show twice
1255 # Remove used named arguments from the list, no need to show twice
1256 for namedArg in set(namedArgs) - usedNamedArgs:
1256 for namedArg in set(namedArgs) - usedNamedArgs:
1257 if namedArg.startswith(text):
1257 if namedArg.startswith(text):
1258 argMatches.append(u"%s=" %namedArg)
1258 argMatches.append(u"%s=" %namedArg)
1259 return argMatches
1259 return argMatches
1260
1260
1261 def dict_key_matches(self, text):
1261 def dict_key_matches(self, text):
1262 "Match string keys in a dictionary, after e.g. 'foo[' "
1262 "Match string keys in a dictionary, after e.g. 'foo[' "
1263 def get_keys(obj):
1263 def get_keys(obj):
1264 # Objects can define their own completions by defining an
1264 # Objects can define their own completions by defining an
1265 # _ipy_key_completions_() method.
1265 # _ipy_key_completions_() method.
1266 method = get_real_method(obj, '_ipython_key_completions_')
1266 method = get_real_method(obj, '_ipython_key_completions_')
1267 if method is not None:
1267 if method is not None:
1268 return method()
1268 return method()
1269
1269
1270 # Special case some common in-memory dict-like types
1270 # Special case some common in-memory dict-like types
1271 if isinstance(obj, dict) or\
1271 if isinstance(obj, dict) or\
1272 _safe_isinstance(obj, 'pandas', 'DataFrame'):
1272 _safe_isinstance(obj, 'pandas', 'DataFrame'):
1273 try:
1273 try:
1274 return list(obj.keys())
1274 return list(obj.keys())
1275 except Exception:
1275 except Exception:
1276 return []
1276 return []
1277 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
1277 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
1278 _safe_isinstance(obj, 'numpy', 'void'):
1278 _safe_isinstance(obj, 'numpy', 'void'):
1279 return obj.dtype.names or []
1279 return obj.dtype.names or []
1280 return []
1280 return []
1281
1281
1282 try:
1282 try:
1283 regexps = self.__dict_key_regexps
1283 regexps = self.__dict_key_regexps
1284 except AttributeError:
1284 except AttributeError:
1285 dict_key_re_fmt = r'''(?x)
1285 dict_key_re_fmt = r'''(?x)
1286 ( # match dict-referring expression wrt greedy setting
1286 ( # match dict-referring expression wrt greedy setting
1287 %s
1287 %s
1288 )
1288 )
1289 \[ # open bracket
1289 \[ # open bracket
1290 \s* # and optional whitespace
1290 \s* # and optional whitespace
1291 ([uUbB]? # string prefix (r not handled)
1291 ([uUbB]? # string prefix (r not handled)
1292 (?: # unclosed string
1292 (?: # unclosed string
1293 '(?:[^']|(?<!\\)\\')*
1293 '(?:[^']|(?<!\\)\\')*
1294 |
1294 |
1295 "(?:[^"]|(?<!\\)\\")*
1295 "(?:[^"]|(?<!\\)\\")*
1296 )
1296 )
1297 )?
1297 )?
1298 $
1298 $
1299 '''
1299 '''
1300 regexps = self.__dict_key_regexps = {
1300 regexps = self.__dict_key_regexps = {
1301 False: re.compile(dict_key_re_fmt % '''
1301 False: re.compile(dict_key_re_fmt % '''
1302 # identifiers separated by .
1302 # identifiers separated by .
1303 (?!\d)\w+
1303 (?!\d)\w+
1304 (?:\.(?!\d)\w+)*
1304 (?:\.(?!\d)\w+)*
1305 '''),
1305 '''),
1306 True: re.compile(dict_key_re_fmt % '''
1306 True: re.compile(dict_key_re_fmt % '''
1307 .+
1307 .+
1308 ''')
1308 ''')
1309 }
1309 }
1310
1310
1311 match = regexps[self.greedy].search(self.text_until_cursor)
1311 match = regexps[self.greedy].search(self.text_until_cursor)
1312 if match is None:
1312 if match is None:
1313 return []
1313 return []
1314
1314
1315 expr, prefix = match.groups()
1315 expr, prefix = match.groups()
1316 try:
1316 try:
1317 obj = eval(expr, self.namespace)
1317 obj = eval(expr, self.namespace)
1318 except Exception:
1318 except Exception:
1319 try:
1319 try:
1320 obj = eval(expr, self.global_namespace)
1320 obj = eval(expr, self.global_namespace)
1321 except Exception:
1321 except Exception:
1322 return []
1322 return []
1323
1323
1324 keys = get_keys(obj)
1324 keys = get_keys(obj)
1325 if not keys:
1325 if not keys:
1326 return keys
1326 return keys
1327 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1327 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1328 if not matches:
1328 if not matches:
1329 return matches
1329 return matches
1330
1330
1331 # get the cursor position of
1331 # get the cursor position of
1332 # - the text being completed
1332 # - the text being completed
1333 # - the start of the key text
1333 # - the start of the key text
1334 # - the start of the completion
1334 # - the start of the completion
1335 text_start = len(self.text_until_cursor) - len(text)
1335 text_start = len(self.text_until_cursor) - len(text)
1336 if prefix:
1336 if prefix:
1337 key_start = match.start(2)
1337 key_start = match.start(2)
1338 completion_start = key_start + token_offset
1338 completion_start = key_start + token_offset
1339 else:
1339 else:
1340 key_start = completion_start = match.end()
1340 key_start = completion_start = match.end()
1341
1341
1342 # grab the leading prefix, to make sure all completions start with `text`
1342 # grab the leading prefix, to make sure all completions start with `text`
1343 if text_start > key_start:
1343 if text_start > key_start:
1344 leading = ''
1344 leading = ''
1345 else:
1345 else:
1346 leading = text[text_start:completion_start]
1346 leading = text[text_start:completion_start]
1347
1347
1348 # the index of the `[` character
1348 # the index of the `[` character
1349 bracket_idx = match.end(1)
1349 bracket_idx = match.end(1)
1350
1350
1351 # append closing quote and bracket as appropriate
1351 # append closing quote and bracket as appropriate
1352 # this is *not* appropriate if the opening quote or bracket is outside
1352 # this is *not* appropriate if the opening quote or bracket is outside
1353 # the text given to this method
1353 # the text given to this method
1354 suf = ''
1354 suf = ''
1355 continuation = self.line_buffer[len(self.text_until_cursor):]
1355 continuation = self.line_buffer[len(self.text_until_cursor):]
1356 if key_start > text_start and closing_quote:
1356 if key_start > text_start and closing_quote:
1357 # quotes were opened inside text, maybe close them
1357 # quotes were opened inside text, maybe close them
1358 if continuation.startswith(closing_quote):
1358 if continuation.startswith(closing_quote):
1359 continuation = continuation[len(closing_quote):]
1359 continuation = continuation[len(closing_quote):]
1360 else:
1360 else:
1361 suf += closing_quote
1361 suf += closing_quote
1362 if bracket_idx > text_start:
1362 if bracket_idx > text_start:
1363 # brackets were opened inside text, maybe close them
1363 # brackets were opened inside text, maybe close them
1364 if not continuation.startswith(']'):
1364 if not continuation.startswith(']'):
1365 suf += ']'
1365 suf += ']'
1366
1366
1367 return [leading + k + suf for k in matches]
1367 return [leading + k + suf for k in matches]
1368
1368
1369 def unicode_name_matches(self, text):
1369 def unicode_name_matches(self, text):
1370 u"""Match Latex-like syntax for unicode characters base
1370 u"""Match Latex-like syntax for unicode characters base
1371 on the name of the character.
1371 on the name of the character.
1372
1372
1373 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
1373 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
1374
1374
1375 Works only on valid python 3 identifier, or on combining characters that
1375 Works only on valid python 3 identifier, or on combining characters that
1376 will combine to form a valid identifier.
1376 will combine to form a valid identifier.
1377
1377
1378 Used on Python 3 only.
1378 Used on Python 3 only.
1379 """
1379 """
1380 slashpos = text.rfind('\\')
1380 slashpos = text.rfind('\\')
1381 if slashpos > -1:
1381 if slashpos > -1:
1382 s = text[slashpos+1:]
1382 s = text[slashpos+1:]
1383 try :
1383 try :
1384 unic = unicodedata.lookup(s)
1384 unic = unicodedata.lookup(s)
1385 # allow combining chars
1385 # allow combining chars
1386 if ('a'+unic).isidentifier():
1386 if ('a'+unic).isidentifier():
1387 return '\\'+s,[unic]
1387 return '\\'+s,[unic]
1388 except KeyError:
1388 except KeyError:
1389 pass
1389 pass
1390 return u'', []
1390 return u'', []
1391
1391
1392
1392
1393 def latex_matches(self, text):
1393 def latex_matches(self, text):
1394 u"""Match Latex syntax for unicode characters.
1394 u"""Match Latex syntax for unicode characters.
1395
1395
1396 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
1396 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
1397
1397
1398 Used on Python 3 only.
1398 Used on Python 3 only.
1399 """
1399 """
1400 slashpos = text.rfind('\\')
1400 slashpos = text.rfind('\\')
1401 if slashpos > -1:
1401 if slashpos > -1:
1402 s = text[slashpos:]
1402 s = text[slashpos:]
1403 if s in latex_symbols:
1403 if s in latex_symbols:
1404 # Try to complete a full latex symbol to unicode
1404 # Try to complete a full latex symbol to unicode
1405 # \\alpha -> Ξ±
1405 # \\alpha -> Ξ±
1406 return s, [latex_symbols[s]]
1406 return s, [latex_symbols[s]]
1407 else:
1407 else:
1408 # If a user has partially typed a latex symbol, give them
1408 # If a user has partially typed a latex symbol, give them
1409 # a full list of options \al -> [\aleph, \alpha]
1409 # a full list of options \al -> [\aleph, \alpha]
1410 matches = [k for k in latex_symbols if k.startswith(s)]
1410 matches = [k for k in latex_symbols if k.startswith(s)]
1411 return s, matches
1411 return s, matches
1412 return u'', []
1412 return u'', []
1413
1413
1414 def dispatch_custom_completer(self, text):
1414 def dispatch_custom_completer(self, text):
1415 if not self.custom_completers:
1415 if not self.custom_completers:
1416 return
1416 return
1417
1417
1418 line = self.line_buffer
1418 line = self.line_buffer
1419 if not line.strip():
1419 if not line.strip():
1420 return None
1420 return None
1421
1421
1422 # Create a little structure to pass all the relevant information about
1422 # Create a little structure to pass all the relevant information about
1423 # the current completion to any custom completer.
1423 # the current completion to any custom completer.
1424 event = SimpleNamespace()
1424 event = SimpleNamespace()
1425 event.line = line
1425 event.line = line
1426 event.symbol = text
1426 event.symbol = text
1427 cmd = line.split(None,1)[0]
1427 cmd = line.split(None,1)[0]
1428 event.command = cmd
1428 event.command = cmd
1429 event.text_until_cursor = self.text_until_cursor
1429 event.text_until_cursor = self.text_until_cursor
1430
1430
1431 # for foo etc, try also to find completer for %foo
1431 # for foo etc, try also to find completer for %foo
1432 if not cmd.startswith(self.magic_escape):
1432 if not cmd.startswith(self.magic_escape):
1433 try_magic = self.custom_completers.s_matches(
1433 try_magic = self.custom_completers.s_matches(
1434 self.magic_escape + cmd)
1434 self.magic_escape + cmd)
1435 else:
1435 else:
1436 try_magic = []
1436 try_magic = []
1437
1437
1438 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1438 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1439 try_magic,
1439 try_magic,
1440 self.custom_completers.flat_matches(self.text_until_cursor)):
1440 self.custom_completers.flat_matches(self.text_until_cursor)):
1441 try:
1441 try:
1442 res = c(event)
1442 res = c(event)
1443 if res:
1443 if res:
1444 # first, try case sensitive match
1444 # first, try case sensitive match
1445 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1445 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1446 if withcase:
1446 if withcase:
1447 return withcase
1447 return withcase
1448 # if none, then case insensitive ones are ok too
1448 # if none, then case insensitive ones are ok too
1449 text_low = text.lower()
1449 text_low = text.lower()
1450 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1450 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1451 except TryNext:
1451 except TryNext:
1452 pass
1452 pass
1453
1453
1454 return None
1454 return None
1455
1455
1456 def completions(self, text: str, offset: int)->Iterator[Completion]:
1456 def completions(self, text: str, offset: int)->Iterator[Completion]:
1457 """
1457 """
1458 Returns an iterator over the possible completions
1458 Returns an iterator over the possible completions
1459
1459
1460 .. warning:: Unstable
1460 .. warning:: Unstable
1461
1461
1462 This function is unstable, API may change without warning.
1462 This function is unstable, API may change without warning.
1463 It will also raise unless use in proper context manager.
1463 It will also raise unless use in proper context manager.
1464
1464
1465 Parameters
1465 Parameters
1466 ----------
1466 ----------
1467
1467
1468 text:str
1468 text:str
1469 Full text of the current input, multi line string.
1469 Full text of the current input, multi line string.
1470 offset:int
1470 offset:int
1471 Integer representing the position of the cursor in ``text``. Offset
1471 Integer representing the position of the cursor in ``text``. Offset
1472 is 0-based indexed.
1472 is 0-based indexed.
1473
1473
1474 Yields
1474 Yields
1475 ------
1475 ------
1476 :any:`Completion` object
1476 :any:`Completion` object
1477
1477
1478
1478
1479 The cursor on a text can either be seen as being "in between"
1479 The cursor on a text can either be seen as being "in between"
1480 characters or "On" a character depending on the interface visible to
1480 characters or "On" a character depending on the interface visible to
1481 the user. For consistency the cursor being on "in between" characters X
1481 the user. For consistency the cursor being on "in between" characters X
1482 and Y is equivalent to the cursor being "on" character Y, that is to say
1482 and Y is equivalent to the cursor being "on" character Y, that is to say
1483 the character the cursor is on is considered as being after the cursor.
1483 the character the cursor is on is considered as being after the cursor.
1484
1484
1485 Combining characters may span more that one position in the
1485 Combining characters may span more that one position in the
1486 text.
1486 text.
1487
1487
1488
1488
1489 .. note::
1489 .. note::
1490
1490
1491 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
1491 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
1492 fake Completion token to distinguish completion returned by Jedi
1492 fake Completion token to distinguish completion returned by Jedi
1493 and usual IPython completion.
1493 and usual IPython completion.
1494
1494
1495 """
1495 """
1496 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
1496 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
1497 "It may change without warnings. "
1497 "It may change without warnings. "
1498 "Use in corresponding context manager.",
1498 "Use in corresponding context manager.",
1499 category=ProvisionalCompleterWarning, stacklevel=2)
1499 category=ProvisionalCompleterWarning, stacklevel=2)
1500
1500
1501 # Possible Improvements / Known limitation
1501 # Possible Improvements / Known limitation
1502 ##########################################
1502 ##########################################
1503 # Completions may be identical even if they have different ranges and
1503 # Completions may be identical even if they have different ranges and
1504 # text. For example:
1504 # text. For example:
1505 # >>> a=1
1505 # >>> a=1
1506 # >>> a.<tab>
1506 # >>> a.<tab>
1507 # May returns:
1507 # May returns:
1508 # - `a.real` from 0 to 2
1508 # - `a.real` from 0 to 2
1509 # - `.real` from 1 to 2
1509 # - `.real` from 1 to 2
1510 # the current code does not (yet) check for such equivalence
1510 # the current code does not (yet) check for such equivalence
1511 seen = set()
1511 seen = set()
1512 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
1512 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
1513 if c and (c in seen):
1513 if c and (c in seen):
1514 continue
1514 continue
1515 yield c
1515 yield c
1516 seen.add(c)
1516 seen.add(c)
1517
1517
1518 def _completions(self, full_text: str, offset: int, *, _timeout)->Iterator[Completion]:
1518 def _completions(self, full_text: str, offset: int, *, _timeout)->Iterator[Completion]:
1519 """
1519 """
1520 Core completion module.Same signature as :any:`completions`, with the
1520 Core completion module.Same signature as :any:`completions`, with the
1521 extra `timeout` parameter (in seconds).
1521 extra `timeout` parameter (in seconds).
1522
1522
1523
1523
1524 Computing jedi's completion ``.type`` can be quite expensive (it is a
1524 Computing jedi's completion ``.type`` can be quite expensive (it is a
1525 lazy property) and can require some warm-up, more warm up than just
1525 lazy property) and can require some warm-up, more warm up than just
1526 computing the ``name`` of a completion. The warm-up can be :
1526 computing the ``name`` of a completion. The warm-up can be :
1527
1527
1528 - Long warm-up the fisrt time a module is encountered after
1528 - Long warm-up the fisrt time a module is encountered after
1529 install/update: actually build parse/inference tree.
1529 install/update: actually build parse/inference tree.
1530
1530
1531 - first time the module is encountered in a session: load tree from
1531 - first time the module is encountered in a session: load tree from
1532 disk.
1532 disk.
1533
1533
1534 We don't want to block completions for tens of seconds so we give the
1534 We don't want to block completions for tens of seconds so we give the
1535 completer a "budget" of ``_timeout`` seconds per invocation to compute
1535 completer a "budget" of ``_timeout`` seconds per invocation to compute
1536 completions types, the completions that have not yet been computed will
1536 completions types, the completions that have not yet been computed will
1537 be marked as "unknown" an will have a chance to be computed next round
1537 be marked as "unknown" an will have a chance to be computed next round
1538 are things get cached.
1538 are things get cached.
1539
1539
1540 Keep in mind that Jedi is not the only thing treating the completion so
1540 Keep in mind that Jedi is not the only thing treating the completion so
1541 keep the timeout short-ish as if we take more than 0.3 second we still
1541 keep the timeout short-ish as if we take more than 0.3 second we still
1542 have lots of processing to do.
1542 have lots of processing to do.
1543
1543
1544 """
1544 """
1545 deadline = time.monotonic() + _timeout
1545 deadline = time.monotonic() + _timeout
1546
1546
1547
1547
1548 before = full_text[:offset]
1548 before = full_text[:offset]
1549 cursor_line, cursor_column = position_to_cursor(full_text, offset)
1549 cursor_line, cursor_column = position_to_cursor(full_text, offset)
1550
1550
1551 matched_text, matches, matches_origin, jedi_matches = self._complete(
1551 matched_text, matches, matches_origin, jedi_matches = self._complete(
1552 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column)
1552 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column)
1553
1553
1554 iter_jm = iter(jedi_matches)
1554 iter_jm = iter(jedi_matches)
1555 if _timeout:
1555 if _timeout:
1556 for jm in iter_jm:
1556 for jm in iter_jm:
1557 try:
1558 type_ = jm.type
1559 except Exception:
1560 if self.debug:
1561 print("Error in Jedi getting type of ", jm)
1562 type_ = None
1557 delta = len(jm.name_with_symbols) - len(jm.complete)
1563 delta = len(jm.name_with_symbols) - len(jm.complete)
1558 yield Completion(start=offset - delta,
1564 yield Completion(start=offset - delta,
1559 end=offset,
1565 end=offset,
1560 text=jm.name_with_symbols,
1566 text=jm.name_with_symbols,
1561 type=jm.type,
1567 type=type_,
1562 _origin='jedi')
1568 _origin='jedi')
1563
1569
1564 if time.monotonic() > deadline:
1570 if time.monotonic() > deadline:
1565 break
1571 break
1566
1572
1567 for jm in iter_jm:
1573 for jm in iter_jm:
1568 delta = len(jm.name_with_symbols) - len(jm.complete)
1574 delta = len(jm.name_with_symbols) - len(jm.complete)
1569 yield Completion(start=offset - delta,
1575 yield Completion(start=offset - delta,
1570 end=offset,
1576 end=offset,
1571 text=jm.name_with_symbols,
1577 text=jm.name_with_symbols,
1572 type='<unknown>', # don't compute type for speed
1578 type='<unknown>', # don't compute type for speed
1573 _origin='jedi')
1579 _origin='jedi')
1574
1580
1575
1581
1576 start_offset = before.rfind(matched_text)
1582 start_offset = before.rfind(matched_text)
1577
1583
1578 # TODO:
1584 # TODO:
1579 # Supress this, right now just for debug.
1585 # Supress this, right now just for debug.
1580 if jedi_matches and matches and self.debug:
1586 if jedi_matches and matches and self.debug:
1581 yield Completion(start=start_offset, end=offset, text='--jedi/ipython--', _origin='debug')
1587 yield Completion(start=start_offset, end=offset, text='--jedi/ipython--', _origin='debug')
1582
1588
1583 # I'm unsure if this is always true, so let's assert and see if it
1589 # I'm unsure if this is always true, so let's assert and see if it
1584 # crash
1590 # crash
1585 assert before.endswith(matched_text)
1591 assert before.endswith(matched_text)
1586 for m, t in zip(matches, matches_origin):
1592 for m, t in zip(matches, matches_origin):
1587 yield Completion(start=start_offset, end=offset, text=m, _origin=t)
1593 yield Completion(start=start_offset, end=offset, text=m, _origin=t)
1588
1594
1589
1595
1590 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1596 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1591 """Find completions for the given text and line context.
1597 """Find completions for the given text and line context.
1592
1598
1593 Note that both the text and the line_buffer are optional, but at least
1599 Note that both the text and the line_buffer are optional, but at least
1594 one of them must be given.
1600 one of them must be given.
1595
1601
1596 Parameters
1602 Parameters
1597 ----------
1603 ----------
1598 text : string, optional
1604 text : string, optional
1599 Text to perform the completion on. If not given, the line buffer
1605 Text to perform the completion on. If not given, the line buffer
1600 is split using the instance's CompletionSplitter object.
1606 is split using the instance's CompletionSplitter object.
1601
1607
1602 line_buffer : string, optional
1608 line_buffer : string, optional
1603 If not given, the completer attempts to obtain the current line
1609 If not given, the completer attempts to obtain the current line
1604 buffer via readline. This keyword allows clients which are
1610 buffer via readline. This keyword allows clients which are
1605 requesting for text completions in non-readline contexts to inform
1611 requesting for text completions in non-readline contexts to inform
1606 the completer of the entire text.
1612 the completer of the entire text.
1607
1613
1608 cursor_pos : int, optional
1614 cursor_pos : int, optional
1609 Index of the cursor in the full line buffer. Should be provided by
1615 Index of the cursor in the full line buffer. Should be provided by
1610 remote frontends where kernel has no access to frontend state.
1616 remote frontends where kernel has no access to frontend state.
1611
1617
1612 Returns
1618 Returns
1613 -------
1619 -------
1614 text : str
1620 text : str
1615 Text that was actually used in the completion.
1621 Text that was actually used in the completion.
1616
1622
1617 matches : list
1623 matches : list
1618 A list of completion matches.
1624 A list of completion matches.
1619
1625
1620
1626
1621 .. note::
1627 .. note::
1622
1628
1623 This API is likely to be deprecated and replaced by
1629 This API is likely to be deprecated and replaced by
1624 :any:`IPCompleter.completions` in the future.
1630 :any:`IPCompleter.completions` in the future.
1625
1631
1626
1632
1627 """
1633 """
1628 warnings.warn('`Completer.complete` is pending deprecation since '
1634 warnings.warn('`Completer.complete` is pending deprecation since '
1629 'IPython 6.0 and will be replaced by `Completer.completions`.',
1635 'IPython 6.0 and will be replaced by `Completer.completions`.',
1630 PendingDeprecationWarning)
1636 PendingDeprecationWarning)
1631 # potential todo, FOLD the 3rd throw away argument of _complete
1637 # potential todo, FOLD the 3rd throw away argument of _complete
1632 # into the first 2 one.
1638 # into the first 2 one.
1633 return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2]
1639 return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2]
1634
1640
1635 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
1641 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
1636 full_text=None, return_jedi_results=True) -> (str, List[str], List[object]):
1642 full_text=None, return_jedi_results=True) -> (str, List[str], List[object]):
1637 """
1643 """
1638
1644
1639 Like complete but can also returns raw jedi completions as well as the
1645 Like complete but can also returns raw jedi completions as well as the
1640 origin of the completion text. This could (and should) be made much
1646 origin of the completion text. This could (and should) be made much
1641 cleaner but that will be simpler once we drop the old (and stateful)
1647 cleaner but that will be simpler once we drop the old (and stateful)
1642 :any:`complete` API.
1648 :any:`complete` API.
1643
1649
1644
1650
1645 With current provisional API, cursor_pos act both (depending on the
1651 With current provisional API, cursor_pos act both (depending on the
1646 caller) as the offset in the ``text`` or ``line_buffer``, or as the
1652 caller) as the offset in the ``text`` or ``line_buffer``, or as the
1647 ``column`` when passing multiline strings this could/should be renamed
1653 ``column`` when passing multiline strings this could/should be renamed
1648 but would add extra noise.
1654 but would add extra noise.
1649 """
1655 """
1650
1656
1651 # if the cursor position isn't given, the only sane assumption we can
1657 # if the cursor position isn't given, the only sane assumption we can
1652 # make is that it's at the end of the line (the common case)
1658 # make is that it's at the end of the line (the common case)
1653 if cursor_pos is None:
1659 if cursor_pos is None:
1654 cursor_pos = len(line_buffer) if text is None else len(text)
1660 cursor_pos = len(line_buffer) if text is None else len(text)
1655
1661
1656 if self.use_main_ns:
1662 if self.use_main_ns:
1657 self.namespace = __main__.__dict__
1663 self.namespace = __main__.__dict__
1658
1664
1659 # if text is either None or an empty string, rely on the line buffer
1665 # if text is either None or an empty string, rely on the line buffer
1660 if (not line_buffer) and full_text:
1666 if (not line_buffer) and full_text:
1661 line_buffer = full_text.split('\n')[cursor_line]
1667 line_buffer = full_text.split('\n')[cursor_line]
1662 if not text:
1668 if not text:
1663 text = self.splitter.split_line(line_buffer, cursor_pos)
1669 text = self.splitter.split_line(line_buffer, cursor_pos)
1664
1670
1665 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1671 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1666 latex_text, latex_matches = self.latex_matches(base_text)
1672 latex_text, latex_matches = self.latex_matches(base_text)
1667 if latex_matches:
1673 if latex_matches:
1668 return latex_text, latex_matches, ['latex_matches']*len(latex_matches), ()
1674 return latex_text, latex_matches, ['latex_matches']*len(latex_matches), ()
1669 name_text = ''
1675 name_text = ''
1670 name_matches = []
1676 name_matches = []
1671 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1677 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1672 name_text, name_matches = meth(base_text)
1678 name_text, name_matches = meth(base_text)
1673 if name_text:
1679 if name_text:
1674 return name_text, name_matches, [meth.__qualname__]*len(name_matches), {}
1680 return name_text, name_matches, [meth.__qualname__]*len(name_matches), {}
1675
1681
1676
1682
1677 # If no line buffer is given, assume the input text is all there was
1683 # If no line buffer is given, assume the input text is all there was
1678 if line_buffer is None:
1684 if line_buffer is None:
1679 line_buffer = text
1685 line_buffer = text
1680
1686
1681 self.line_buffer = line_buffer
1687 self.line_buffer = line_buffer
1682 self.text_until_cursor = self.line_buffer[:cursor_pos]
1688 self.text_until_cursor = self.line_buffer[:cursor_pos]
1683
1689
1684 # Start with a clean slate of completions
1690 # Start with a clean slate of completions
1685 matches = []
1691 matches = []
1686 custom_res = self.dispatch_custom_completer(text)
1692 custom_res = self.dispatch_custom_completer(text)
1687 # FIXME: we should extend our api to return a dict with completions for
1693 # FIXME: we should extend our api to return a dict with completions for
1688 # different types of objects. The rlcomplete() method could then
1694 # different types of objects. The rlcomplete() method could then
1689 # simply collapse the dict into a list for readline, but we'd have
1695 # simply collapse the dict into a list for readline, but we'd have
1690 # richer completion semantics in other evironments.
1696 # richer completion semantics in other evironments.
1691 completions = ()
1697 completions = ()
1692 if self.use_jedi and return_jedi_results:
1698 if self.use_jedi and return_jedi_results:
1693 if not full_text:
1699 if not full_text:
1694 full_text = line_buffer
1700 full_text = line_buffer
1695 completions = self._jedi_matches(
1701 completions = self._jedi_matches(
1696 cursor_pos, cursor_line, full_text)
1702 cursor_pos, cursor_line, full_text)
1697 if custom_res is not None:
1703 if custom_res is not None:
1698 # did custom completers produce something?
1704 # did custom completers produce something?
1699 matches = [(m, 'custom') for m in custom_res]
1705 matches = [(m, 'custom') for m in custom_res]
1700 else:
1706 else:
1701 # Extend the list of completions with the results of each
1707 # Extend the list of completions with the results of each
1702 # matcher, so we return results to the user from all
1708 # matcher, so we return results to the user from all
1703 # namespaces.
1709 # namespaces.
1704 if self.merge_completions:
1710 if self.merge_completions:
1705 matches = []
1711 matches = []
1706 for matcher in self.matchers:
1712 for matcher in self.matchers:
1707 try:
1713 try:
1708 matches.extend([(m, matcher.__qualname__)
1714 matches.extend([(m, matcher.__qualname__)
1709 for m in matcher(text)])
1715 for m in matcher(text)])
1710 except:
1716 except:
1711 # Show the ugly traceback if the matcher causes an
1717 # Show the ugly traceback if the matcher causes an
1712 # exception, but do NOT crash the kernel!
1718 # exception, but do NOT crash the kernel!
1713 sys.excepthook(*sys.exc_info())
1719 sys.excepthook(*sys.exc_info())
1714 else:
1720 else:
1715 for matcher in self.matchers:
1721 for matcher in self.matchers:
1716 matches = [(m, matcher.__qualname__)
1722 matches = [(m, matcher.__qualname__)
1717 for m in matcher(text)]
1723 for m in matcher(text)]
1718 if matches:
1724 if matches:
1719 break
1725 break
1720 seen = set()
1726 seen = set()
1721 filtered_matches = set()
1727 filtered_matches = set()
1722 for m in matches:
1728 for m in matches:
1723 t, c = m
1729 t, c = m
1724 if t not in seen:
1730 if t not in seen:
1725 filtered_matches.add(m)
1731 filtered_matches.add(m)
1726 seen.add(t)
1732 seen.add(t)
1727
1733
1728 filtered_matches = sorted(
1734 filtered_matches = sorted(
1729 set(filtered_matches), key=lambda x: completions_sorting_key(x[0]))
1735 set(filtered_matches), key=lambda x: completions_sorting_key(x[0]))
1730
1736
1731 matches = [m[0] for m in filtered_matches]
1737 matches = [m[0] for m in filtered_matches]
1732 origins = [m[1] for m in filtered_matches]
1738 origins = [m[1] for m in filtered_matches]
1733
1739
1734 self.matches = matches
1740 self.matches = matches
1735
1741
1736 return text, matches, origins, completions
1742 return text, matches, origins, completions
General Comments 0
You need to be logged in to leave comments. Login now