5757 "oct" , "hex" , "index" , "coerce" , "enter" , "exit" ]]
5858
5959
60- def attr_complete (text , namespace = None , mode = SIMPLE ):
61- """Return list of matches """
62- if namespace is None :
63- namespace = __main__ .__dict__
64-
65- assert '.' in text
66-
67- for i in range (1 , len (text ) + 1 ):
68- if text [- i ] == '[' :
69- i -= 1
70- break
71- methodtext = text [- i :]
72- matches = ['' .join ([text [:- i ], m ]) for m in
73- attr_matches (methodtext , namespace , mode )]
74-
75- # unless the first character is a _ filter out all attributes starting with a _
76- if not text .split ('.' )[- 1 ].startswith ('_' ):
77- matches = [match for match in matches
78- if not match .split ('.' )[- 1 ].startswith ('_' )]
79- return matches
80-
81-
82- class SafeEvalFailed (Exception ):
83- """If this object is returned, safe_eval failed"""
84- # Because every normal Python value is a possible return value of safe_eval
85-
86- def safe_eval (expr , namespace ):
87- """Not all that safe, just catches some errors"""
88- if expr .isdigit ():
89- # Special case: float literal, using attrs here will result in
90- # a SyntaxError
91- return SafeEvalFailed
92- try :
93- obj = eval (expr , namespace )
94- return obj
95- except (NameError ,) as e :
96- # If debugging safe_eval, raise this!
97- # raise e
98- return SafeEvalFailed
99-
100- def attr_matches (text , namespace , autocomplete_mode ):
101- """Taken from rlcompleter.py and bent to my will.
102- """
103-
104- # Gna, Py 2.6's rlcompleter searches for __call__ inside the
105- # instance instead of the type, so we monkeypatch to prevent
106- # side-effects (__getattr__/__getattribute__)
107- m = re .match (r"(\w+(\.\w+)*)\.(\w*)" , text )
108- if not m :
109- return []
110-
111- expr , attr = m .group (1 , 3 )
112- obj = safe_eval (expr , namespace )
113- if obj is SafeEvalFailed :
114- return []
115- with inspection .AttrCleaner (obj ):
116- matches = attr_lookup (obj , expr , attr , autocomplete_mode )
117- return matches
118-
119- def attr_lookup (obj , expr , attr , autocomplete_mode ):
120- """Second half of original attr_matches method factored out so it can
121- be wrapped in a safe try/finally block in case anything bad happens to
122- restore the original __getattribute__ method."""
123- words = dir (obj )
124- if hasattr (obj , '__class__' ):
125- words .append ('__class__' )
126- words = words + rlcompleter .get_class_members (obj .__class__ )
127- if has_abc and not isinstance (obj .__class__ , abc .ABCMeta ):
128- try :
129- words .remove ('__abstractmethods__' )
130- except ValueError :
131- pass
132-
133- matches = []
134- n = len (attr )
135- for word in words :
136- if method_match (word , n , attr , autocomplete_mode ) and word != "__builtins__" :
137- matches .append ("%s.%s" % (expr , word ))
138- return matches
139-
140- def _callable_postfix (value , word ):
141- """rlcompleter's _callable_postfix done right."""
142- with inspection .AttrCleaner (value ):
143- if inspection .is_callable (value ):
144- word += '('
145- return word
146-
147- def global_matches (text , namespace , autocomplete_mode ):
148- """Compute matches when text is a simple name.
149- Return a list of all keywords, built-in functions and names currently
150- defined in self.namespace that match.
151- """
152-
153- hash = {}
154- n = len (text )
155- import keyword
156- for word in keyword .kwlist :
157- if method_match (word , n , text , autocomplete_mode ):
158- hash [word ] = 1
159- for nspace in [__builtin__ .__dict__ , namespace ]:
160- for word , val in nspace .items ():
161- if method_match (word , len (text ), text , autocomplete_mode ) and word != "__builtins__" :
162- hash [_callable_postfix (val , word )] = 1
163- matches = hash .keys ()
164- matches .sort ()
165- return matches
166-
167- #TODO use method_match everywhere instead of startswith to implement other completion modes
168- # will also need to rewrite checking mode so cseq replace doesn't happen in frontends
169- def method_match (word , size , text , autocomplete_mode ):
170- if autocomplete_mode == SIMPLE :
171- return word [:size ] == text
172- elif autocomplete_mode == SUBSTRING :
173- s = r'.*%s.*' % text
174- return re .search (s , word )
175- else :
176- s = r'.*%s.*' % '.*' .join (list (text ))
177- return re .search (s , word )
178-
179- def filename_matches (cs ):
180- matches = []
181- username = cs .split (os .path .sep , 1 )[0 ]
182- user_dir = os .path .expanduser (username )
183- for filename in glob (os .path .expanduser (cs + '*' )):
184- if os .path .isdir (filename ):
185- filename += os .path .sep
186- if cs .startswith ('~' ):
187- filename = username + filename [len (user_dir ):]
188- matches .append (filename )
189- return matches
190-
191- def last_part_of_filename (filename ):
192- filename .rstrip (os .sep ).rsplit (os .sep )[- 1 ]
193- if os .sep in filename [:- 1 ]:
194- return filename [filename .rindex (os .sep , 0 , - 1 )+ 1 :]
195- else :
196- return filename
197-
198- def after_last_dot (name ):
199- return name .rstrip ('.' ).rsplit ('.' )[- 1 ]
200-
20160def get_completer (cursor_offset , current_line , locals_ , argspec , full_code , mode , complete_magic_methods ):
20261 """Returns a list of matches and a class for what kind of completion is happening
20362
@@ -233,7 +92,6 @@ def get_completer(cursor_offset, current_line, locals_, argspec, full_code, mode
23392 return None , None
23493 return sorted (set (current_word_matches )), AttrCompletion
23594
236-
23795class BaseCompletionType (object ):
23896 """Describes different completion types"""
23997 def matches (cls , cursor_offset , line , ** kwargs ):
@@ -271,7 +129,9 @@ class ImportCompletion(BaseCompletionType):
271129 def matches (cls , cursor_offset , current_line , ** kwargs ):
272130 return importcompletion .complete (cursor_offset , current_line )
273131 locate = staticmethod (lineparts .current_word )
274- format = staticmethod (after_last_dot )
132+ @classmethod
133+ def format (cls , name ):
134+ return name .rstrip ('.' ).rsplit ('.' )[- 1 ]
275135
276136class FilenameCompletion (BaseCompletionType ):
277137 shown_before_tab = False
@@ -280,20 +140,59 @@ def matches(cls, cursor_offset, current_line, **kwargs):
280140 cs = lineparts .current_string (cursor_offset , current_line )
281141 if cs is None :
282142 return None
283- return filename_matches (cs [2 ])
143+ start , end , text = cs
144+ matches = []
145+ username = text .split (os .path .sep , 1 )[0 ]
146+ user_dir = os .path .expanduser (username )
147+ for filename in glob (os .path .expanduser (text + '*' )):
148+ if os .path .isdir (filename ):
149+ filename += os .path .sep
150+ if text .startswith ('~' ):
151+ filename = username + filename [len (user_dir ):]
152+ matches .append (filename )
153+ return matches
154+
284155 locate = staticmethod (lineparts .current_string )
285- format = staticmethod (last_part_of_filename )
156+ @classmethod
157+ def format (cls , filename ):
158+ filename .rstrip (os .sep ).rsplit (os .sep )[- 1 ]
159+ if os .sep in filename [:- 1 ]:
160+ return filename [filename .rindex (os .sep , 0 , - 1 )+ 1 :]
161+ else :
162+ return filename
286163
287164class AttrCompletion (BaseCompletionType ):
288165 @classmethod
289166 def matches (cls , cursor_offset , line , locals_ , mode , ** kwargs ):
290167 r = cls .locate (cursor_offset , line )
291168 if r is None :
292169 return None
293- cw = r [2 ]
294- return attr_complete (cw , namespace = locals_ , mode = mode )
170+ text = r [2 ]
171+
172+ if locals_ is None :
173+ locals_ = __main__ .__dict__
174+
175+ assert '.' in text
176+
177+ for i in range (1 , len (text ) + 1 ):
178+ if text [- i ] == '[' :
179+ i -= 1
180+ break
181+ methodtext = text [- i :]
182+ matches = ['' .join ([text [:- i ], m ]) for m in
183+ attr_matches (methodtext , locals_ , mode )]
184+
185+ #TODO add open paren for methods via _callable_prefix (or decide not to)
186+ # unless the first character is a _ filter out all attributes starting with a _
187+ if not text .split ('.' )[- 1 ].startswith ('_' ):
188+ matches = [match for match in matches
189+ if not match .split ('.' )[- 1 ].startswith ('_' )]
190+ return matches
191+
295192 locate = staticmethod (lineparts .current_dotted_attribute )
296- format = staticmethod (after_last_dot )
193+ @classmethod
194+ def format (cls , name ):
195+ return name .rstrip ('.' ).rsplit ('.' )[- 1 ]
297196
298197class DictKeyCompletion (BaseCompletionType ):
299198 locate = staticmethod (lineparts .current_dict_key )
@@ -354,3 +253,138 @@ def matches(cls, cursor_offset, line, argspec, **kwargs):
354253 if name .startswith (word ))
355254 return matches
356255 locate = staticmethod (lineparts .current_word )
256+
257+ class MagicMethodCompletion (BaseCompletionType ):
258+ locate = staticmethod (lineparts .current_method_definition_name )
259+ @classmethod
260+ def matches (cls , cursor_offset , line , full_code , ** kwargs ):
261+ r = cls .locate (cursor_offset , line )
262+ if r is None :
263+ return None
264+ if 'class' not in full_code :
265+ return None
266+ start , end , word = r
267+ return [name for name in MAGIC_METHODS if name .startswith (word )]
268+
269+ class GlobalCompletion (BaseCompletionType ):
270+ @classmethod
271+ def matches (cls , cursor_offset , line , locals_ , mode , ** kwargs ):
272+ """Compute matches when text is a simple name.
273+ Return a list of all keywords, built-in functions and names currently
274+ defined in self.namespace that match.
275+ """
276+ r = cls .locate (cursor_offset , line )
277+ if r is None :
278+ return None
279+ start , end , text = r
280+
281+ hash = {}
282+ n = len (text )
283+ import keyword
284+ for word in keyword .kwlist :
285+ if method_match (word , n , text , mode ):
286+ hash [word ] = 1
287+ for nspace in [__builtin__ .__dict__ , locals_ ]:
288+ for word , val in nspace .items ():
289+ if method_match (word , len (text ), text , mode ) and word != "__builtins__" :
290+ hash [_callable_postfix (val , word )] = 1
291+ matches = hash .keys ()
292+ matches .sort ()
293+ return matches
294+
295+ locate = staticmethod (lineparts .current_single_word )
296+
297+ class ParameterNameCompletion (BaseCompletionType ):
298+ @classmethod
299+ def matches (cls , cursor_offset , line , argspec , ** kwargs ):
300+ if not argspec :
301+ return None
302+ r = cls .locate (cursor_offset , line )
303+ if r is None :
304+ return None
305+ start , end , word = r
306+ if argspec :
307+ matches = [name + '=' for name in argspec [1 ][0 ]
308+ if isinstance (name , basestring ) and name .startswith (word )]
309+ if py3 :
310+ matches .extend (name + '=' for name in argspec [1 ][4 ]
311+ if name .startswith (word ))
312+ return matches
313+ locate = staticmethod (lineparts .current_word )
314+
315+ class SafeEvalFailed (Exception ):
316+ """If this object is returned, safe_eval failed"""
317+ # Because every normal Python value is a possible return value of safe_eval
318+
319+ def safe_eval (expr , namespace ):
320+ """Not all that safe, just catches some errors"""
321+ if expr .isdigit ():
322+ # Special case: float literal, using attrs here will result in
323+ # a SyntaxError
324+ return SafeEvalFailed
325+ try :
326+ obj = eval (expr , namespace )
327+ return obj
328+ except (NameError ,) as e :
329+ # If debugging safe_eval, raise this!
330+ # raise e
331+ return SafeEvalFailed
332+
333+ def attr_matches (text , namespace , autocomplete_mode ):
334+ """Taken from rlcompleter.py and bent to my will.
335+ """
336+
337+ # Gna, Py 2.6's rlcompleter searches for __call__ inside the
338+ # instance instead of the type, so we monkeypatch to prevent
339+ # side-effects (__getattr__/__getattribute__)
340+ m = re .match (r"(\w+(\.\w+)*)\.(\w*)" , text )
341+ if not m :
342+ return []
343+
344+ expr , attr = m .group (1 , 3 )
345+ obj = safe_eval (expr , namespace )
346+ if obj is SafeEvalFailed :
347+ return []
348+ with inspection .AttrCleaner (obj ):
349+ matches = attr_lookup (obj , expr , attr , autocomplete_mode )
350+ return matches
351+
352+ def attr_lookup (obj , expr , attr , autocomplete_mode ):
353+ """Second half of original attr_matches method factored out so it can
354+ be wrapped in a safe try/finally block in case anything bad happens to
355+ restore the original __getattribute__ method."""
356+ words = dir (obj )
357+ if hasattr (obj , '__class__' ):
358+ words .append ('__class__' )
359+ words = words + rlcompleter .get_class_members (obj .__class__ )
360+ if has_abc and not isinstance (obj .__class__ , abc .ABCMeta ):
361+ try :
362+ words .remove ('__abstractmethods__' )
363+ except ValueError :
364+ pass
365+
366+ matches = []
367+ n = len (attr )
368+ for word in words :
369+ if method_match (word , n , attr , autocomplete_mode ) and word != "__builtins__" :
370+ matches .append ("%s.%s" % (expr , word ))
371+ return matches
372+
373+ def _callable_postfix (value , word ):
374+ """rlcompleter's _callable_postfix done right."""
375+ with inspection .AttrCleaner (value ):
376+ if inspection .is_callable (value ):
377+ word += '('
378+ return word
379+
380+ #TODO use method_match everywhere instead of startswith to implement other completion modes
381+ # will also need to rewrite checking mode so cseq replace doesn't happen in frontends
382+ def method_match (word , size , text , autocomplete_mode ):
383+ if autocomplete_mode == SIMPLE :
384+ return word [:size ] == text
385+ elif autocomplete_mode == SUBSTRING :
386+ s = r'.*%s.*' % text
387+ return re .search (s , word )
388+ else :
389+ s = r'.*%s.*' % '.*' .join (list (text ))
390+ return re .search (s , word )
0 commit comments