##// END OF EJS Templates
First step in reintegrating Jedi...
Matthias Bussonnier -
Show More
@@ -0,0 +1,9 b''
1 The completer Completion API has seen an overhaul. The old
2 ``Completer.complete()`` API is waiting deprecation and will soon be replaced
3 by the ``Completer.completions()`` one. While the ``Completer.complete()`` API
4 was assuming completions would all replace the same range of text in the
5 completed buffer, ``Completer.completions()`` does not. To smooth the transition
6 we provide two utility methods ``regulrize...`` and ``stufff`` which can
7 partially adapt between the old and new API. The new API is marked as
8 "unstable" and can only be use explicitly when called from within a decorator
9 we provide.
This diff has been collapsed as it changes many lines, (618 lines changed) Show them Hide them
@@ -1,12 +1,57 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Word completion for IPython.
2 """Completion for IPython.
3
3
4 This module started as fork of the rlcompleter module in the Python standard
4 This module started as fork of the rlcompleter module in the Python standard
5 library. The original enhancements made to rlcompleter have been sent
5 library. The original enhancements made to rlcompleter have been sent
6 upstream and were accepted as of Python 2.3,
6 upstream and were accepted as of Python 2.3,
7
7
8 This module now support a wide variety of completion mechanism both available
9 for normal classic Python code, as well as completer for IPython specific
10 Syntax like magics.
11
12 Experimental
13 ============
14
15 Starting with IPython 6.0, this module can make use of the Jedi library to
16 generate completions both using static analysis of the code, and dynamically
17 inspecting multiple namespaces. The APIs attached to this new mechanism is
18 unstable and will raise unless use in an :any:`provisionalcompleter` context
19 manager.
20
21 You will find that the following are experimental:
22
23 - :any:`provisionalcompleter`
24 - :any:`IPCompleter.completions`
25 - :any:`Completion`
26 - :any:`rectify_completions`
27
28 .. note::
29
30 better name for :any:`rectify_completions` ?
31
32 We welcome any feedback on these new API, and we also encourage you to try this
33 module in debug mode (start IPython with ``--Completer.debug=True``) in order
34 to have extra logging information is :any:`jedi` is crashing, or if current
35 IPython completer pending deprecations are returning results not yet handled
36 by :any:`jedi`.
37
38 Using Jedi for tab completion allow snippets like the following to work without
39 having to execute any code:
40
41 >>> myvar = ['hello', 42]
42 ... myvar[1].bi<tab>
43
44 Tab completion will be able to infer that ``myvar[1]`` is a real number without
45 executing any code unlike the previously available ``IPCompleter.greedy``
46 option.
47
48 Be sure to update :any:`jedi` to the latest stable version or to try the
49 current development version to get better completions.
8 """
50 """
9
51
52 # skip module docstests
53 skip_doctest = True
54
10 # Copyright (c) IPython Development Team.
55 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
56 # Distributed under the terms of the Modified BSD License.
12 #
57 #
@@ -26,19 +71,31 b' import sys'
26 import unicodedata
71 import unicodedata
27 import string
72 import string
28 import warnings
73 import warnings
74
75 from contextlib import contextmanager
29 from importlib import import_module
76 from importlib import import_module
77 from typing import Iterator, List
78 from types import SimpleNamespace
30
79
31 from traitlets.config.configurable import Configurable
80 from traitlets.config.configurable import Configurable
32 from IPython.core.error import TryNext
81 from IPython.core.error import TryNext
33 from IPython.core.inputsplitter import ESC_MAGIC
82 from IPython.core.inputsplitter import ESC_MAGIC
34 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
83 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
35 from IPython.utils import generics
84 from IPython.utils import generics
36 from IPython.utils.decorators import undoc
37 from IPython.utils.dir2 import dir2, get_real_method
85 from IPython.utils.dir2 import dir2, get_real_method
38 from IPython.utils.process import arg_split
86 from IPython.utils.process import arg_split
39 from IPython.utils.py3compat import cast_unicode_py2
87 from IPython.utils.py3compat import cast_unicode_py2
40 from traitlets import Bool, Enum, observe
88 from traitlets import Bool, Enum, observe
41
89
90 try:
91 import jedi
92 import jedi.api.helpers
93 JEDI_INSTALLED = True
94 except ImportError:
95 JEDI_INSTALLED = False
96 #-----------------------------------------------------------------------------
97 # Globals
98 #-----------------------------------------------------------------------------
42
99
43 # Public API
100 # Public API
44 __all__ = ['Completer','IPCompleter']
101 __all__ = ['Completer','IPCompleter']
@@ -49,6 +106,50 b' else:'
49 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
106 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
50
107
51
108
109 _deprecation_readline_sentinel = object()
110
111
112 class ProvisionalCompleterWarning(FutureWarning):
113 """
114 Exception raise by an experimental feature in this module.
115
116 Wrap code in :any:`provisionalcompleter` context manager if you
117 are certain you want to use an unstable feature.
118 """
119 pass
120
121 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
122
123 @contextmanager
124 def provisionalcompleter(action='ignore'):
125 """
126
127
128 This contest manager has to be used in any place where unstable completer
129 behavior and API may be called.
130
131 >>> with provisionalcompleter():
132 ... completer.do_experimetal_things() # works
133
134 >>> completer.do_experimental_things() # raises.
135
136 .. note:: Unstable
137
138 By using this context manager you agree that the API in use may change
139 without warning, and that you won't complain if they do so.
140
141 You also understand that if the API is not to you liking you should report
142 a bug to explain your use case upstream and improve the API and will loose
143 credibility if you complain after the API is make stable.
144
145 We'll be happy to get your feedback , feature request and improvement on
146 any of the unstable APIs !
147 """
148 with warnings.catch_warnings():
149 warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
150 yield
151
152
52 def has_open_quotes(s):
153 def has_open_quotes(s):
53 """Return whether a string has open quotes.
154 """Return whether a string has open quotes.
54
155
@@ -82,7 +183,7 b' def protect_filename(s):'
82
183
83
184
84 def expand_user(path):
185 def expand_user(path):
85 """Expand '~'-style usernames in strings.
186 """Expand ``~``-style usernames in strings.
86
187
87 This is similar to :func:`os.path.expanduser`, but it computes and returns
188 This is similar to :func:`os.path.expanduser`, but it computes and returns
88 extra information that will be useful if the input was being used in
189 extra information that will be useful if the input was being used in
@@ -167,8 +268,135 b' def completions_sorting_key(word):'
167 return prio1, word, prio2
268 return prio1, word, prio2
168
269
169
270
170 @undoc
271 class _FakeJediCompletion:
171 class Bunch(object): pass
272 """
273 This is a workaround to communicate to the UI that Jedi has crashed and to
274 report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
275
276 Added in IPython 6.0 so should likely be removed for 7.0
277
278 """
279
280 def __init__(self, name):
281
282 self.name = name
283 self.complete = name
284 self.type = 'crashed'
285 self.name_with_symbols = name
286
287 def __repr__(self):
288 return '<Fake completion object jedi has crashed>'
289
290
291 class Completion:
292 """
293 Completion object used and return by IPython completers.
294
295 .. warning:: Unstable
296
297 This function is unstable, API may change without warning.
298 It will also raise unless use in proper context manager.
299
300 This act as a middle ground :any:`Completion` object between the
301 :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
302 object. While Jedi need a lot of information about evaluator and how the
303 code should be ran/inspected, PromptToolkit (and other frontend) mostly
304 need user facing information.
305
306 - Which range should be replaced replaced by what.
307 - Some metadata (like completion type), or meta informations to displayed to
308 the use user.
309
310 For debugging purpose we can also store the origin of the completion (``jedi``,
311 ``IPython.python_matches``, ``IPython.magics_matches``...).
312 """
313
314 def __init__(self, start: int, end: int, text: str, *, type: str=None, _origin=''):
315 warnings.warn("``Completion`` is a provisional API (as of IPython 6.0). "
316 "It may change without warnings. "
317 "Use in corresponding context manager.",
318 category=ProvisionalCompleterWarning, stacklevel=2)
319
320 self.start = start
321 self.end = end
322 self.text = text
323 self.type = type
324 self._origin = _origin
325
326 def __repr__(self):
327 return '<Completion start=%s end=%s text=%r type=%r>' % (self.start, self.end, self.text, self.type or '?')
328
329 def __eq__(self, other)->Bool:
330 """
331 Equality and hash do not hash the type (as some completer may not be
332 able to infer the type), but are use to (partially) de-duplicate
333 completion.
334
335 Completely de-duplicating completion is a bit tricker that just
336 comparing as it depends on surrounding text, which Completions are not
337 aware of.
338 """
339 return self.start == other.start and \
340 self.end == other.end and \
341 self.text == other.text
342
343 def __hash__(self):
344 return hash((self.start, self.end, self.text))
345
346 _IC = Iterator[Completion]
347
348 def rectify_completions(text:str, completion:_IC, *, _debug=False)->_IC:
349 """
350 Rectify a set of completion to all have the same ``start`` and ``end``
351
352 .. warning:: Unstable
353
354 This function is unstable, API may change without warning.
355 It will also raise unless use in proper context manager.
356
357 Parameters
358 ----------
359 text: str
360 text that should be completed.
361 completion: Iterator[Completion]
362 iterator over the completions to rectify
363
364
365 :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
366 the Jupyter Protocol requires them to behave like so. This will readjust
367 the completion to have the same ``start`` and ``end` by padding both
368 extremities with surrounding text.
369
370 During stabilisation should support a ``_debug`` option to log which
371 completion are return by the IPython completer and not found in Jedi in
372 order to make upstream bug report.
373 """
374 warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
375 "It may change without warnings. "
376 "Use in corresponding context manager.",
377 category=ProvisionalCompleterWarning, stacklevel=2)
378
379 completions = list(completion)
380 if not completions:
381 return
382 starts = (c.start for c in completions)
383 ends = (c.end for c in completions)
384
385 new_start = min(starts)
386 new_end = max(ends)
387
388 seen_jedi = set()
389 seen_python_matches = set()
390 for c in completions:
391 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
392 if c._origin == 'jedi':
393 seen_jedi.add(new_text)
394 elif c._origin == 'IPCompleter.python_matches':
395 seen_python_matches.add(new_text)
396 yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin)
397 diff = seen_python_matches.difference(seen_jedi)
398 if diff and _debug:
399 print('IPython.python matches have extras:', diff)
172
400
173
401
174 if sys.platform == 'win32':
402 if sys.platform == 'win32':
@@ -189,7 +417,7 b' class CompletionSplitter(object):'
189 entire line.
417 entire line.
190
418
191 What characters are used as splitting delimiters can be controlled by
419 What characters are used as splitting delimiters can be controlled by
192 setting the `delims` attribute (this is a property that internally
420 setting the ``delims`` attribute (this is a property that internally
193 automatically builds the necessary regular expression)"""
421 automatically builds the necessary regular expression)"""
194
422
195 # Private interface
423 # Private interface
@@ -230,6 +458,7 b' class CompletionSplitter(object):'
230 return self._delim_re.split(l)[-1]
458 return self._delim_re.split(l)[-1]
231
459
232
460
461
233 class Completer(Configurable):
462 class Completer(Configurable):
234
463
235 greedy = Bool(False,
464 greedy = Bool(False,
@@ -240,7 +469,16 b' class Completer(Configurable):'
240 but can be unsafe because the code is actually evaluated on TAB.
469 but can be unsafe because the code is actually evaluated on TAB.
241 """
470 """
242 ).tag(config=True)
471 ).tag(config=True)
243
472
473 use_jedi = Bool(default_value=JEDI_INSTALLED,
474 help="Experimental: Use Jedi to generate autocompletions. "
475 "Default to True if jedi is installed").tag(config=True)
476
477 debug = Bool(default_value=False,
478 help='Enable debug for the Completer. Mostly print extra '
479 'information for experimental jedi integration.')\
480 .tag(config=True)
481
244
482
245 def __init__(self, namespace=None, global_namespace=None, **kwargs):
483 def __init__(self, namespace=None, global_namespace=None, **kwargs):
246 """Create a new completer for the command line.
484 """Create a new completer for the command line.
@@ -254,20 +492,15 b' class Completer(Configurable):'
254 An optional second namespace can be given. This allows the completer
492 An optional second namespace can be given. This allows the completer
255 to handle cases where both the local and global scopes need to be
493 to handle cases where both the local and global scopes need to be
256 distinguished.
494 distinguished.
257
258 Completer instances should be used as the completion mechanism of
259 readline via the set_completer() call:
260
261 readline.set_completer(Completer(my_namespace).complete)
262 """
495 """
263
496
264 # Don't bind to namespace quite yet, but flag whether the user wants a
497 # Don't bind to namespace quite yet, but flag whether the user wants a
265 # specific namespace or to use __main__.__dict__. This will allow us
498 # specific namespace or to use __main__.__dict__. This will allow us
266 # to bind to __main__.__dict__ at completion time, not now.
499 # to bind to __main__.__dict__ at completion time, not now.
267 if namespace is None:
500 if namespace is None:
268 self.use_main_ns = 1
501 self.use_main_ns = True
269 else:
502 else:
270 self.use_main_ns = 0
503 self.use_main_ns = False
271 self.namespace = namespace
504 self.namespace = namespace
272
505
273 # The global namespace, if given, can be bound directly
506 # The global namespace, if given, can be bound directly
@@ -354,13 +587,15 b' class Completer(Configurable):'
354
587
355 if self.limit_to__all__ and hasattr(obj, '__all__'):
588 if self.limit_to__all__ and hasattr(obj, '__all__'):
356 words = get__all__entries(obj)
589 words = get__all__entries(obj)
357 else:
590 else:
358 words = dir2(obj)
591 words = dir2(obj)
359
592
360 try:
593 try:
361 words = generics.complete_object(obj, words)
594 words = generics.complete_object(obj, words)
362 except TryNext:
595 except TryNext:
363 pass
596 pass
597 except AssertionError:
598 raise
364 except Exception:
599 except Exception:
365 # Silence errors from completion function
600 # Silence errors from completion function
366 #raise # dbg
601 #raise # dbg
@@ -376,7 +611,7 b' def get__all__entries(obj):'
376 words = getattr(obj, '__all__')
611 words = getattr(obj, '__all__')
377 except:
612 except:
378 return []
613 return []
379
614
380 return [cast_unicode_py2(w) for w in words if isinstance(w, str)]
615 return [cast_unicode_py2(w) for w in words if isinstance(w, str)]
381
616
382
617
@@ -431,6 +666,73 b' def match_dict_keys(keys, prefix, delims):'
431 return quote, token_start, matched
666 return quote, token_start, matched
432
667
433
668
669 def cursor_to_position(text:int, line:int, column:int)->int:
670 """
671
672 Convert the (line,column) position of the cursor in text to an offset in a
673 string.
674
675 Parameter
676 ---------
677
678 text : str
679 The text in which to calculate the cursor offset
680 line : int
681 Line of the cursor; 0-indexed
682 column : int
683 Column of the cursor 0-indexed
684
685 Return
686 ------
687 Position of the cursor in ``text``, 0-indexed.
688
689 See Also
690 --------
691 position_to_cursor: reciprocal of this function
692
693 """
694 lines = text.split('\n')
695 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
696
697 return sum(len(l) + 1 for l in lines[:line]) + column
698
699 def position_to_cursor(text:str, offset:int)->(int, int):
700 """
701 Convert the position of the cursor in text (0 indexed) to a line
702 number(0-indexed) and a column number (0-indexed) pair
703
704 Position should be a valid position in ``text``.
705
706 Parameter
707 ---------
708
709 text : str
710 The text in which to calculate the cursor offset
711 offset : int
712 Position of the cursor in ``text``, 0-indexed.
713
714 Return
715 ------
716 (line, column) : (int, int)
717 Line of the cursor; 0-indexed, column of the cursor 0-indexed
718
719
720 See Also
721 --------
722 cursor_to_position : reciprocal of this function
723
724
725 """
726
727 assert 0 < offset <= len(text) , "0 < %s <= %s" % (offset , len(text))
728
729 before = text[:offset]
730 blines = before.split('\n') # ! splitnes trim trailing \n
731 line = before.count('\n')
732 col = len(blines[-1])
733 return line, col
734
735
434 def _safe_isinstance(obj, module, class_name):
736 def _safe_isinstance(obj, module, class_name):
435 """Checks if obj is an instance of module.class_name if loaded
737 """Checks if obj is an instance of module.class_name if loaded
436 """
738 """
@@ -441,7 +743,7 b' def _safe_isinstance(obj, module, class_name):'
441 def back_unicode_name_matches(text):
743 def back_unicode_name_matches(text):
442 u"""Match unicode characters back to unicode name
744 u"""Match unicode characters back to unicode name
443
745
444 This does ☃ -> \\snowman
746 This does ```` -> ``\\snowman``
445
747
446 Note that snowman is not a valid python3 combining character but will be expanded.
748 Note that snowman is not a valid python3 combining character but will be expanded.
447 Though it will not recombine back to the snowman character by the completion machinery.
749 Though it will not recombine back to the snowman character by the completion machinery.
@@ -468,10 +770,10 b' def back_unicode_name_matches(text):'
468 pass
770 pass
469 return u'', ()
771 return u'', ()
470
772
471 def back_latex_name_matches(text):
773 def back_latex_name_matches(text:str):
472 u"""Match latex characters back to unicode name
774 """Match latex characters back to unicode name
473
775
474 This does ->\\sqrt
776 This does ``\\ℵ`` -> ``\\aleph``
475
777
476 Used on Python 3 only.
778 Used on Python 3 only.
477 """
779 """
@@ -536,7 +838,7 b' class IPCompleter(Completer):'
536
838
537 When True: only those names in obj.__all__ will be included.
839 When True: only those names in obj.__all__ will be included.
538
840
539 When False [default]: the __all__ attribute is ignored
841 When False [default]: the __all__ attribute is ignored
540 """,
842 """,
541 ).tag(config=True)
843 ).tag(config=True)
542
844
@@ -548,33 +850,36 b' class IPCompleter(Completer):'
548 UserWarning)
850 UserWarning)
549
851
550 def __init__(self, shell=None, namespace=None, global_namespace=None,
852 def __init__(self, shell=None, namespace=None, global_namespace=None,
551 use_readline=False, config=None, **kwargs):
853 use_readline=_deprecation_readline_sentinel, config=None, **kwargs):
552 """IPCompleter() -> completer
854 """IPCompleter() -> completer
553
855
554 Return a completer object suitable for use by the readline library
856 Return a completer object.
555 via readline.set_completer().
556
857
557 Inputs:
858 Parameters
558
859 ----------
559 - shell: a pointer to the ipython shell itself. This is needed
560 because this completer knows about magic functions, and those can
561 only be accessed via the ipython instance.
562
860
563 - namespace: an optional dict where completions are performed.
861 shell
862 a pointer to the ipython shell itself. This is needed
863 because this completer knows about magic functions, and those can
864 only be accessed via the ipython instance.
564
865
565 - global_namespace: secondary optional dict for completions, to
866 namespace : dict, optional
566 handle cases (such as IPython embedded inside functions) where
867 an optional dict where completions are performed.
567 both Python scopes are visible.
568
868
869 global_namespace : dict, optional
870 secondary optional dict for completions, to
871 handle cases (such as IPython embedded inside functions) where
872 both Python scopes are visible.
873
569 use_readline : bool, optional
874 use_readline : bool, optional
570 DEPRECATED, ignored.
875 DEPRECATED, ignored since IPython 6.0, will have no effects
571 """
876 """
572
877
573 self.magic_escape = ESC_MAGIC
878 self.magic_escape = ESC_MAGIC
574 self.splitter = CompletionSplitter()
879 self.splitter = CompletionSplitter()
575
880
576 if use_readline:
881 if use_readline is not _deprecation_readline_sentinel:
577 warnings.warn('The use_readline parameter is deprecated and ignored since IPython 6.0.',
882 warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.',
578 DeprecationWarning, stacklevel=2)
883 DeprecationWarning, stacklevel=2)
579
884
580 # _greedy_changed() depends on splitter and readline being defined:
885 # _greedy_changed() depends on splitter and readline being defined:
@@ -733,6 +1038,55 b' class IPCompleter(Completer):'
733 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
1038 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
734 return [cast_unicode_py2(c) for c in comp]
1039 return [cast_unicode_py2(c) for c in comp]
735
1040
1041 def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str):
1042 """
1043
1044 Return a list of :any:`jedi.api.Completions` object from a ``text`` and
1045 cursor position.
1046
1047 Parameters
1048 ----------
1049 cursor_column : int
1050 column position of the cursor in ``text``, 0-indexed.
1051 cursor_line : int
1052 line position of the cursor in ``text``, 0-indexed
1053 text : str
1054 text to complete
1055
1056 Debugging
1057 ---------
1058
1059 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
1060 object containing a string with the Jedi debug information attached.
1061 """
1062 namespaces = [self.namespace]
1063 if self.global_namespace is not None:
1064 namespaces.append(self.global_namespace)
1065
1066 # cursor_pos is an it, jedi wants line and column
1067 offset = cursor_to_position(text, cursor_line, cursor_column)
1068 if offset:
1069 pre = text[offset-1]
1070 completion_filter = lambda x:x
1071 if pre == '.':
1072 if self.omit__names == 2:
1073 completion_filter = lambda c:not c.name.startswith('_')
1074 elif self.omit__names == 1:
1075 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
1076 elif self.omit__names == 0:
1077 completion_filter = lambda x:x
1078 else:
1079 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
1080
1081 interpreter = jedi.Interpreter(
1082 text, namespaces, column=cursor_column, line=cursor_line + 1)
1083 try:
1084 return filter(completion_filter, interpreter.completions())
1085 except Exception as e:
1086 if self.debug:
1087 return [_FakeJediCompletion('Opps Jedi has crash please report a bug with the following:\n"""\n%s\ns"""' % (e))]
1088 else:
1089 return []
736
1090
737 def python_matches(self, text):
1091 def python_matches(self, text):
738 """Match attributes or global python names"""
1092 """Match attributes or global python names"""
@@ -1006,12 +1360,12 b' class IPCompleter(Completer):'
1006 return [leading + k + suf for k in matches]
1360 return [leading + k + suf for k in matches]
1007
1361
1008 def unicode_name_matches(self, text):
1362 def unicode_name_matches(self, text):
1009 u"""Match Latex-like syntax for unicode characters base
1363 u"""Match Latex-like syntax for unicode characters base
1010 on the name of the character.
1364 on the name of the character.
1011
1365
1012 This does \\GREEK SMALL LETTER ETA -> η
1366 This does ``\\GREEK SMALL LETTER ETA`` -> ``η``
1013
1367
1014 Works only on valid python 3 identifier, or on combining characters that
1368 Works only on valid python 3 identifier, or on combining characters that
1015 will combine to form a valid identifier.
1369 will combine to form a valid identifier.
1016
1370
1017 Used on Python 3 only.
1371 Used on Python 3 only.
@@ -1029,13 +1383,11 b' class IPCompleter(Completer):'
1029 return u'', []
1383 return u'', []
1030
1384
1031
1385
1032
1033
1034 def latex_matches(self, text):
1386 def latex_matches(self, text):
1035 u"""Match Latex syntax for unicode characters.
1387 u"""Match Latex syntax for unicode characters.
1036
1388
1037 This does both \\alp -> \\alpha and \\alpha -> α
1389 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``α``
1038
1390
1039 Used on Python 3 only.
1391 Used on Python 3 only.
1040 """
1392 """
1041 slashpos = text.rfind('\\')
1393 slashpos = text.rfind('\\')
@@ -1062,7 +1414,7 b' class IPCompleter(Completer):'
1062
1414
1063 # Create a little structure to pass all the relevant information about
1415 # Create a little structure to pass all the relevant information about
1064 # the current completion to any custom completer.
1416 # the current completion to any custom completer.
1065 event = Bunch()
1417 event = SimpleNamespace()
1066 event.line = line
1418 event.line = line
1067 event.symbol = text
1419 event.symbol = text
1068 cmd = line.split(None,1)[0]
1420 cmd = line.split(None,1)[0]
@@ -1094,6 +1446,94 b' class IPCompleter(Completer):'
1094
1446
1095 return None
1447 return None
1096
1448
1449 def completions(self, text: str, offset: int)->Iterator[Completion]:
1450 """
1451 Returns an iterator over the possible completions
1452
1453 .. warning:: Unstable
1454
1455 This function is unstable, API may change without warning.
1456 It will also raise unless use in proper context manager.
1457
1458 Parameters
1459 ----------
1460
1461 text:str
1462 Full text of the current input, multi line string.
1463 offset:int
1464 Integer representing the position of the cursor in ``text``. Offset
1465 is 0-based indexed.
1466
1467 Yields
1468 ------
1469 :any:`Completion` object
1470
1471
1472 The cursor on a text can either be seen as being "in between"
1473 characters or "On" a character depending on the interface visible to
1474 the user. For consistency the cursor being on "in between" characters X
1475 and Y is equivalent to the cursor being "on" character Y, that is to say
1476 the character the cursor is on is considered as being after the cursor.
1477
1478 Combining characters may span more that one position in the
1479 text.
1480
1481
1482 .. note::
1483
1484 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
1485 fake Completion token to distinguish completion returned by Jedi
1486 and usual IPython completion.
1487
1488 """
1489 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
1490 "It may change without warnings. "
1491 "Use in corresponding context manager.",
1492 category=ProvisionalCompleterWarning, stacklevel=2)
1493
1494 # Possible Improvements / Known limitation
1495 ##########################################
1496 # Completions may be identical even if they have different ranges and
1497 # text. For example:
1498 # >>> a=1
1499 # >>> a.<tab>
1500 # May returns:
1501 # - `a.real` from 0 to 2
1502 # - `.real` from 1 to 2
1503 # the current code does not (yet) check for such equivalence
1504 seen = set()
1505 for c in self._completions(text, offset):
1506 if c and (c in seen):
1507 continue
1508 yield c
1509 seen.add(c)
1510
1511 def _completions(self, full_text: str, offset: int)->Iterator[Completion]:
1512 before = full_text[:offset]
1513 cursor_line, cursor_column = position_to_cursor(full_text, offset)
1514
1515 matched_text, matches, matches_origin, jedi_matches = self._complete(
1516 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column)
1517
1518 for jm in jedi_matches:
1519 delta = len(jm.name_with_symbols) - len(jm.complete)
1520 yield Completion(start=offset - delta, end=offset, text=jm.name_with_symbols, type=jm.type, _origin='jedi')
1521
1522
1523 start_offset = before.rfind(matched_text)
1524
1525 # TODO:
1526 # Supress this, right now just for debug.
1527 if jedi_matches and matches and self.debug:
1528 yield Completion(start=start_offset, end=offset, text='--jedi/ipython--', _origin='debug')
1529
1530 # I'm unsure if this is always true, so let's assert and see if it
1531 # crash
1532 assert before.endswith(matched_text)
1533 for m, t in zip(matches, matches_origin):
1534 yield Completion(start=start_offset, end=offset, text=m, _origin=t)
1535
1536
1097 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1537 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1098 """Find completions for the given text and line context.
1538 """Find completions for the given text and line context.
1099
1539
@@ -1123,7 +1563,38 b' class IPCompleter(Completer):'
1123
1563
1124 matches : list
1564 matches : list
1125 A list of completion matches.
1565 A list of completion matches.
1566
1567
1568 .. note::
1569
1570 This API is likely to be deprecated and replaced by
1571 :any:`IPCompleter.completions` in the future.
1572
1573
1574 """
1575 warnings.warn('`Completer.complete` is pending deprecation since '
1576 'IPython 6.0 and will be replaced by `Completer.completions`.',
1577 PendingDeprecationWarning)
1578 # potential todo, FOLD the 3rd throw away argument of _complete
1579 # into the first 2 one.
1580 return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2]
1581
1582 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
1583 full_text=None, return_jedi_results=True) -> (str, List[str], List[object]):
1584 """
1585
1586 Like complete but can also returns raw jedi completions as well as the
1587 origin of the completion text. This could (and should) be made much
1588 cleaner but that will be simpler once we drop the old (and stateful)
1589 :any:`complete` API.
1590
1591
1592 With current provisional API, cursor_pos act both (depending on the
1593 caller) as the offset in the ``text`` or ``line_buffer``, or as the
1594 ``column`` when passing multiline strings this could/should be renamed
1595 but would add extra noise.
1126 """
1596 """
1597
1127 # if the cursor position isn't given, the only sane assumption we can
1598 # if the cursor position isn't given, the only sane assumption we can
1128 # make is that it's at the end of the line (the common case)
1599 # make is that it's at the end of the line (the common case)
1129 if cursor_pos is None:
1600 if cursor_pos is None:
@@ -1132,20 +1603,23 b' class IPCompleter(Completer):'
1132 if self.use_main_ns:
1603 if self.use_main_ns:
1133 self.namespace = __main__.__dict__
1604 self.namespace = __main__.__dict__
1134
1605
1606 # if text is either None or an empty string, rely on the line buffer
1607 if (not line_buffer) and full_text:
1608 line_buffer = full_text.split('\n')[cursor_line]
1609 if not text:
1610 text = self.splitter.split_line(line_buffer, cursor_pos)
1611
1135 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1612 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1136 latex_text, latex_matches = self.latex_matches(base_text)
1613 latex_text, latex_matches = self.latex_matches(base_text)
1137 if latex_matches:
1614 if latex_matches:
1138 return latex_text, latex_matches
1615 return latex_text, latex_matches, ['latex_matches']*len(latex_matches), ()
1139 name_text = ''
1616 name_text = ''
1140 name_matches = []
1617 name_matches = []
1141 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1618 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1142 name_text, name_matches = meth(base_text)
1619 name_text, name_matches = meth(base_text)
1143 if name_text:
1620 if name_text:
1144 return name_text, name_matches
1621 return name_text, name_matches, [meth.__qualname__]*len(name_matches), {}
1145
1622
1146 # if text is either None or an empty string, rely on the line buffer
1147 if not text:
1148 text = self.splitter.split_line(line_buffer, cursor_pos)
1149
1623
1150 # If no line buffer is given, assume the input text is all there was
1624 # If no line buffer is given, assume the input text is all there was
1151 if line_buffer is None:
1625 if line_buffer is None:
@@ -1155,33 +1629,55 b' class IPCompleter(Completer):'
1155 self.text_until_cursor = self.line_buffer[:cursor_pos]
1629 self.text_until_cursor = self.line_buffer[:cursor_pos]
1156
1630
1157 # Start with a clean slate of completions
1631 # Start with a clean slate of completions
1158 self.matches[:] = []
1632 matches = []
1159 custom_res = self.dispatch_custom_completer(text)
1633 custom_res = self.dispatch_custom_completer(text)
1634 # FIXME: we should extend our api to return a dict with completions for
1635 # different types of objects. The rlcomplete() method could then
1636 # simply collapse the dict into a list for readline, but we'd have
1637 # richer completion semantics in other evironments.
1638 completions = ()
1639 if self.use_jedi and return_jedi_results:
1640 if not full_text:
1641 full_text = line_buffer
1642 completions = self._jedi_matches(
1643 cursor_pos, cursor_line, full_text)
1160 if custom_res is not None:
1644 if custom_res is not None:
1161 # did custom completers produce something?
1645 # did custom completers produce something?
1162 self.matches = custom_res
1646 matches = [(m, 'custom') for m in custom_res]
1163 else:
1647 else:
1164 # Extend the list of completions with the results of each
1648 # Extend the list of completions with the results of each
1165 # matcher, so we return results to the user from all
1649 # matcher, so we return results to the user from all
1166 # namespaces.
1650 # namespaces.
1167 if self.merge_completions:
1651 if self.merge_completions:
1168 self.matches = []
1652 matches = []
1169 for matcher in self.matchers:
1653 for matcher in self.matchers:
1170 try:
1654 try:
1171 self.matches.extend(matcher(text))
1655 matches.extend([(m, matcher.__qualname__)
1656 for m in matcher(text)])
1172 except:
1657 except:
1173 # Show the ugly traceback if the matcher causes an
1658 # Show the ugly traceback if the matcher causes an
1174 # exception, but do NOT crash the kernel!
1659 # exception, but do NOT crash the kernel!
1175 sys.excepthook(*sys.exc_info())
1660 sys.excepthook(*sys.exc_info())
1176 else:
1661 else:
1177 for matcher in self.matchers:
1662 for matcher in self.matchers:
1178 self.matches = matcher(text)
1663 matches = [(m, matcher.__qualname__)
1179 if self.matches:
1664 for m in matcher(text)]
1665 if matches:
1180 break
1666 break
1181 # FIXME: we should extend our api to return a dict with completions for
1667 seen = set()
1182 # different types of objects. The rlcomplete() method could then
1668 filtered_matches = set()
1183 # simply collapse the dict into a list for readline, but we'd have
1669 for m in matches:
1184 # richer completion semantics in other evironments.
1670 t, c = m
1185 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1671 if t not in seen:
1672 filtered_matches.add(m)
1673 seen.add(t)
1674
1675 filtered_matches = sorted(
1676 set(filtered_matches), key=lambda x: completions_sorting_key(x[0]))
1677
1678 matches = [m[0] for m in filtered_matches]
1679 origins = [m[1] for m in filtered_matches]
1680
1681 self.matches = matches
1186
1682
1187 return text, self.matches
1683 return text, matches, origins, completions
@@ -11,7 +11,6 b''
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13
13
14 import __future__
15 import abc
14 import abc
16 import ast
15 import ast
17 import atexit
16 import atexit
@@ -20,6 +20,9 b' from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory'
20 from IPython.utils.generics import complete_object
20 from IPython.utils.generics import complete_object
21 from IPython.testing import decorators as dec
21 from IPython.testing import decorators as dec
22
22
23 from IPython.core.completer import Completion, provisionalcompleter
24 from nose.tools import assert_in, assert_not_in
25
23 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
24 # Test functions
27 # Test functions
25 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
@@ -269,23 +272,62 b' def test_local_file_completions():'
269 nt.assert_true(comp.issubset(set(c)))
272 nt.assert_true(comp.issubset(set(c)))
270
273
271
274
275 def test_jedi():
276 """
277 A couple of issue we had with Jedi
278 """
279 ip = get_ipython()
280
281 def _test_complete(reason, s, comp, start=None, end=None):
282 l = len(s)
283 start = start if start is not None else l
284 end = end if end is not None else l
285 with provisionalcompleter():
286 completions = set(ip.Completer.completions(s, l))
287 assert_in(Completion(start, end, comp), completions, reason)
288
289 def _test_not_complete(reason, s, comp):
290 l = len(s)
291 with provisionalcompleter():
292 completions = set(ip.Completer.completions(s, l))
293 assert_not_in(Completion(l, l, comp), completions, reason)
294
295 yield _test_complete, 'jedi >0.9 should complete and not crash', 'a=1;a.', 'real'
296 yield _test_complete, 'can infer first argument', 'a=(1,"foo");a[0].', 'real'
297 yield _test_complete, 'can infer second argument', 'a=(1,"foo");a[1].', 'capitalize'
298 yield _test_complete, 'cover duplicate completions', 'im', 'import', 0, 2
299
300 yield _test_not_complete, 'does not mix types', 'a=(1,"foo");a[0].', 'capitalize'
301
302
272 def test_greedy_completions():
303 def test_greedy_completions():
304 """
305 Test the capability of the Greedy completer.
306
307 Most of the test here do not really show off the greedy completer, for proof
308 each of the text bellow now pass with Jedi. The greedy completer is capable of more.
309
310 See the :any:`test_dict_key_completion_contexts`
311
312 """
273 ip = get_ipython()
313 ip = get_ipython()
274 ip.ex('a=list(range(5))')
314 ip.ex('a=list(range(5))')
275 _,c = ip.complete('.',line='a[0].')
315 _,c = ip.complete('.',line='a[0].')
276 nt.assert_false('.real' in c,
316 nt.assert_false('.real' in c,
277 "Shouldn't have completed on a[0]: %s"%c)
317 "Shouldn't have completed on a[0]: %s"%c)
278 with greedy_completion():
318 with greedy_completion(), provisionalcompleter():
279 def _(line, cursor_pos, expect, message):
319 def _(line, cursor_pos, expect, message, completion):
280 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
320 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
321 with provisionalcompleter():
322 completions = ip.Completer.completions(line, cursor_pos)
281 nt.assert_in(expect, c, message%c)
323 nt.assert_in(expect, c, message%c)
324 nt.assert_in(completion, completions)
282
325
283 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s"
326 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s", Completion(5,5, 'real')
284 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s"
327 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s", Completion(5,6, 'real')
285
286 if sys.version_info > (3,4):
287 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s"
288
328
329 if sys.version_info > (3, 4):
330 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s", Completion(5, 10, 'from_bytes')
289
331
290
332
291 def test_omit__names():
333 def test_omit__names():
@@ -298,27 +340,58 b' def test_omit__names():'
298 cfg = Config()
340 cfg = Config()
299 cfg.IPCompleter.omit__names = 0
341 cfg.IPCompleter.omit__names = 0
300 c.update_config(cfg)
342 c.update_config(cfg)
301 s,matches = c.complete('ip.')
343 with provisionalcompleter():
302 nt.assert_in('ip.__str__', matches)
344 s,matches = c.complete('ip.')
303 nt.assert_in('ip._hidden_attr', matches)
345 completions = set(c.completions('ip.', 3))
346
347 nt.assert_in('ip.__str__', matches)
348 nt.assert_in(Completion(3, 3, '__str__'), completions)
349
350 nt.assert_in('ip._hidden_attr', matches)
351 nt.assert_in(Completion(3,3, "_hidden_attr"), completions)
352
353
304 cfg = Config()
354 cfg = Config()
305 cfg.IPCompleter.omit__names = 1
355 cfg.IPCompleter.omit__names = 1
306 c.update_config(cfg)
356 c.update_config(cfg)
307 s,matches = c.complete('ip.')
357 with provisionalcompleter():
308 nt.assert_not_in('ip.__str__', matches)
358 s,matches = c.complete('ip.')
309 nt.assert_in('ip._hidden_attr', matches)
359 completions = set(c.completions('ip.', 3))
360
361 nt.assert_not_in('ip.__str__', matches)
362 nt.assert_not_in(Completion(3,3,'__str__'), completions)
363
364 # nt.assert_in('ip._hidden_attr', matches)
365 nt.assert_in(Completion(3,3, "_hidden_attr"), completions)
366
310 cfg = Config()
367 cfg = Config()
311 cfg.IPCompleter.omit__names = 2
368 cfg.IPCompleter.omit__names = 2
312 c.update_config(cfg)
369 c.update_config(cfg)
313 s,matches = c.complete('ip.')
370 with provisionalcompleter():
314 nt.assert_not_in('ip.__str__', matches)
371 s,matches = c.complete('ip.')
315 nt.assert_not_in('ip._hidden_attr', matches)
372 completions = set(c.completions('ip.', 3))
316 s,matches = c.complete('ip._x.')
373
317 nt.assert_in('ip._x.keys', matches)
374 nt.assert_not_in('ip.__str__', matches)
375 nt.assert_not_in(Completion(3,3,'__str__'), completions)
376
377 nt.assert_not_in('ip._hidden_attr', matches)
378 nt.assert_not_in(Completion(3,3, "_hidden_attr"), completions)
379
380 with provisionalcompleter():
381 s,matches = c.complete('ip._x.')
382 completions = set(c.completions('ip._x.', 6))
383
384 nt.assert_in('ip._x.keys', matches)
385 nt.assert_in(Completion(6,6, "keys"), completions)
386
318 del ip._hidden_attr
387 del ip._hidden_attr
388 del ip._x
319
389
320
390
321 def test_limit_to__all__False_ok():
391 def test_limit_to__all__False_ok():
392 """
393 Limit to all is deprecated, once we remove it this test can go away.
394 """
322 ip = get_ipython()
395 ip = get_ipython()
323 c = ip.Completer
396 c = ip.Completer
324 ip.ex('class D: x=24')
397 ip.ex('class D: x=24')
@@ -10,13 +10,17 b' not to be used outside IPython.'
10 import unicodedata
10 import unicodedata
11 from wcwidth import wcwidth
11 from wcwidth import wcwidth
12
12
13 from IPython.core.completer import IPCompleter
13 from IPython.core.completer import IPCompleter, provisionalcompleter, rectify_completions, cursor_to_position
14 from prompt_toolkit.completion import Completer, Completion
14 from prompt_toolkit.completion import Completer, Completion
15 from prompt_toolkit.layout.lexers import Lexer
15 from prompt_toolkit.layout.lexers import Lexer
16 from prompt_toolkit.layout.lexers import PygmentsLexer
16 from prompt_toolkit.layout.lexers import PygmentsLexer
17
17
18 import pygments.lexers as pygments_lexers
18 import pygments.lexers as pygments_lexers
19
19
20 _completion_sentinel = object()
21
22
23
20
24
21 class IPythonPTCompleter(Completer):
25 class IPythonPTCompleter(Completer):
22 """Adaptor to provide IPython completions to prompt_toolkit"""
26 """Adaptor to provide IPython completions to prompt_toolkit"""
@@ -39,35 +43,44 b' class IPythonPTCompleter(Completer):'
39 def get_completions(self, document, complete_event):
43 def get_completions(self, document, complete_event):
40 if not document.current_line.strip():
44 if not document.current_line.strip():
41 return
45 return
42
43 # Some bits of our completion system may print stuff (e.g. if a module
46 # Some bits of our completion system may print stuff (e.g. if a module
44 # is imported). This context manager ensures that doesn't interfere with
47 # is imported). This context manager ensures that doesn't interfere with
45 # the prompt.
48 # the prompt.
46 with self.patch_stdout():
49
47 used, matches = self.ipy_completer.complete(
50 with self.patch_stdout_context(), provisionalcompleter():
48 line_buffer=document.current_line,
51 body = document.text
49 cursor_pos=document.cursor_position_col
52 cursor_row = document.cursor_position_row
50 )
53 cursor_col = document.cursor_position_col
51 start_pos = -len(used)
54 cursor_position = document.cursor_position
52 for m in matches:
55 offset = cursor_to_position(body, cursor_row, cursor_col)
53 if not m:
56 yield from self._get_completions(body, offset, cursor_position, self.ipy_completer)
57
58 @staticmethod
59 def _get_completions(body, offset, cursor_position, ipyc):
60 """
61 Private equivalent of get_completions() use only for unit_testing.
62 """
63 debug = getattr(ipyc, 'debug', False)
64 completions = rectify_completions(
65 body, ipyc.completions(body, offset), _debug=debug)
66 for c in completions:
67 if not c.text:
54 # Guard against completion machinery giving us an empty string.
68 # Guard against completion machinery giving us an empty string.
55 continue
69 continue
56
70 text = unicodedata.normalize('NFC', c.text)
57 m = unicodedata.normalize('NFC', m)
58
59 # When the first character of the completion has a zero length,
71 # When the first character of the completion has a zero length,
60 # then it's probably a decomposed unicode character. E.g. caused by
72 # then it's probably a decomposed unicode character. E.g. caused by
61 # the "\dot" completion. Try to compose again with the previous
73 # the "\dot" completion. Try to compose again with the previous
62 # character.
74 # character.
63 if wcwidth(m[0]) == 0:
75 if wcwidth(text[0]) == 0:
64 if document.cursor_position + start_pos > 0:
76 if cursor_position + c.start > 0:
65 char_before = document.text[document.cursor_position + start_pos - 1]
77 char_before = body[c.start - 1]
66 m = unicodedata.normalize('NFC', char_before + m)
78 fixed_text = unicodedata.normalize(
79 'NFC', char_before + text)
67
80
68 # Yield the modified completion instead, if this worked.
81 # Yield the modified completion instead, if this worked.
69 if wcwidth(m[0:1]) == 1:
82 if wcwidth(text[0:1]) == 1:
70 yield Completion(m, start_position=start_pos - 1)
83 yield Completion(fixed_text, start_position=c.start - offset - 1)
71 continue
84 continue
72
85
73 # TODO: Use Jedi to determine meta_text
86 # TODO: Use Jedi to determine meta_text
@@ -75,7 +88,7 b' class IPythonPTCompleter(Completer):'
75 # meta_text = ''
88 # meta_text = ''
76 # yield Completion(m, start_position=start_pos,
89 # yield Completion(m, start_position=start_pos,
77 # display_meta=meta_text)
90 # display_meta=meta_text)
78 yield Completion(m, start_position=start_pos)
91 yield Completion(c.text, start_position=c.start - offset, display_meta=c.type)
79
92
80 class IPythonPTLexer(Lexer):
93 class IPythonPTLexer(Lexer):
81 """
94 """
@@ -58,11 +58,24 b" warnings.filterwarnings('error', message='.*disable_gui.*', category=Deprecation"
58
58
59 warnings.filterwarnings('error', message='.*ExceptionColors global is deprecated.*', category=DeprecationWarning, module='.*')
59 warnings.filterwarnings('error', message='.*ExceptionColors global is deprecated.*', category=DeprecationWarning, module='.*')
60
60
61 # Jedi older versions
62 warnings.filterwarnings(
63 'error', message='.*elementwise != comparison failed and.*', category=FutureWarning, module='.*')
64
61 if version_info < (6,):
65 if version_info < (6,):
62 # nose.tools renames all things from `camelCase` to `snake_case` which raise an
66 # nose.tools renames all things from `camelCase` to `snake_case` which raise an
63 # warning with the runner they also import from standard import library. (as of Dec 2015)
67 # warning with the runner they also import from standard import library. (as of Dec 2015)
64 # Ignore, let's revisit that in a couple of years for IPython 6.
68 # Ignore, let's revisit that in a couple of years for IPython 6.
65 warnings.filterwarnings('ignore', message='.*Please use assertEqual instead', category=Warning, module='IPython.*')
69 warnings.filterwarnings(
70 'ignore', message='.*Please use assertEqual instead', category=Warning, module='IPython.*')
71
72 if version_info < (7,):
73 warnings.filterwarnings('ignore', message='.*Completer.complete.*',
74 category=PendingDeprecationWarning, module='.*')
75 else:
76 warnings.warn(
77 'Completer.complete was pending deprecation and should be changed to Deprecated', FutureWarning)
78
66
79
67
80
68 # ------------------------------------------------------------------------------
81 # ------------------------------------------------------------------------------
@@ -11,12 +11,9 b' test suite.'
11
11
12
12
13 import argparse
13 import argparse
14 import json
15 import multiprocessing.pool
14 import multiprocessing.pool
16 import os
15 import os
17 import stat
16 import stat
18 import re
19 import requests
20 import shutil
17 import shutil
21 import signal
18 import signal
22 import sys
19 import sys
@@ -25,13 +22,11 b' import time'
25
22
26 from .iptest import (
23 from .iptest import (
27 have, test_group_names as py_test_group_names, test_sections, StreamCapturer,
24 have, test_group_names as py_test_group_names, test_sections, StreamCapturer,
28 test_for,
29 )
25 )
30 from IPython.utils.path import compress_user
26 from IPython.utils.path import compress_user
31 from IPython.utils.py3compat import bytes_to_str
27 from IPython.utils.py3compat import bytes_to_str
32 from IPython.utils.sysinfo import get_sys_info
28 from IPython.utils.sysinfo import get_sys_info
33 from IPython.utils.tempdir import TemporaryDirectory
29 from IPython.utils.tempdir import TemporaryDirectory
34 from IPython.utils.text import strip_ansi
35
30
36 try:
31 try:
37 # Python >= 3.3
32 # Python >= 3.3
@@ -50,8 +45,6 b' except ImportError:'
50 if p.poll() is None:
45 if p.poll() is None:
51 raise TimeoutExpired
46 raise TimeoutExpired
52
47
53 NOTEBOOK_SHUTDOWN_TIMEOUT = 10
54
55 class TestController(object):
48 class TestController(object):
56 """Run tests in a subprocess
49 """Run tests in a subprocess
57 """
50 """
@@ -228,6 +228,8 b" intersphinx_mapping = {'python': ('https://docs.python.org/3/', None),"
228 'jupyterclient': ('https://jupyter-client.readthedocs.io/en/latest/', None),
228 'jupyterclient': ('https://jupyter-client.readthedocs.io/en/latest/', None),
229 'ipyparallel': ('https://ipyparallel.readthedocs.io/en/latest/', None),
229 'ipyparallel': ('https://ipyparallel.readthedocs.io/en/latest/', None),
230 'jupyter': ('https://jupyter.readthedocs.io/en/latest/', None),
230 'jupyter': ('https://jupyter.readthedocs.io/en/latest/', None),
231 'jedi': ('https://jedi.readthedocs.io/en/latest/', None),
232 'traitlets': ('https://traitlets.readthedocs.io/en/latest/', None),
231 }
233 }
232
234
233 # Options for LaTeX output
235 # Options for LaTeX output
@@ -104,6 +104,7 b' repository <http://github.com/ipython/ipython>`_.'
104
104
105
105
106 .. only:: html
106 .. only:: html
107
107 * :ref:`genindex`
108 * :ref:`genindex`
108 * :ref:`modindex`
109 * :ref:`modindex`
109 * :ref:`search`
110 * :ref:`search`
@@ -201,6 +201,8 b' extras_require = dict('
201
201
202 install_requires = [
202 install_requires = [
203 'setuptools>=18.5',
203 'setuptools>=18.5',
204 'jedi',
205 'typing',
204 'decorator',
206 'decorator',
205 'pickleshare',
207 'pickleshare',
206 'simplegeneric>0.8',
208 'simplegeneric>0.8',
General Comments 0
You need to be logged in to leave comments. Login now