##// END OF EJS Templates
PR cleanup according to comments.
Antony Lee -
Show More
@@ -1,1270 +1,1270 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Word completion for IPython.
2 """Word completion for IPython.
3
3
4 This module is a fork of the rlcompleter module in the Python standard
4 This module is a fork of the rlcompleter module in the Python standard
5 library. The original enhancements made to rlcompleter have been sent
5 library. The original enhancements made to rlcompleter have been sent
6 upstream and were accepted as of Python 2.3, but we need a lot more
6 upstream and were accepted as of Python 2.3, but we need a lot more
7 functionality specific to IPython, so this module will continue to live as an
7 functionality specific to IPython, so this module will continue to live as an
8 IPython-specific utility.
8 IPython-specific utility.
9
9
10 Original rlcompleter documentation:
10 Original rlcompleter documentation:
11
11
12 This requires the latest extension to the readline module (the
12 This requires the latest extension to the readline module (the
13 completes keywords, built-ins and globals in __main__; when completing
13 completes keywords, built-ins and globals in __main__; when completing
14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
15 completes its attributes.
15 completes its attributes.
16
16
17 It's very cool to do "import string" type "string.", hit the
17 It's very cool to do "import string" type "string.", hit the
18 completion key (twice), and see the list of names defined by the
18 completion key (twice), and see the list of names defined by the
19 string module!
19 string module!
20
20
21 Tip: to use the tab key as the completion key, call
21 Tip: to use the tab key as the completion key, call
22
22
23 readline.parse_and_bind("tab: complete")
23 readline.parse_and_bind("tab: complete")
24
24
25 Notes:
25 Notes:
26
26
27 - Exceptions raised by the completer function are *ignored* (and
27 - Exceptions raised by the completer function are *ignored* (and
28 generally cause the completion to fail). This is a feature -- since
28 generally cause the completion to fail). This is a feature -- since
29 readline sets the tty device in raw (or cbreak) mode, printing a
29 readline sets the tty device in raw (or cbreak) mode, printing a
30 traceback wouldn't work well without some complicated hoopla to save,
30 traceback wouldn't work well without some complicated hoopla to save,
31 reset and restore the tty state.
31 reset and restore the tty state.
32
32
33 - The evaluation of the NAME.NAME... form may cause arbitrary
33 - The evaluation of the NAME.NAME... form may cause arbitrary
34 application defined code to be executed if an object with a
34 application defined code to be executed if an object with a
35 ``__getattr__`` hook is found. Since it is the responsibility of the
35 ``__getattr__`` hook is found. Since it is the responsibility of the
36 application (or the user) to enable this feature, I consider this an
36 application (or the user) to enable this feature, I consider this an
37 acceptable risk. More complicated expressions (e.g. function calls or
37 acceptable risk. More complicated expressions (e.g. function calls or
38 indexing operations) are *not* evaluated.
38 indexing operations) are *not* evaluated.
39
39
40 - GNU readline is also used by the built-in functions input() and
40 - GNU readline is also used by the built-in functions input() and
41 raw_input(), and thus these also benefit/suffer from the completer
41 raw_input(), and thus these also benefit/suffer from the completer
42 features. Clearly an interactive application can benefit by
42 features. Clearly an interactive application can benefit by
43 specifying its own completer function and using raw_input() for all
43 specifying its own completer function and using raw_input() for all
44 its input.
44 its input.
45
45
46 - When the original stdin is not a tty device, GNU readline is never
46 - When the original stdin is not a tty device, GNU readline is never
47 used, and this module (and the readline module) are silently inactive.
47 used, and this module (and the readline module) are silently inactive.
48 """
48 """
49
49
50 # Copyright (c) IPython Development Team.
50 # Copyright (c) IPython Development Team.
51 # Distributed under the terms of the Modified BSD License.
51 # Distributed under the terms of the Modified BSD License.
52 #
52 #
53 # Some of this code originated from rlcompleter in the Python standard library
53 # Some of this code originated from rlcompleter in the Python standard library
54 # Copyright (C) 2001 Python Software Foundation, www.python.org
54 # Copyright (C) 2001 Python Software Foundation, www.python.org
55
55
56 from __future__ import print_function
56 from __future__ import print_function
57
57
58 import __main__
58 import __main__
59 import glob
59 import glob
60 import inspect
60 import inspect
61 import itertools
61 import itertools
62 import keyword
62 import keyword
63 import os
63 import os
64 import re
64 import re
65 import sys
65 import sys
66 import unicodedata
66 import unicodedata
67 import string
67 import string
68
68
69 from traitlets.config.configurable import Configurable
69 from traitlets.config.configurable import Configurable
70 from IPython.core.error import TryNext
70 from IPython.core.error import TryNext
71 from IPython.core.inputsplitter import ESC_MAGIC
71 from IPython.core.inputsplitter import ESC_MAGIC
72 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
72 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
73 from IPython.utils import generics
73 from IPython.utils import generics
74 from IPython.utils.decorators import undoc
74 from IPython.utils.decorators import undoc
75 from IPython.utils.dir2 import dir2, get_real_method
75 from IPython.utils.dir2 import dir2, get_real_method
76 from IPython.utils.process import arg_split
76 from IPython.utils.process import arg_split
77 from IPython.utils.py3compat import builtin_mod, string_types, PY3, cast_unicode_py2
77 from IPython.utils.py3compat import builtin_mod, string_types, PY3, cast_unicode_py2
78 from traitlets import Bool, Enum, observe
78 from traitlets import Bool, Enum, observe
79
79
80 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
81 # Globals
81 # Globals
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83
83
84 # Public API
84 # Public API
85 __all__ = ['Completer','IPCompleter']
85 __all__ = ['Completer','IPCompleter']
86
86
87 if sys.platform == 'win32':
87 if sys.platform == 'win32':
88 PROTECTABLES = ' '
88 PROTECTABLES = ' '
89 else:
89 else:
90 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
90 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
91
91
92
92
93 #-----------------------------------------------------------------------------
93 #-----------------------------------------------------------------------------
94 # Main functions and classes
94 # Main functions and classes
95 #-----------------------------------------------------------------------------
95 #-----------------------------------------------------------------------------
96
96
97 def has_open_quotes(s):
97 def has_open_quotes(s):
98 """Return whether a string has open quotes.
98 """Return whether a string has open quotes.
99
99
100 This simply counts whether the number of quote characters of either type in
100 This simply counts whether the number of quote characters of either type in
101 the string is odd.
101 the string is odd.
102
102
103 Returns
103 Returns
104 -------
104 -------
105 If there is an open quote, the quote character is returned. Else, return
105 If there is an open quote, the quote character is returned. Else, return
106 False.
106 False.
107 """
107 """
108 # We check " first, then ', so complex cases with nested quotes will get
108 # We check " first, then ', so complex cases with nested quotes will get
109 # the " to take precedence.
109 # the " to take precedence.
110 if s.count('"') % 2:
110 if s.count('"') % 2:
111 return '"'
111 return '"'
112 elif s.count("'") % 2:
112 elif s.count("'") % 2:
113 return "'"
113 return "'"
114 else:
114 else:
115 return False
115 return False
116
116
117
117
118 def protect_filename(s):
118 def protect_filename(s):
119 """Escape a string to protect certain characters."""
119 """Escape a string to protect certain characters."""
120 if set(s) & set(PROTECTABLES):
120 if set(s) & set(PROTECTABLES):
121 if sys.platform == "win32":
121 if sys.platform == "win32":
122 return '"' + s + '"'
122 return '"' + s + '"'
123 else:
123 else:
124 return "".join("\\" + c if c in PROTECTABLES else c for c in s)
124 return "".join(("\\" + c if c in PROTECTABLES else c) for c in s)
125 else:
125 else:
126 return s
126 return s
127
127
128
128
129 def expand_user(path):
129 def expand_user(path):
130 """Expand '~'-style usernames in strings.
130 """Expand '~'-style usernames in strings.
131
131
132 This is similar to :func:`os.path.expanduser`, but it computes and returns
132 This is similar to :func:`os.path.expanduser`, but it computes and returns
133 extra information that will be useful if the input was being used in
133 extra information that will be useful if the input was being used in
134 computing completions, and you wish to return the completions with the
134 computing completions, and you wish to return the completions with the
135 original '~' instead of its expanded value.
135 original '~' instead of its expanded value.
136
136
137 Parameters
137 Parameters
138 ----------
138 ----------
139 path : str
139 path : str
140 String to be expanded. If no ~ is present, the output is the same as the
140 String to be expanded. If no ~ is present, the output is the same as the
141 input.
141 input.
142
142
143 Returns
143 Returns
144 -------
144 -------
145 newpath : str
145 newpath : str
146 Result of ~ expansion in the input path.
146 Result of ~ expansion in the input path.
147 tilde_expand : bool
147 tilde_expand : bool
148 Whether any expansion was performed or not.
148 Whether any expansion was performed or not.
149 tilde_val : str
149 tilde_val : str
150 The value that ~ was replaced with.
150 The value that ~ was replaced with.
151 """
151 """
152 # Default values
152 # Default values
153 tilde_expand = False
153 tilde_expand = False
154 tilde_val = ''
154 tilde_val = ''
155 newpath = path
155 newpath = path
156
156
157 if path.startswith('~'):
157 if path.startswith('~'):
158 tilde_expand = True
158 tilde_expand = True
159 rest = len(path)-1
159 rest = len(path)-1
160 newpath = os.path.expanduser(path)
160 newpath = os.path.expanduser(path)
161 if rest:
161 if rest:
162 tilde_val = newpath[:-rest]
162 tilde_val = newpath[:-rest]
163 else:
163 else:
164 tilde_val = newpath
164 tilde_val = newpath
165
165
166 return newpath, tilde_expand, tilde_val
166 return newpath, tilde_expand, tilde_val
167
167
168
168
169 def compress_user(path, tilde_expand, tilde_val):
169 def compress_user(path, tilde_expand, tilde_val):
170 """Does the opposite of expand_user, with its outputs.
170 """Does the opposite of expand_user, with its outputs.
171 """
171 """
172 if tilde_expand:
172 if tilde_expand:
173 return path.replace(tilde_val, '~')
173 return path.replace(tilde_val, '~')
174 else:
174 else:
175 return path
175 return path
176
176
177
177
178 def completions_sorting_key(word):
178 def completions_sorting_key(word):
179 """key for sorting completions
179 """key for sorting completions
180
180
181 This does several things:
181 This does several things:
182
182
183 - Lowercase all completions, so they are sorted alphabetically with
183 - Lowercase all completions, so they are sorted alphabetically with
184 upper and lower case words mingled
184 upper and lower case words mingled
185 - Demote any completions starting with underscores to the end
185 - Demote any completions starting with underscores to the end
186 - Insert any %magic and %%cellmagic completions in the alphabetical order
186 - Insert any %magic and %%cellmagic completions in the alphabetical order
187 by their name
187 by their name
188 """
188 """
189 # Case insensitive sort
189 # Case insensitive sort
190 word = word.lower()
190 word = word.lower()
191
191
192 prio1, prio2 = 0, 0
192 prio1, prio2 = 0, 0
193
193
194 if word.startswith('__'):
194 if word.startswith('__'):
195 prio1 = 2
195 prio1 = 2
196 elif word.startswith('_'):
196 elif word.startswith('_'):
197 prio1 = 1
197 prio1 = 1
198
198
199 if word.endswith('='):
199 if word.endswith('='):
200 prio1 = -1
200 prio1 = -1
201
201
202 if word.startswith('%%'):
202 if word.startswith('%%'):
203 # If there's another % in there, this is something else, so leave it alone
203 # If there's another % in there, this is something else, so leave it alone
204 if not "%" in word[2:]:
204 if not "%" in word[2:]:
205 word = word[2:]
205 word = word[2:]
206 prio2 = 2
206 prio2 = 2
207 elif word.startswith('%'):
207 elif word.startswith('%'):
208 if not "%" in word[1:]:
208 if not "%" in word[1:]:
209 word = word[1:]
209 word = word[1:]
210 prio2 = 1
210 prio2 = 1
211
211
212 return prio1, word, prio2
212 return prio1, word, prio2
213
213
214
214
215 @undoc
215 @undoc
216 class Bunch(object): pass
216 class Bunch(object): pass
217
217
218
218
219 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
219 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
220 GREEDY_DELIMS = ' =\r\n'
220 GREEDY_DELIMS = ' =\r\n'
221
221
222
222
223 class CompletionSplitter(object):
223 class CompletionSplitter(object):
224 """An object to split an input line in a manner similar to readline.
224 """An object to split an input line in a manner similar to readline.
225
225
226 By having our own implementation, we can expose readline-like completion in
226 By having our own implementation, we can expose readline-like completion in
227 a uniform manner to all frontends. This object only needs to be given the
227 a uniform manner to all frontends. This object only needs to be given the
228 line of text to be split and the cursor position on said line, and it
228 line of text to be split and the cursor position on said line, and it
229 returns the 'word' to be completed on at the cursor after splitting the
229 returns the 'word' to be completed on at the cursor after splitting the
230 entire line.
230 entire line.
231
231
232 What characters are used as splitting delimiters can be controlled by
232 What characters are used as splitting delimiters can be controlled by
233 setting the `delims` attribute (this is a property that internally
233 setting the `delims` attribute (this is a property that internally
234 automatically builds the necessary regular expression)"""
234 automatically builds the necessary regular expression)"""
235
235
236 # Private interface
236 # Private interface
237
237
238 # A string of delimiter characters. The default value makes sense for
238 # A string of delimiter characters. The default value makes sense for
239 # IPython's most typical usage patterns.
239 # IPython's most typical usage patterns.
240 _delims = DELIMS
240 _delims = DELIMS
241
241
242 # The expression (a normal string) to be compiled into a regular expression
242 # The expression (a normal string) to be compiled into a regular expression
243 # for actual splitting. We store it as an attribute mostly for ease of
243 # for actual splitting. We store it as an attribute mostly for ease of
244 # debugging, since this type of code can be so tricky to debug.
244 # debugging, since this type of code can be so tricky to debug.
245 _delim_expr = None
245 _delim_expr = None
246
246
247 # The regular expression that does the actual splitting
247 # The regular expression that does the actual splitting
248 _delim_re = None
248 _delim_re = None
249
249
250 def __init__(self, delims=None):
250 def __init__(self, delims=None):
251 delims = CompletionSplitter._delims if delims is None else delims
251 delims = CompletionSplitter._delims if delims is None else delims
252 self.delims = delims
252 self.delims = delims
253
253
254 @property
254 @property
255 def delims(self):
255 def delims(self):
256 """Return the string of delimiter characters."""
256 """Return the string of delimiter characters."""
257 return self._delims
257 return self._delims
258
258
259 @delims.setter
259 @delims.setter
260 def delims(self, delims):
260 def delims(self, delims):
261 """Set the delimiters for line splitting."""
261 """Set the delimiters for line splitting."""
262 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
262 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
263 self._delim_re = re.compile(expr)
263 self._delim_re = re.compile(expr)
264 self._delims = delims
264 self._delims = delims
265 self._delim_expr = expr
265 self._delim_expr = expr
266
266
267 def split_line(self, line, cursor_pos=None):
267 def split_line(self, line, cursor_pos=None):
268 """Split a line of text with a cursor at the given position.
268 """Split a line of text with a cursor at the given position.
269 """
269 """
270 l = line if cursor_pos is None else line[:cursor_pos]
270 l = line if cursor_pos is None else line[:cursor_pos]
271 return self._delim_re.split(l)[-1]
271 return self._delim_re.split(l)[-1]
272
272
273
273
274 class Completer(Configurable):
274 class Completer(Configurable):
275
275
276 greedy = Bool(False,
276 greedy = Bool(False,
277 help="""Activate greedy completion
277 help="""Activate greedy completion
278 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
278 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
279
279
280 This will enable completion on elements of lists, results of function calls, etc.,
280 This will enable completion on elements of lists, results of function calls, etc.,
281 but can be unsafe because the code is actually evaluated on TAB.
281 but can be unsafe because the code is actually evaluated on TAB.
282 """
282 """
283 ).tag(config=True)
283 ).tag(config=True)
284
284
285
285
286 def __init__(self, namespace=None, global_namespace=None, **kwargs):
286 def __init__(self, namespace=None, global_namespace=None, **kwargs):
287 """Create a new completer for the command line.
287 """Create a new completer for the command line.
288
288
289 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
289 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
290
290
291 If unspecified, the default namespace where completions are performed
291 If unspecified, the default namespace where completions are performed
292 is __main__ (technically, __main__.__dict__). Namespaces should be
292 is __main__ (technically, __main__.__dict__). Namespaces should be
293 given as dictionaries.
293 given as dictionaries.
294
294
295 An optional second namespace can be given. This allows the completer
295 An optional second namespace can be given. This allows the completer
296 to handle cases where both the local and global scopes need to be
296 to handle cases where both the local and global scopes need to be
297 distinguished.
297 distinguished.
298
298
299 Completer instances should be used as the completion mechanism of
299 Completer instances should be used as the completion mechanism of
300 readline via the set_completer() call:
300 readline via the set_completer() call:
301
301
302 readline.set_completer(Completer(my_namespace).complete)
302 readline.set_completer(Completer(my_namespace).complete)
303 """
303 """
304
304
305 # Don't bind to namespace quite yet, but flag whether the user wants a
305 # Don't bind to namespace quite yet, but flag whether the user wants a
306 # specific namespace or to use __main__.__dict__. This will allow us
306 # specific namespace or to use __main__.__dict__. This will allow us
307 # to bind to __main__.__dict__ at completion time, not now.
307 # to bind to __main__.__dict__ at completion time, not now.
308 if namespace is None:
308 if namespace is None:
309 self.use_main_ns = 1
309 self.use_main_ns = 1
310 else:
310 else:
311 self.use_main_ns = 0
311 self.use_main_ns = 0
312 self.namespace = namespace
312 self.namespace = namespace
313
313
314 # The global namespace, if given, can be bound directly
314 # The global namespace, if given, can be bound directly
315 if global_namespace is None:
315 if global_namespace is None:
316 self.global_namespace = {}
316 self.global_namespace = {}
317 else:
317 else:
318 self.global_namespace = global_namespace
318 self.global_namespace = global_namespace
319
319
320 super(Completer, self).__init__(**kwargs)
320 super(Completer, self).__init__(**kwargs)
321
321
322 def complete(self, text, state):
322 def complete(self, text, state):
323 """Return the next possible completion for 'text'.
323 """Return the next possible completion for 'text'.
324
324
325 This is called successively with state == 0, 1, 2, ... until it
325 This is called successively with state == 0, 1, 2, ... until it
326 returns None. The completion should begin with 'text'.
326 returns None. The completion should begin with 'text'.
327
327
328 """
328 """
329 if self.use_main_ns:
329 if self.use_main_ns:
330 self.namespace = __main__.__dict__
330 self.namespace = __main__.__dict__
331
331
332 if state == 0:
332 if state == 0:
333 if "." in text:
333 if "." in text:
334 self.matches = self.attr_matches(text)
334 self.matches = self.attr_matches(text)
335 else:
335 else:
336 self.matches = self.global_matches(text)
336 self.matches = self.global_matches(text)
337 try:
337 try:
338 return self.matches[state]
338 return self.matches[state]
339 except IndexError:
339 except IndexError:
340 return None
340 return None
341
341
342 def global_matches(self, text):
342 def global_matches(self, text):
343 """Compute matches when text is a simple name.
343 """Compute matches when text is a simple name.
344
344
345 Return a list of all keywords, built-in functions and names currently
345 Return a list of all keywords, built-in functions and names currently
346 defined in self.namespace or self.global_namespace that match.
346 defined in self.namespace or self.global_namespace that match.
347
347
348 """
348 """
349 matches = []
349 matches = []
350 match_append = matches.append
350 match_append = matches.append
351 n = len(text)
351 n = len(text)
352 for lst in [keyword.kwlist,
352 for lst in [keyword.kwlist,
353 builtin_mod.__dict__.keys(),
353 builtin_mod.__dict__.keys(),
354 self.namespace.keys(),
354 self.namespace.keys(),
355 self.global_namespace.keys()]:
355 self.global_namespace.keys()]:
356 for word in lst:
356 for word in lst:
357 if word[:n] == text and word != "__builtins__":
357 if word[:n] == text and word != "__builtins__":
358 match_append(word)
358 match_append(word)
359 return [cast_unicode_py2(m) for m in matches]
359 return [cast_unicode_py2(m) for m in matches]
360
360
361 def attr_matches(self, text):
361 def attr_matches(self, text):
362 """Compute matches when text contains a dot.
362 """Compute matches when text contains a dot.
363
363
364 Assuming the text is of the form NAME.NAME....[NAME], and is
364 Assuming the text is of the form NAME.NAME....[NAME], and is
365 evaluatable in self.namespace or self.global_namespace, it will be
365 evaluatable in self.namespace or self.global_namespace, it will be
366 evaluated and its attributes (as revealed by dir()) are used as
366 evaluated and its attributes (as revealed by dir()) are used as
367 possible completions. (For class instances, class members are are
367 possible completions. (For class instances, class members are are
368 also considered.)
368 also considered.)
369
369
370 WARNING: this can still invoke arbitrary C code, if an object
370 WARNING: this can still invoke arbitrary C code, if an object
371 with a __getattr__ hook is evaluated.
371 with a __getattr__ hook is evaluated.
372
372
373 """
373 """
374
374
375 # Another option, seems to work great. Catches things like ''.<tab>
375 # Another option, seems to work great. Catches things like ''.<tab>
376 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
376 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
377
377
378 if m:
378 if m:
379 expr, attr = m.group(1, 3)
379 expr, attr = m.group(1, 3)
380 elif self.greedy:
380 elif self.greedy:
381 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
381 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
382 if not m2:
382 if not m2:
383 return []
383 return []
384 expr, attr = m2.group(1,2)
384 expr, attr = m2.group(1,2)
385 else:
385 else:
386 return []
386 return []
387
387
388 try:
388 try:
389 obj = eval(expr, self.namespace)
389 obj = eval(expr, self.namespace)
390 except:
390 except:
391 try:
391 try:
392 obj = eval(expr, self.global_namespace)
392 obj = eval(expr, self.global_namespace)
393 except:
393 except:
394 return []
394 return []
395
395
396 if self.limit_to__all__ and hasattr(obj, '__all__'):
396 if self.limit_to__all__ and hasattr(obj, '__all__'):
397 words = get__all__entries(obj)
397 words = get__all__entries(obj)
398 else:
398 else:
399 words = dir2(obj)
399 words = dir2(obj)
400
400
401 try:
401 try:
402 words = generics.complete_object(obj, words)
402 words = generics.complete_object(obj, words)
403 except TryNext:
403 except TryNext:
404 pass
404 pass
405 except Exception:
405 except Exception:
406 # Silence errors from completion function
406 # Silence errors from completion function
407 #raise # dbg
407 #raise # dbg
408 pass
408 pass
409 # Build match list to return
409 # Build match list to return
410 n = len(attr)
410 n = len(attr)
411 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
411 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
412
412
413
413
414 def get__all__entries(obj):
414 def get__all__entries(obj):
415 """returns the strings in the __all__ attribute"""
415 """returns the strings in the __all__ attribute"""
416 try:
416 try:
417 words = getattr(obj, '__all__')
417 words = getattr(obj, '__all__')
418 except:
418 except:
419 return []
419 return []
420
420
421 return [cast_unicode_py2(w) for w in words if isinstance(w, string_types)]
421 return [cast_unicode_py2(w) for w in words if isinstance(w, string_types)]
422
422
423
423
424 def match_dict_keys(keys, prefix, delims):
424 def match_dict_keys(keys, prefix, delims):
425 """Used by dict_key_matches, matching the prefix to a list of keys"""
425 """Used by dict_key_matches, matching the prefix to a list of keys"""
426 if not prefix:
426 if not prefix:
427 return None, 0, [repr(k) for k in keys
427 return None, 0, [repr(k) for k in keys
428 if isinstance(k, (string_types, bytes))]
428 if isinstance(k, (string_types, bytes))]
429 quote_match = re.search('["\']', prefix)
429 quote_match = re.search('["\']', prefix)
430 quote = quote_match.group()
430 quote = quote_match.group()
431 try:
431 try:
432 prefix_str = eval(prefix + quote, {})
432 prefix_str = eval(prefix + quote, {})
433 except Exception:
433 except Exception:
434 return None, 0, []
434 return None, 0, []
435
435
436 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
436 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
437 token_match = re.search(pattern, prefix, re.UNICODE)
437 token_match = re.search(pattern, prefix, re.UNICODE)
438 token_start = token_match.start()
438 token_start = token_match.start()
439 token_prefix = token_match.group()
439 token_prefix = token_match.group()
440
440
441 # TODO: support bytes in Py3k
441 # TODO: support bytes in Py3k
442 matched = []
442 matched = []
443 for key in keys:
443 for key in keys:
444 try:
444 try:
445 if not key.startswith(prefix_str):
445 if not key.startswith(prefix_str):
446 continue
446 continue
447 except (AttributeError, TypeError, UnicodeError):
447 except (AttributeError, TypeError, UnicodeError):
448 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
448 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
449 continue
449 continue
450
450
451 # reformat remainder of key to begin with prefix
451 # reformat remainder of key to begin with prefix
452 rem = key[len(prefix_str):]
452 rem = key[len(prefix_str):]
453 # force repr wrapped in '
453 # force repr wrapped in '
454 rem_repr = repr(rem + '"')
454 rem_repr = repr(rem + '"')
455 if rem_repr.startswith('u') and prefix[0] not in 'uU':
455 if rem_repr.startswith('u') and prefix[0] not in 'uU':
456 # Found key is unicode, but prefix is Py2 string.
456 # Found key is unicode, but prefix is Py2 string.
457 # Therefore attempt to interpret key as string.
457 # Therefore attempt to interpret key as string.
458 try:
458 try:
459 rem_repr = repr(rem.encode('ascii') + '"')
459 rem_repr = repr(rem.encode('ascii') + '"')
460 except UnicodeEncodeError:
460 except UnicodeEncodeError:
461 continue
461 continue
462
462
463 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
463 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
464 if quote == '"':
464 if quote == '"':
465 # The entered prefix is quoted with ",
465 # The entered prefix is quoted with ",
466 # but the match is quoted with '.
466 # but the match is quoted with '.
467 # A contained " hence needs escaping for comparison:
467 # A contained " hence needs escaping for comparison:
468 rem_repr = rem_repr.replace('"', '\\"')
468 rem_repr = rem_repr.replace('"', '\\"')
469
469
470 # then reinsert prefix from start of token
470 # then reinsert prefix from start of token
471 matched.append('%s%s' % (token_prefix, rem_repr))
471 matched.append('%s%s' % (token_prefix, rem_repr))
472 return quote, token_start, matched
472 return quote, token_start, matched
473
473
474
474
475 def _safe_isinstance(obj, module, class_name):
475 def _safe_isinstance(obj, module, class_name):
476 """Checks if obj is an instance of module.class_name if loaded
476 """Checks if obj is an instance of module.class_name if loaded
477 """
477 """
478 return (module in sys.modules and
478 return (module in sys.modules and
479 isinstance(obj, getattr(__import__(module), class_name)))
479 isinstance(obj, getattr(__import__(module), class_name)))
480
480
481
481
482 def back_unicode_name_matches(text):
482 def back_unicode_name_matches(text):
483 u"""Match unicode characters back to unicode name
483 u"""Match unicode characters back to unicode name
484
484
485 This does β˜ƒ -> \\snowman
485 This does β˜ƒ -> \\snowman
486
486
487 Note that snowman is not a valid python3 combining character but will be expanded.
487 Note that snowman is not a valid python3 combining character but will be expanded.
488 Though it will not recombine back to the snowman character by the completion machinery.
488 Though it will not recombine back to the snowman character by the completion machinery.
489
489
490 This will not either back-complete standard sequences like \\n, \\b ...
490 This will not either back-complete standard sequences like \\n, \\b ...
491
491
492 Used on Python 3 only.
492 Used on Python 3 only.
493 """
493 """
494 if len(text)<2:
494 if len(text)<2:
495 return u'', ()
495 return u'', ()
496 maybe_slash = text[-2]
496 maybe_slash = text[-2]
497 if maybe_slash != '\\':
497 if maybe_slash != '\\':
498 return u'', ()
498 return u'', ()
499
499
500 char = text[-1]
500 char = text[-1]
501 # no expand on quote for completion in strings.
501 # no expand on quote for completion in strings.
502 # nor backcomplete standard ascii keys
502 # nor backcomplete standard ascii keys
503 if char in string.ascii_letters or char in ['"',"'"]:
503 if char in string.ascii_letters or char in ['"',"'"]:
504 return u'', ()
504 return u'', ()
505 try :
505 try :
506 unic = unicodedata.name(char)
506 unic = unicodedata.name(char)
507 return '\\'+char,['\\'+unic]
507 return '\\'+char,['\\'+unic]
508 except KeyError:
508 except KeyError:
509 pass
509 pass
510 return u'', ()
510 return u'', ()
511
511
512 def back_latex_name_matches(text):
512 def back_latex_name_matches(text):
513 u"""Match latex characters back to unicode name
513 u"""Match latex characters back to unicode name
514
514
515 This does ->\\sqrt
515 This does ->\\sqrt
516
516
517 Used on Python 3 only.
517 Used on Python 3 only.
518 """
518 """
519 if len(text)<2:
519 if len(text)<2:
520 return u'', ()
520 return u'', ()
521 maybe_slash = text[-2]
521 maybe_slash = text[-2]
522 if maybe_slash != '\\':
522 if maybe_slash != '\\':
523 return u'', ()
523 return u'', ()
524
524
525
525
526 char = text[-1]
526 char = text[-1]
527 # no expand on quote for completion in strings.
527 # no expand on quote for completion in strings.
528 # nor backcomplete standard ascii keys
528 # nor backcomplete standard ascii keys
529 if char in string.ascii_letters or char in ['"',"'"]:
529 if char in string.ascii_letters or char in ['"',"'"]:
530 return u'', ()
530 return u'', ()
531 try :
531 try :
532 latex = reverse_latex_symbol[char]
532 latex = reverse_latex_symbol[char]
533 # '\\' replace the \ as well
533 # '\\' replace the \ as well
534 return '\\'+char,[latex]
534 return '\\'+char,[latex]
535 except KeyError:
535 except KeyError:
536 pass
536 pass
537 return u'', ()
537 return u'', ()
538
538
539
539
540 class IPCompleter(Completer):
540 class IPCompleter(Completer):
541 """Extension of the completer class with IPython-specific features"""
541 """Extension of the completer class with IPython-specific features"""
542
542
543 @observe('greedy')
543 @observe('greedy')
544 def _greedy_changed(self, change):
544 def _greedy_changed(self, change):
545 """update the splitter and readline delims when greedy is changed"""
545 """update the splitter and readline delims when greedy is changed"""
546 if change['new']:
546 if change['new']:
547 self.splitter.delims = GREEDY_DELIMS
547 self.splitter.delims = GREEDY_DELIMS
548 else:
548 else:
549 self.splitter.delims = DELIMS
549 self.splitter.delims = DELIMS
550
550
551 if self.readline:
551 if self.readline:
552 self.readline.set_completer_delims(self.splitter.delims)
552 self.readline.set_completer_delims(self.splitter.delims)
553
553
554 merge_completions = Bool(True,
554 merge_completions = Bool(True,
555 help="""Whether to merge completion results into a single list
555 help="""Whether to merge completion results into a single list
556
556
557 If False, only the completion results from the first non-empty
557 If False, only the completion results from the first non-empty
558 completer will be returned.
558 completer will be returned.
559 """
559 """
560 ).tag(config=True)
560 ).tag(config=True)
561 omit__names = Enum((0,1,2), default_value=2,
561 omit__names = Enum((0,1,2), default_value=2,
562 help="""Instruct the completer to omit private method names
562 help="""Instruct the completer to omit private method names
563
563
564 Specifically, when completing on ``object.<tab>``.
564 Specifically, when completing on ``object.<tab>``.
565
565
566 When 2 [default]: all names that start with '_' will be excluded.
566 When 2 [default]: all names that start with '_' will be excluded.
567
567
568 When 1: all 'magic' names (``__foo__``) will be excluded.
568 When 1: all 'magic' names (``__foo__``) will be excluded.
569
569
570 When 0: nothing will be excluded.
570 When 0: nothing will be excluded.
571 """
571 """
572 ).tag(config=True)
572 ).tag(config=True)
573 limit_to__all__ = Bool(False,
573 limit_to__all__ = Bool(False,
574 help="""
574 help="""
575 DEPRECATED as of version 5.0.
575 DEPRECATED as of version 5.0.
576
576
577 Instruct the completer to use __all__ for the completion
577 Instruct the completer to use __all__ for the completion
578
578
579 Specifically, when completing on ``object.<tab>``.
579 Specifically, when completing on ``object.<tab>``.
580
580
581 When True: only those names in obj.__all__ will be included.
581 When True: only those names in obj.__all__ will be included.
582
582
583 When False [default]: the __all__ attribute is ignored
583 When False [default]: the __all__ attribute is ignored
584 """,
584 """,
585 ).tag(config=True)
585 ).tag(config=True)
586
586
587 def __init__(self, shell=None, namespace=None, global_namespace=None,
587 def __init__(self, shell=None, namespace=None, global_namespace=None,
588 use_readline=True, config=None, **kwargs):
588 use_readline=True, config=None, **kwargs):
589 """IPCompleter() -> completer
589 """IPCompleter() -> completer
590
590
591 Return a completer object suitable for use by the readline library
591 Return a completer object suitable for use by the readline library
592 via readline.set_completer().
592 via readline.set_completer().
593
593
594 Inputs:
594 Inputs:
595
595
596 - shell: a pointer to the ipython shell itself. This is needed
596 - shell: a pointer to the ipython shell itself. This is needed
597 because this completer knows about magic functions, and those can
597 because this completer knows about magic functions, and those can
598 only be accessed via the ipython instance.
598 only be accessed via the ipython instance.
599
599
600 - namespace: an optional dict where completions are performed.
600 - namespace: an optional dict where completions are performed.
601
601
602 - global_namespace: secondary optional dict for completions, to
602 - global_namespace: secondary optional dict for completions, to
603 handle cases (such as IPython embedded inside functions) where
603 handle cases (such as IPython embedded inside functions) where
604 both Python scopes are visible.
604 both Python scopes are visible.
605
605
606 use_readline : bool, optional
606 use_readline : bool, optional
607 If true, use the readline library. This completer can still function
607 If true, use the readline library. This completer can still function
608 without readline, though in that case callers must provide some extra
608 without readline, though in that case callers must provide some extra
609 information on each call about the current line."""
609 information on each call about the current line."""
610
610
611 self.magic_escape = ESC_MAGIC
611 self.magic_escape = ESC_MAGIC
612 self.splitter = CompletionSplitter()
612 self.splitter = CompletionSplitter()
613
613
614 # Readline configuration, only used by the rlcompleter method.
614 # Readline configuration, only used by the rlcompleter method.
615 if use_readline:
615 if use_readline:
616 # We store the right version of readline so that later code
616 # We store the right version of readline so that later code
617 import IPython.utils.rlineimpl as readline
617 import IPython.utils.rlineimpl as readline
618 self.readline = readline
618 self.readline = readline
619 else:
619 else:
620 self.readline = None
620 self.readline = None
621
621
622 # _greedy_changed() depends on splitter and readline being defined:
622 # _greedy_changed() depends on splitter and readline being defined:
623 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
623 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
624 config=config, **kwargs)
624 config=config, **kwargs)
625
625
626 # List where completion matches will be stored
626 # List where completion matches will be stored
627 self.matches = []
627 self.matches = []
628 self.shell = shell
628 self.shell = shell
629 # Regexp to split filenames with spaces in them
629 # Regexp to split filenames with spaces in them
630 self.space_name_re = re.compile(r'([^\\] )')
630 self.space_name_re = re.compile(r'([^\\] )')
631 # Hold a local ref. to glob.glob for speed
631 # Hold a local ref. to glob.glob for speed
632 self.glob = glob.glob
632 self.glob = glob.glob
633
633
634 # Determine if we are running on 'dumb' terminals, like (X)Emacs
634 # Determine if we are running on 'dumb' terminals, like (X)Emacs
635 # buffers, to avoid completion problems.
635 # buffers, to avoid completion problems.
636 term = os.environ.get('TERM','xterm')
636 term = os.environ.get('TERM','xterm')
637 self.dumb_terminal = term in ['dumb','emacs']
637 self.dumb_terminal = term in ['dumb','emacs']
638
638
639 # Special handling of backslashes needed in win32 platforms
639 # Special handling of backslashes needed in win32 platforms
640 if sys.platform == "win32":
640 if sys.platform == "win32":
641 self.clean_glob = self._clean_glob_win32
641 self.clean_glob = self._clean_glob_win32
642 else:
642 else:
643 self.clean_glob = self._clean_glob
643 self.clean_glob = self._clean_glob
644
644
645 #regexp to parse docstring for function signature
645 #regexp to parse docstring for function signature
646 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
646 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
647 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
647 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
648 #use this if positional argument name is also needed
648 #use this if positional argument name is also needed
649 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
649 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
650
650
651 # All active matcher routines for completion
651 # All active matcher routines for completion
652 self.matchers = [
652 self.matchers = [
653 self.python_matches,
653 self.python_matches,
654 self.file_matches,
654 self.file_matches,
655 self.magic_matches,
655 self.magic_matches,
656 self.python_func_kw_matches,
656 self.python_func_kw_matches,
657 self.dict_key_matches,
657 self.dict_key_matches,
658 ]
658 ]
659
659
660 def all_completions(self, text):
660 def all_completions(self, text):
661 """
661 """
662 Wrapper around the complete method for the benefit of emacs.
662 Wrapper around the complete method for the benefit of emacs.
663 """
663 """
664 return self.complete(text)[1]
664 return self.complete(text)[1]
665
665
666 def _clean_glob(self, text):
666 def _clean_glob(self, text):
667 return self.glob("%s*" % text)
667 return self.glob("%s*" % text)
668
668
669 def _clean_glob_win32(self,text):
669 def _clean_glob_win32(self,text):
670 return [f.replace("\\","/")
670 return [f.replace("\\","/")
671 for f in self.glob("%s*" % text)]
671 for f in self.glob("%s*" % text)]
672
672
673 def file_matches(self, text):
673 def file_matches(self, text):
674 """Match filenames, expanding ~USER type strings.
674 """Match filenames, expanding ~USER type strings.
675
675
676 Most of the seemingly convoluted logic in this completer is an
676 Most of the seemingly convoluted logic in this completer is an
677 attempt to handle filenames with spaces in them. And yet it's not
677 attempt to handle filenames with spaces in them. And yet it's not
678 quite perfect, because Python's readline doesn't expose all of the
678 quite perfect, because Python's readline doesn't expose all of the
679 GNU readline details needed for this to be done correctly.
679 GNU readline details needed for this to be done correctly.
680
680
681 For a filename with a space in it, the printed completions will be
681 For a filename with a space in it, the printed completions will be
682 only the parts after what's already been typed (instead of the
682 only the parts after what's already been typed (instead of the
683 full completions, as is normally done). I don't think with the
683 full completions, as is normally done). I don't think with the
684 current (as of Python 2.3) Python readline it's possible to do
684 current (as of Python 2.3) Python readline it's possible to do
685 better."""
685 better."""
686
686
687 # chars that require escaping with backslash - i.e. chars
687 # chars that require escaping with backslash - i.e. chars
688 # that readline treats incorrectly as delimiters, but we
688 # that readline treats incorrectly as delimiters, but we
689 # don't want to treat as delimiters in filename matching
689 # don't want to treat as delimiters in filename matching
690 # when escaped with backslash
690 # when escaped with backslash
691 if text.startswith('!'):
691 if text.startswith('!'):
692 text = text[1:]
692 text = text[1:]
693 text_prefix = u'!'
693 text_prefix = u'!'
694 else:
694 else:
695 text_prefix = u''
695 text_prefix = u''
696
696
697 text_until_cursor = self.text_until_cursor
697 text_until_cursor = self.text_until_cursor
698 # track strings with open quotes
698 # track strings with open quotes
699 open_quotes = has_open_quotes(text_until_cursor)
699 open_quotes = has_open_quotes(text_until_cursor)
700
700
701 if '(' in text_until_cursor or '[' in text_until_cursor:
701 if '(' in text_until_cursor or '[' in text_until_cursor:
702 lsplit = text
702 lsplit = text
703 else:
703 else:
704 try:
704 try:
705 # arg_split ~ shlex.split, but with unicode bugs fixed by us
705 # arg_split ~ shlex.split, but with unicode bugs fixed by us
706 lsplit = arg_split(text_until_cursor)[-1]
706 lsplit = arg_split(text_until_cursor)[-1]
707 except ValueError:
707 except ValueError:
708 # typically an unmatched ", or backslash without escaped char.
708 # typically an unmatched ", or backslash without escaped char.
709 if open_quotes:
709 if open_quotes:
710 lsplit = text_until_cursor.split(open_quotes)[-1]
710 lsplit = text_until_cursor.split(open_quotes)[-1]
711 else:
711 else:
712 return []
712 return []
713 except IndexError:
713 except IndexError:
714 # tab pressed on empty line
714 # tab pressed on empty line
715 lsplit = ""
715 lsplit = ""
716
716
717 if not open_quotes and lsplit != protect_filename(lsplit):
717 if not open_quotes and lsplit != protect_filename(lsplit):
718 # if protectables are found, do matching on the whole escaped name
718 # if protectables are found, do matching on the whole escaped name
719 has_protectables = True
719 has_protectables = True
720 text0,text = text,lsplit
720 text0,text = text,lsplit
721 else:
721 else:
722 has_protectables = False
722 has_protectables = False
723 text = os.path.expanduser(text)
723 text = os.path.expanduser(text)
724
724
725 if text == "":
725 if text == "":
726 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
726 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
727
727
728 # Compute the matches from the filesystem
728 # Compute the matches from the filesystem
729 m0 = self.clean_glob(text.replace('\\',''))
729 m0 = self.clean_glob(text.replace('\\',''))
730
730
731 if has_protectables:
731 if has_protectables:
732 # If we had protectables, we need to revert our changes to the
732 # If we had protectables, we need to revert our changes to the
733 # beginning of filename so that we don't double-write the part
733 # beginning of filename so that we don't double-write the part
734 # of the filename we have so far
734 # of the filename we have so far
735 len_lsplit = len(lsplit)
735 len_lsplit = len(lsplit)
736 matches = [text_prefix + text0 +
736 matches = [text_prefix + text0 +
737 protect_filename(f[len_lsplit:]) for f in m0]
737 protect_filename(f[len_lsplit:]) for f in m0]
738 else:
738 else:
739 if open_quotes:
739 if open_quotes:
740 # if we have a string with an open quote, we don't need to
740 # if we have a string with an open quote, we don't need to
741 # protect the names at all (and we _shouldn't_, as it
741 # protect the names at all (and we _shouldn't_, as it
742 # would cause bugs when the filesystem call is made).
742 # would cause bugs when the filesystem call is made).
743 matches = m0
743 matches = m0
744 else:
744 else:
745 matches = [text_prefix +
745 matches = [text_prefix +
746 protect_filename(f) for f in m0]
746 protect_filename(f) for f in m0]
747
747
748 # Mark directories in input list by appending '/' to their names.
748 # Mark directories in input list by appending '/' to their names.
749 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
749 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
750
750
751 def magic_matches(self, text):
751 def magic_matches(self, text):
752 """Match magics"""
752 """Match magics"""
753 # Get all shell magics now rather than statically, so magics loaded at
753 # Get all shell magics now rather than statically, so magics loaded at
754 # runtime show up too.
754 # runtime show up too.
755 lsm = self.shell.magics_manager.lsmagic()
755 lsm = self.shell.magics_manager.lsmagic()
756 line_magics = lsm['line']
756 line_magics = lsm['line']
757 cell_magics = lsm['cell']
757 cell_magics = lsm['cell']
758 pre = self.magic_escape
758 pre = self.magic_escape
759 pre2 = pre+pre
759 pre2 = pre+pre
760
760
761 # Completion logic:
761 # Completion logic:
762 # - user gives %%: only do cell magics
762 # - user gives %%: only do cell magics
763 # - user gives %: do both line and cell magics
763 # - user gives %: do both line and cell magics
764 # - no prefix: do both
764 # - no prefix: do both
765 # In other words, line magics are skipped if the user gives %% explicitly
765 # In other words, line magics are skipped if the user gives %% explicitly
766 bare_text = text.lstrip(pre)
766 bare_text = text.lstrip(pre)
767 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
767 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
768 if not text.startswith(pre2):
768 if not text.startswith(pre2):
769 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
769 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
770 return [cast_unicode_py2(c) for c in comp]
770 return [cast_unicode_py2(c) for c in comp]
771
771
772
772
773 def python_matches(self, text):
773 def python_matches(self, text):
774 """Match attributes or global python names"""
774 """Match attributes or global python names"""
775 if "." in text:
775 if "." in text:
776 try:
776 try:
777 matches = self.attr_matches(text)
777 matches = self.attr_matches(text)
778 if text.endswith('.') and self.omit__names:
778 if text.endswith('.') and self.omit__names:
779 if self.omit__names == 1:
779 if self.omit__names == 1:
780 # true if txt is _not_ a __ name, false otherwise:
780 # true if txt is _not_ a __ name, false otherwise:
781 no__name = (lambda txt:
781 no__name = (lambda txt:
782 re.match(r'.*\.__.*?__',txt) is None)
782 re.match(r'.*\.__.*?__',txt) is None)
783 else:
783 else:
784 # true if txt is _not_ a _ name, false otherwise:
784 # true if txt is _not_ a _ name, false otherwise:
785 no__name = (lambda txt:
785 no__name = (lambda txt:
786 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
786 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
787 matches = filter(no__name, matches)
787 matches = filter(no__name, matches)
788 except NameError:
788 except NameError:
789 # catches <undefined attributes>.<tab>
789 # catches <undefined attributes>.<tab>
790 matches = []
790 matches = []
791 else:
791 else:
792 matches = self.global_matches(text)
792 matches = self.global_matches(text)
793 return matches
793 return matches
794
794
795 def _default_arguments_from_docstring(self, doc):
795 def _default_arguments_from_docstring(self, doc):
796 """Parse the first line of docstring for call signature.
796 """Parse the first line of docstring for call signature.
797
797
798 Docstring should be of the form 'min(iterable[, key=func])\n'.
798 Docstring should be of the form 'min(iterable[, key=func])\n'.
799 It can also parse cython docstring of the form
799 It can also parse cython docstring of the form
800 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
800 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
801 """
801 """
802 if doc is None:
802 if doc is None:
803 return []
803 return []
804
804
805 #care only the firstline
805 #care only the firstline
806 line = doc.lstrip().splitlines()[0]
806 line = doc.lstrip().splitlines()[0]
807
807
808 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
808 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
809 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
809 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
810 sig = self.docstring_sig_re.search(line)
810 sig = self.docstring_sig_re.search(line)
811 if sig is None:
811 if sig is None:
812 return []
812 return []
813 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
813 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
814 sig = sig.groups()[0].split(',')
814 sig = sig.groups()[0].split(',')
815 ret = []
815 ret = []
816 for s in sig:
816 for s in sig:
817 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
817 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
818 ret += self.docstring_kwd_re.findall(s)
818 ret += self.docstring_kwd_re.findall(s)
819 return ret
819 return ret
820
820
821 def _default_arguments(self, obj):
821 def _default_arguments(self, obj):
822 """Return the list of default arguments of obj if it is callable,
822 """Return the list of default arguments of obj if it is callable,
823 or empty list otherwise."""
823 or empty list otherwise."""
824 call_obj = obj
824 call_obj = obj
825 ret = []
825 ret = []
826 if inspect.isbuiltin(obj):
826 if inspect.isbuiltin(obj):
827 pass
827 pass
828 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
828 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
829 if inspect.isclass(obj):
829 if inspect.isclass(obj):
830 #for cython embededsignature=True the constructor docstring
830 #for cython embededsignature=True the constructor docstring
831 #belongs to the object itself not __init__
831 #belongs to the object itself not __init__
832 ret += self._default_arguments_from_docstring(
832 ret += self._default_arguments_from_docstring(
833 getattr(obj, '__doc__', ''))
833 getattr(obj, '__doc__', ''))
834 # for classes, check for __init__,__new__
834 # for classes, check for __init__,__new__
835 call_obj = (getattr(obj, '__init__', None) or
835 call_obj = (getattr(obj, '__init__', None) or
836 getattr(obj, '__new__', None))
836 getattr(obj, '__new__', None))
837 # for all others, check if they are __call__able
837 # for all others, check if they are __call__able
838 elif hasattr(obj, '__call__'):
838 elif hasattr(obj, '__call__'):
839 call_obj = obj.__call__
839 call_obj = obj.__call__
840 ret += self._default_arguments_from_docstring(
840 ret += self._default_arguments_from_docstring(
841 getattr(call_obj, '__doc__', ''))
841 getattr(call_obj, '__doc__', ''))
842
842
843 if PY3:
843 if PY3:
844 _keeps = (inspect.Parameter.KEYWORD_ONLY,
844 _keeps = (inspect.Parameter.KEYWORD_ONLY,
845 inspect.Parameter.POSITIONAL_OR_KEYWORD)
845 inspect.Parameter.POSITIONAL_OR_KEYWORD)
846 signature = inspect.signature
846 signature = inspect.signature
847 else:
847 else:
848 import IPython.utils.signatures
848 import IPython.utils.signatures
849 _keeps = (IPython.utils.signatures.Parameter.KEYWORD_ONLY,
849 _keeps = (IPython.utils.signatures.Parameter.KEYWORD_ONLY,
850 IPython.utils.signatures.Parameter.POSITIONAL_OR_KEYWORD)
850 IPython.utils.signatures.Parameter.POSITIONAL_OR_KEYWORD)
851 signature = IPython.utils.signatures.signature
851 signature = IPython.utils.signatures.signature
852
852
853 try:
853 try:
854 sig = signature(call_obj)
854 sig = signature(call_obj)
855 ret.extend(k for k, v in sig.parameters.items() if
855 ret.extend(k for k, v in sig.parameters.items() if
856 v.kind in _keeps)
856 v.kind in _keeps)
857 except ValueError:
857 except ValueError:
858 pass
858 pass
859
859
860 return list(set(ret))
860 return list(set(ret))
861
861
862 def python_func_kw_matches(self,text):
862 def python_func_kw_matches(self,text):
863 """Match named parameters (kwargs) of the last open function"""
863 """Match named parameters (kwargs) of the last open function"""
864
864
865 if "." in text: # a parameter cannot be dotted
865 if "." in text: # a parameter cannot be dotted
866 return []
866 return []
867 try: regexp = self.__funcParamsRegex
867 try: regexp = self.__funcParamsRegex
868 except AttributeError:
868 except AttributeError:
869 regexp = self.__funcParamsRegex = re.compile(r'''
869 regexp = self.__funcParamsRegex = re.compile(r'''
870 '.*?(?<!\\)' | # single quoted strings or
870 '.*?(?<!\\)' | # single quoted strings or
871 ".*?(?<!\\)" | # double quoted strings or
871 ".*?(?<!\\)" | # double quoted strings or
872 \w+ | # identifier
872 \w+ | # identifier
873 \S # other characters
873 \S # other characters
874 ''', re.VERBOSE | re.DOTALL)
874 ''', re.VERBOSE | re.DOTALL)
875 # 1. find the nearest identifier that comes before an unclosed
875 # 1. find the nearest identifier that comes before an unclosed
876 # parenthesis before the cursor
876 # parenthesis before the cursor
877 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
877 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
878 tokens = regexp.findall(self.text_until_cursor)
878 tokens = regexp.findall(self.text_until_cursor)
879 tokens.reverse()
879 tokens.reverse()
880 iterTokens = iter(tokens); openPar = 0
880 iterTokens = iter(tokens); openPar = 0
881
881
882 for token in iterTokens:
882 for token in iterTokens:
883 if token == ')':
883 if token == ')':
884 openPar -= 1
884 openPar -= 1
885 elif token == '(':
885 elif token == '(':
886 openPar += 1
886 openPar += 1
887 if openPar > 0:
887 if openPar > 0:
888 # found the last unclosed parenthesis
888 # found the last unclosed parenthesis
889 break
889 break
890 else:
890 else:
891 return []
891 return []
892 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
892 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
893 ids = []
893 ids = []
894 isId = re.compile(r'\w+$').match
894 isId = re.compile(r'\w+$').match
895
895
896 while True:
896 while True:
897 try:
897 try:
898 ids.append(next(iterTokens))
898 ids.append(next(iterTokens))
899 if not isId(ids[-1]):
899 if not isId(ids[-1]):
900 ids.pop(); break
900 ids.pop(); break
901 if not next(iterTokens) == '.':
901 if not next(iterTokens) == '.':
902 break
902 break
903 except StopIteration:
903 except StopIteration:
904 break
904 break
905 # lookup the candidate callable matches either using global_matches
905 # lookup the candidate callable matches either using global_matches
906 # or attr_matches for dotted names
906 # or attr_matches for dotted names
907 if len(ids) == 1:
907 if len(ids) == 1:
908 callableMatches = self.global_matches(ids[0])
908 callableMatches = self.global_matches(ids[0])
909 else:
909 else:
910 callableMatches = self.attr_matches('.'.join(ids[::-1]))
910 callableMatches = self.attr_matches('.'.join(ids[::-1]))
911 argMatches = []
911 argMatches = []
912 for callableMatch in callableMatches:
912 for callableMatch in callableMatches:
913 try:
913 try:
914 namedArgs = self._default_arguments(eval(callableMatch,
914 namedArgs = self._default_arguments(eval(callableMatch,
915 self.namespace))
915 self.namespace))
916 except:
916 except:
917 continue
917 continue
918
918
919 for namedArg in namedArgs:
919 for namedArg in namedArgs:
920 if namedArg.startswith(text):
920 if namedArg.startswith(text):
921 argMatches.append(u"%s=" %namedArg)
921 argMatches.append(u"%s=" %namedArg)
922 return argMatches
922 return argMatches
923
923
924 def dict_key_matches(self, text):
924 def dict_key_matches(self, text):
925 "Match string keys in a dictionary, after e.g. 'foo[' "
925 "Match string keys in a dictionary, after e.g. 'foo[' "
926 def get_keys(obj):
926 def get_keys(obj):
927 # Objects can define their own completions by defining an
927 # Objects can define their own completions by defining an
928 # _ipy_key_completions_() method.
928 # _ipy_key_completions_() method.
929 method = get_real_method(obj, '_ipython_key_completions_')
929 method = get_real_method(obj, '_ipython_key_completions_')
930 if method is not None:
930 if method is not None:
931 return method()
931 return method()
932
932
933 # Special case some common in-memory dict-like types
933 # Special case some common in-memory dict-like types
934 if isinstance(obj, dict) or\
934 if isinstance(obj, dict) or\
935 _safe_isinstance(obj, 'pandas', 'DataFrame'):
935 _safe_isinstance(obj, 'pandas', 'DataFrame'):
936 try:
936 try:
937 return list(obj.keys())
937 return list(obj.keys())
938 except Exception:
938 except Exception:
939 return []
939 return []
940 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
940 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
941 _safe_isinstance(obj, 'numpy', 'void'):
941 _safe_isinstance(obj, 'numpy', 'void'):
942 return obj.dtype.names or []
942 return obj.dtype.names or []
943 return []
943 return []
944
944
945 try:
945 try:
946 regexps = self.__dict_key_regexps
946 regexps = self.__dict_key_regexps
947 except AttributeError:
947 except AttributeError:
948 dict_key_re_fmt = r'''(?x)
948 dict_key_re_fmt = r'''(?x)
949 ( # match dict-referring expression wrt greedy setting
949 ( # match dict-referring expression wrt greedy setting
950 %s
950 %s
951 )
951 )
952 \[ # open bracket
952 \[ # open bracket
953 \s* # and optional whitespace
953 \s* # and optional whitespace
954 ([uUbB]? # string prefix (r not handled)
954 ([uUbB]? # string prefix (r not handled)
955 (?: # unclosed string
955 (?: # unclosed string
956 '(?:[^']|(?<!\\)\\')*
956 '(?:[^']|(?<!\\)\\')*
957 |
957 |
958 "(?:[^"]|(?<!\\)\\")*
958 "(?:[^"]|(?<!\\)\\")*
959 )
959 )
960 )?
960 )?
961 $
961 $
962 '''
962 '''
963 regexps = self.__dict_key_regexps = {
963 regexps = self.__dict_key_regexps = {
964 False: re.compile(dict_key_re_fmt % '''
964 False: re.compile(dict_key_re_fmt % '''
965 # identifiers separated by .
965 # identifiers separated by .
966 (?!\d)\w+
966 (?!\d)\w+
967 (?:\.(?!\d)\w+)*
967 (?:\.(?!\d)\w+)*
968 '''),
968 '''),
969 True: re.compile(dict_key_re_fmt % '''
969 True: re.compile(dict_key_re_fmt % '''
970 .+
970 .+
971 ''')
971 ''')
972 }
972 }
973
973
974 match = regexps[self.greedy].search(self.text_until_cursor)
974 match = regexps[self.greedy].search(self.text_until_cursor)
975 if match is None:
975 if match is None:
976 return []
976 return []
977
977
978 expr, prefix = match.groups()
978 expr, prefix = match.groups()
979 try:
979 try:
980 obj = eval(expr, self.namespace)
980 obj = eval(expr, self.namespace)
981 except Exception:
981 except Exception:
982 try:
982 try:
983 obj = eval(expr, self.global_namespace)
983 obj = eval(expr, self.global_namespace)
984 except Exception:
984 except Exception:
985 return []
985 return []
986
986
987 keys = get_keys(obj)
987 keys = get_keys(obj)
988 if not keys:
988 if not keys:
989 return keys
989 return keys
990 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
990 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
991 if not matches:
991 if not matches:
992 return matches
992 return matches
993
993
994 # get the cursor position of
994 # get the cursor position of
995 # - the text being completed
995 # - the text being completed
996 # - the start of the key text
996 # - the start of the key text
997 # - the start of the completion
997 # - the start of the completion
998 text_start = len(self.text_until_cursor) - len(text)
998 text_start = len(self.text_until_cursor) - len(text)
999 if prefix:
999 if prefix:
1000 key_start = match.start(2)
1000 key_start = match.start(2)
1001 completion_start = key_start + token_offset
1001 completion_start = key_start + token_offset
1002 else:
1002 else:
1003 key_start = completion_start = match.end()
1003 key_start = completion_start = match.end()
1004
1004
1005 # grab the leading prefix, to make sure all completions start with `text`
1005 # grab the leading prefix, to make sure all completions start with `text`
1006 if text_start > key_start:
1006 if text_start > key_start:
1007 leading = ''
1007 leading = ''
1008 else:
1008 else:
1009 leading = text[text_start:completion_start]
1009 leading = text[text_start:completion_start]
1010
1010
1011 # the index of the `[` character
1011 # the index of the `[` character
1012 bracket_idx = match.end(1)
1012 bracket_idx = match.end(1)
1013
1013
1014 # append closing quote and bracket as appropriate
1014 # append closing quote and bracket as appropriate
1015 # this is *not* appropriate if the opening quote or bracket is outside
1015 # this is *not* appropriate if the opening quote or bracket is outside
1016 # the text given to this method
1016 # the text given to this method
1017 suf = ''
1017 suf = ''
1018 continuation = self.line_buffer[len(self.text_until_cursor):]
1018 continuation = self.line_buffer[len(self.text_until_cursor):]
1019 if key_start > text_start and closing_quote:
1019 if key_start > text_start and closing_quote:
1020 # quotes were opened inside text, maybe close them
1020 # quotes were opened inside text, maybe close them
1021 if continuation.startswith(closing_quote):
1021 if continuation.startswith(closing_quote):
1022 continuation = continuation[len(closing_quote):]
1022 continuation = continuation[len(closing_quote):]
1023 else:
1023 else:
1024 suf += closing_quote
1024 suf += closing_quote
1025 if bracket_idx > text_start:
1025 if bracket_idx > text_start:
1026 # brackets were opened inside text, maybe close them
1026 # brackets were opened inside text, maybe close them
1027 if not continuation.startswith(']'):
1027 if not continuation.startswith(']'):
1028 suf += ']'
1028 suf += ']'
1029
1029
1030 return [leading + k + suf for k in matches]
1030 return [leading + k + suf for k in matches]
1031
1031
1032 def unicode_name_matches(self, text):
1032 def unicode_name_matches(self, text):
1033 u"""Match Latex-like syntax for unicode characters base
1033 u"""Match Latex-like syntax for unicode characters base
1034 on the name of the character.
1034 on the name of the character.
1035
1035
1036 This does \\GREEK SMALL LETTER ETA -> Ξ·
1036 This does \\GREEK SMALL LETTER ETA -> Ξ·
1037
1037
1038 Works only on valid python 3 identifier, or on combining characters that
1038 Works only on valid python 3 identifier, or on combining characters that
1039 will combine to form a valid identifier.
1039 will combine to form a valid identifier.
1040
1040
1041 Used on Python 3 only.
1041 Used on Python 3 only.
1042 """
1042 """
1043 slashpos = text.rfind('\\')
1043 slashpos = text.rfind('\\')
1044 if slashpos > -1:
1044 if slashpos > -1:
1045 s = text[slashpos+1:]
1045 s = text[slashpos+1:]
1046 try :
1046 try :
1047 unic = unicodedata.lookup(s)
1047 unic = unicodedata.lookup(s)
1048 # allow combining chars
1048 # allow combining chars
1049 if ('a'+unic).isidentifier():
1049 if ('a'+unic).isidentifier():
1050 return '\\'+s,[unic]
1050 return '\\'+s,[unic]
1051 except KeyError:
1051 except KeyError:
1052 pass
1052 pass
1053 return u'', []
1053 return u'', []
1054
1054
1055
1055
1056
1056
1057
1057
1058 def latex_matches(self, text):
1058 def latex_matches(self, text):
1059 u"""Match Latex syntax for unicode characters.
1059 u"""Match Latex syntax for unicode characters.
1060
1060
1061 This does both \\alp -> \\alpha and \\alpha -> Ξ±
1061 This does both \\alp -> \\alpha and \\alpha -> Ξ±
1062
1062
1063 Used on Python 3 only.
1063 Used on Python 3 only.
1064 """
1064 """
1065 slashpos = text.rfind('\\')
1065 slashpos = text.rfind('\\')
1066 if slashpos > -1:
1066 if slashpos > -1:
1067 s = text[slashpos:]
1067 s = text[slashpos:]
1068 if s in latex_symbols:
1068 if s in latex_symbols:
1069 # Try to complete a full latex symbol to unicode
1069 # Try to complete a full latex symbol to unicode
1070 # \\alpha -> Ξ±
1070 # \\alpha -> Ξ±
1071 return s, [latex_symbols[s]]
1071 return s, [latex_symbols[s]]
1072 else:
1072 else:
1073 # If a user has partially typed a latex symbol, give them
1073 # If a user has partially typed a latex symbol, give them
1074 # a full list of options \al -> [\aleph, \alpha]
1074 # a full list of options \al -> [\aleph, \alpha]
1075 matches = [k for k in latex_symbols if k.startswith(s)]
1075 matches = [k for k in latex_symbols if k.startswith(s)]
1076 return s, matches
1076 return s, matches
1077 return u'', []
1077 return u'', []
1078
1078
1079 def dispatch_custom_completer(self, text):
1079 def dispatch_custom_completer(self, text):
1080 line = self.line_buffer
1080 line = self.line_buffer
1081 if not line.strip():
1081 if not line.strip():
1082 return None
1082 return None
1083
1083
1084 # Create a little structure to pass all the relevant information about
1084 # Create a little structure to pass all the relevant information about
1085 # the current completion to any custom completer.
1085 # the current completion to any custom completer.
1086 event = Bunch()
1086 event = Bunch()
1087 event.line = line
1087 event.line = line
1088 event.symbol = text
1088 event.symbol = text
1089 cmd = line.split(None,1)[0]
1089 cmd = line.split(None,1)[0]
1090 event.command = cmd
1090 event.command = cmd
1091 event.text_until_cursor = self.text_until_cursor
1091 event.text_until_cursor = self.text_until_cursor
1092
1092
1093 # for foo etc, try also to find completer for %foo
1093 # for foo etc, try also to find completer for %foo
1094 if not cmd.startswith(self.magic_escape):
1094 if not cmd.startswith(self.magic_escape):
1095 try_magic = self.custom_completers.s_matches(
1095 try_magic = self.custom_completers.s_matches(
1096 self.magic_escape + cmd)
1096 self.magic_escape + cmd)
1097 else:
1097 else:
1098 try_magic = []
1098 try_magic = []
1099
1099
1100 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1100 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1101 try_magic,
1101 try_magic,
1102 self.custom_completers.flat_matches(self.text_until_cursor)):
1102 self.custom_completers.flat_matches(self.text_until_cursor)):
1103 try:
1103 try:
1104 res = c(event)
1104 res = c(event)
1105 if res:
1105 if res:
1106 # first, try case sensitive match
1106 # first, try case sensitive match
1107 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1107 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1108 if withcase:
1108 if withcase:
1109 return withcase
1109 return withcase
1110 # if none, then case insensitive ones are ok too
1110 # if none, then case insensitive ones are ok too
1111 text_low = text.lower()
1111 text_low = text.lower()
1112 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1112 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1113 except TryNext:
1113 except TryNext:
1114 pass
1114 pass
1115
1115
1116 return None
1116 return None
1117
1117
1118 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1118 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1119 """Find completions for the given text and line context.
1119 """Find completions for the given text and line context.
1120
1120
1121 Note that both the text and the line_buffer are optional, but at least
1121 Note that both the text and the line_buffer are optional, but at least
1122 one of them must be given.
1122 one of them must be given.
1123
1123
1124 Parameters
1124 Parameters
1125 ----------
1125 ----------
1126 text : string, optional
1126 text : string, optional
1127 Text to perform the completion on. If not given, the line buffer
1127 Text to perform the completion on. If not given, the line buffer
1128 is split using the instance's CompletionSplitter object.
1128 is split using the instance's CompletionSplitter object.
1129
1129
1130 line_buffer : string, optional
1130 line_buffer : string, optional
1131 If not given, the completer attempts to obtain the current line
1131 If not given, the completer attempts to obtain the current line
1132 buffer via readline. This keyword allows clients which are
1132 buffer via readline. This keyword allows clients which are
1133 requesting for text completions in non-readline contexts to inform
1133 requesting for text completions in non-readline contexts to inform
1134 the completer of the entire text.
1134 the completer of the entire text.
1135
1135
1136 cursor_pos : int, optional
1136 cursor_pos : int, optional
1137 Index of the cursor in the full line buffer. Should be provided by
1137 Index of the cursor in the full line buffer. Should be provided by
1138 remote frontends where kernel has no access to frontend state.
1138 remote frontends where kernel has no access to frontend state.
1139
1139
1140 Returns
1140 Returns
1141 -------
1141 -------
1142 text : str
1142 text : str
1143 Text that was actually used in the completion.
1143 Text that was actually used in the completion.
1144
1144
1145 matches : list
1145 matches : list
1146 A list of completion matches.
1146 A list of completion matches.
1147 """
1147 """
1148 # if the cursor position isn't given, the only sane assumption we can
1148 # if the cursor position isn't given, the only sane assumption we can
1149 # make is that it's at the end of the line (the common case)
1149 # make is that it's at the end of the line (the common case)
1150 if cursor_pos is None:
1150 if cursor_pos is None:
1151 cursor_pos = len(line_buffer) if text is None else len(text)
1151 cursor_pos = len(line_buffer) if text is None else len(text)
1152
1152
1153 if PY3:
1153 if PY3:
1154
1154
1155 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1155 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1156 latex_text, latex_matches = self.latex_matches(base_text)
1156 latex_text, latex_matches = self.latex_matches(base_text)
1157 if latex_matches:
1157 if latex_matches:
1158 return latex_text, latex_matches
1158 return latex_text, latex_matches
1159 name_text = ''
1159 name_text = ''
1160 name_matches = []
1160 name_matches = []
1161 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1161 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1162 name_text, name_matches = meth(base_text)
1162 name_text, name_matches = meth(base_text)
1163 if name_text:
1163 if name_text:
1164 return name_text, name_matches
1164 return name_text, name_matches
1165
1165
1166 # if text is either None or an empty string, rely on the line buffer
1166 # if text is either None or an empty string, rely on the line buffer
1167 if not text:
1167 if not text:
1168 text = self.splitter.split_line(line_buffer, cursor_pos)
1168 text = self.splitter.split_line(line_buffer, cursor_pos)
1169
1169
1170 # If no line buffer is given, assume the input text is all there was
1170 # If no line buffer is given, assume the input text is all there was
1171 if line_buffer is None:
1171 if line_buffer is None:
1172 line_buffer = text
1172 line_buffer = text
1173
1173
1174 self.line_buffer = line_buffer
1174 self.line_buffer = line_buffer
1175 self.text_until_cursor = self.line_buffer[:cursor_pos]
1175 self.text_until_cursor = self.line_buffer[:cursor_pos]
1176
1176
1177 # Start with a clean slate of completions
1177 # Start with a clean slate of completions
1178 self.matches[:] = []
1178 self.matches[:] = []
1179 custom_res = self.dispatch_custom_completer(text)
1179 custom_res = self.dispatch_custom_completer(text)
1180 if custom_res is not None:
1180 if custom_res is not None:
1181 # did custom completers produce something?
1181 # did custom completers produce something?
1182 self.matches = custom_res
1182 self.matches = custom_res
1183 else:
1183 else:
1184 # Extend the list of completions with the results of each
1184 # Extend the list of completions with the results of each
1185 # matcher, so we return results to the user from all
1185 # matcher, so we return results to the user from all
1186 # namespaces.
1186 # namespaces.
1187 if self.merge_completions:
1187 if self.merge_completions:
1188 self.matches = []
1188 self.matches = []
1189 for matcher in self.matchers:
1189 for matcher in self.matchers:
1190 try:
1190 try:
1191 self.matches.extend(matcher(text))
1191 self.matches.extend(matcher(text))
1192 except:
1192 except:
1193 # Show the ugly traceback if the matcher causes an
1193 # Show the ugly traceback if the matcher causes an
1194 # exception, but do NOT crash the kernel!
1194 # exception, but do NOT crash the kernel!
1195 sys.excepthook(*sys.exc_info())
1195 sys.excepthook(*sys.exc_info())
1196 else:
1196 else:
1197 for matcher in self.matchers:
1197 for matcher in self.matchers:
1198 self.matches = matcher(text)
1198 self.matches = matcher(text)
1199 if self.matches:
1199 if self.matches:
1200 break
1200 break
1201 # FIXME: we should extend our api to return a dict with completions for
1201 # FIXME: we should extend our api to return a dict with completions for
1202 # different types of objects. The rlcomplete() method could then
1202 # different types of objects. The rlcomplete() method could then
1203 # simply collapse the dict into a list for readline, but we'd have
1203 # simply collapse the dict into a list for readline, but we'd have
1204 # richer completion semantics in other evironments.
1204 # richer completion semantics in other evironments.
1205 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1205 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1206
1206
1207 return text, self.matches
1207 return text, self.matches
1208
1208
1209 def rlcomplete(self, text, state):
1209 def rlcomplete(self, text, state):
1210 """Return the state-th possible completion for 'text'.
1210 """Return the state-th possible completion for 'text'.
1211
1211
1212 This is called successively with state == 0, 1, 2, ... until it
1212 This is called successively with state == 0, 1, 2, ... until it
1213 returns None. The completion should begin with 'text'.
1213 returns None. The completion should begin with 'text'.
1214
1214
1215 Parameters
1215 Parameters
1216 ----------
1216 ----------
1217 text : string
1217 text : string
1218 Text to perform the completion on.
1218 Text to perform the completion on.
1219
1219
1220 state : int
1220 state : int
1221 Counter used by readline.
1221 Counter used by readline.
1222 """
1222 """
1223 if state==0:
1223 if state==0:
1224
1224
1225 self.line_buffer = line_buffer = self.readline.get_line_buffer()
1225 self.line_buffer = line_buffer = self.readline.get_line_buffer()
1226 cursor_pos = self.readline.get_endidx()
1226 cursor_pos = self.readline.get_endidx()
1227
1227
1228 #io.rprint("\nRLCOMPLETE: %r %r %r" %
1228 #io.rprint("\nRLCOMPLETE: %r %r %r" %
1229 # (text, line_buffer, cursor_pos) ) # dbg
1229 # (text, line_buffer, cursor_pos) ) # dbg
1230
1230
1231 # if there is only a tab on a line with only whitespace, instead of
1231 # if there is only a tab on a line with only whitespace, instead of
1232 # the mostly useless 'do you want to see all million completions'
1232 # the mostly useless 'do you want to see all million completions'
1233 # message, just do the right thing and give the user his tab!
1233 # message, just do the right thing and give the user his tab!
1234 # Incidentally, this enables pasting of tabbed text from an editor
1234 # Incidentally, this enables pasting of tabbed text from an editor
1235 # (as long as autoindent is off).
1235 # (as long as autoindent is off).
1236
1236
1237 # It should be noted that at least pyreadline still shows file
1237 # It should be noted that at least pyreadline still shows file
1238 # completions - is there a way around it?
1238 # completions - is there a way around it?
1239
1239
1240 # don't apply this on 'dumb' terminals, such as emacs buffers, so
1240 # don't apply this on 'dumb' terminals, such as emacs buffers, so
1241 # we don't interfere with their own tab-completion mechanism.
1241 # we don't interfere with their own tab-completion mechanism.
1242 if not (self.dumb_terminal or line_buffer.strip()):
1242 if not (self.dumb_terminal or line_buffer.strip()):
1243 self.readline.insert_text('\t')
1243 self.readline.insert_text('\t')
1244 sys.stdout.flush()
1244 sys.stdout.flush()
1245 return None
1245 return None
1246
1246
1247 # Note: debugging exceptions that may occur in completion is very
1247 # Note: debugging exceptions that may occur in completion is very
1248 # tricky, because readline unconditionally silences them. So if
1248 # tricky, because readline unconditionally silences them. So if
1249 # during development you suspect a bug in the completion code, turn
1249 # during development you suspect a bug in the completion code, turn
1250 # this flag on temporarily by uncommenting the second form (don't
1250 # this flag on temporarily by uncommenting the second form (don't
1251 # flip the value in the first line, as the '# dbg' marker can be
1251 # flip the value in the first line, as the '# dbg' marker can be
1252 # automatically detected and is used elsewhere).
1252 # automatically detected and is used elsewhere).
1253 DEBUG = False
1253 DEBUG = False
1254 #DEBUG = True # dbg
1254 #DEBUG = True # dbg
1255 if DEBUG:
1255 if DEBUG:
1256 try:
1256 try:
1257 self.complete(text, line_buffer, cursor_pos)
1257 self.complete(text, line_buffer, cursor_pos)
1258 except:
1258 except:
1259 import traceback; traceback.print_exc()
1259 import traceback; traceback.print_exc()
1260 else:
1260 else:
1261 # The normal production version is here
1261 # The normal production version is here
1262
1262
1263 # This method computes the self.matches array
1263 # This method computes the self.matches array
1264 self.complete(text, line_buffer, cursor_pos)
1264 self.complete(text, line_buffer, cursor_pos)
1265
1265
1266 try:
1266 try:
1267 return self.matches[state]
1267 return self.matches[state]
1268 except IndexError:
1268 except IndexError:
1269 return None
1269 return None
1270
1270
@@ -1,449 +1,452 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Utilities for path handling.
3 Utilities for path handling.
4 """
4 """
5
5
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 import os
9 import os
10 import sys
10 import sys
11 import errno
11 import errno
12 import shutil
12 import shutil
13 import random
13 import random
14 import tempfile
14 import tempfile
15 import glob
15 import glob
16 from warnings import warn
16 from warnings import warn
17 from hashlib import md5
17 from hashlib import md5
18
18
19 from IPython.utils.process import system
19 from IPython.utils.process import system
20 from IPython.utils import py3compat
20 from IPython.utils import py3compat
21 from IPython.utils.decorators import undoc
21 from IPython.utils.decorators import undoc
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Code
24 # Code
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 fs_encoding = sys.getfilesystemencoding()
27 fs_encoding = sys.getfilesystemencoding()
28
28
29 def _writable_dir(path):
29 def _writable_dir(path):
30 """Whether `path` is a directory, to which the user has write access."""
30 """Whether `path` is a directory, to which the user has write access."""
31 return os.path.isdir(path) and os.access(path, os.W_OK)
31 return os.path.isdir(path) and os.access(path, os.W_OK)
32
32
33 if sys.platform == 'win32':
33 if sys.platform == 'win32':
34 def _get_long_path_name(path):
34 def _get_long_path_name(path):
35 """Get a long path name (expand ~) on Windows using ctypes.
35 """Get a long path name (expand ~) on Windows using ctypes.
36
36
37 Examples
37 Examples
38 --------
38 --------
39
39
40 >>> get_long_path_name('c:\\docume~1')
40 >>> get_long_path_name('c:\\docume~1')
41 u'c:\\\\Documents and Settings'
41 u'c:\\\\Documents and Settings'
42
42
43 """
43 """
44 try:
44 try:
45 import ctypes
45 import ctypes
46 except ImportError:
46 except ImportError:
47 raise ImportError('you need to have ctypes installed for this to work')
47 raise ImportError('you need to have ctypes installed for this to work')
48 _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
48 _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
49 _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
49 _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
50 ctypes.c_uint ]
50 ctypes.c_uint ]
51
51
52 buf = ctypes.create_unicode_buffer(260)
52 buf = ctypes.create_unicode_buffer(260)
53 rv = _GetLongPathName(path, buf, 260)
53 rv = _GetLongPathName(path, buf, 260)
54 if rv == 0 or rv > 260:
54 if rv == 0 or rv > 260:
55 return path
55 return path
56 else:
56 else:
57 return buf.value
57 return buf.value
58 else:
58 else:
59 def _get_long_path_name(path):
59 def _get_long_path_name(path):
60 """Dummy no-op."""
60 """Dummy no-op."""
61 return path
61 return path
62
62
63
63
64
64
65 def get_long_path_name(path):
65 def get_long_path_name(path):
66 """Expand a path into its long form.
66 """Expand a path into its long form.
67
67
68 On Windows this expands any ~ in the paths. On other platforms, it is
68 On Windows this expands any ~ in the paths. On other platforms, it is
69 a null operation.
69 a null operation.
70 """
70 """
71 return _get_long_path_name(path)
71 return _get_long_path_name(path)
72
72
73
73
74 def unquote_filename(name, win32=(sys.platform=='win32')):
74 def unquote_filename(name, win32=(sys.platform=='win32')):
75 """ On Windows, remove leading and trailing quotes from filenames.
75 """ On Windows, remove leading and trailing quotes from filenames.
76
77 This function has been deprecated and should not be used any more:
78 unquoting is now taken care of by :func:`IPython.utils.process.arg_split`.
76 """
79 """
77 warn("'unquote_filename' is deprecated", DeprecationWarning)
80 warn("'unquote_filename' is deprecated", DeprecationWarning)
78 if win32:
81 if win32:
79 if name.startswith(("'", '"')) and name.endswith(("'", '"')):
82 if name.startswith(("'", '"')) and name.endswith(("'", '"')):
80 name = name[1:-1]
83 name = name[1:-1]
81 return name
84 return name
82
85
83
86
84 def compress_user(path):
87 def compress_user(path):
85 """Reverse of :func:`os.path.expanduser`
88 """Reverse of :func:`os.path.expanduser`
86 """
89 """
87 path = py3compat.unicode_to_str(path, sys.getfilesystemencoding())
90 path = py3compat.unicode_to_str(path, sys.getfilesystemencoding())
88 home = os.path.expanduser('~')
91 home = os.path.expanduser('~')
89 if path.startswith(home):
92 if path.startswith(home):
90 path = "~" + path[len(home):]
93 path = "~" + path[len(home):]
91 return path
94 return path
92
95
93 def get_py_filename(name, force_win32=None):
96 def get_py_filename(name, force_win32=None):
94 """Return a valid python filename in the current directory.
97 """Return a valid python filename in the current directory.
95
98
96 If the given name is not a file, it adds '.py' and searches again.
99 If the given name is not a file, it adds '.py' and searches again.
97 Raises IOError with an informative message if the file isn't found.
100 Raises IOError with an informative message if the file isn't found.
98
101
99 On Windows, apply Windows semantics to the filename. In particular, remove
102 On Windows, apply Windows semantics to the filename. In particular, remove
100 any quoting that has been applied to it. This option can be forced for
103 any quoting that has been applied to it. This option can be forced for
101 testing purposes.
104 testing purposes.
102 """
105 """
103
106
104 name = os.path.expanduser(name)
107 name = os.path.expanduser(name)
105 if force_win32 is None:
108 if force_win32 is None:
106 win32 = (sys.platform == 'win32')
109 win32 = (sys.platform == 'win32')
107 else:
110 else:
108 win32 = force_win32
111 win32 = force_win32
109 name = unquote_filename(name, win32=win32)
112 name = unquote_filename(name, win32=win32)
110 if not os.path.isfile(name) and not name.endswith('.py'):
113 if not os.path.isfile(name) and not name.endswith('.py'):
111 name += '.py'
114 name += '.py'
112 if os.path.isfile(name):
115 if os.path.isfile(name):
113 return name
116 return name
114 else:
117 else:
115 raise IOError('File `%r` not found.' % name)
118 raise IOError('File `%r` not found.' % name)
116
119
117
120
118 def filefind(filename, path_dirs=None):
121 def filefind(filename, path_dirs=None):
119 """Find a file by looking through a sequence of paths.
122 """Find a file by looking through a sequence of paths.
120
123
121 This iterates through a sequence of paths looking for a file and returns
124 This iterates through a sequence of paths looking for a file and returns
122 the full, absolute path of the first occurence of the file. If no set of
125 the full, absolute path of the first occurence of the file. If no set of
123 path dirs is given, the filename is tested as is, after running through
126 path dirs is given, the filename is tested as is, after running through
124 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
127 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
125
128
126 filefind('myfile.txt')
129 filefind('myfile.txt')
127
130
128 will find the file in the current working dir, but::
131 will find the file in the current working dir, but::
129
132
130 filefind('~/myfile.txt')
133 filefind('~/myfile.txt')
131
134
132 Will find the file in the users home directory. This function does not
135 Will find the file in the users home directory. This function does not
133 automatically try any paths, such as the cwd or the user's home directory.
136 automatically try any paths, such as the cwd or the user's home directory.
134
137
135 Parameters
138 Parameters
136 ----------
139 ----------
137 filename : str
140 filename : str
138 The filename to look for.
141 The filename to look for.
139 path_dirs : str, None or sequence of str
142 path_dirs : str, None or sequence of str
140 The sequence of paths to look for the file in. If None, the filename
143 The sequence of paths to look for the file in. If None, the filename
141 need to be absolute or be in the cwd. If a string, the string is
144 need to be absolute or be in the cwd. If a string, the string is
142 put into a sequence and the searched. If a sequence, walk through
145 put into a sequence and the searched. If a sequence, walk through
143 each element and join with ``filename``, calling :func:`expandvars`
146 each element and join with ``filename``, calling :func:`expandvars`
144 and :func:`expanduser` before testing for existence.
147 and :func:`expanduser` before testing for existence.
145
148
146 Returns
149 Returns
147 -------
150 -------
148 Raises :exc:`IOError` or returns absolute path to file.
151 Raises :exc:`IOError` or returns absolute path to file.
149 """
152 """
150
153
151 # If paths are quoted, abspath gets confused, strip them...
154 # If paths are quoted, abspath gets confused, strip them...
152 filename = filename.strip('"').strip("'")
155 filename = filename.strip('"').strip("'")
153 # If the input is an absolute path, just check it exists
156 # If the input is an absolute path, just check it exists
154 if os.path.isabs(filename) and os.path.isfile(filename):
157 if os.path.isabs(filename) and os.path.isfile(filename):
155 return filename
158 return filename
156
159
157 if path_dirs is None:
160 if path_dirs is None:
158 path_dirs = ("",)
161 path_dirs = ("",)
159 elif isinstance(path_dirs, py3compat.string_types):
162 elif isinstance(path_dirs, py3compat.string_types):
160 path_dirs = (path_dirs,)
163 path_dirs = (path_dirs,)
161
164
162 for path in path_dirs:
165 for path in path_dirs:
163 if path == '.': path = py3compat.getcwd()
166 if path == '.': path = py3compat.getcwd()
164 testname = expand_path(os.path.join(path, filename))
167 testname = expand_path(os.path.join(path, filename))
165 if os.path.isfile(testname):
168 if os.path.isfile(testname):
166 return os.path.abspath(testname)
169 return os.path.abspath(testname)
167
170
168 raise IOError("File %r does not exist in any of the search paths: %r" %
171 raise IOError("File %r does not exist in any of the search paths: %r" %
169 (filename, path_dirs) )
172 (filename, path_dirs) )
170
173
171
174
172 class HomeDirError(Exception):
175 class HomeDirError(Exception):
173 pass
176 pass
174
177
175
178
176 def get_home_dir(require_writable=False):
179 def get_home_dir(require_writable=False):
177 """Return the 'home' directory, as a unicode string.
180 """Return the 'home' directory, as a unicode string.
178
181
179 Uses os.path.expanduser('~'), and checks for writability.
182 Uses os.path.expanduser('~'), and checks for writability.
180
183
181 See stdlib docs for how this is determined.
184 See stdlib docs for how this is determined.
182 $HOME is first priority on *ALL* platforms.
185 $HOME is first priority on *ALL* platforms.
183
186
184 Parameters
187 Parameters
185 ----------
188 ----------
186
189
187 require_writable : bool [default: False]
190 require_writable : bool [default: False]
188 if True:
191 if True:
189 guarantees the return value is a writable directory, otherwise
192 guarantees the return value is a writable directory, otherwise
190 raises HomeDirError
193 raises HomeDirError
191 if False:
194 if False:
192 The path is resolved, but it is not guaranteed to exist or be writable.
195 The path is resolved, but it is not guaranteed to exist or be writable.
193 """
196 """
194
197
195 homedir = os.path.expanduser('~')
198 homedir = os.path.expanduser('~')
196 # Next line will make things work even when /home/ is a symlink to
199 # Next line will make things work even when /home/ is a symlink to
197 # /usr/home as it is on FreeBSD, for example
200 # /usr/home as it is on FreeBSD, for example
198 homedir = os.path.realpath(homedir)
201 homedir = os.path.realpath(homedir)
199
202
200 if not _writable_dir(homedir) and os.name == 'nt':
203 if not _writable_dir(homedir) and os.name == 'nt':
201 # expanduser failed, use the registry to get the 'My Documents' folder.
204 # expanduser failed, use the registry to get the 'My Documents' folder.
202 try:
205 try:
203 try:
206 try:
204 import winreg as wreg # Py 3
207 import winreg as wreg # Py 3
205 except ImportError:
208 except ImportError:
206 import _winreg as wreg # Py 2
209 import _winreg as wreg # Py 2
207 key = wreg.OpenKey(
210 key = wreg.OpenKey(
208 wreg.HKEY_CURRENT_USER,
211 wreg.HKEY_CURRENT_USER,
209 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
212 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
210 )
213 )
211 homedir = wreg.QueryValueEx(key,'Personal')[0]
214 homedir = wreg.QueryValueEx(key,'Personal')[0]
212 key.Close()
215 key.Close()
213 except:
216 except:
214 pass
217 pass
215
218
216 if (not require_writable) or _writable_dir(homedir):
219 if (not require_writable) or _writable_dir(homedir):
217 return py3compat.cast_unicode(homedir, fs_encoding)
220 return py3compat.cast_unicode(homedir, fs_encoding)
218 else:
221 else:
219 raise HomeDirError('%s is not a writable dir, '
222 raise HomeDirError('%s is not a writable dir, '
220 'set $HOME environment variable to override' % homedir)
223 'set $HOME environment variable to override' % homedir)
221
224
222 def get_xdg_dir():
225 def get_xdg_dir():
223 """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
226 """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
224
227
225 This is only for non-OS X posix (Linux,Unix,etc.) systems.
228 This is only for non-OS X posix (Linux,Unix,etc.) systems.
226 """
229 """
227
230
228 env = os.environ
231 env = os.environ
229
232
230 if os.name == 'posix' and sys.platform != 'darwin':
233 if os.name == 'posix' and sys.platform != 'darwin':
231 # Linux, Unix, AIX, etc.
234 # Linux, Unix, AIX, etc.
232 # use ~/.config if empty OR not set
235 # use ~/.config if empty OR not set
233 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
236 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
234 if xdg and _writable_dir(xdg):
237 if xdg and _writable_dir(xdg):
235 return py3compat.cast_unicode(xdg, fs_encoding)
238 return py3compat.cast_unicode(xdg, fs_encoding)
236
239
237 return None
240 return None
238
241
239
242
240 def get_xdg_cache_dir():
243 def get_xdg_cache_dir():
241 """Return the XDG_CACHE_HOME, if it is defined and exists, else None.
244 """Return the XDG_CACHE_HOME, if it is defined and exists, else None.
242
245
243 This is only for non-OS X posix (Linux,Unix,etc.) systems.
246 This is only for non-OS X posix (Linux,Unix,etc.) systems.
244 """
247 """
245
248
246 env = os.environ
249 env = os.environ
247
250
248 if os.name == 'posix' and sys.platform != 'darwin':
251 if os.name == 'posix' and sys.platform != 'darwin':
249 # Linux, Unix, AIX, etc.
252 # Linux, Unix, AIX, etc.
250 # use ~/.cache if empty OR not set
253 # use ~/.cache if empty OR not set
251 xdg = env.get("XDG_CACHE_HOME", None) or os.path.join(get_home_dir(), '.cache')
254 xdg = env.get("XDG_CACHE_HOME", None) or os.path.join(get_home_dir(), '.cache')
252 if xdg and _writable_dir(xdg):
255 if xdg and _writable_dir(xdg):
253 return py3compat.cast_unicode(xdg, fs_encoding)
256 return py3compat.cast_unicode(xdg, fs_encoding)
254
257
255 return None
258 return None
256
259
257
260
258 @undoc
261 @undoc
259 def get_ipython_dir():
262 def get_ipython_dir():
260 warn("get_ipython_dir has moved to the IPython.paths module")
263 warn("get_ipython_dir has moved to the IPython.paths module")
261 from IPython.paths import get_ipython_dir
264 from IPython.paths import get_ipython_dir
262 return get_ipython_dir()
265 return get_ipython_dir()
263
266
264 @undoc
267 @undoc
265 def get_ipython_cache_dir():
268 def get_ipython_cache_dir():
266 warn("get_ipython_cache_dir has moved to the IPython.paths module")
269 warn("get_ipython_cache_dir has moved to the IPython.paths module")
267 from IPython.paths import get_ipython_cache_dir
270 from IPython.paths import get_ipython_cache_dir
268 return get_ipython_cache_dir()
271 return get_ipython_cache_dir()
269
272
270 @undoc
273 @undoc
271 def get_ipython_package_dir():
274 def get_ipython_package_dir():
272 warn("get_ipython_package_dir has moved to the IPython.paths module")
275 warn("get_ipython_package_dir has moved to the IPython.paths module")
273 from IPython.paths import get_ipython_package_dir
276 from IPython.paths import get_ipython_package_dir
274 return get_ipython_package_dir()
277 return get_ipython_package_dir()
275
278
276 @undoc
279 @undoc
277 def get_ipython_module_path(module_str):
280 def get_ipython_module_path(module_str):
278 warn("get_ipython_module_path has moved to the IPython.paths module")
281 warn("get_ipython_module_path has moved to the IPython.paths module")
279 from IPython.paths import get_ipython_module_path
282 from IPython.paths import get_ipython_module_path
280 return get_ipython_module_path(module_str)
283 return get_ipython_module_path(module_str)
281
284
282 @undoc
285 @undoc
283 def locate_profile(profile='default'):
286 def locate_profile(profile='default'):
284 warn("locate_profile has moved to the IPython.paths module")
287 warn("locate_profile has moved to the IPython.paths module")
285 from IPython.paths import locate_profile
288 from IPython.paths import locate_profile
286 return locate_profile(profile=profile)
289 return locate_profile(profile=profile)
287
290
288 def expand_path(s):
291 def expand_path(s):
289 """Expand $VARS and ~names in a string, like a shell
292 """Expand $VARS and ~names in a string, like a shell
290
293
291 :Examples:
294 :Examples:
292
295
293 In [2]: os.environ['FOO']='test'
296 In [2]: os.environ['FOO']='test'
294
297
295 In [3]: expand_path('variable FOO is $FOO')
298 In [3]: expand_path('variable FOO is $FOO')
296 Out[3]: 'variable FOO is test'
299 Out[3]: 'variable FOO is test'
297 """
300 """
298 # This is a pretty subtle hack. When expand user is given a UNC path
301 # This is a pretty subtle hack. When expand user is given a UNC path
299 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
302 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
300 # the $ to get (\\server\share\%username%). I think it considered $
303 # the $ to get (\\server\share\%username%). I think it considered $
301 # alone an empty var. But, we need the $ to remains there (it indicates
304 # alone an empty var. But, we need the $ to remains there (it indicates
302 # a hidden share).
305 # a hidden share).
303 if os.name=='nt':
306 if os.name=='nt':
304 s = s.replace('$\\', 'IPYTHON_TEMP')
307 s = s.replace('$\\', 'IPYTHON_TEMP')
305 s = os.path.expandvars(os.path.expanduser(s))
308 s = os.path.expandvars(os.path.expanduser(s))
306 if os.name=='nt':
309 if os.name=='nt':
307 s = s.replace('IPYTHON_TEMP', '$\\')
310 s = s.replace('IPYTHON_TEMP', '$\\')
308 return s
311 return s
309
312
310
313
311 def unescape_glob(string):
314 def unescape_glob(string):
312 """Unescape glob pattern in `string`."""
315 """Unescape glob pattern in `string`."""
313 def unescape(s):
316 def unescape(s):
314 for pattern in '*[]!?':
317 for pattern in '*[]!?':
315 s = s.replace(r'\{0}'.format(pattern), pattern)
318 s = s.replace(r'\{0}'.format(pattern), pattern)
316 return s
319 return s
317 return '\\'.join(map(unescape, string.split('\\\\')))
320 return '\\'.join(map(unescape, string.split('\\\\')))
318
321
319
322
320 def shellglob(args):
323 def shellglob(args):
321 """
324 """
322 Do glob expansion for each element in `args` and return a flattened list.
325 Do glob expansion for each element in `args` and return a flattened list.
323
326
324 Unmatched glob pattern will remain as-is in the returned list.
327 Unmatched glob pattern will remain as-is in the returned list.
325
328
326 """
329 """
327 expanded = []
330 expanded = []
328 # Do not unescape backslash in Windows as it is interpreted as
331 # Do not unescape backslash in Windows as it is interpreted as
329 # path separator:
332 # path separator:
330 unescape = unescape_glob if sys.platform != 'win32' else lambda x: x
333 unescape = unescape_glob if sys.platform != 'win32' else lambda x: x
331 for a in args:
334 for a in args:
332 expanded.extend(glob.glob(a) or [unescape(a)])
335 expanded.extend(glob.glob(a) or [unescape(a)])
333 return expanded
336 return expanded
334
337
335
338
336 def target_outdated(target,deps):
339 def target_outdated(target,deps):
337 """Determine whether a target is out of date.
340 """Determine whether a target is out of date.
338
341
339 target_outdated(target,deps) -> 1/0
342 target_outdated(target,deps) -> 1/0
340
343
341 deps: list of filenames which MUST exist.
344 deps: list of filenames which MUST exist.
342 target: single filename which may or may not exist.
345 target: single filename which may or may not exist.
343
346
344 If target doesn't exist or is older than any file listed in deps, return
347 If target doesn't exist or is older than any file listed in deps, return
345 true, otherwise return false.
348 true, otherwise return false.
346 """
349 """
347 try:
350 try:
348 target_time = os.path.getmtime(target)
351 target_time = os.path.getmtime(target)
349 except os.error:
352 except os.error:
350 return 1
353 return 1
351 for dep in deps:
354 for dep in deps:
352 dep_time = os.path.getmtime(dep)
355 dep_time = os.path.getmtime(dep)
353 if dep_time > target_time:
356 if dep_time > target_time:
354 #print "For target",target,"Dep failed:",dep # dbg
357 #print "For target",target,"Dep failed:",dep # dbg
355 #print "times (dep,tar):",dep_time,target_time # dbg
358 #print "times (dep,tar):",dep_time,target_time # dbg
356 return 1
359 return 1
357 return 0
360 return 0
358
361
359
362
360 def target_update(target,deps,cmd):
363 def target_update(target,deps,cmd):
361 """Update a target with a given command given a list of dependencies.
364 """Update a target with a given command given a list of dependencies.
362
365
363 target_update(target,deps,cmd) -> runs cmd if target is outdated.
366 target_update(target,deps,cmd) -> runs cmd if target is outdated.
364
367
365 This is just a wrapper around target_outdated() which calls the given
368 This is just a wrapper around target_outdated() which calls the given
366 command if target is outdated."""
369 command if target is outdated."""
367
370
368 if target_outdated(target,deps):
371 if target_outdated(target,deps):
369 system(cmd)
372 system(cmd)
370
373
371 @undoc
374 @undoc
372 def filehash(path):
375 def filehash(path):
373 """Make an MD5 hash of a file, ignoring any differences in line
376 """Make an MD5 hash of a file, ignoring any differences in line
374 ending characters."""
377 ending characters."""
375 warn("filehash() is deprecated")
378 warn("filehash() is deprecated")
376 with open(path, "rU") as f:
379 with open(path, "rU") as f:
377 return md5(py3compat.str_to_bytes(f.read())).hexdigest()
380 return md5(py3compat.str_to_bytes(f.read())).hexdigest()
378
381
379 ENOLINK = 1998
382 ENOLINK = 1998
380
383
381 def link(src, dst):
384 def link(src, dst):
382 """Hard links ``src`` to ``dst``, returning 0 or errno.
385 """Hard links ``src`` to ``dst``, returning 0 or errno.
383
386
384 Note that the special errno ``ENOLINK`` will be returned if ``os.link`` isn't
387 Note that the special errno ``ENOLINK`` will be returned if ``os.link`` isn't
385 supported by the operating system.
388 supported by the operating system.
386 """
389 """
387
390
388 if not hasattr(os, "link"):
391 if not hasattr(os, "link"):
389 return ENOLINK
392 return ENOLINK
390 link_errno = 0
393 link_errno = 0
391 try:
394 try:
392 os.link(src, dst)
395 os.link(src, dst)
393 except OSError as e:
396 except OSError as e:
394 link_errno = e.errno
397 link_errno = e.errno
395 return link_errno
398 return link_errno
396
399
397
400
398 def link_or_copy(src, dst):
401 def link_or_copy(src, dst):
399 """Attempts to hardlink ``src`` to ``dst``, copying if the link fails.
402 """Attempts to hardlink ``src`` to ``dst``, copying if the link fails.
400
403
401 Attempts to maintain the semantics of ``shutil.copy``.
404 Attempts to maintain the semantics of ``shutil.copy``.
402
405
403 Because ``os.link`` does not overwrite files, a unique temporary file
406 Because ``os.link`` does not overwrite files, a unique temporary file
404 will be used if the target already exists, then that file will be moved
407 will be used if the target already exists, then that file will be moved
405 into place.
408 into place.
406 """
409 """
407
410
408 if os.path.isdir(dst):
411 if os.path.isdir(dst):
409 dst = os.path.join(dst, os.path.basename(src))
412 dst = os.path.join(dst, os.path.basename(src))
410
413
411 link_errno = link(src, dst)
414 link_errno = link(src, dst)
412 if link_errno == errno.EEXIST:
415 if link_errno == errno.EEXIST:
413 if os.stat(src).st_ino == os.stat(dst).st_ino:
416 if os.stat(src).st_ino == os.stat(dst).st_ino:
414 # dst is already a hard link to the correct file, so we don't need
417 # dst is already a hard link to the correct file, so we don't need
415 # to do anything else. If we try to link and rename the file
418 # to do anything else. If we try to link and rename the file
416 # anyway, we get duplicate files - see http://bugs.python.org/issue21876
419 # anyway, we get duplicate files - see http://bugs.python.org/issue21876
417 return
420 return
418
421
419 new_dst = dst + "-temp-%04X" %(random.randint(1, 16**4), )
422 new_dst = dst + "-temp-%04X" %(random.randint(1, 16**4), )
420 try:
423 try:
421 link_or_copy(src, new_dst)
424 link_or_copy(src, new_dst)
422 except:
425 except:
423 try:
426 try:
424 os.remove(new_dst)
427 os.remove(new_dst)
425 except OSError:
428 except OSError:
426 pass
429 pass
427 raise
430 raise
428 os.rename(new_dst, dst)
431 os.rename(new_dst, dst)
429 elif link_errno != 0:
432 elif link_errno != 0:
430 # Either link isn't supported, or the filesystem doesn't support
433 # Either link isn't supported, or the filesystem doesn't support
431 # linking, or 'src' and 'dst' are on different filesystems.
434 # linking, or 'src' and 'dst' are on different filesystems.
432 shutil.copy(src, dst)
435 shutil.copy(src, dst)
433
436
434 def ensure_dir_exists(path, mode=0o755):
437 def ensure_dir_exists(path, mode=0o755):
435 """ensure that a directory exists
438 """ensure that a directory exists
436
439
437 If it doesn't exist, try to create it and protect against a race condition
440 If it doesn't exist, try to create it and protect against a race condition
438 if another process is doing the same.
441 if another process is doing the same.
439
442
440 The default permissions are 755, which differ from os.makedirs default of 777.
443 The default permissions are 755, which differ from os.makedirs default of 777.
441 """
444 """
442 if not os.path.exists(path):
445 if not os.path.exists(path):
443 try:
446 try:
444 os.makedirs(path, mode=mode)
447 os.makedirs(path, mode=mode)
445 except OSError as e:
448 except OSError as e:
446 if e.errno != errno.EEXIST:
449 if e.errno != errno.EEXIST:
447 raise
450 raise
448 elif not os.path.isdir(path):
451 elif not os.path.isdir(path):
449 raise IOError("%r exists but is not a directory" % path)
452 raise IOError("%r exists but is not a directory" % path)
General Comments 0
You need to be logged in to leave comments. Login now