2121# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2222# THE SOFTWARE.
2323
24+ # To gradually migrate to mypy we aren't setting these globally yet
25+ # mypy: disallow_untyped_defs=True
2426
2527import __main__
2628import abc
3537from enum import Enum
3638from typing import (
3739 Any ,
40+ cast ,
3841 Dict ,
3942 Iterator ,
4043 List ,
4144 Match ,
45+ Optional ,
4246 Set ,
4347 Union ,
4448 Tuple ,
5054from .line import LinePart
5155from .lazyre import LazyReCompile
5256from .simpleeval import safe_eval , evaluate_current_expression , EvaluationError
57+ from .importcompletion import ModuleGatherer
5358
5459
5560# Autocomplete modes
@@ -60,7 +65,7 @@ class AutocompleteModes(Enum):
6065 FUZZY = "fuzzy"
6166
6267 @classmethod
63- def from_string (cls , value ) -> Union [Any , None ]:
68+ def from_string (cls , value : str ) -> Union [Any , None ]:
6469 if value .upper () in cls .__members__ :
6570 return cls .__members__ [value .upper ()]
6671 return None
@@ -177,7 +182,7 @@ def after_last_dot(name: str) -> str:
177182 return name .rstrip ("." ).rsplit ("." )[- 1 ]
178183
179184
180- def few_enough_underscores (current , match ) -> bool :
185+ def few_enough_underscores (current : str , match : str ) -> bool :
181186 """Returns whether match should be shown based on current
182187
183188 if current is _, True if match starts with 0 or 1 underscore
@@ -203,7 +208,7 @@ def method_match_substring(word: str, size: int, text: str) -> bool:
203208 return text in word
204209
205210
206- def method_match_fuzzy (word , size , text ) -> Union [Match , None ]:
211+ def method_match_fuzzy (word : str , size : int , text : str ) -> Union [Match , None ]:
207212 s = r".*%s.*" % ".*" .join (list (text ))
208213 return re .search (s , word )
209214
@@ -220,14 +225,16 @@ class BaseCompletionType:
220225 """Describes different completion types"""
221226
222227 def __init__ (
223- self , shown_before_tab : bool = True , mode = AutocompleteModes .SIMPLE
228+ self ,
229+ shown_before_tab : bool = True ,
230+ mode : AutocompleteModes = AutocompleteModes .SIMPLE ,
224231 ) -> None :
225232 self ._shown_before_tab = shown_before_tab
226233 self .method_match = MODES_MAP [mode ]
227234
228235 @abc .abstractmethod
229236 def matches (
230- self , cursor_offset : int , line : str , ** kwargs
237+ self , cursor_offset : int , line : str , ** kwargs : Any
231238 ) -> Union [Set [str ], None ]:
232239 """Returns a list of possible matches given a line and cursor, or None
233240 if this completion type isn't applicable.
@@ -255,10 +262,12 @@ def locate(self, cursor_offset: int, line: str) -> Union[LinePart, None]:
255262 the cursor."""
256263 raise NotImplementedError
257264
258- def format (self , word ) :
265+ def format (self , word : str ) -> str :
259266 return word
260267
261- def substitute (self , cursor_offset , line , match ) -> Tuple [int , str ]:
268+ def substitute (
269+ self , cursor_offset : int , line : str , match : str
270+ ) -> Tuple [int , str ]:
262271 """Returns a cursor offset and line with match swapped in"""
263272 lpart = self .locate (cursor_offset , line )
264273 assert lpart
@@ -289,18 +298,18 @@ def __init__(
289298
290299 super ().__init__ (True , mode )
291300
292- def locate (self , current_offset , line ) :
301+ def locate (self , cursor_offset : int , line : str ) -> Union [ LinePart , None ] :
293302 for completer in self ._completers :
294- return_value = completer .locate (current_offset , line )
303+ return_value = completer .locate (cursor_offset , line )
295304 if return_value is not None :
296305 return return_value
297306 return None
298307
299- def format (self , word ) :
308+ def format (self , word : str ) -> str :
300309 return self ._completers [0 ].format (word )
301310
302311 def matches (
303- self , cursor_offset : int , line : str , ** kwargs
312+ self , cursor_offset : int , line : str , ** kwargs : Any
304313 ) -> Union [None , Set ]:
305314 return_value = None
306315 all_matches = set ()
@@ -316,28 +325,36 @@ def matches(
316325
317326
318327class ImportCompletion (BaseCompletionType ):
319- def __init__ (self , module_gatherer , mode = AutocompleteModes .SIMPLE ):
328+ def __init__ (
329+ self ,
330+ module_gatherer : ModuleGatherer ,
331+ mode : AutocompleteModes = AutocompleteModes .SIMPLE ,
332+ ):
320333 super ().__init__ (False , mode )
321334 self .module_gatherer = module_gatherer
322335
323- def matches (self , cursor_offset , line , ** kwargs ):
336+ def matches (
337+ self , cursor_offset : int , line : str , ** kwargs : Any
338+ ) -> Union [None , Set ]:
324339 return self .module_gatherer .complete (cursor_offset , line )
325340
326- def locate (self , current_offset , line ) :
327- return lineparts .current_word (current_offset , line )
341+ def locate (self , cursor_offset : int , line : str ) -> Union [ LinePart , None ] :
342+ return lineparts .current_word (cursor_offset , line )
328343
329- def format (self , word ) :
344+ def format (self , word : str ) -> str :
330345 return after_last_dot (word )
331346
332347
333348class FilenameCompletion (BaseCompletionType ):
334- def __init__ (self , mode = AutocompleteModes .SIMPLE ):
349+ def __init__ (self , mode : AutocompleteModes = AutocompleteModes .SIMPLE ):
335350 super ().__init__ (False , mode )
336351
337- def safe_glob (self , pathname ) -> Iterator :
352+ def safe_glob (self , pathname : str ) -> Iterator [ str ] :
338353 return glob .iglob (glob .escape (pathname ) + "*" )
339354
340- def matches (self , cursor_offset , line , ** kwargs ) -> Union [None , set ]:
355+ def matches (
356+ self , cursor_offset : int , line : str , ** kwargs : Any
357+ ) -> Union [None , Set ]:
341358 cs = lineparts .current_string (cursor_offset , line )
342359 if cs is None :
343360 return None
@@ -352,10 +369,10 @@ def matches(self, cursor_offset, line, **kwargs) -> Union[None, set]:
352369 matches .add (filename )
353370 return matches
354371
355- def locate (self , current_offset , line ) :
356- return lineparts .current_string (current_offset , line )
372+ def locate (self , cursor_offset : int , line : str ) -> Union [ LinePart , None ] :
373+ return lineparts .current_string (cursor_offset , line )
357374
358- def format (self , filename ) :
375+ def format (self , filename : str ) -> str :
359376 filename .rstrip (os .sep ).rsplit (os .sep )[- 1 ]
360377 if os .sep in filename [:- 1 ]:
361378 return filename [filename .rindex (os .sep , 0 , - 1 ) + 1 :]
@@ -367,10 +384,12 @@ class AttrCompletion(BaseCompletionType):
367384
368385 attr_matches_re = LazyReCompile (r"(\w+(\.\w+)*)\.(\w*)" )
369386
370- def matches (self , cursor_offset , line , ** kwargs ) -> Union [None , Set ]:
387+ def matches (
388+ self , cursor_offset : int , line : str , ** kwargs : Any
389+ ) -> Union [None , Set ]:
371390 if "locals_" not in kwargs :
372391 return None
373- locals_ = kwargs ["locals_" ]
392+ locals_ = cast ( Dict [ str , Any ], kwargs ["locals_" ])
374393
375394 r = self .locate (cursor_offset , line )
376395 if r is None :
@@ -397,13 +416,13 @@ def matches(self, cursor_offset, line, **kwargs) -> Union[None, Set]:
397416 if few_enough_underscores (r .word .split ("." )[- 1 ], m .split ("." )[- 1 ])
398417 }
399418
400- def locate (self , current_offset , line ) :
401- return lineparts .current_dotted_attribute (current_offset , line )
419+ def locate (self , cursor_offset : int , line : str ) -> Union [ LinePart , None ] :
420+ return lineparts .current_dotted_attribute (cursor_offset , line )
402421
403- def format (self , word ) :
422+ def format (self , word : str ) -> str :
404423 return after_last_dot (word )
405424
406- def attr_matches (self , text , namespace ) -> List :
425+ def attr_matches (self , text : str , namespace : Dict [ str , Any ] ) -> List :
407426 """Taken from rlcompleter.py and bent to my will."""
408427
409428 m = self .attr_matches_re .match (text )
@@ -422,7 +441,7 @@ def attr_matches(self, text, namespace) -> List:
422441 matches = self .attr_lookup (obj , expr , attr )
423442 return matches
424443
425- def attr_lookup (self , obj , expr , attr ) -> List :
444+ def attr_lookup (self , obj : Any , expr : str , attr : str ) -> List :
426445 """Second half of attr_matches."""
427446 words = self .list_attributes (obj )
428447 if inspection .hasattr_safe (obj , "__class__" ):
@@ -442,15 +461,17 @@ def attr_lookup(self, obj, expr, attr) -> List:
442461 matches .append (f"{ expr } .{ word } " )
443462 return matches
444463
445- def list_attributes (self , obj ) -> List [str ]:
464+ def list_attributes (self , obj : Any ) -> List [str ]:
446465 # TODO: re-implement dir using getattr_static to avoid using
447466 # AttrCleaner here?
448467 with inspection .AttrCleaner (obj ):
449468 return dir (obj )
450469
451470
452471class DictKeyCompletion (BaseCompletionType ):
453- def matches (self , cursor_offset , line , ** kwargs ) -> Union [None , Set ]:
472+ def matches (
473+ self , cursor_offset : int , line : str , ** kwargs : Any
474+ ) -> Union [None , Set ]:
454475 if "locals_" not in kwargs :
455476 return None
456477 locals_ = kwargs ["locals_" ]
@@ -473,15 +494,17 @@ def matches(self, cursor_offset, line, **kwargs) -> Union[None, Set]:
473494 else :
474495 return None
475496
476- def locate (self , current_offset , line ) -> Union [LinePart , None ]:
477- return lineparts .current_dict_key (current_offset , line )
497+ def locate (self , cursor_offset : int , line : str ) -> Union [LinePart , None ]:
498+ return lineparts .current_dict_key (cursor_offset , line )
478499
479- def format (self , match ) :
500+ def format (self , match : str ) -> str :
480501 return match [:- 1 ]
481502
482503
483504class MagicMethodCompletion (BaseCompletionType ):
484- def matches (self , cursor_offset , line , ** kwargs ) -> Union [None , Set ]:
505+ def matches (
506+ self , cursor_offset : int , line : str , ** kwargs : Any
507+ ) -> Union [None , Set ]:
485508 if "current_block" not in kwargs :
486509 return None
487510 current_block = kwargs ["current_block" ]
@@ -493,12 +516,14 @@ def matches(self, cursor_offset, line, **kwargs) -> Union[None, Set]:
493516 return None
494517 return {name for name in MAGIC_METHODS if name .startswith (r .word )}
495518
496- def locate (self , current_offset , line ) -> Union [LinePart , None ]:
497- return lineparts .current_method_definition_name (current_offset , line )
519+ def locate (self , cursor_offset : int , line : str ) -> Union [LinePart , None ]:
520+ return lineparts .current_method_definition_name (cursor_offset , line )
498521
499522
500523class GlobalCompletion (BaseCompletionType ):
501- def matches (self , cursor_offset , line , ** kwargs ) -> Union [Set , None ]:
524+ def matches (
525+ self , cursor_offset : int , line : str , ** kwargs : Any
526+ ) -> Union [None , Set ]:
502527 """Compute matches when text is a simple name.
503528 Return a list of all keywords, built-in functions and names currently
504529 defined in self.namespace that match.
@@ -528,12 +553,14 @@ def matches(self, cursor_offset, line, **kwargs) -> Union[Set, None]:
528553 matches .add (_callable_postfix (val , word ))
529554 return matches if matches else None
530555
531- def locate (self , current_offset , line ) -> Union [LinePart , None ]:
532- return lineparts .current_single_word (current_offset , line )
556+ def locate (self , cursor_offset : int , line : str ) -> Union [LinePart , None ]:
557+ return lineparts .current_single_word (cursor_offset , line )
533558
534559
535560class ParameterNameCompletion (BaseCompletionType ):
536- def matches (self , cursor_offset , line , ** kwargs ) -> Union [None , Set ]:
561+ def matches (
562+ self , cursor_offset : int , line : str , ** kwargs : Any
563+ ) -> Union [None , Set ]:
537564 if "argspec" not in kwargs :
538565 return None
539566 argspec = kwargs ["argspec" ]
@@ -554,16 +581,18 @@ def matches(self, cursor_offset, line, **kwargs) -> Union[None, Set]:
554581 )
555582 return matches if matches else None
556583
557- def locate (self , current_offset , line ) -> Union [LinePart , None ]:
558- return lineparts .current_word (current_offset , line )
584+ def locate (self , cursor_offset : int , line : str ) -> Union [LinePart , None ]:
585+ return lineparts .current_word (cursor_offset , line )
559586
560587
561588class ExpressionAttributeCompletion (AttrCompletion ):
562589 # could replace attr completion as a more general case with some work
563- def locate (self , current_offset , line ) -> Union [LinePart , None ]:
564- return lineparts .current_expression_attribute (current_offset , line )
590+ def locate (self , cursor_offset : int , line : str ) -> Union [LinePart , None ]:
591+ return lineparts .current_expression_attribute (cursor_offset , line )
565592
566- def matches (self , cursor_offset , line , ** kwargs ) -> Union [Set , None ]:
593+ def matches (
594+ self , cursor_offset : int , line : str , ** kwargs : Any
595+ ) -> Union [None , Set ]:
567596 if "locals_" not in kwargs :
568597 return None
569598 locals_ = kwargs ["locals_" ]
@@ -589,7 +618,14 @@ def matches(self, cursor_offset, line, **kwargs) -> Union[Set, None]:
589618except ImportError :
590619
591620 class MultilineJediCompletion (BaseCompletionType ): # type: ignore [no-redef]
592- def matches (self , cursor_offset , line , ** kwargs ) -> None :
621+ def matches (
622+ self , cursor_offset : int , line : str , ** kwargs : Any
623+ ) -> Union [None , Set ]:
624+ return None
625+
626+ def locate (
627+ self , cursor_offset : int , line : str
628+ ) -> Union [LinePart , None ]:
593629 return None
594630
595631
@@ -598,7 +634,9 @@ def matches(self, cursor_offset, line, **kwargs) -> None:
598634 class JediCompletion (BaseCompletionType ):
599635 _orig_start : Union [int , None ]
600636
601- def matches (self , cursor_offset , line , ** kwargs ) -> Union [None , Set ]:
637+ def matches (
638+ self , cursor_offset : int , line : str , ** kwargs : Any
639+ ) -> Union [None , Set ]:
602640 if "history" not in kwargs :
603641 return None
604642 history = kwargs ["history" ]
@@ -646,7 +684,9 @@ def locate(self, cursor_offset: int, line: str) -> LinePart:
646684 return LinePart (start , end , line [start :end ])
647685
648686 class MultilineJediCompletion (JediCompletion ): # type: ignore [no-redef]
649- def matches (self , cursor_offset , line , ** kwargs ) -> Union [Set , None ]:
687+ def matches (
688+ self , cursor_offset : int , line : str , ** kwargs : Any
689+ ) -> Union [None , Set ]:
650690 if "current_block" not in kwargs or "history" not in kwargs :
651691 return None
652692 current_block = kwargs ["current_block" ]
@@ -663,7 +703,12 @@ def matches(self, cursor_offset, line, **kwargs) -> Union[Set, None]:
663703 return None
664704
665705
666- def get_completer (completers , cursor_offset , line , ** kwargs ):
706+ def get_completer (
707+ completers : Sequence [BaseCompletionType ],
708+ cursor_offset : int ,
709+ line : str ,
710+ ** kwargs : Any ,
711+ ) -> Tuple [List [str ], Optional [BaseCompletionType ]]:
667712 """Returns a list of matches and an applicable completer
668713
669714 If no matches available, returns a tuple of an empty list and None
@@ -698,7 +743,9 @@ def get_completer(completers, cursor_offset, line, **kwargs):
698743 return [], None
699744
700745
701- def get_default_completer (mode = AutocompleteModes .SIMPLE , module_gatherer = None ):
746+ def get_default_completer (
747+ mode : AutocompleteModes , module_gatherer : ModuleGatherer
748+ ) -> Tuple [BaseCompletionType , ...]:
702749 return (
703750 (
704751 DictKeyCompletion (mode = mode ),
@@ -721,7 +768,7 @@ def get_default_completer(mode=AutocompleteModes.SIMPLE, module_gatherer=None):
721768 )
722769
723770
724- def _callable_postfix (value , word ) :
771+ def _callable_postfix (value : Any , word : str ) -> str :
725772 """rlcompleter's _callable_postfix done right."""
726773 if callable (value ):
727774 word += "("
0 commit comments