##// END OF EJS Templates
deprecate IPython.utils.signatures...
Min RK -
Show More
@@ -1,1236 +1,1229 b''
1 1 # encoding: utf-8
2 2 """Word completion for IPython.
3 3
4 4 This module started as 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,
7 7
8 8 """
9 9
10 10 # Copyright (c) IPython Development Team.
11 11 # Distributed under the terms of the Modified BSD License.
12 12 #
13 13 # Some of this code originated from rlcompleter in the Python standard library
14 14 # Copyright (C) 2001 Python Software Foundation, www.python.org
15 15
16 16
17 17 import __main__
18 18 import glob
19 19 import inspect
20 20 import itertools
21 21 import keyword
22 22 import os
23 23 import re
24 24 import sys
25 25 import unicodedata
26 26 import string
27 27 import warnings
28 28 from importlib import import_module
29 29
30 30 from traitlets.config.configurable import Configurable
31 31 from IPython.core.error import TryNext
32 32 from IPython.core.inputsplitter import ESC_MAGIC
33 33 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
34 34 from IPython.utils import generics
35 35 from IPython.utils.decorators import undoc
36 36 from IPython.utils.dir2 import dir2, get_real_method
37 37 from IPython.utils.process import arg_split
38 38 from IPython.utils.py3compat import builtin_mod, string_types, PY3, cast_unicode_py2
39 39 from traitlets import Bool, Enum, observe
40 40
41 41 from functools import wraps
42 42
43 43 #-----------------------------------------------------------------------------
44 44 # Globals
45 45 #-----------------------------------------------------------------------------
46 46
47 47 # Public API
48 48 __all__ = ['Completer','IPCompleter']
49 49
50 50 if sys.platform == 'win32':
51 51 PROTECTABLES = ' '
52 52 else:
53 53 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
54 54
55 55
56 56 #-----------------------------------------------------------------------------
57 57 # Work around BUG decorators.
58 58 #-----------------------------------------------------------------------------
59 59
60 60 def _strip_single_trailing_space(complete):
61 61 """
62 62 This is a workaround for a weird IPython/Prompt_toolkit behavior,
63 63 that can be removed once we rely on a slightly more recent prompt_toolkit
64 64 version (likely > 1.0.3). So this can likely be removed in IPython 6.0
65 65
66 66 cf https://github.com/ipython/ipython/issues/9658
67 67 and https://github.com/jonathanslenders/python-prompt-toolkit/pull/328
68 68
69 69 The bug is due to the fact that in PTK the completer will reinvoke itself
70 70 after trying to completer to the longuest common prefix of all the
71 71 completions, unless only one completion is available.
72 72
73 73 This logic is faulty if the completion ends with space, which can happen in
74 74 case like::
75 75
76 76 from foo import im<ta>
77 77
78 78 which only matching completion is `import `. Note the leading space at the
79 79 end. So leaving a space at the end is a reasonable request, but for now
80 80 we'll strip it.
81 81 """
82 82
83 83 @wraps(complete)
84 84 def comp(*args, **kwargs):
85 85 text, matches = complete(*args, **kwargs)
86 86 if len(matches) == 1:
87 87 return text, [matches[0].rstrip()]
88 88 return text, matches
89 89
90 90 return comp
91 91
92 92
93 93
94 94 #-----------------------------------------------------------------------------
95 95 # Main functions and classes
96 96 #-----------------------------------------------------------------------------
97 97
98 98 def has_open_quotes(s):
99 99 """Return whether a string has open quotes.
100 100
101 101 This simply counts whether the number of quote characters of either type in
102 102 the string is odd.
103 103
104 104 Returns
105 105 -------
106 106 If there is an open quote, the quote character is returned. Else, return
107 107 False.
108 108 """
109 109 # We check " first, then ', so complex cases with nested quotes will get
110 110 # the " to take precedence.
111 111 if s.count('"') % 2:
112 112 return '"'
113 113 elif s.count("'") % 2:
114 114 return "'"
115 115 else:
116 116 return False
117 117
118 118
119 119 def protect_filename(s):
120 120 """Escape a string to protect certain characters."""
121 121 if set(s) & set(PROTECTABLES):
122 122 if sys.platform == "win32":
123 123 return '"' + s + '"'
124 124 else:
125 125 return "".join(("\\" + c if c in PROTECTABLES else c) for c in s)
126 126 else:
127 127 return s
128 128
129 129
130 130 def expand_user(path):
131 131 """Expand '~'-style usernames in strings.
132 132
133 133 This is similar to :func:`os.path.expanduser`, but it computes and returns
134 134 extra information that will be useful if the input was being used in
135 135 computing completions, and you wish to return the completions with the
136 136 original '~' instead of its expanded value.
137 137
138 138 Parameters
139 139 ----------
140 140 path : str
141 141 String to be expanded. If no ~ is present, the output is the same as the
142 142 input.
143 143
144 144 Returns
145 145 -------
146 146 newpath : str
147 147 Result of ~ expansion in the input path.
148 148 tilde_expand : bool
149 149 Whether any expansion was performed or not.
150 150 tilde_val : str
151 151 The value that ~ was replaced with.
152 152 """
153 153 # Default values
154 154 tilde_expand = False
155 155 tilde_val = ''
156 156 newpath = path
157 157
158 158 if path.startswith('~'):
159 159 tilde_expand = True
160 160 rest = len(path)-1
161 161 newpath = os.path.expanduser(path)
162 162 if rest:
163 163 tilde_val = newpath[:-rest]
164 164 else:
165 165 tilde_val = newpath
166 166
167 167 return newpath, tilde_expand, tilde_val
168 168
169 169
170 170 def compress_user(path, tilde_expand, tilde_val):
171 171 """Does the opposite of expand_user, with its outputs.
172 172 """
173 173 if tilde_expand:
174 174 return path.replace(tilde_val, '~')
175 175 else:
176 176 return path
177 177
178 178
179 179 def completions_sorting_key(word):
180 180 """key for sorting completions
181 181
182 182 This does several things:
183 183
184 184 - Lowercase all completions, so they are sorted alphabetically with
185 185 upper and lower case words mingled
186 186 - Demote any completions starting with underscores to the end
187 187 - Insert any %magic and %%cellmagic completions in the alphabetical order
188 188 by their name
189 189 """
190 190 # Case insensitive sort
191 191 word = word.lower()
192 192
193 193 prio1, prio2 = 0, 0
194 194
195 195 if word.startswith('__'):
196 196 prio1 = 2
197 197 elif word.startswith('_'):
198 198 prio1 = 1
199 199
200 200 if word.endswith('='):
201 201 prio1 = -1
202 202
203 203 if word.startswith('%%'):
204 204 # If there's another % in there, this is something else, so leave it alone
205 205 if not "%" in word[2:]:
206 206 word = word[2:]
207 207 prio2 = 2
208 208 elif word.startswith('%'):
209 209 if not "%" in word[1:]:
210 210 word = word[1:]
211 211 prio2 = 1
212 212
213 213 return prio1, word, prio2
214 214
215 215
216 216 @undoc
217 217 class Bunch(object): pass
218 218
219 219
220 220 if sys.platform == 'win32':
221 221 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
222 222 else:
223 223 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
224 224
225 225 GREEDY_DELIMS = ' =\r\n'
226 226
227 227
228 228 class CompletionSplitter(object):
229 229 """An object to split an input line in a manner similar to readline.
230 230
231 231 By having our own implementation, we can expose readline-like completion in
232 232 a uniform manner to all frontends. This object only needs to be given the
233 233 line of text to be split and the cursor position on said line, and it
234 234 returns the 'word' to be completed on at the cursor after splitting the
235 235 entire line.
236 236
237 237 What characters are used as splitting delimiters can be controlled by
238 238 setting the `delims` attribute (this is a property that internally
239 239 automatically builds the necessary regular expression)"""
240 240
241 241 # Private interface
242 242
243 243 # A string of delimiter characters. The default value makes sense for
244 244 # IPython's most typical usage patterns.
245 245 _delims = DELIMS
246 246
247 247 # The expression (a normal string) to be compiled into a regular expression
248 248 # for actual splitting. We store it as an attribute mostly for ease of
249 249 # debugging, since this type of code can be so tricky to debug.
250 250 _delim_expr = None
251 251
252 252 # The regular expression that does the actual splitting
253 253 _delim_re = None
254 254
255 255 def __init__(self, delims=None):
256 256 delims = CompletionSplitter._delims if delims is None else delims
257 257 self.delims = delims
258 258
259 259 @property
260 260 def delims(self):
261 261 """Return the string of delimiter characters."""
262 262 return self._delims
263 263
264 264 @delims.setter
265 265 def delims(self, delims):
266 266 """Set the delimiters for line splitting."""
267 267 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
268 268 self._delim_re = re.compile(expr)
269 269 self._delims = delims
270 270 self._delim_expr = expr
271 271
272 272 def split_line(self, line, cursor_pos=None):
273 273 """Split a line of text with a cursor at the given position.
274 274 """
275 275 l = line if cursor_pos is None else line[:cursor_pos]
276 276 return self._delim_re.split(l)[-1]
277 277
278 278
279 279 class Completer(Configurable):
280 280
281 281 greedy = Bool(False,
282 282 help="""Activate greedy completion
283 283 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
284 284
285 285 This will enable completion on elements of lists, results of function calls, etc.,
286 286 but can be unsafe because the code is actually evaluated on TAB.
287 287 """
288 288 ).tag(config=True)
289 289
290 290
291 291 def __init__(self, namespace=None, global_namespace=None, **kwargs):
292 292 """Create a new completer for the command line.
293 293
294 294 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
295 295
296 296 If unspecified, the default namespace where completions are performed
297 297 is __main__ (technically, __main__.__dict__). Namespaces should be
298 298 given as dictionaries.
299 299
300 300 An optional second namespace can be given. This allows the completer
301 301 to handle cases where both the local and global scopes need to be
302 302 distinguished.
303 303
304 304 Completer instances should be used as the completion mechanism of
305 305 readline via the set_completer() call:
306 306
307 307 readline.set_completer(Completer(my_namespace).complete)
308 308 """
309 309
310 310 # Don't bind to namespace quite yet, but flag whether the user wants a
311 311 # specific namespace or to use __main__.__dict__. This will allow us
312 312 # to bind to __main__.__dict__ at completion time, not now.
313 313 if namespace is None:
314 314 self.use_main_ns = 1
315 315 else:
316 316 self.use_main_ns = 0
317 317 self.namespace = namespace
318 318
319 319 # The global namespace, if given, can be bound directly
320 320 if global_namespace is None:
321 321 self.global_namespace = {}
322 322 else:
323 323 self.global_namespace = global_namespace
324 324
325 325 super(Completer, self).__init__(**kwargs)
326 326
327 327 def complete(self, text, state):
328 328 """Return the next possible completion for 'text'.
329 329
330 330 This is called successively with state == 0, 1, 2, ... until it
331 331 returns None. The completion should begin with 'text'.
332 332
333 333 """
334 334 if self.use_main_ns:
335 335 self.namespace = __main__.__dict__
336 336
337 337 if state == 0:
338 338 if "." in text:
339 339 self.matches = self.attr_matches(text)
340 340 else:
341 341 self.matches = self.global_matches(text)
342 342 try:
343 343 return self.matches[state]
344 344 except IndexError:
345 345 return None
346 346
347 347 def global_matches(self, text):
348 348 """Compute matches when text is a simple name.
349 349
350 350 Return a list of all keywords, built-in functions and names currently
351 351 defined in self.namespace or self.global_namespace that match.
352 352
353 353 """
354 354 matches = []
355 355 match_append = matches.append
356 356 n = len(text)
357 357 for lst in [keyword.kwlist,
358 358 builtin_mod.__dict__.keys(),
359 359 self.namespace.keys(),
360 360 self.global_namespace.keys()]:
361 361 for word in lst:
362 362 if word[:n] == text and word != "__builtins__":
363 363 match_append(word)
364 364 return [cast_unicode_py2(m) for m in matches]
365 365
366 366 def attr_matches(self, text):
367 367 """Compute matches when text contains a dot.
368 368
369 369 Assuming the text is of the form NAME.NAME....[NAME], and is
370 370 evaluatable in self.namespace or self.global_namespace, it will be
371 371 evaluated and its attributes (as revealed by dir()) are used as
372 372 possible completions. (For class instances, class members are are
373 373 also considered.)
374 374
375 375 WARNING: this can still invoke arbitrary C code, if an object
376 376 with a __getattr__ hook is evaluated.
377 377
378 378 """
379 379
380 380 # Another option, seems to work great. Catches things like ''.<tab>
381 381 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
382 382
383 383 if m:
384 384 expr, attr = m.group(1, 3)
385 385 elif self.greedy:
386 386 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
387 387 if not m2:
388 388 return []
389 389 expr, attr = m2.group(1,2)
390 390 else:
391 391 return []
392 392
393 393 try:
394 394 obj = eval(expr, self.namespace)
395 395 except:
396 396 try:
397 397 obj = eval(expr, self.global_namespace)
398 398 except:
399 399 return []
400 400
401 401 if self.limit_to__all__ and hasattr(obj, '__all__'):
402 402 words = get__all__entries(obj)
403 403 else:
404 404 words = dir2(obj)
405 405
406 406 try:
407 407 words = generics.complete_object(obj, words)
408 408 except TryNext:
409 409 pass
410 410 except Exception:
411 411 # Silence errors from completion function
412 412 #raise # dbg
413 413 pass
414 414 # Build match list to return
415 415 n = len(attr)
416 416 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
417 417
418 418
419 419 def get__all__entries(obj):
420 420 """returns the strings in the __all__ attribute"""
421 421 try:
422 422 words = getattr(obj, '__all__')
423 423 except:
424 424 return []
425 425
426 426 return [cast_unicode_py2(w) for w in words if isinstance(w, string_types)]
427 427
428 428
429 429 def match_dict_keys(keys, prefix, delims):
430 430 """Used by dict_key_matches, matching the prefix to a list of keys"""
431 431 if not prefix:
432 432 return None, 0, [repr(k) for k in keys
433 433 if isinstance(k, (string_types, bytes))]
434 434 quote_match = re.search('["\']', prefix)
435 435 quote = quote_match.group()
436 436 try:
437 437 prefix_str = eval(prefix + quote, {})
438 438 except Exception:
439 439 return None, 0, []
440 440
441 441 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
442 442 token_match = re.search(pattern, prefix, re.UNICODE)
443 443 token_start = token_match.start()
444 444 token_prefix = token_match.group()
445 445
446 446 # TODO: support bytes in Py3k
447 447 matched = []
448 448 for key in keys:
449 449 try:
450 450 if not key.startswith(prefix_str):
451 451 continue
452 452 except (AttributeError, TypeError, UnicodeError):
453 453 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
454 454 continue
455 455
456 456 # reformat remainder of key to begin with prefix
457 457 rem = key[len(prefix_str):]
458 458 # force repr wrapped in '
459 459 rem_repr = repr(rem + '"')
460 460 if rem_repr.startswith('u') and prefix[0] not in 'uU':
461 461 # Found key is unicode, but prefix is Py2 string.
462 462 # Therefore attempt to interpret key as string.
463 463 try:
464 464 rem_repr = repr(rem.encode('ascii') + '"')
465 465 except UnicodeEncodeError:
466 466 continue
467 467
468 468 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
469 469 if quote == '"':
470 470 # The entered prefix is quoted with ",
471 471 # but the match is quoted with '.
472 472 # A contained " hence needs escaping for comparison:
473 473 rem_repr = rem_repr.replace('"', '\\"')
474 474
475 475 # then reinsert prefix from start of token
476 476 matched.append('%s%s' % (token_prefix, rem_repr))
477 477 return quote, token_start, matched
478 478
479 479
480 480 def _safe_isinstance(obj, module, class_name):
481 481 """Checks if obj is an instance of module.class_name if loaded
482 482 """
483 483 return (module in sys.modules and
484 484 isinstance(obj, getattr(import_module(module), class_name)))
485 485
486 486
487 487 def back_unicode_name_matches(text):
488 488 u"""Match unicode characters back to unicode name
489 489
490 490 This does ☃ -> \\snowman
491 491
492 492 Note that snowman is not a valid python3 combining character but will be expanded.
493 493 Though it will not recombine back to the snowman character by the completion machinery.
494 494
495 495 This will not either back-complete standard sequences like \\n, \\b ...
496 496
497 497 Used on Python 3 only.
498 498 """
499 499 if len(text)<2:
500 500 return u'', ()
501 501 maybe_slash = text[-2]
502 502 if maybe_slash != '\\':
503 503 return u'', ()
504 504
505 505 char = text[-1]
506 506 # no expand on quote for completion in strings.
507 507 # nor backcomplete standard ascii keys
508 508 if char in string.ascii_letters or char in ['"',"'"]:
509 509 return u'', ()
510 510 try :
511 511 unic = unicodedata.name(char)
512 512 return '\\'+char,['\\'+unic]
513 513 except KeyError:
514 514 pass
515 515 return u'', ()
516 516
517 517 def back_latex_name_matches(text):
518 518 u"""Match latex characters back to unicode name
519 519
520 520 This does ->\\sqrt
521 521
522 522 Used on Python 3 only.
523 523 """
524 524 if len(text)<2:
525 525 return u'', ()
526 526 maybe_slash = text[-2]
527 527 if maybe_slash != '\\':
528 528 return u'', ()
529 529
530 530
531 531 char = text[-1]
532 532 # no expand on quote for completion in strings.
533 533 # nor backcomplete standard ascii keys
534 534 if char in string.ascii_letters or char in ['"',"'"]:
535 535 return u'', ()
536 536 try :
537 537 latex = reverse_latex_symbol[char]
538 538 # '\\' replace the \ as well
539 539 return '\\'+char,[latex]
540 540 except KeyError:
541 541 pass
542 542 return u'', ()
543 543
544 544
545 545 class IPCompleter(Completer):
546 546 """Extension of the completer class with IPython-specific features"""
547 547
548 548 @observe('greedy')
549 549 def _greedy_changed(self, change):
550 550 """update the splitter and readline delims when greedy is changed"""
551 551 if change['new']:
552 552 self.splitter.delims = GREEDY_DELIMS
553 553 else:
554 554 self.splitter.delims = DELIMS
555 555
556 556 merge_completions = Bool(True,
557 557 help="""Whether to merge completion results into a single list
558 558
559 559 If False, only the completion results from the first non-empty
560 560 completer will be returned.
561 561 """
562 562 ).tag(config=True)
563 563 omit__names = Enum((0,1,2), default_value=2,
564 564 help="""Instruct the completer to omit private method names
565 565
566 566 Specifically, when completing on ``object.<tab>``.
567 567
568 568 When 2 [default]: all names that start with '_' will be excluded.
569 569
570 570 When 1: all 'magic' names (``__foo__``) will be excluded.
571 571
572 572 When 0: nothing will be excluded.
573 573 """
574 574 ).tag(config=True)
575 575 limit_to__all__ = Bool(False,
576 576 help="""
577 577 DEPRECATED as of version 5.0.
578 578
579 579 Instruct the completer to use __all__ for the completion
580 580
581 581 Specifically, when completing on ``object.<tab>``.
582 582
583 583 When True: only those names in obj.__all__ will be included.
584 584
585 585 When False [default]: the __all__ attribute is ignored
586 586 """,
587 587 ).tag(config=True)
588 588
589 589 def __init__(self, shell=None, namespace=None, global_namespace=None,
590 590 use_readline=False, config=None, **kwargs):
591 591 """IPCompleter() -> completer
592 592
593 593 Return a completer object suitable for use by the readline library
594 594 via readline.set_completer().
595 595
596 596 Inputs:
597 597
598 598 - shell: a pointer to the ipython shell itself. This is needed
599 599 because this completer knows about magic functions, and those can
600 600 only be accessed via the ipython instance.
601 601
602 602 - namespace: an optional dict where completions are performed.
603 603
604 604 - global_namespace: secondary optional dict for completions, to
605 605 handle cases (such as IPython embedded inside functions) where
606 606 both Python scopes are visible.
607 607
608 608 use_readline : bool, optional
609 609 DEPRECATED, ignored.
610 610 """
611 611
612 612 self.magic_escape = ESC_MAGIC
613 613 self.splitter = CompletionSplitter()
614 614
615 615 if use_readline:
616 616 warnings.warn('The use_readline parameter is deprecated and ignored since IPython 6.0.',
617 617 DeprecationWarning, stacklevel=2)
618 618
619 619 # _greedy_changed() depends on splitter and readline being defined:
620 620 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
621 621 config=config, **kwargs)
622 622
623 623 # List where completion matches will be stored
624 624 self.matches = []
625 625 self.shell = shell
626 626 # Regexp to split filenames with spaces in them
627 627 self.space_name_re = re.compile(r'([^\\] )')
628 628 # Hold a local ref. to glob.glob for speed
629 629 self.glob = glob.glob
630 630
631 631 # Determine if we are running on 'dumb' terminals, like (X)Emacs
632 632 # buffers, to avoid completion problems.
633 633 term = os.environ.get('TERM','xterm')
634 634 self.dumb_terminal = term in ['dumb','emacs']
635 635
636 636 # Special handling of backslashes needed in win32 platforms
637 637 if sys.platform == "win32":
638 638 self.clean_glob = self._clean_glob_win32
639 639 else:
640 640 self.clean_glob = self._clean_glob
641 641
642 642 #regexp to parse docstring for function signature
643 643 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
644 644 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
645 645 #use this if positional argument name is also needed
646 646 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
647 647
648 648 # All active matcher routines for completion
649 649 self.matchers = [
650 650 self.python_matches,
651 651 self.file_matches,
652 652 self.magic_matches,
653 653 self.python_func_kw_matches,
654 654 self.dict_key_matches,
655 655 ]
656 656
657 657 # This is set externally by InteractiveShell
658 658 self.custom_completers = None
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 if sys.platform == 'win32':
730 730 m0 = self.clean_glob(text)
731 731 else:
732 732 m0 = self.clean_glob(text.replace('\\', ''))
733 733
734 734 if has_protectables:
735 735 # If we had protectables, we need to revert our changes to the
736 736 # beginning of filename so that we don't double-write the part
737 737 # of the filename we have so far
738 738 len_lsplit = len(lsplit)
739 739 matches = [text_prefix + text0 +
740 740 protect_filename(f[len_lsplit:]) for f in m0]
741 741 else:
742 742 if open_quotes:
743 743 # if we have a string with an open quote, we don't need to
744 744 # protect the names at all (and we _shouldn't_, as it
745 745 # would cause bugs when the filesystem call is made).
746 746 matches = m0
747 747 else:
748 748 matches = [text_prefix +
749 749 protect_filename(f) for f in m0]
750 750
751 751 # Mark directories in input list by appending '/' to their names.
752 752 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
753 753
754 754 def magic_matches(self, text):
755 755 """Match magics"""
756 756 # Get all shell magics now rather than statically, so magics loaded at
757 757 # runtime show up too.
758 758 lsm = self.shell.magics_manager.lsmagic()
759 759 line_magics = lsm['line']
760 760 cell_magics = lsm['cell']
761 761 pre = self.magic_escape
762 762 pre2 = pre+pre
763 763
764 764 # Completion logic:
765 765 # - user gives %%: only do cell magics
766 766 # - user gives %: do both line and cell magics
767 767 # - no prefix: do both
768 768 # In other words, line magics are skipped if the user gives %% explicitly
769 769 bare_text = text.lstrip(pre)
770 770 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
771 771 if not text.startswith(pre2):
772 772 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
773 773 return [cast_unicode_py2(c) for c in comp]
774 774
775 775
776 776 def python_matches(self, text):
777 777 """Match attributes or global python names"""
778 778 if "." in text:
779 779 try:
780 780 matches = self.attr_matches(text)
781 781 if text.endswith('.') and self.omit__names:
782 782 if self.omit__names == 1:
783 783 # true if txt is _not_ a __ name, false otherwise:
784 784 no__name = (lambda txt:
785 785 re.match(r'.*\.__.*?__',txt) is None)
786 786 else:
787 787 # true if txt is _not_ a _ name, false otherwise:
788 788 no__name = (lambda txt:
789 789 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
790 790 matches = filter(no__name, matches)
791 791 except NameError:
792 792 # catches <undefined attributes>.<tab>
793 793 matches = []
794 794 else:
795 795 matches = self.global_matches(text)
796 796 return matches
797 797
798 798 def _default_arguments_from_docstring(self, doc):
799 799 """Parse the first line of docstring for call signature.
800 800
801 801 Docstring should be of the form 'min(iterable[, key=func])\n'.
802 802 It can also parse cython docstring of the form
803 803 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
804 804 """
805 805 if doc is None:
806 806 return []
807 807
808 808 #care only the firstline
809 809 line = doc.lstrip().splitlines()[0]
810 810
811 811 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
812 812 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
813 813 sig = self.docstring_sig_re.search(line)
814 814 if sig is None:
815 815 return []
816 816 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
817 817 sig = sig.groups()[0].split(',')
818 818 ret = []
819 819 for s in sig:
820 820 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
821 821 ret += self.docstring_kwd_re.findall(s)
822 822 return ret
823 823
824 824 def _default_arguments(self, obj):
825 825 """Return the list of default arguments of obj if it is callable,
826 826 or empty list otherwise."""
827 827 call_obj = obj
828 828 ret = []
829 829 if inspect.isbuiltin(obj):
830 830 pass
831 831 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
832 832 if inspect.isclass(obj):
833 833 #for cython embededsignature=True the constructor docstring
834 834 #belongs to the object itself not __init__
835 835 ret += self._default_arguments_from_docstring(
836 836 getattr(obj, '__doc__', ''))
837 837 # for classes, check for __init__,__new__
838 838 call_obj = (getattr(obj, '__init__', None) or
839 839 getattr(obj, '__new__', None))
840 840 # for all others, check if they are __call__able
841 841 elif hasattr(obj, '__call__'):
842 842 call_obj = obj.__call__
843 843 ret += self._default_arguments_from_docstring(
844 844 getattr(call_obj, '__doc__', ''))
845 845
846 if PY3:
847 _keeps = (inspect.Parameter.KEYWORD_ONLY,
848 inspect.Parameter.POSITIONAL_OR_KEYWORD)
849 signature = inspect.signature
850 else:
851 import IPython.utils.signatures
852 _keeps = (IPython.utils.signatures.Parameter.KEYWORD_ONLY,
853 IPython.utils.signatures.Parameter.POSITIONAL_OR_KEYWORD)
854 signature = IPython.utils.signatures.signature
846 _keeps = (inspect.Parameter.KEYWORD_ONLY,
847 inspect.Parameter.POSITIONAL_OR_KEYWORD)
855 848
856 849 try:
857 sig = signature(call_obj)
850 sig = inspect.signature(call_obj)
858 851 ret.extend(k for k, v in sig.parameters.items() if
859 852 v.kind in _keeps)
860 853 except ValueError:
861 854 pass
862 855
863 856 return list(set(ret))
864 857
865 858 def python_func_kw_matches(self,text):
866 859 """Match named parameters (kwargs) of the last open function"""
867 860
868 861 if "." in text: # a parameter cannot be dotted
869 862 return []
870 863 try: regexp = self.__funcParamsRegex
871 864 except AttributeError:
872 865 regexp = self.__funcParamsRegex = re.compile(r'''
873 866 '.*?(?<!\\)' | # single quoted strings or
874 867 ".*?(?<!\\)" | # double quoted strings or
875 868 \w+ | # identifier
876 869 \S # other characters
877 870 ''', re.VERBOSE | re.DOTALL)
878 871 # 1. find the nearest identifier that comes before an unclosed
879 872 # parenthesis before the cursor
880 873 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
881 874 tokens = regexp.findall(self.text_until_cursor)
882 875 iterTokens = reversed(tokens); openPar = 0
883 876
884 877 for token in iterTokens:
885 878 if token == ')':
886 879 openPar -= 1
887 880 elif token == '(':
888 881 openPar += 1
889 882 if openPar > 0:
890 883 # found the last unclosed parenthesis
891 884 break
892 885 else:
893 886 return []
894 887 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
895 888 ids = []
896 889 isId = re.compile(r'\w+$').match
897 890
898 891 while True:
899 892 try:
900 893 ids.append(next(iterTokens))
901 894 if not isId(ids[-1]):
902 895 ids.pop(); break
903 896 if not next(iterTokens) == '.':
904 897 break
905 898 except StopIteration:
906 899 break
907 900
908 901 # Find all named arguments already assigned to, as to avoid suggesting
909 902 # them again
910 903 usedNamedArgs = set()
911 904 par_level = -1
912 905 for token, next_token in zip(tokens, tokens[1:]):
913 906 if token == '(':
914 907 par_level += 1
915 908 elif token == ')':
916 909 par_level -= 1
917 910
918 911 if par_level != 0:
919 912 continue
920 913
921 914 if next_token != '=':
922 915 continue
923 916
924 917 usedNamedArgs.add(token)
925 918
926 919 # lookup the candidate callable matches either using global_matches
927 920 # or attr_matches for dotted names
928 921 if len(ids) == 1:
929 922 callableMatches = self.global_matches(ids[0])
930 923 else:
931 924 callableMatches = self.attr_matches('.'.join(ids[::-1]))
932 925 argMatches = []
933 926 for callableMatch in callableMatches:
934 927 try:
935 928 namedArgs = self._default_arguments(eval(callableMatch,
936 929 self.namespace))
937 930 except:
938 931 continue
939 932
940 933 # Remove used named arguments from the list, no need to show twice
941 934 for namedArg in set(namedArgs) - usedNamedArgs:
942 935 if namedArg.startswith(text):
943 936 argMatches.append(u"%s=" %namedArg)
944 937 return argMatches
945 938
946 939 def dict_key_matches(self, text):
947 940 "Match string keys in a dictionary, after e.g. 'foo[' "
948 941 def get_keys(obj):
949 942 # Objects can define their own completions by defining an
950 943 # _ipy_key_completions_() method.
951 944 method = get_real_method(obj, '_ipython_key_completions_')
952 945 if method is not None:
953 946 return method()
954 947
955 948 # Special case some common in-memory dict-like types
956 949 if isinstance(obj, dict) or\
957 950 _safe_isinstance(obj, 'pandas', 'DataFrame'):
958 951 try:
959 952 return list(obj.keys())
960 953 except Exception:
961 954 return []
962 955 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
963 956 _safe_isinstance(obj, 'numpy', 'void'):
964 957 return obj.dtype.names or []
965 958 return []
966 959
967 960 try:
968 961 regexps = self.__dict_key_regexps
969 962 except AttributeError:
970 963 dict_key_re_fmt = r'''(?x)
971 964 ( # match dict-referring expression wrt greedy setting
972 965 %s
973 966 )
974 967 \[ # open bracket
975 968 \s* # and optional whitespace
976 969 ([uUbB]? # string prefix (r not handled)
977 970 (?: # unclosed string
978 971 '(?:[^']|(?<!\\)\\')*
979 972 |
980 973 "(?:[^"]|(?<!\\)\\")*
981 974 )
982 975 )?
983 976 $
984 977 '''
985 978 regexps = self.__dict_key_regexps = {
986 979 False: re.compile(dict_key_re_fmt % '''
987 980 # identifiers separated by .
988 981 (?!\d)\w+
989 982 (?:\.(?!\d)\w+)*
990 983 '''),
991 984 True: re.compile(dict_key_re_fmt % '''
992 985 .+
993 986 ''')
994 987 }
995 988
996 989 match = regexps[self.greedy].search(self.text_until_cursor)
997 990 if match is None:
998 991 return []
999 992
1000 993 expr, prefix = match.groups()
1001 994 try:
1002 995 obj = eval(expr, self.namespace)
1003 996 except Exception:
1004 997 try:
1005 998 obj = eval(expr, self.global_namespace)
1006 999 except Exception:
1007 1000 return []
1008 1001
1009 1002 keys = get_keys(obj)
1010 1003 if not keys:
1011 1004 return keys
1012 1005 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1013 1006 if not matches:
1014 1007 return matches
1015 1008
1016 1009 # get the cursor position of
1017 1010 # - the text being completed
1018 1011 # - the start of the key text
1019 1012 # - the start of the completion
1020 1013 text_start = len(self.text_until_cursor) - len(text)
1021 1014 if prefix:
1022 1015 key_start = match.start(2)
1023 1016 completion_start = key_start + token_offset
1024 1017 else:
1025 1018 key_start = completion_start = match.end()
1026 1019
1027 1020 # grab the leading prefix, to make sure all completions start with `text`
1028 1021 if text_start > key_start:
1029 1022 leading = ''
1030 1023 else:
1031 1024 leading = text[text_start:completion_start]
1032 1025
1033 1026 # the index of the `[` character
1034 1027 bracket_idx = match.end(1)
1035 1028
1036 1029 # append closing quote and bracket as appropriate
1037 1030 # this is *not* appropriate if the opening quote or bracket is outside
1038 1031 # the text given to this method
1039 1032 suf = ''
1040 1033 continuation = self.line_buffer[len(self.text_until_cursor):]
1041 1034 if key_start > text_start and closing_quote:
1042 1035 # quotes were opened inside text, maybe close them
1043 1036 if continuation.startswith(closing_quote):
1044 1037 continuation = continuation[len(closing_quote):]
1045 1038 else:
1046 1039 suf += closing_quote
1047 1040 if bracket_idx > text_start:
1048 1041 # brackets were opened inside text, maybe close them
1049 1042 if not continuation.startswith(']'):
1050 1043 suf += ']'
1051 1044
1052 1045 return [leading + k + suf for k in matches]
1053 1046
1054 1047 def unicode_name_matches(self, text):
1055 1048 u"""Match Latex-like syntax for unicode characters base
1056 1049 on the name of the character.
1057 1050
1058 1051 This does \\GREEK SMALL LETTER ETA -> η
1059 1052
1060 1053 Works only on valid python 3 identifier, or on combining characters that
1061 1054 will combine to form a valid identifier.
1062 1055
1063 1056 Used on Python 3 only.
1064 1057 """
1065 1058 slashpos = text.rfind('\\')
1066 1059 if slashpos > -1:
1067 1060 s = text[slashpos+1:]
1068 1061 try :
1069 1062 unic = unicodedata.lookup(s)
1070 1063 # allow combining chars
1071 1064 if ('a'+unic).isidentifier():
1072 1065 return '\\'+s,[unic]
1073 1066 except KeyError:
1074 1067 pass
1075 1068 return u'', []
1076 1069
1077 1070
1078 1071
1079 1072
1080 1073 def latex_matches(self, text):
1081 1074 u"""Match Latex syntax for unicode characters.
1082 1075
1083 1076 This does both \\alp -> \\alpha and \\alpha -> α
1084 1077
1085 1078 Used on Python 3 only.
1086 1079 """
1087 1080 slashpos = text.rfind('\\')
1088 1081 if slashpos > -1:
1089 1082 s = text[slashpos:]
1090 1083 if s in latex_symbols:
1091 1084 # Try to complete a full latex symbol to unicode
1092 1085 # \\alpha -> α
1093 1086 return s, [latex_symbols[s]]
1094 1087 else:
1095 1088 # If a user has partially typed a latex symbol, give them
1096 1089 # a full list of options \al -> [\aleph, \alpha]
1097 1090 matches = [k for k in latex_symbols if k.startswith(s)]
1098 1091 return s, matches
1099 1092 return u'', []
1100 1093
1101 1094 def dispatch_custom_completer(self, text):
1102 1095 if not self.custom_completers:
1103 1096 return
1104 1097
1105 1098 line = self.line_buffer
1106 1099 if not line.strip():
1107 1100 return None
1108 1101
1109 1102 # Create a little structure to pass all the relevant information about
1110 1103 # the current completion to any custom completer.
1111 1104 event = Bunch()
1112 1105 event.line = line
1113 1106 event.symbol = text
1114 1107 cmd = line.split(None,1)[0]
1115 1108 event.command = cmd
1116 1109 event.text_until_cursor = self.text_until_cursor
1117 1110
1118 1111 # for foo etc, try also to find completer for %foo
1119 1112 if not cmd.startswith(self.magic_escape):
1120 1113 try_magic = self.custom_completers.s_matches(
1121 1114 self.magic_escape + cmd)
1122 1115 else:
1123 1116 try_magic = []
1124 1117
1125 1118 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1126 1119 try_magic,
1127 1120 self.custom_completers.flat_matches(self.text_until_cursor)):
1128 1121 try:
1129 1122 res = c(event)
1130 1123 if res:
1131 1124 # first, try case sensitive match
1132 1125 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1133 1126 if withcase:
1134 1127 return withcase
1135 1128 # if none, then case insensitive ones are ok too
1136 1129 text_low = text.lower()
1137 1130 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1138 1131 except TryNext:
1139 1132 pass
1140 1133
1141 1134 return None
1142 1135
1143 1136 @_strip_single_trailing_space
1144 1137 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1145 1138 """Find completions for the given text and line context.
1146 1139
1147 1140 Note that both the text and the line_buffer are optional, but at least
1148 1141 one of them must be given.
1149 1142
1150 1143 Parameters
1151 1144 ----------
1152 1145 text : string, optional
1153 1146 Text to perform the completion on. If not given, the line buffer
1154 1147 is split using the instance's CompletionSplitter object.
1155 1148
1156 1149 line_buffer : string, optional
1157 1150 If not given, the completer attempts to obtain the current line
1158 1151 buffer via readline. This keyword allows clients which are
1159 1152 requesting for text completions in non-readline contexts to inform
1160 1153 the completer of the entire text.
1161 1154
1162 1155 cursor_pos : int, optional
1163 1156 Index of the cursor in the full line buffer. Should be provided by
1164 1157 remote frontends where kernel has no access to frontend state.
1165 1158
1166 1159 Returns
1167 1160 -------
1168 1161 text : str
1169 1162 Text that was actually used in the completion.
1170 1163
1171 1164 matches : list
1172 1165 A list of completion matches.
1173 1166 """
1174 1167 # if the cursor position isn't given, the only sane assumption we can
1175 1168 # make is that it's at the end of the line (the common case)
1176 1169 if cursor_pos is None:
1177 1170 cursor_pos = len(line_buffer) if text is None else len(text)
1178 1171
1179 1172 if self.use_main_ns:
1180 1173 self.namespace = __main__.__dict__
1181 1174
1182 1175 if PY3:
1183 1176
1184 1177 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1185 1178 latex_text, latex_matches = self.latex_matches(base_text)
1186 1179 if latex_matches:
1187 1180 return latex_text, latex_matches
1188 1181 name_text = ''
1189 1182 name_matches = []
1190 1183 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1191 1184 name_text, name_matches = meth(base_text)
1192 1185 if name_text:
1193 1186 return name_text, name_matches
1194 1187
1195 1188 # if text is either None or an empty string, rely on the line buffer
1196 1189 if not text:
1197 1190 text = self.splitter.split_line(line_buffer, cursor_pos)
1198 1191
1199 1192 # If no line buffer is given, assume the input text is all there was
1200 1193 if line_buffer is None:
1201 1194 line_buffer = text
1202 1195
1203 1196 self.line_buffer = line_buffer
1204 1197 self.text_until_cursor = self.line_buffer[:cursor_pos]
1205 1198
1206 1199 # Start with a clean slate of completions
1207 1200 self.matches[:] = []
1208 1201 custom_res = self.dispatch_custom_completer(text)
1209 1202 if custom_res is not None:
1210 1203 # did custom completers produce something?
1211 1204 self.matches = custom_res
1212 1205 else:
1213 1206 # Extend the list of completions with the results of each
1214 1207 # matcher, so we return results to the user from all
1215 1208 # namespaces.
1216 1209 if self.merge_completions:
1217 1210 self.matches = []
1218 1211 for matcher in self.matchers:
1219 1212 try:
1220 1213 self.matches.extend(matcher(text))
1221 1214 except:
1222 1215 # Show the ugly traceback if the matcher causes an
1223 1216 # exception, but do NOT crash the kernel!
1224 1217 sys.excepthook(*sys.exc_info())
1225 1218 else:
1226 1219 for matcher in self.matchers:
1227 1220 self.matches = matcher(text)
1228 1221 if self.matches:
1229 1222 break
1230 1223 # FIXME: we should extend our api to return a dict with completions for
1231 1224 # different types of objects. The rlcomplete() method could then
1232 1225 # simply collapse the dict into a list for readline, but we'd have
1233 1226 # richer completion semantics in other evironments.
1234 1227 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1235 1228
1236 1229 return text, self.matches
@@ -1,1009 +1,1009 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for inspecting Python objects.
3 3
4 4 Uses syntax highlighting for presenting the various information elements.
5 5
6 6 Similar in spirit to the inspect module, but all calls take a name argument to
7 7 reference the name under which an object is being read.
8 8 """
9 9
10 10 # Copyright (c) IPython Development Team.
11 11 # Distributed under the terms of the Modified BSD License.
12 12
13 13 __all__ = ['Inspector','InspectColors']
14 14
15 15 # stdlib modules
16 16 import inspect
17 from inspect import signature
17 18 import linecache
18 19 import warnings
19 20 import os
20 21 from textwrap import dedent
21 22 import types
22 23 import io as stdlib_io
23 24
24 25 try:
25 26 from itertools import izip_longest
26 27 except ImportError:
27 28 from itertools import zip_longest as izip_longest
28 29
29 30 # IPython's own
30 31 from IPython.core import page
31 32 from IPython.lib.pretty import pretty
32 33 from IPython.testing.skipdoctest import skip_doctest
33 34 from IPython.utils import PyColorize
34 35 from IPython.utils import openpy
35 36 from IPython.utils import py3compat
36 37 from IPython.utils.dir2 import safe_hasattr
37 38 from IPython.utils.path import compress_user
38 39 from IPython.utils.text import indent
39 40 from IPython.utils.wildcard import list_namespace
40 41 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
41 42 from IPython.utils.py3compat import cast_unicode, string_types, PY3
42 from IPython.utils.signatures import signature
43 43 from IPython.utils.colorable import Colorable
44 44
45 45 from pygments import highlight
46 46 from pygments.lexers import PythonLexer
47 47 from pygments.formatters import HtmlFormatter
48 48
49 49 def pylight(code):
50 50 return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True))
51 51
52 52 # builtin docstrings to ignore
53 53 _func_call_docstring = types.FunctionType.__call__.__doc__
54 54 _object_init_docstring = object.__init__.__doc__
55 55 _builtin_type_docstrings = {
56 56 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
57 57 types.FunctionType, property)
58 58 }
59 59
60 60 _builtin_func_type = type(all)
61 61 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
62 62 #****************************************************************************
63 63 # Builtin color schemes
64 64
65 65 Colors = TermColors # just a shorthand
66 66
67 67 InspectColors = PyColorize.ANSICodeColors
68 68
69 69 #****************************************************************************
70 70 # Auxiliary functions and objects
71 71
72 72 # See the messaging spec for the definition of all these fields. This list
73 73 # effectively defines the order of display
74 74 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
75 75 'length', 'file', 'definition', 'docstring', 'source',
76 76 'init_definition', 'class_docstring', 'init_docstring',
77 77 'call_def', 'call_docstring',
78 78 # These won't be printed but will be used to determine how to
79 79 # format the object
80 80 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
81 81 ]
82 82
83 83
84 84 def object_info(**kw):
85 85 """Make an object info dict with all fields present."""
86 86 infodict = dict(izip_longest(info_fields, [None]))
87 87 infodict.update(kw)
88 88 return infodict
89 89
90 90
91 91 def get_encoding(obj):
92 92 """Get encoding for python source file defining obj
93 93
94 94 Returns None if obj is not defined in a sourcefile.
95 95 """
96 96 ofile = find_file(obj)
97 97 # run contents of file through pager starting at line where the object
98 98 # is defined, as long as the file isn't binary and is actually on the
99 99 # filesystem.
100 100 if ofile is None:
101 101 return None
102 102 elif ofile.endswith(('.so', '.dll', '.pyd')):
103 103 return None
104 104 elif not os.path.isfile(ofile):
105 105 return None
106 106 else:
107 107 # Print only text files, not extension binaries. Note that
108 108 # getsourcelines returns lineno with 1-offset and page() uses
109 109 # 0-offset, so we must adjust.
110 110 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
111 111 encoding, lines = openpy.detect_encoding(buffer.readline)
112 112 return encoding
113 113
114 114 def getdoc(obj):
115 115 """Stable wrapper around inspect.getdoc.
116 116
117 117 This can't crash because of attribute problems.
118 118
119 119 It also attempts to call a getdoc() method on the given object. This
120 120 allows objects which provide their docstrings via non-standard mechanisms
121 121 (like Pyro proxies) to still be inspected by ipython's ? system.
122 122 """
123 123 # Allow objects to offer customized documentation via a getdoc method:
124 124 try:
125 125 ds = obj.getdoc()
126 126 except Exception:
127 127 pass
128 128 else:
129 129 # if we get extra info, we add it to the normal docstring.
130 130 if isinstance(ds, string_types):
131 131 return inspect.cleandoc(ds)
132 132 try:
133 133 docstr = inspect.getdoc(obj)
134 134 encoding = get_encoding(obj)
135 135 return py3compat.cast_unicode(docstr, encoding=encoding)
136 136 except Exception:
137 137 # Harden against an inspect failure, which can occur with
138 138 # extensions modules.
139 139 raise
140 140 return None
141 141
142 142
143 143 def getsource(obj, oname=''):
144 144 """Wrapper around inspect.getsource.
145 145
146 146 This can be modified by other projects to provide customized source
147 147 extraction.
148 148
149 149 Parameters
150 150 ----------
151 151 obj : object
152 152 an object whose source code we will attempt to extract
153 153 oname : str
154 154 (optional) a name under which the object is known
155 155
156 156 Returns
157 157 -------
158 158 src : unicode or None
159 159
160 160 """
161 161
162 162 if isinstance(obj, property):
163 163 sources = []
164 164 for attrname in ['fget', 'fset', 'fdel']:
165 165 fn = getattr(obj, attrname)
166 166 if fn is not None:
167 167 encoding = get_encoding(fn)
168 168 oname_prefix = ('%s.' % oname) if oname else ''
169 169 sources.append(cast_unicode(
170 170 ''.join(('# ', oname_prefix, attrname)),
171 171 encoding=encoding))
172 172 if inspect.isfunction(fn):
173 173 sources.append(dedent(getsource(fn)))
174 174 else:
175 175 # Default str/repr only prints function name,
176 176 # pretty.pretty prints module name too.
177 177 sources.append(cast_unicode(
178 178 '%s%s = %s\n' % (
179 179 oname_prefix, attrname, pretty(fn)),
180 180 encoding=encoding))
181 181 if sources:
182 182 return '\n'.join(sources)
183 183 else:
184 184 return None
185 185
186 186 else:
187 187 # Get source for non-property objects.
188 188
189 189 obj = _get_wrapped(obj)
190 190
191 191 try:
192 192 src = inspect.getsource(obj)
193 193 except TypeError:
194 194 # The object itself provided no meaningful source, try looking for
195 195 # its class definition instead.
196 196 if hasattr(obj, '__class__'):
197 197 try:
198 198 src = inspect.getsource(obj.__class__)
199 199 except TypeError:
200 200 return None
201 201
202 202 encoding = get_encoding(obj)
203 203 return cast_unicode(src, encoding=encoding)
204 204
205 205
206 206 def is_simple_callable(obj):
207 207 """True if obj is a function ()"""
208 208 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
209 209 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
210 210
211 211
212 212 def getargspec(obj):
213 213 """Wrapper around :func:`inspect.getfullargspec` on Python 3, and
214 214 :func:inspect.getargspec` on Python 2.
215 215
216 216 In addition to functions and methods, this can also handle objects with a
217 217 ``__call__`` attribute.
218 218 """
219 219 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
220 220 obj = obj.__call__
221 221
222 222 return inspect.getfullargspec(obj) if PY3 else inspect.getargspec(obj)
223 223
224 224
225 225 def format_argspec(argspec):
226 226 """Format argspect, convenience wrapper around inspect's.
227 227
228 228 This takes a dict instead of ordered arguments and calls
229 229 inspect.format_argspec with the arguments in the necessary order.
230 230 """
231 231 return inspect.formatargspec(argspec['args'], argspec['varargs'],
232 232 argspec['varkw'], argspec['defaults'])
233 233
234 234
235 235 def call_tip(oinfo, format_call=True):
236 236 """Extract call tip data from an oinfo dict.
237 237
238 238 Parameters
239 239 ----------
240 240 oinfo : dict
241 241
242 242 format_call : bool, optional
243 243 If True, the call line is formatted and returned as a string. If not, a
244 244 tuple of (name, argspec) is returned.
245 245
246 246 Returns
247 247 -------
248 248 call_info : None, str or (str, dict) tuple.
249 249 When format_call is True, the whole call information is formattted as a
250 250 single string. Otherwise, the object's name and its argspec dict are
251 251 returned. If no call information is available, None is returned.
252 252
253 253 docstring : str or None
254 254 The most relevant docstring for calling purposes is returned, if
255 255 available. The priority is: call docstring for callable instances, then
256 256 constructor docstring for classes, then main object's docstring otherwise
257 257 (regular functions).
258 258 """
259 259 # Get call definition
260 260 argspec = oinfo.get('argspec')
261 261 if argspec is None:
262 262 call_line = None
263 263 else:
264 264 # Callable objects will have 'self' as their first argument, prune
265 265 # it out if it's there for clarity (since users do *not* pass an
266 266 # extra first argument explicitly).
267 267 try:
268 268 has_self = argspec['args'][0] == 'self'
269 269 except (KeyError, IndexError):
270 270 pass
271 271 else:
272 272 if has_self:
273 273 argspec['args'] = argspec['args'][1:]
274 274
275 275 call_line = oinfo['name']+format_argspec(argspec)
276 276
277 277 # Now get docstring.
278 278 # The priority is: call docstring, constructor docstring, main one.
279 279 doc = oinfo.get('call_docstring')
280 280 if doc is None:
281 281 doc = oinfo.get('init_docstring')
282 282 if doc is None:
283 283 doc = oinfo.get('docstring','')
284 284
285 285 return call_line, doc
286 286
287 287
288 288 def _get_wrapped(obj):
289 289 """Get the original object if wrapped in one or more @decorators
290 290
291 291 Some objects automatically construct similar objects on any unrecognised
292 292 attribute access (e.g. unittest.mock.call). To protect against infinite loops,
293 293 this will arbitrarily cut off after 100 levels of obj.__wrapped__
294 294 attribute access. --TK, Jan 2016
295 295 """
296 296 orig_obj = obj
297 297 i = 0
298 298 while safe_hasattr(obj, '__wrapped__'):
299 299 obj = obj.__wrapped__
300 300 i += 1
301 301 if i > 100:
302 302 # __wrapped__ is probably a lie, so return the thing we started with
303 303 return orig_obj
304 304 return obj
305 305
306 306 def find_file(obj):
307 307 """Find the absolute path to the file where an object was defined.
308 308
309 309 This is essentially a robust wrapper around `inspect.getabsfile`.
310 310
311 311 Returns None if no file can be found.
312 312
313 313 Parameters
314 314 ----------
315 315 obj : any Python object
316 316
317 317 Returns
318 318 -------
319 319 fname : str
320 320 The absolute path to the file where the object was defined.
321 321 """
322 322 obj = _get_wrapped(obj)
323 323
324 324 fname = None
325 325 try:
326 326 fname = inspect.getabsfile(obj)
327 327 except TypeError:
328 328 # For an instance, the file that matters is where its class was
329 329 # declared.
330 330 if hasattr(obj, '__class__'):
331 331 try:
332 332 fname = inspect.getabsfile(obj.__class__)
333 333 except TypeError:
334 334 # Can happen for builtins
335 335 pass
336 336 except:
337 337 pass
338 338 return cast_unicode(fname)
339 339
340 340
341 341 def find_source_lines(obj):
342 342 """Find the line number in a file where an object was defined.
343 343
344 344 This is essentially a robust wrapper around `inspect.getsourcelines`.
345 345
346 346 Returns None if no file can be found.
347 347
348 348 Parameters
349 349 ----------
350 350 obj : any Python object
351 351
352 352 Returns
353 353 -------
354 354 lineno : int
355 355 The line number where the object definition starts.
356 356 """
357 357 obj = _get_wrapped(obj)
358 358
359 359 try:
360 360 try:
361 361 lineno = inspect.getsourcelines(obj)[1]
362 362 except TypeError:
363 363 # For instances, try the class object like getsource() does
364 364 if hasattr(obj, '__class__'):
365 365 lineno = inspect.getsourcelines(obj.__class__)[1]
366 366 else:
367 367 lineno = None
368 368 except:
369 369 return None
370 370
371 371 return lineno
372 372
373 373 class Inspector(Colorable):
374 374
375 375 def __init__(self, color_table=InspectColors,
376 376 code_color_table=PyColorize.ANSICodeColors,
377 377 scheme='NoColor',
378 378 str_detail_level=0,
379 379 parent=None, config=None):
380 380 super(Inspector, self).__init__(parent=parent, config=config)
381 381 self.color_table = color_table
382 382 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
383 383 self.format = self.parser.format
384 384 self.str_detail_level = str_detail_level
385 385 self.set_active_scheme(scheme)
386 386
387 387 def _getdef(self,obj,oname=''):
388 388 """Return the call signature for any callable object.
389 389
390 390 If any exception is generated, None is returned instead and the
391 391 exception is suppressed."""
392 392 try:
393 393 hdef = oname + str(signature(obj))
394 394 return cast_unicode(hdef)
395 395 except:
396 396 return None
397 397
398 398 def __head(self,h):
399 399 """Return a header string with proper colors."""
400 400 return '%s%s%s' % (self.color_table.active_colors.header,h,
401 401 self.color_table.active_colors.normal)
402 402
403 403 def set_active_scheme(self, scheme):
404 404 self.color_table.set_active_scheme(scheme)
405 405 self.parser.color_table.set_active_scheme(scheme)
406 406
407 407 def noinfo(self, msg, oname):
408 408 """Generic message when no information is found."""
409 409 print('No %s found' % msg, end=' ')
410 410 if oname:
411 411 print('for %s' % oname)
412 412 else:
413 413 print()
414 414
415 415 def pdef(self, obj, oname=''):
416 416 """Print the call signature for any callable object.
417 417
418 418 If the object is a class, print the constructor information."""
419 419
420 420 if not callable(obj):
421 421 print('Object is not callable.')
422 422 return
423 423
424 424 header = ''
425 425
426 426 if inspect.isclass(obj):
427 427 header = self.__head('Class constructor information:\n')
428 428 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
429 429 obj = obj.__call__
430 430
431 431 output = self._getdef(obj,oname)
432 432 if output is None:
433 433 self.noinfo('definition header',oname)
434 434 else:
435 435 print(header,self.format(output), end=' ')
436 436
437 437 # In Python 3, all classes are new-style, so they all have __init__.
438 438 @skip_doctest
439 439 def pdoc(self, obj, oname='', formatter=None):
440 440 """Print the docstring for any object.
441 441
442 442 Optional:
443 443 -formatter: a function to run the docstring through for specially
444 444 formatted docstrings.
445 445
446 446 Examples
447 447 --------
448 448
449 449 In [1]: class NoInit:
450 450 ...: pass
451 451
452 452 In [2]: class NoDoc:
453 453 ...: def __init__(self):
454 454 ...: pass
455 455
456 456 In [3]: %pdoc NoDoc
457 457 No documentation found for NoDoc
458 458
459 459 In [4]: %pdoc NoInit
460 460 No documentation found for NoInit
461 461
462 462 In [5]: obj = NoInit()
463 463
464 464 In [6]: %pdoc obj
465 465 No documentation found for obj
466 466
467 467 In [5]: obj2 = NoDoc()
468 468
469 469 In [6]: %pdoc obj2
470 470 No documentation found for obj2
471 471 """
472 472
473 473 head = self.__head # For convenience
474 474 lines = []
475 475 ds = getdoc(obj)
476 476 if formatter:
477 477 ds = formatter(ds).get('plain/text', ds)
478 478 if ds:
479 479 lines.append(head("Class docstring:"))
480 480 lines.append(indent(ds))
481 481 if inspect.isclass(obj) and hasattr(obj, '__init__'):
482 482 init_ds = getdoc(obj.__init__)
483 483 if init_ds is not None:
484 484 lines.append(head("Init docstring:"))
485 485 lines.append(indent(init_ds))
486 486 elif hasattr(obj,'__call__'):
487 487 call_ds = getdoc(obj.__call__)
488 488 if call_ds:
489 489 lines.append(head("Call docstring:"))
490 490 lines.append(indent(call_ds))
491 491
492 492 if not lines:
493 493 self.noinfo('documentation',oname)
494 494 else:
495 495 page.page('\n'.join(lines))
496 496
497 497 def psource(self, obj, oname=''):
498 498 """Print the source code for an object."""
499 499
500 500 # Flush the source cache because inspect can return out-of-date source
501 501 linecache.checkcache()
502 502 try:
503 503 src = getsource(obj, oname=oname)
504 504 except Exception:
505 505 src = None
506 506
507 507 if src is None:
508 508 self.noinfo('source', oname)
509 509 else:
510 510 page.page(self.format(src))
511 511
512 512 def pfile(self, obj, oname=''):
513 513 """Show the whole file where an object was defined."""
514 514
515 515 lineno = find_source_lines(obj)
516 516 if lineno is None:
517 517 self.noinfo('file', oname)
518 518 return
519 519
520 520 ofile = find_file(obj)
521 521 # run contents of file through pager starting at line where the object
522 522 # is defined, as long as the file isn't binary and is actually on the
523 523 # filesystem.
524 524 if ofile.endswith(('.so', '.dll', '.pyd')):
525 525 print('File %r is binary, not printing.' % ofile)
526 526 elif not os.path.isfile(ofile):
527 527 print('File %r does not exist, not printing.' % ofile)
528 528 else:
529 529 # Print only text files, not extension binaries. Note that
530 530 # getsourcelines returns lineno with 1-offset and page() uses
531 531 # 0-offset, so we must adjust.
532 532 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
533 533
534 534 def _format_fields(self, fields, title_width=0):
535 535 """Formats a list of fields for display.
536 536
537 537 Parameters
538 538 ----------
539 539 fields : list
540 540 A list of 2-tuples: (field_title, field_content)
541 541 title_width : int
542 542 How many characters to pad titles to. Default to longest title.
543 543 """
544 544 out = []
545 545 header = self.__head
546 546 if title_width == 0:
547 547 title_width = max(len(title) + 2 for title, _ in fields)
548 548 for title, content in fields:
549 549 if len(content.splitlines()) > 1:
550 550 title = header(title + ':') + '\n'
551 551 else:
552 552 title = header((title + ':').ljust(title_width))
553 553 out.append(cast_unicode(title) + cast_unicode(content))
554 554 return "\n".join(out)
555 555
556 556 def _mime_format(self, text, formatter=None):
557 557 """Return a mime bundle representation of the input text.
558 558
559 559 - if `formatter` is None, the returned mime bundle has
560 560 a `text/plain` field, with the input text.
561 561 a `text/html` field with a `<pre>` tag containing the input text.
562 562
563 563 - if `formatter` is not None, it must be a callable transforming the
564 564 input text into a mime bundle. Default values for `text/plain` and
565 565 `text/html` representations are the ones described above.
566 566
567 567 Note:
568 568
569 569 Formatters returning strings are supported but this behavior is deprecated.
570 570
571 571 """
572 572 text = cast_unicode(text)
573 573 defaults = {
574 574 'text/plain': text,
575 575 'text/html': '<pre>' + text + '</pre>'
576 576 }
577 577
578 578 if formatter is None:
579 579 return defaults
580 580 else:
581 581 formatted = formatter(text)
582 582
583 583 if not isinstance(formatted, dict):
584 584 # Handle the deprecated behavior of a formatter returning
585 585 # a string instead of a mime bundle.
586 586 return {
587 587 'text/plain': formatted,
588 588 'text/html': '<pre>' + formatted + '</pre>'
589 589 }
590 590
591 591 else:
592 592 return dict(defaults, **formatted)
593 593
594 594
595 595 def format_mime(self, bundle):
596 596
597 597 text_plain = bundle['text/plain']
598 598
599 599 text = ''
600 600 heads, bodies = list(zip(*text_plain))
601 601 _len = max(len(h) for h in heads)
602 602
603 603 for head, body in zip(heads, bodies):
604 604 body = body.strip('\n')
605 605 delim = '\n' if '\n' in body else ' '
606 606 text += self.__head(head+':') + (_len - len(head))*' ' +delim + body +'\n'
607 607
608 608 bundle['text/plain'] = text
609 609 return bundle
610 610
611 611 def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
612 612 """Retrieve an info dict and format it."""
613 613
614 614 info = self._info(obj, oname=oname, info=info, detail_level=detail_level)
615 615
616 616 _mime = {
617 617 'text/plain': [],
618 618 'text/html': '',
619 619 }
620 620
621 621 def append_field(bundle, title, key, formatter=None):
622 622 field = info[key]
623 623 if field is not None:
624 624 formatted_field = self._mime_format(field, formatter)
625 625 bundle['text/plain'].append((title, formatted_field['text/plain']))
626 626 bundle['text/html'] += '<h1>' + title + '</h1>\n' + formatted_field['text/html'] + '\n'
627 627
628 628 def code_formatter(text):
629 629 return {
630 630 'text/plain': self.format(text),
631 631 'text/html': pylight(text)
632 632 }
633 633
634 634 if info['isalias']:
635 635 append_field(_mime, 'Repr', 'string_form')
636 636
637 637 elif info['ismagic']:
638 638 if detail_level > 0:
639 639 append_field(_mime, 'Source', 'source', code_formatter)
640 640 else:
641 641 append_field(_mime, 'Docstring', 'docstring', formatter)
642 642 append_field(_mime, 'File', 'file')
643 643
644 644 elif info['isclass'] or is_simple_callable(obj):
645 645 # Functions, methods, classes
646 646 append_field(_mime, 'Signature', 'definition', code_formatter)
647 647 append_field(_mime, 'Init signature', 'init_definition', code_formatter)
648 648 if detail_level > 0:
649 649 append_field(_mime, 'Source', 'source', code_formatter)
650 650 else:
651 651 append_field(_mime, 'Docstring', 'docstring', formatter)
652 652 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
653 653
654 654 append_field(_mime, 'File', 'file')
655 655 append_field(_mime, 'Type', 'type_name')
656 656
657 657 else:
658 658 # General Python objects
659 659 append_field(_mime, 'Signature', 'definition', code_formatter)
660 660 append_field(_mime, 'Call signature', 'call_def', code_formatter)
661 661
662 662 append_field(_mime, 'Type', 'type_name')
663 663
664 664 # Base class for old-style instances
665 665 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
666 666 append_field(_mime, 'Base Class', 'base_class')
667 667
668 668 append_field(_mime, 'String form', 'string_form')
669 669
670 670 # Namespace
671 671 if info['namespace'] != 'Interactive':
672 672 append_field(_mime, 'Namespace', 'namespace')
673 673
674 674 append_field(_mime, 'Length', 'length')
675 675 append_field(_mime, 'File', 'file')
676 676
677 677 # Source or docstring, depending on detail level and whether
678 678 # source found.
679 679 if detail_level > 0:
680 680 append_field(_mime, 'Source', 'source', code_formatter)
681 681 else:
682 682 append_field(_mime, 'Docstring', 'docstring', formatter)
683 683
684 684 append_field(_mime, 'Class docstring', 'class_docstring', formatter)
685 685 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
686 686 append_field(_mime, 'Call docstring', 'call_docstring', formatter)
687 687
688 688
689 689 return self.format_mime(_mime)
690 690
691 691 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0, enable_html_pager=True):
692 692 """Show detailed information about an object.
693 693
694 694 Optional arguments:
695 695
696 696 - oname: name of the variable pointing to the object.
697 697
698 698 - formatter: callable (optional)
699 699 A special formatter for docstrings.
700 700
701 701 The formatter is a callable that takes a string as an input
702 702 and returns either a formatted string or a mime type bundle
703 703 in the form of a dictionnary.
704 704
705 705 Although the support of custom formatter returning a string
706 706 instead of a mime type bundle is deprecated.
707 707
708 708 - info: a structure with some information fields which may have been
709 709 precomputed already.
710 710
711 711 - detail_level: if set to 1, more information is given.
712 712 """
713 713 info = self._get_info(obj, oname, formatter, info, detail_level)
714 714 if not enable_html_pager:
715 715 del info['text/html']
716 716 page.page(info)
717 717
718 718 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
719 719 """DEPRECATED. Compute a dict with detailed information about an object.
720 720 """
721 721 if formatter is not None:
722 722 warnings.warn('The `formatter` keyword argument to `Inspector.info`'
723 723 'is deprecated as of IPython 5.0 and will have no effects.',
724 724 DeprecationWarning, stacklevel=2)
725 725 return self._info(obj, oname=oname, info=info, detail_level=detail_level)
726 726
727 727 def _info(self, obj, oname='', info=None, detail_level=0):
728 728 """Compute a dict with detailed information about an object.
729 729
730 730 Optional arguments:
731 731
732 732 - oname: name of the variable pointing to the object.
733 733
734 734 - info: a structure with some information fields which may have been
735 735 precomputed already.
736 736
737 737 - detail_level: if set to 1, more information is given.
738 738 """
739 739
740 740 obj_type = type(obj)
741 741
742 742 if info is None:
743 743 ismagic = 0
744 744 isalias = 0
745 745 ospace = ''
746 746 else:
747 747 ismagic = info.ismagic
748 748 isalias = info.isalias
749 749 ospace = info.namespace
750 750
751 751 # Get docstring, special-casing aliases:
752 752 if isalias:
753 753 if not callable(obj):
754 754 try:
755 755 ds = "Alias to the system command:\n %s" % obj[1]
756 756 except:
757 757 ds = "Alias: " + str(obj)
758 758 else:
759 759 ds = "Alias to " + str(obj)
760 760 if obj.__doc__:
761 761 ds += "\nDocstring:\n" + obj.__doc__
762 762 else:
763 763 ds = getdoc(obj)
764 764 if ds is None:
765 765 ds = '<no docstring>'
766 766
767 767 # store output in a dict, we initialize it here and fill it as we go
768 768 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
769 769
770 770 string_max = 200 # max size of strings to show (snipped if longer)
771 771 shalf = int((string_max - 5) / 2)
772 772
773 773 if ismagic:
774 774 obj_type_name = 'Magic function'
775 775 elif isalias:
776 776 obj_type_name = 'System alias'
777 777 else:
778 778 obj_type_name = obj_type.__name__
779 779 out['type_name'] = obj_type_name
780 780
781 781 try:
782 782 bclass = obj.__class__
783 783 out['base_class'] = str(bclass)
784 784 except: pass
785 785
786 786 # String form, but snip if too long in ? form (full in ??)
787 787 if detail_level >= self.str_detail_level:
788 788 try:
789 789 ostr = str(obj)
790 790 str_head = 'string_form'
791 791 if not detail_level and len(ostr)>string_max:
792 792 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
793 793 ostr = ("\n" + " " * len(str_head.expandtabs())).\
794 794 join(q.strip() for q in ostr.split("\n"))
795 795 out[str_head] = ostr
796 796 except:
797 797 pass
798 798
799 799 if ospace:
800 800 out['namespace'] = ospace
801 801
802 802 # Length (for strings and lists)
803 803 try:
804 804 out['length'] = str(len(obj))
805 805 except: pass
806 806
807 807 # Filename where object was defined
808 808 binary_file = False
809 809 fname = find_file(obj)
810 810 if fname is None:
811 811 # if anything goes wrong, we don't want to show source, so it's as
812 812 # if the file was binary
813 813 binary_file = True
814 814 else:
815 815 if fname.endswith(('.so', '.dll', '.pyd')):
816 816 binary_file = True
817 817 elif fname.endswith('<string>'):
818 818 fname = 'Dynamically generated function. No source code available.'
819 819 out['file'] = compress_user(fname)
820 820
821 821 # Original source code for a callable, class or property.
822 822 if detail_level:
823 823 # Flush the source cache because inspect can return out-of-date
824 824 # source
825 825 linecache.checkcache()
826 826 try:
827 827 if isinstance(obj, property) or not binary_file:
828 828 src = getsource(obj, oname)
829 829 if src is not None:
830 830 src = src.rstrip()
831 831 out['source'] = src
832 832
833 833 except Exception:
834 834 pass
835 835
836 836 # Add docstring only if no source is to be shown (avoid repetitions).
837 837 if ds and out.get('source', None) is None:
838 838 out['docstring'] = ds
839 839
840 840 # Constructor docstring for classes
841 841 if inspect.isclass(obj):
842 842 out['isclass'] = True
843 843
844 844 # get the init signature:
845 845 try:
846 846 init_def = self._getdef(obj, oname)
847 847 except AttributeError:
848 848 init_def = None
849 849
850 850 # get the __init__ docstring
851 851 try:
852 852 obj_init = obj.__init__
853 853 except AttributeError:
854 854 init_ds = None
855 855 else:
856 856 if init_def is None:
857 857 # Get signature from init if top-level sig failed.
858 858 # Can happen for built-in types (list, etc.).
859 859 try:
860 860 init_def = self._getdef(obj_init, oname)
861 861 except AttributeError:
862 862 pass
863 863 init_ds = getdoc(obj_init)
864 864 # Skip Python's auto-generated docstrings
865 865 if init_ds == _object_init_docstring:
866 866 init_ds = None
867 867
868 868 if init_def:
869 869 out['init_definition'] = init_def
870 870
871 871 if init_ds:
872 872 out['init_docstring'] = init_ds
873 873
874 874 # and class docstring for instances:
875 875 else:
876 876 # reconstruct the function definition and print it:
877 877 defln = self._getdef(obj, oname)
878 878 if defln:
879 879 out['definition'] = defln
880 880
881 881 # First, check whether the instance docstring is identical to the
882 882 # class one, and print it separately if they don't coincide. In
883 883 # most cases they will, but it's nice to print all the info for
884 884 # objects which use instance-customized docstrings.
885 885 if ds:
886 886 try:
887 887 cls = getattr(obj,'__class__')
888 888 except:
889 889 class_ds = None
890 890 else:
891 891 class_ds = getdoc(cls)
892 892 # Skip Python's auto-generated docstrings
893 893 if class_ds in _builtin_type_docstrings:
894 894 class_ds = None
895 895 if class_ds and ds != class_ds:
896 896 out['class_docstring'] = class_ds
897 897
898 898 # Next, try to show constructor docstrings
899 899 try:
900 900 init_ds = getdoc(obj.__init__)
901 901 # Skip Python's auto-generated docstrings
902 902 if init_ds == _object_init_docstring:
903 903 init_ds = None
904 904 except AttributeError:
905 905 init_ds = None
906 906 if init_ds:
907 907 out['init_docstring'] = init_ds
908 908
909 909 # Call form docstring for callable instances
910 910 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
911 911 call_def = self._getdef(obj.__call__, oname)
912 912 if call_def and (call_def != out.get('definition')):
913 913 # it may never be the case that call def and definition differ,
914 914 # but don't include the same signature twice
915 915 out['call_def'] = call_def
916 916 call_ds = getdoc(obj.__call__)
917 917 # Skip Python's auto-generated docstrings
918 918 if call_ds == _func_call_docstring:
919 919 call_ds = None
920 920 if call_ds:
921 921 out['call_docstring'] = call_ds
922 922
923 923 # Compute the object's argspec as a callable. The key is to decide
924 924 # whether to pull it from the object itself, from its __init__ or
925 925 # from its __call__ method.
926 926
927 927 if inspect.isclass(obj):
928 928 # Old-style classes need not have an __init__
929 929 callable_obj = getattr(obj, "__init__", None)
930 930 elif callable(obj):
931 931 callable_obj = obj
932 932 else:
933 933 callable_obj = None
934 934
935 935 if callable_obj is not None:
936 936 try:
937 937 argspec = getargspec(callable_obj)
938 938 except (TypeError, AttributeError):
939 939 # For extensions/builtins we can't retrieve the argspec
940 940 pass
941 941 else:
942 942 # named tuples' _asdict() method returns an OrderedDict, but we
943 943 # we want a normal
944 944 out['argspec'] = argspec_dict = dict(argspec._asdict())
945 945 # We called this varkw before argspec became a named tuple.
946 946 # With getfullargspec it's also called varkw.
947 947 if 'varkw' not in argspec_dict:
948 948 argspec_dict['varkw'] = argspec_dict.pop('keywords')
949 949
950 950 return object_info(**out)
951 951
952 952 def psearch(self,pattern,ns_table,ns_search=[],
953 953 ignore_case=False,show_all=False):
954 954 """Search namespaces with wildcards for objects.
955 955
956 956 Arguments:
957 957
958 958 - pattern: string containing shell-like wildcards to use in namespace
959 959 searches and optionally a type specification to narrow the search to
960 960 objects of that type.
961 961
962 962 - ns_table: dict of name->namespaces for search.
963 963
964 964 Optional arguments:
965 965
966 966 - ns_search: list of namespace names to include in search.
967 967
968 968 - ignore_case(False): make the search case-insensitive.
969 969
970 970 - show_all(False): show all names, including those starting with
971 971 underscores.
972 972 """
973 973 #print 'ps pattern:<%r>' % pattern # dbg
974 974
975 975 # defaults
976 976 type_pattern = 'all'
977 977 filter = ''
978 978
979 979 cmds = pattern.split()
980 980 len_cmds = len(cmds)
981 981 if len_cmds == 1:
982 982 # Only filter pattern given
983 983 filter = cmds[0]
984 984 elif len_cmds == 2:
985 985 # Both filter and type specified
986 986 filter,type_pattern = cmds
987 987 else:
988 988 raise ValueError('invalid argument string for psearch: <%s>' %
989 989 pattern)
990 990
991 991 # filter search namespaces
992 992 for name in ns_search:
993 993 if name not in ns_table:
994 994 raise ValueError('invalid namespace <%s>. Valid names: %s' %
995 995 (name,ns_table.keys()))
996 996
997 997 #print 'type_pattern:',type_pattern # dbg
998 998 search_result, namespaces_seen = set(), set()
999 999 for ns_name in ns_search:
1000 1000 ns = ns_table[ns_name]
1001 1001 # Normally, locals and globals are the same, so we just check one.
1002 1002 if id(ns) in namespaces_seen:
1003 1003 continue
1004 1004 namespaces_seen.add(id(ns))
1005 1005 tmp_res = list_namespace(ns, type_pattern, filter,
1006 1006 ignore_case=ignore_case, show_all=show_all)
1007 1007 search_result.update(tmp_res)
1008 1008
1009 1009 page.page('\n'.join(sorted(search_result)))
@@ -1,454 +1,455 b''
1 1 """Tests for the object inspection functionality.
2 2 """
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7
8 from inspect import Signature, Parameter
8 9 import os
9 10 import re
10 11 import sys
11 12
12 13 import nose.tools as nt
13 14
14 15 from .. import oinspect
15 16 from IPython.core.magic import (Magics, magics_class, line_magic,
16 17 cell_magic, line_cell_magic,
17 18 register_line_magic, register_cell_magic,
18 19 register_line_cell_magic)
19 20 from decorator import decorator
21 from IPython import get_ipython
20 22 from IPython.testing.decorators import skipif
21 23 from IPython.testing.tools import AssertPrints
22 24 from IPython.utils.path import compress_user
23 25 from IPython.utils import py3compat
24 from IPython.utils.signatures import Signature, Parameter
25 26
26 27
27 28 #-----------------------------------------------------------------------------
28 29 # Globals and constants
29 30 #-----------------------------------------------------------------------------
30 31
31 32 inspector = oinspect.Inspector()
32 33 ip = get_ipython()
33 34
34 35 #-----------------------------------------------------------------------------
35 36 # Local utilities
36 37 #-----------------------------------------------------------------------------
37 38
38 39 # WARNING: since this test checks the line number where a function is
39 40 # defined, if any code is inserted above, the following line will need to be
40 41 # updated. Do NOT insert any whitespace between the next line and the function
41 42 # definition below.
42 THIS_LINE_NUMBER = 42 # Put here the actual number of this line
43 THIS_LINE_NUMBER = 43 # Put here the actual number of this line
43 44
44 45 from unittest import TestCase
45 46
46 47 class Test(TestCase):
47 48
48 49 def test_find_source_lines(self):
49 50 self.assertEqual(oinspect.find_source_lines(Test.test_find_source_lines),
50 51 THIS_LINE_NUMBER+6)
51 52
52 53
53 54 # A couple of utilities to ensure these tests work the same from a source or a
54 55 # binary install
55 56 def pyfile(fname):
56 57 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
57 58
58 59
59 60 def match_pyfiles(f1, f2):
60 61 nt.assert_equal(pyfile(f1), pyfile(f2))
61 62
62 63
63 64 def test_find_file():
64 65 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
65 66
66 67
67 68 def test_find_file_decorated1():
68 69
69 70 @decorator
70 71 def noop1(f):
71 def wrapper():
72 def wrapper(*a, **kw):
72 73 return f(*a, **kw)
73 74 return wrapper
74 75
75 76 @noop1
76 77 def f(x):
77 78 "My docstring"
78 79
79 80 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
80 81 nt.assert_equal(f.__doc__, "My docstring")
81 82
82 83
83 84 def test_find_file_decorated2():
84 85
85 86 @decorator
86 87 def noop2(f, *a, **kw):
87 88 return f(*a, **kw)
88 89
89 90 @noop2
90 91 @noop2
91 92 @noop2
92 93 def f(x):
93 94 "My docstring 2"
94 95
95 96 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
96 97 nt.assert_equal(f.__doc__, "My docstring 2")
97 98
98 99
99 100 def test_find_file_magic():
100 101 run = ip.find_line_magic('run')
101 102 nt.assert_not_equal(oinspect.find_file(run), None)
102 103
103 104
104 105 # A few generic objects we can then inspect in the tests below
105 106
106 107 class Call(object):
107 108 """This is the class docstring."""
108 109
109 110 def __init__(self, x, y=1):
110 111 """This is the constructor docstring."""
111 112
112 113 def __call__(self, *a, **kw):
113 114 """This is the call docstring."""
114 115
115 116 def method(self, x, z=2):
116 117 """Some method's docstring"""
117 118
118 119 class HasSignature(object):
119 120 """This is the class docstring."""
120 121 __signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)])
121 122
122 123 def __init__(self, *args):
123 124 """This is the init docstring"""
124 125
125 126
126 127 class SimpleClass(object):
127 128 def method(self, x, z=2):
128 129 """Some method's docstring"""
129 130
130 131
131 132 class OldStyle:
132 133 """An old-style class for testing."""
133 134 pass
134 135
135 136
136 137 def f(x, y=2, *a, **kw):
137 138 """A simple function."""
138 139
139 140
140 141 def g(y, z=3, *a, **kw):
141 142 pass # no docstring
142 143
143 144
144 145 @register_line_magic
145 146 def lmagic(line):
146 147 "A line magic"
147 148
148 149
149 150 @register_cell_magic
150 151 def cmagic(line, cell):
151 152 "A cell magic"
152 153
153 154
154 155 @register_line_cell_magic
155 156 def lcmagic(line, cell=None):
156 157 "A line/cell magic"
157 158
158 159
159 160 @magics_class
160 161 class SimpleMagics(Magics):
161 162 @line_magic
162 163 def Clmagic(self, cline):
163 164 "A class-based line magic"
164 165
165 166 @cell_magic
166 167 def Ccmagic(self, cline, ccell):
167 168 "A class-based cell magic"
168 169
169 170 @line_cell_magic
170 171 def Clcmagic(self, cline, ccell=None):
171 172 "A class-based line/cell magic"
172 173
173 174
174 175 class Awkward(object):
175 176 def __getattr__(self, name):
176 177 raise Exception(name)
177 178
178 179 class NoBoolCall:
179 180 """
180 181 callable with `__bool__` raising should still be inspect-able.
181 182 """
182 183
183 184 def __call__(self):
184 185 """does nothing"""
185 186 pass
186 187
187 188 def __bool__(self):
188 189 """just raise NotImplemented"""
189 190 raise NotImplementedError('Must be implemented')
190 191
191 192
192 193 class SerialLiar(object):
193 194 """Attribute accesses always get another copy of the same class.
194 195
195 196 unittest.mock.call does something similar, but it's not ideal for testing
196 197 as the failure mode is to eat all your RAM. This gives up after 10k levels.
197 198 """
198 199 def __init__(self, max_fibbing_twig, lies_told=0):
199 200 if lies_told > 10000:
200 201 raise RuntimeError('Nose too long, honesty is the best policy')
201 202 self.max_fibbing_twig = max_fibbing_twig
202 203 self.lies_told = lies_told
203 204 max_fibbing_twig[0] = max(max_fibbing_twig[0], lies_told)
204 205
205 206 def __getattr__(self, item):
206 207 return SerialLiar(self.max_fibbing_twig, self.lies_told + 1)
207 208
208 209
209 210 def check_calltip(obj, name, call, docstring):
210 211 """Generic check pattern all calltip tests will use"""
211 212 info = inspector.info(obj, name)
212 213 call_line, ds = oinspect.call_tip(info)
213 214 nt.assert_equal(call_line, call)
214 215 nt.assert_equal(ds, docstring)
215 216
216 217 #-----------------------------------------------------------------------------
217 218 # Tests
218 219 #-----------------------------------------------------------------------------
219 220
220 221 def test_calltip_class():
221 222 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
222 223
223 224
224 225 def test_calltip_instance():
225 226 c = Call(1)
226 227 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
227 228
228 229
229 230 def test_calltip_method():
230 231 c = Call(1)
231 232 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
232 233
233 234
234 235 def test_calltip_function():
235 236 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
236 237
237 238
238 239 def test_calltip_function2():
239 240 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
240 241
241 242
242 243 @skipif(sys.version_info >= (3, 5))
243 244 def test_calltip_builtin():
244 245 check_calltip(sum, 'sum', None, sum.__doc__)
245 246
246 247
247 248 def test_calltip_line_magic():
248 249 check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
249 250
250 251
251 252 def test_calltip_cell_magic():
252 253 check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
253 254
254 255
255 256 def test_calltip_line_cell_magic():
256 257 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
257 258 "A line/cell magic")
258 259
259 260
260 261 def test_class_magics():
261 262 cm = SimpleMagics(ip)
262 263 ip.register_magics(cm)
263 264 check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
264 265 "A class-based line magic")
265 266 check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
266 267 "A class-based cell magic")
267 268 check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
268 269 "A class-based line/cell magic")
269 270
270 271
271 272 def test_info():
272 273 "Check that Inspector.info fills out various fields as expected."
273 274 i = inspector.info(Call, oname='Call')
274 275 nt.assert_equal(i['type_name'], 'type')
275 276 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
276 277 nt.assert_equal(i['base_class'], expted_class)
277 278 nt.assert_regex(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'( at 0x[0-9a-f]{1,9})?>")
278 279 fname = __file__
279 280 if fname.endswith(".pyc"):
280 281 fname = fname[:-1]
281 282 # case-insensitive comparison needed on some filesystems
282 283 # e.g. Windows:
283 284 nt.assert_equal(i['file'].lower(), compress_user(fname).lower())
284 285 nt.assert_equal(i['definition'], None)
285 286 nt.assert_equal(i['docstring'], Call.__doc__)
286 287 nt.assert_equal(i['source'], None)
287 288 nt.assert_true(i['isclass'])
288 289 _self_py2 = '' if py3compat.PY3 else 'self, '
289 290 nt.assert_equal(i['init_definition'], "Call(%sx, y=1)" % _self_py2)
290 291 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
291 292
292 293 i = inspector.info(Call, detail_level=1)
293 294 nt.assert_not_equal(i['source'], None)
294 295 nt.assert_equal(i['docstring'], None)
295 296
296 297 c = Call(1)
297 298 c.__doc__ = "Modified instance docstring"
298 299 i = inspector.info(c)
299 300 nt.assert_equal(i['type_name'], 'Call')
300 301 nt.assert_equal(i['docstring'], "Modified instance docstring")
301 302 nt.assert_equal(i['class_docstring'], Call.__doc__)
302 303 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
303 304 nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
304 305
305 306 # Test old-style classes, which for example may not have an __init__ method.
306 307 if not py3compat.PY3:
307 308 i = inspector.info(OldStyle)
308 309 nt.assert_equal(i['type_name'], 'classobj')
309 310
310 311 i = inspector.info(OldStyle())
311 312 nt.assert_equal(i['type_name'], 'instance')
312 313 nt.assert_equal(i['docstring'], OldStyle.__doc__)
313 314
314 315 def test_class_signature():
315 316 info = inspector.info(HasSignature, 'HasSignature')
316 317 nt.assert_equal(info['init_definition'], "HasSignature(test)")
317 318 nt.assert_equal(info['init_docstring'], HasSignature.__init__.__doc__)
318 319
319 320 def test_info_awkward():
320 321 # Just test that this doesn't throw an error.
321 322 inspector.info(Awkward())
322 323
323 324 def test_bool_raise():
324 325 inspector.info(NoBoolCall())
325 326
326 327 def test_info_serialliar():
327 328 fib_tracker = [0]
328 329 inspector.info(SerialLiar(fib_tracker))
329 330
330 331 # Nested attribute access should be cut off at 100 levels deep to avoid
331 332 # infinite loops: https://github.com/ipython/ipython/issues/9122
332 333 nt.assert_less(fib_tracker[0], 9000)
333 334
334 335 def test_calldef_none():
335 336 # We should ignore __call__ for all of these.
336 337 for obj in [f, SimpleClass().method, any, str.upper]:
337 338 print(obj)
338 339 i = inspector.info(obj)
339 340 nt.assert_is(i['call_def'], None)
340 341
341 342 def f_kwarg(pos, *, kwonly):
342 343 pass
343 344
344 345 def test_definition_kwonlyargs():
345 346 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
346 347 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)")
347 348
348 349 def test_getdoc():
349 350 class A(object):
350 351 """standard docstring"""
351 352 pass
352 353
353 354 class B(object):
354 355 """standard docstring"""
355 356 def getdoc(self):
356 357 return "custom docstring"
357 358
358 359 class C(object):
359 360 """standard docstring"""
360 361 def getdoc(self):
361 362 return None
362 363
363 364 a = A()
364 365 b = B()
365 366 c = C()
366 367
367 368 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
368 369 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
369 370 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
370 371
371 372
372 373 def test_empty_property_has_no_source():
373 374 i = inspector.info(property(), detail_level=1)
374 375 nt.assert_is(i['source'], None)
375 376
376 377
377 378 def test_property_sources():
378 379 import zlib
379 380
380 381 class A(object):
381 382 @property
382 383 def foo(self):
383 384 return 'bar'
384 385
385 386 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
386 387
387 388 id = property(id)
388 389 compress = property(zlib.compress)
389 390
390 391 i = inspector.info(A.foo, detail_level=1)
391 392 nt.assert_in('def foo(self):', i['source'])
392 393 nt.assert_in('lambda self, v:', i['source'])
393 394
394 395 i = inspector.info(A.id, detail_level=1)
395 396 nt.assert_in('fget = <function id>', i['source'])
396 397
397 398 i = inspector.info(A.compress, detail_level=1)
398 399 nt.assert_in('fget = <function zlib.compress>', i['source'])
399 400
400 401
401 402 def test_property_docstring_is_in_info_for_detail_level_0():
402 403 class A(object):
403 404 @property
404 405 def foobar(self):
405 406 """This is `foobar` property."""
406 407 pass
407 408
408 409 ip.user_ns['a_obj'] = A()
409 410 nt.assert_equals(
410 411 'This is `foobar` property.',
411 412 ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
412 413
413 414 ip.user_ns['a_cls'] = A
414 415 nt.assert_equals(
415 416 'This is `foobar` property.',
416 417 ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
417 418
418 419
419 420 def test_pdef():
420 421 # See gh-1914
421 422 def foo(): pass
422 423 inspector.pdef(foo, 'foo')
423 424
424 425
425 426 def test_pinfo_nonascii():
426 427 # See gh-1177
427 428 from . import nonascii2
428 429 ip.user_ns['nonascii2'] = nonascii2
429 430 ip._inspect('pinfo', 'nonascii2', detail_level=1)
430 431
431 432
432 433 def test_pinfo_magic():
433 434 with AssertPrints('Docstring:'):
434 435 ip._inspect('pinfo', 'lsmagic', detail_level=0)
435 436
436 437 with AssertPrints('Source:'):
437 438 ip._inspect('pinfo', 'lsmagic', detail_level=1)
438 439
439 440
440 441 def test_init_colors():
441 442 # ensure colors are not present in signature info
442 443 info = inspector.info(HasSignature)
443 444 init_def = info['init_definition']
444 445 nt.assert_not_in('[0m', init_def)
445 446
446 447
447 448 def test_builtin_init():
448 449 info = inspector.info(list)
449 450 init_def = info['init_definition']
450 451 # Python < 3.4 can't get init definition from builtins,
451 452 # but still exercise the inspection in case of error-raising bugs.
452 453 if sys.version_info >= (3,4):
453 454 nt.assert_is_not_none(init_def)
454 455
@@ -1,11 +1,11 b''
1 """Function signature objects for callables.
1 """DEPRECATED: Function signature objects for callables.
2 2
3 3 Use the standard library version if available, as it is more up to date.
4 4 Fallback on backport otherwise.
5 5 """
6 6
7 import warnings
8 warnings.warn("{} backport for Python 2 is deprecated in IPython 6, which only supports Python 3".format(__name__),
9 DeprecationWarning, stacklevel=2)
7 10
8 try:
9 from inspect import BoundArguments, Parameter, Signature, signature
10 except ImportError:
11 from ._signatures import BoundArguments, Parameter, Signature, signature
11 from inspect import BoundArguments, Parameter, Signature, signature
1 NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (816 lines changed) Show them Hide them
General Comments 0
You need to be logged in to leave comments. Login now