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