@@ -71,7 +71,7 @@ def __init__(self, namespace: Mapping[str, Any] | None = None) -> None:
7171 self ._curr_sys_path : list [str ] = sys .path [:]
7272 self ._stdlib_path = os .path .dirname (importlib .__path__ [0 ])
7373
74- def get_completions (self , line : str ) -> tuple [list [str ], CompletionAction | None ] | None :
74+ def get_completions (self , line : str ) -> tuple [list [str ], list [ Any ], CompletionAction | None ] | None :
7575 """Return the next possible import completions for 'line'.
7676
7777 For attributes completion, if the module to complete from is not
@@ -86,26 +86,32 @@ def get_completions(self, line: str) -> tuple[list[str], CompletionAction | None
8686 except Exception :
8787 # Some unexpected error occurred, make it look like
8888 # no completions are available
89- return [], None
89+ return [], [], None
9090
91- def complete (self , from_name : str | None , name : str | None ) -> tuple [list [str ], CompletionAction | None ]:
91+ def complete (self , from_name : str | None , name : str | None ) -> tuple [list [str ], list [ Any ], CompletionAction | None ]:
9292 if from_name is None :
9393 # import x.y.z<tab>
9494 assert name is not None
9595 path , prefix = self .get_path_and_prefix (name )
9696 modules = self .find_modules (path , prefix )
97- return [self .format_completion (path , module ) for module in modules ], None
97+ names = [self .format_completion (path , module ) for module in modules ]
98+ return names , [None ] * len (names ), None
9899
99100 if name is None :
100101 # from x.y.z<tab>
101102 path , prefix = self .get_path_and_prefix (from_name )
102103 modules = self .find_modules (path , prefix )
103- return [self .format_completion (path , module ) for module in modules ], None
104+ names = [self .format_completion (path , module ) for module in modules ]
105+ return names , [None ] * len (names ), None
104106
105107 # from x.y import z<tab>
106108 submodules = self .find_modules (from_name , name )
107- attributes , action = self .find_attributes (from_name , name )
108- return sorted ({* submodules , * attributes }), action
109+ attr_names , attr_values , action = self .find_attributes (from_name , name )
110+ all_names = sorted ({* submodules , * attr_names })
111+ # Build values list matching the sorted order
112+ attr_map = dict (zip (attr_names , attr_values ))
113+ all_values = [attr_map .get (n ) for n in all_names ]
114+ return all_names , all_values , action
109115
110116 def find_modules (self , path : str , prefix : str ) -> list [str ]:
111117 """Find all modules under 'path' that start with 'prefix'."""
@@ -166,31 +172,43 @@ def _is_stdlib_module(self, module_info: pkgutil.ModuleInfo) -> bool:
166172 return (isinstance (module_info .module_finder , FileFinder )
167173 and module_info .module_finder .path == self ._stdlib_path )
168174
169- def find_attributes (self , path : str , prefix : str ) -> tuple [list [str ], CompletionAction | None ]:
175+ def find_attributes (self , path : str , prefix : str ) -> tuple [list [str ], list [ Any ], CompletionAction | None ]:
170176 """Find all attributes of module 'path' that start with 'prefix'."""
171- attributes , action = self ._find_attributes (path , prefix )
177+ attributes , values , action = self ._find_attributes (path , prefix )
172178 # Filter out invalid attribute names
173179 # (for example those containing dashes that cannot be imported with 'import')
174- return [attr for attr in attributes if attr .isidentifier ()], action
175-
176- def _find_attributes (self , path : str , prefix : str ) -> tuple [list [str ], CompletionAction | None ]:
180+ filtered = [(attr , val ) for attr , val in zip (attributes , values )
181+ if attr .isidentifier ()]
182+ if filtered :
183+ attrs , vals = zip (* filtered )
184+ return list (attrs ), list (vals ), action
185+ return [], [], action
186+
187+ def _find_attributes (self , path : str , prefix : str ) -> tuple [list [str ], list [Any ], CompletionAction | None ]:
177188 path = self ._resolve_relative_path (path ) # type: ignore[assignment]
178189 if path is None :
179- return [], None
190+ return [], [], None
180191
181192 imported_module = sys .modules .get (path )
182193 if not imported_module :
183194 if path in self ._failed_imports : # Do not propose to import again
184- return [], None
195+ return [], [], None
185196 imported_module = self ._maybe_import_module (path )
186197 if not imported_module :
187- return [], self ._get_import_completion_action (path )
198+ return [], [], self ._get_import_completion_action (path )
188199 try :
189200 module_attributes = dir (imported_module )
190201 except Exception :
191202 module_attributes = []
192- return [attr_name for attr_name in module_attributes
193- if self .is_suggestion_match (attr_name , prefix )], None
203+ from .fancycompleter import safe_getattr
204+ names = []
205+ values = []
206+ for attr_name in module_attributes :
207+ if not self .is_suggestion_match (attr_name , prefix ):
208+ continue
209+ names .append (attr_name )
210+ values .append (safe_getattr (imported_module , attr_name ))
211+ return names , values , None
194212
195213 def is_suggestion_match (self , module_name : str , prefix : str ) -> bool :
196214 if prefix :
0 commit comments