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