33
33
import builtins
34
34
35
35
from enum import Enum
36
+ from typing import Any , Dict , Iterator , List , Match , NoReturn , Set , Union
36
37
from . import inspection
37
38
from . import line as lineparts
38
39
from .line import LinePart
@@ -48,7 +49,7 @@ class AutocompleteModes(Enum):
48
49
FUZZY = "fuzzy"
49
50
50
51
@classmethod
51
- def from_string (cls , value ):
52
+ def from_string (cls , value ) -> Union [ Any , None ] :
52
53
if value .upper () in cls .__members__ :
53
54
return cls .__members__ [value .upper ()]
54
55
return None
@@ -161,11 +162,11 @@ def from_string(cls, value):
161
162
KEYWORDS = frozenset (keyword .kwlist )
162
163
163
164
164
- def after_last_dot (name ) :
165
+ def after_last_dot (name : str ) -> str :
165
166
return name .rstrip ("." ).rsplit ("." )[- 1 ]
166
167
167
168
168
- def few_enough_underscores (current , match ):
169
+ def few_enough_underscores (current , match ) -> bool :
169
170
"""Returns whether match should be shown based on current
170
171
171
172
if current is _, True if match starts with 0 or 1 underscore
@@ -179,19 +180,19 @@ def few_enough_underscores(current, match):
179
180
return not match .startswith ("_" )
180
181
181
182
182
- def method_match_none (word , size , text ):
183
+ def method_match_none (word , size , text ) -> False :
183
184
return False
184
185
185
186
186
- def method_match_simple (word , size , text ):
187
+ def method_match_simple (word , size , text ) -> bool :
187
188
return word [:size ] == text
188
189
189
190
190
- def method_match_substring (word , size , text ):
191
+ def method_match_substring (word , size , text ) -> bool :
191
192
return text in word
192
193
193
194
194
- def method_match_fuzzy (word , size , text ):
195
+ def method_match_fuzzy (word , size , text ) -> Union [ Match , None ] :
195
196
s = r".*%s.*" % ".*" .join (list (text ))
196
197
return re .search (s , word )
197
198
@@ -207,11 +208,11 @@ def method_match_fuzzy(word, size, text):
207
208
class BaseCompletionType :
208
209
"""Describes different completion types"""
209
210
210
- def __init__ (self , shown_before_tab = True , mode = AutocompleteModes .SIMPLE ):
211
+ def __init__ (self , shown_before_tab : bool = True , mode = AutocompleteModes .SIMPLE ) -> None :
211
212
self ._shown_before_tab = shown_before_tab
212
213
self .method_match = MODES_MAP [mode ]
213
214
214
- def matches (self , cursor_offset , line , ** kwargs ):
215
+ def matches (self , cursor_offset , line , ** kwargs ) -> NoReturn :
215
216
"""Returns a list of possible matches given a line and cursor, or None
216
217
if this completion type isn't applicable.
217
218
@@ -229,7 +230,7 @@ def matches(self, cursor_offset, line, **kwargs):
229
230
"""
230
231
raise NotImplementedError
231
232
232
- def locate (self , cursor_offset , line ):
233
+ def locate (self , cursor_offset , line ) -> NoReturn :
233
234
"""Returns a Linepart namedtuple instance or None given cursor and line
234
235
235
236
A Linepart namedtuple contains a start, stop, and word. None is
@@ -240,15 +241,15 @@ def locate(self, cursor_offset, line):
240
241
def format (self , word ):
241
242
return word
242
243
243
- def substitute (self , cursor_offset , line , match ):
244
+ def substitute (self , cursor_offset , line , match ) -> NoReturn :
244
245
"""Returns a cursor offset and line with match swapped in"""
245
246
lpart = self .locate (cursor_offset , line )
246
247
offset = lpart .start + len (match )
247
248
changed_line = line [: lpart .start ] + match + line [lpart .stop :]
248
249
return offset , changed_line
249
250
250
251
@property
251
- def shown_before_tab (self ):
252
+ def shown_before_tab (self ) -> bool :
252
253
"""Whether suggestions should be shown before the user hits tab, or only
253
254
once that has happened."""
254
255
return self ._shown_before_tab
@@ -257,7 +258,7 @@ def shown_before_tab(self):
257
258
class CumulativeCompleter (BaseCompletionType ):
258
259
"""Returns combined matches from several completers"""
259
260
260
- def __init__ (self , completers , mode = AutocompleteModes .SIMPLE ):
261
+ def __init__ (self , completers , mode = AutocompleteModes .SIMPLE ) -> None :
261
262
if not completers :
262
263
raise ValueError (
263
264
"CumulativeCompleter requires at least one completer"
@@ -266,7 +267,7 @@ def __init__(self, completers, mode=AutocompleteModes.SIMPLE):
266
267
267
268
super ().__init__ (True , mode )
268
269
269
- def locate (self , current_offset , line ):
270
+ def locate (self , current_offset , line ) -> Union [ None , NoReturn ] :
270
271
for completer in self ._completers :
271
272
return_value = completer .locate (current_offset , line )
272
273
if return_value is not None :
@@ -275,7 +276,7 @@ def locate(self, current_offset, line):
275
276
def format (self , word ):
276
277
return self ._completers [0 ].format (word )
277
278
278
- def matches (self , cursor_offset , line , ** kwargs ):
279
+ def matches (self , cursor_offset , line , ** kwargs ) -> Union [ None , Set ] :
279
280
return_value = None
280
281
all_matches = set ()
281
282
for completer in self ._completers :
@@ -308,10 +309,10 @@ class FilenameCompletion(BaseCompletionType):
308
309
def __init__ (self , mode = AutocompleteModes .SIMPLE ):
309
310
super ().__init__ (False , mode )
310
311
311
- def safe_glob (self , pathname ):
312
+ def safe_glob (self , pathname ) -> Iterator :
312
313
return glob .iglob (glob .escape (pathname ) + "*" )
313
314
314
- def matches (self , cursor_offset , line , ** kwargs ):
315
+ def matches (self , cursor_offset , line , ** kwargs ) -> Union [ None , set ] :
315
316
cs = lineparts .current_string (cursor_offset , line )
316
317
if cs is None :
317
318
return None
@@ -341,7 +342,7 @@ class AttrCompletion(BaseCompletionType):
341
342
342
343
attr_matches_re = LazyReCompile (r"(\w+(\.\w+)*)\.(\w*)" )
343
344
344
- def matches (self , cursor_offset , line , ** kwargs ):
345
+ def matches (self , cursor_offset , line , ** kwargs ) -> Union [ None , Dict ] :
345
346
if "locals_" not in kwargs :
346
347
return None
347
348
locals_ = kwargs ["locals_" ]
@@ -377,7 +378,7 @@ def locate(self, current_offset, line):
377
378
def format (self , word ):
378
379
return after_last_dot (word )
379
380
380
- def attr_matches (self , text , namespace ):
381
+ def attr_matches (self , text , namespace ) -> List :
381
382
"""Taken from rlcompleter.py and bent to my will."""
382
383
383
384
m = self .attr_matches_re .match (text )
@@ -396,7 +397,7 @@ def attr_matches(self, text, namespace):
396
397
matches = self .attr_lookup (obj , expr , attr )
397
398
return matches
398
399
399
- def attr_lookup (self , obj , expr , attr ):
400
+ def attr_lookup (self , obj , expr , attr ) -> List :
400
401
"""Second half of attr_matches."""
401
402
words = self .list_attributes (obj )
402
403
if inspection .hasattr_safe (obj , "__class__" ):
@@ -416,15 +417,15 @@ def attr_lookup(self, obj, expr, attr):
416
417
matches .append (f"{ expr } .{ word } " )
417
418
return matches
418
419
419
- def list_attributes (self , obj ):
420
+ def list_attributes (self , obj ) -> List [ str ] :
420
421
# TODO: re-implement dir using getattr_static to avoid using
421
422
# AttrCleaner here?
422
423
with inspection .AttrCleaner (obj ):
423
424
return dir (obj )
424
425
425
426
426
427
class DictKeyCompletion (BaseCompletionType ):
427
- def matches (self , cursor_offset , line , ** kwargs ):
428
+ def matches (self , cursor_offset , line , ** kwargs ) -> Union [ None , Dict ] :
428
429
if "locals_" not in kwargs :
429
430
return None
430
431
locals_ = kwargs ["locals_" ]
@@ -445,15 +446,15 @@ def matches(self, cursor_offset, line, **kwargs):
445
446
else :
446
447
return None
447
448
448
- def locate (self , current_offset , line ):
449
+ def locate (self , current_offset , line ) -> Union [ LinePart , None ] :
449
450
return lineparts .current_dict_key (current_offset , line )
450
451
451
452
def format (self , match ):
452
453
return match [:- 1 ]
453
454
454
455
455
456
class MagicMethodCompletion (BaseCompletionType ):
456
- def matches (self , cursor_offset , line , ** kwargs ):
457
+ def matches (self , cursor_offset , line , ** kwargs ) -> Union [ None , Dict ] :
457
458
if "current_block" not in kwargs :
458
459
return None
459
460
current_block = kwargs ["current_block" ]
@@ -465,12 +466,12 @@ def matches(self, cursor_offset, line, **kwargs):
465
466
return None
466
467
return {name for name in MAGIC_METHODS if name .startswith (r .word )}
467
468
468
- def locate (self , current_offset , line ):
469
+ def locate (self , current_offset , line ) -> Union [ LinePart , None ] :
469
470
return lineparts .current_method_definition_name (current_offset , line )
470
471
471
472
472
473
class GlobalCompletion (BaseCompletionType ):
473
- def matches (self , cursor_offset , line , ** kwargs ):
474
+ def matches (self , cursor_offset , line , ** kwargs ) -> Union [ Set , None ] :
474
475
"""Compute matches when text is a simple name.
475
476
Return a list of all keywords, built-in functions and names currently
476
477
defined in self.namespace that match.
@@ -500,12 +501,12 @@ def matches(self, cursor_offset, line, **kwargs):
500
501
matches .add (_callable_postfix (val , word ))
501
502
return matches if matches else None
502
503
503
- def locate (self , current_offset , line ):
504
+ def locate (self , current_offset , line ) -> Union [ LinePart , None ] :
504
505
return lineparts .current_single_word (current_offset , line )
505
506
506
507
507
508
class ParameterNameCompletion (BaseCompletionType ):
508
- def matches (self , cursor_offset , line , ** kwargs ):
509
+ def matches (self , cursor_offset , line , ** kwargs ) -> Union [ None , Dict ] :
509
510
if "argspec" not in kwargs :
510
511
return None
511
512
argspec = kwargs ["argspec" ]
@@ -526,16 +527,16 @@ def matches(self, cursor_offset, line, **kwargs):
526
527
)
527
528
return matches if matches else None
528
529
529
- def locate (self , current_offset , line ):
530
+ def locate (self , current_offset , line ) -> Union [ LinePart , None ] :
530
531
return lineparts .current_word (current_offset , line )
531
532
532
533
533
534
class ExpressionAttributeCompletion (AttrCompletion ):
534
535
# could replace attr completion as a more general case with some work
535
- def locate (self , current_offset , line ):
536
+ def locate (self , current_offset , line ) -> Union [ LinePart , None ] :
536
537
return lineparts .current_expression_attribute (current_offset , line )
537
538
538
- def matches (self , cursor_offset , line , ** kwargs ):
539
+ def matches (self , cursor_offset , line , ** kwargs ) -> Union [ Set , Dict , None ] :
539
540
if "locals_" not in kwargs :
540
541
return None
541
542
locals_ = kwargs ["locals_" ]
@@ -560,14 +561,14 @@ def matches(self, cursor_offset, line, **kwargs):
560
561
except ImportError :
561
562
562
563
class MultilineJediCompletion (BaseCompletionType ):
563
- def matches (self , cursor_offset , line , ** kwargs ):
564
+ def matches (self , cursor_offset , line , ** kwargs ) -> None :
564
565
return None
565
566
566
567
567
568
else :
568
569
569
570
class JediCompletion (BaseCompletionType ):
570
- def matches (self , cursor_offset , line , ** kwargs ):
571
+ def matches (self , cursor_offset , line , ** kwargs ) -> Union [ None , Dict ] :
571
572
if "history" not in kwargs :
572
573
return None
573
574
history = kwargs ["history" ]
@@ -607,13 +608,13 @@ def matches(self, cursor_offset, line, **kwargs):
607
608
# case-sensitive matches only
608
609
return {m for m in matches if m .startswith (first_letter )}
609
610
610
- def locate (self , cursor_offset , line ):
611
+ def locate (self , cursor_offset , line ) -> LinePart :
611
612
start = self ._orig_start
612
613
end = cursor_offset
613
614
return LinePart (start , end , line [start :end ])
614
615
615
616
class MultilineJediCompletion (JediCompletion ):
616
- def matches (self , cursor_offset , line , ** kwargs ):
617
+ def matches (self , cursor_offset , line , ** kwargs ) -> Union [ Dict , None ] :
617
618
if "current_block" not in kwargs or "history" not in kwargs :
618
619
return None
619
620
current_block = kwargs ["current_block" ]
0 commit comments