28
28
import __main__
29
29
import abc
30
30
import glob
31
+ import itertools
31
32
import keyword
32
33
import logging
33
34
import os
@@ -383,11 +384,15 @@ class AttrCompletion(BaseCompletionType):
383
384
attr_matches_re = LazyReCompile (r"(\w+(\.\w+)*)\.(\w*)" )
384
385
385
386
def matches (
386
- self , cursor_offset : int , line : str , ** kwargs : Any
387
+ self ,
388
+ cursor_offset : int ,
389
+ line : str ,
390
+ * ,
391
+ locals_ : Optional [Dict [str , Any ]] = None ,
392
+ ** kwargs : Any ,
387
393
) -> Optional [Set ]:
388
- if " locals_" not in kwargs :
394
+ if locals_ is None :
389
395
return None
390
- locals_ = cast (Dict [str , Any ], kwargs ["locals_" ])
391
396
392
397
r = self .locate (cursor_offset , line )
393
398
if r is None :
@@ -465,11 +470,15 @@ def list_attributes(self, obj: Any) -> List[str]:
465
470
466
471
class DictKeyCompletion (BaseCompletionType ):
467
472
def matches (
468
- self , cursor_offset : int , line : str , ** kwargs : Any
473
+ self ,
474
+ cursor_offset : int ,
475
+ line : str ,
476
+ * ,
477
+ locals_ : Optional [Dict [str , Any ]] = None ,
478
+ ** kwargs : Any ,
469
479
) -> Optional [Set ]:
470
- if " locals_" not in kwargs :
480
+ if locals_ is None :
471
481
return None
472
- locals_ = kwargs ["locals_" ]
473
482
474
483
r = self .locate (cursor_offset , line )
475
484
if r is None :
@@ -500,11 +509,16 @@ def format(self, match: str) -> str:
500
509
501
510
class MagicMethodCompletion (BaseCompletionType ):
502
511
def matches (
503
- self , cursor_offset : int , line : str , ** kwargs : Any
512
+ self ,
513
+ cursor_offset : int ,
514
+ line : str ,
515
+ * ,
516
+ current_block : Optional [str ] = None ,
517
+ complete_magic_methods : Optional [bool ] = None ,
518
+ ** kwargs : Any ,
504
519
) -> Optional [Set ]:
505
- if " current_block" not in kwargs :
520
+ if current_block is None or complete_magic_methods is None or not complete_magic_methods :
506
521
return None
507
- current_block = kwargs ["current_block" ]
508
522
509
523
r = self .locate (cursor_offset , line )
510
524
if r is None :
@@ -519,15 +533,19 @@ def locate(self, cursor_offset: int, line: str) -> Optional[LinePart]:
519
533
520
534
class GlobalCompletion (BaseCompletionType ):
521
535
def matches (
522
- self , cursor_offset : int , line : str , ** kwargs : Any
536
+ self ,
537
+ cursor_offset : int ,
538
+ line : str ,
539
+ * ,
540
+ locals_ : Optional [Dict [str , Any ]] = None ,
541
+ ** kwargs : Any ,
523
542
) -> Optional [Set ]:
524
543
"""Compute matches when text is a simple name.
525
544
Return a list of all keywords, built-in functions and names currently
526
545
defined in self.namespace that match.
527
546
"""
528
- if " locals_" not in kwargs :
547
+ if locals_ is None :
529
548
return None
530
- locals_ = kwargs ["locals_" ]
531
549
532
550
r = self .locate (cursor_offset , line )
533
551
if r is None :
@@ -556,25 +574,29 @@ def locate(self, cursor_offset: int, line: str) -> Optional[LinePart]:
556
574
557
575
class ParameterNameCompletion (BaseCompletionType ):
558
576
def matches (
559
- self , cursor_offset : int , line : str , ** kwargs : Any
577
+ self ,
578
+ cursor_offset : int ,
579
+ line : str ,
580
+ * ,
581
+ funcprops : Optional [inspection .FuncProps ] = None ,
582
+ ** kwargs : Any ,
560
583
) -> Optional [Set ]:
561
- if "argspec" not in kwargs :
584
+ if funcprops is None :
562
585
return None
563
- argspec = kwargs ["argspec" ]
564
586
565
- if not argspec :
566
- return None
567
587
r = self .locate (cursor_offset , line )
568
588
if r is None :
569
589
return None
570
590
571
591
matches = {
572
592
f"{ name } ="
573
- for name in argspec .argspec .args
593
+ for name in funcprops .argspec .args
574
594
if isinstance (name , str ) and name .startswith (r .word )
575
595
}
576
596
matches .update (
577
- name + "=" for name in argspec .argspec .kwonly if name .startswith (r .word )
597
+ name + "="
598
+ for name in funcprops .argspec .kwonly
599
+ if name .startswith (r .word )
578
600
)
579
601
return matches if matches else None
580
602
@@ -588,12 +610,13 @@ def locate(self, cursor_offset: int, line: str) -> Optional[LinePart]:
588
610
return lineparts .current_expression_attribute (cursor_offset , line )
589
611
590
612
def matches (
591
- self , cursor_offset : int , line : str , ** kwargs : Any
613
+ self ,
614
+ cursor_offset : int ,
615
+ line : str ,
616
+ * ,
617
+ locals_ : Optional [Dict [str , Any ]] = None ,
618
+ ** kwargs : Any ,
592
619
) -> Optional [Set ]:
593
- if "locals_" not in kwargs :
594
- return None
595
- locals_ = kwargs ["locals_" ]
596
-
597
620
if locals_ is None :
598
621
locals_ = __main__ .__dict__
599
622
@@ -629,20 +652,23 @@ class JediCompletion(BaseCompletionType):
629
652
_orig_start : Optional [int ]
630
653
631
654
def matches (
632
- self , cursor_offset : int , line : str , ** kwargs : Any
655
+ self ,
656
+ cursor_offset : int ,
657
+ line : str ,
658
+ * ,
659
+ history : Optional [List [str ]] = None ,
660
+ ** kwargs : Any ,
633
661
) -> Optional [Set ]:
634
- if " history" not in kwargs :
662
+ if history is None :
635
663
return None
636
- history = kwargs ["history" ]
637
-
638
664
if not lineparts .current_word (cursor_offset , line ):
639
665
return None
640
- history = "\n " .join (history ) + "\n " + line
641
666
667
+ combined_history = "\n " .join (itertools .chain (history , (line ,)))
642
668
try :
643
- script = jedi .Script (history , path = "fake.py" )
669
+ script = jedi .Script (combined_history , path = "fake.py" )
644
670
completions = script .complete (
645
- len (history .splitlines ()), cursor_offset
671
+ len (combined_history .splitlines ()), cursor_offset
646
672
)
647
673
except (jedi .NotFoundError , IndexError , KeyError ):
648
674
# IndexError for #483
@@ -679,12 +705,16 @@ def locate(self, cursor_offset: int, line: str) -> LinePart:
679
705
680
706
class MultilineJediCompletion (JediCompletion ): # type: ignore [no-redef]
681
707
def matches (
682
- self , cursor_offset : int , line : str , ** kwargs : Any
708
+ self ,
709
+ cursor_offset : int ,
710
+ line : str ,
711
+ * ,
712
+ current_block : Optional [str ] = None ,
713
+ history : Optional [List [str ]] = None ,
714
+ ** kwargs : Any ,
683
715
) -> Optional [Set ]:
684
- if " current_block" not in kwargs or " history" not in kwargs :
716
+ if current_block is None or history is None :
685
717
return None
686
- current_block = kwargs ["current_block" ]
687
- history = kwargs ["history" ]
688
718
689
719
if "\n " in current_block :
690
720
assert cursor_offset <= len (line ), "{!r} {!r}" .format (
@@ -701,7 +731,12 @@ def get_completer(
701
731
completers : Sequence [BaseCompletionType ],
702
732
cursor_offset : int ,
703
733
line : str ,
704
- ** kwargs : Any ,
734
+ * ,
735
+ locals_ : Optional [Dict [str , Any ]] = None ,
736
+ argspec : Optional [inspection .FuncProps ] = None ,
737
+ history : Optional [List [str ]] = None ,
738
+ current_block : Optional [str ] = None ,
739
+ complete_magic_methods : Optional [bool ] = None ,
705
740
) -> Tuple [List [str ], Optional [BaseCompletionType ]]:
706
741
"""Returns a list of matches and an applicable completer
707
742
@@ -711,7 +746,7 @@ def get_completer(
711
746
line is a string of the current line
712
747
kwargs (all optional):
713
748
locals_ is a dictionary of the environment
714
- argspec is an inspect .FuncProps instance for the current function where
749
+ argspec is an inspection .FuncProps instance for the current function where
715
750
the cursor is
716
751
current_block is the possibly multiline not-yet-evaluated block of
717
752
code which the current line is part of
@@ -721,7 +756,15 @@ def get_completer(
721
756
722
757
for completer in completers :
723
758
try :
724
- matches = completer .matches (cursor_offset , line , ** kwargs )
759
+ matches = completer .matches (
760
+ cursor_offset ,
761
+ line ,
762
+ locals_ = locals_ ,
763
+ funcprops = argspec ,
764
+ history = history ,
765
+ current_block = current_block ,
766
+ complete_magic_methods = complete_magic_methods ,
767
+ )
725
768
except Exception as e :
726
769
# Instead of crashing the UI, log exceptions from autocompleters.
727
770
logger = logging .getLogger (__name__ )
0 commit comments