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