##// END OF EJS Templates
simplify title_width expression
MinRK -
Show More
@@ -1,882 +1,881 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 #*****************************************************************************
11 11 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #*****************************************************************************
16 16 from __future__ import print_function
17 17
18 18 __all__ = ['Inspector','InspectColors']
19 19
20 20 # stdlib modules
21 21 import inspect
22 22 import linecache
23 23 import os
24 24 import types
25 25 import io as stdlib_io
26 26
27 27 try:
28 28 from itertools import izip_longest
29 29 except ImportError:
30 30 from itertools import zip_longest as izip_longest
31 31
32 32 # IPython's own
33 33 from IPython.core import page
34 34 from IPython.testing.skipdoctest import skip_doctest_py3
35 35 from IPython.utils import PyColorize
36 36 from IPython.utils import io
37 37 from IPython.utils import openpy
38 38 from IPython.utils import py3compat
39 39 from IPython.utils.dir2 import safe_hasattr
40 40 from IPython.utils.text import indent
41 41 from IPython.utils.wildcard import list_namespace
42 42 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
43 43 from IPython.utils.py3compat import cast_unicode, string_types, PY3
44 44
45 45 # builtin docstrings to ignore
46 46 _func_call_docstring = types.FunctionType.__call__.__doc__
47 47 _object_init_docstring = object.__init__.__doc__
48 48 _builtin_type_docstrings = {
49 49 t.__doc__ for t in (types.ModuleType, types.MethodType, types.FunctionType)
50 50 }
51 51
52 52 _builtin_func_type = type(all)
53 53 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
54 54 #****************************************************************************
55 55 # Builtin color schemes
56 56
57 57 Colors = TermColors # just a shorthand
58 58
59 59 # Build a few color schemes
60 60 NoColor = ColorScheme(
61 61 'NoColor',{
62 62 'header' : Colors.NoColor,
63 63 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
64 64 } )
65 65
66 66 LinuxColors = ColorScheme(
67 67 'Linux',{
68 68 'header' : Colors.LightRed,
69 69 'normal' : Colors.Normal # color off (usu. Colors.Normal)
70 70 } )
71 71
72 72 LightBGColors = ColorScheme(
73 73 'LightBG',{
74 74 'header' : Colors.Red,
75 75 'normal' : Colors.Normal # color off (usu. Colors.Normal)
76 76 } )
77 77
78 78 # Build table of color schemes (needed by the parser)
79 79 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
80 80 'Linux')
81 81
82 82 #****************************************************************************
83 83 # Auxiliary functions and objects
84 84
85 85 # See the messaging spec for the definition of all these fields. This list
86 86 # effectively defines the order of display
87 87 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
88 88 'length', 'file', 'definition', 'docstring', 'source',
89 89 'init_definition', 'class_docstring', 'init_docstring',
90 90 'call_def', 'call_docstring',
91 91 # These won't be printed but will be used to determine how to
92 92 # format the object
93 93 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
94 94 ]
95 95
96 96
97 97 def object_info(**kw):
98 98 """Make an object info dict with all fields present."""
99 99 infodict = dict(izip_longest(info_fields, [None]))
100 100 infodict.update(kw)
101 101 return infodict
102 102
103 103
104 104 def get_encoding(obj):
105 105 """Get encoding for python source file defining obj
106 106
107 107 Returns None if obj is not defined in a sourcefile.
108 108 """
109 109 ofile = find_file(obj)
110 110 # run contents of file through pager starting at line where the object
111 111 # is defined, as long as the file isn't binary and is actually on the
112 112 # filesystem.
113 113 if ofile is None:
114 114 return None
115 115 elif ofile.endswith(('.so', '.dll', '.pyd')):
116 116 return None
117 117 elif not os.path.isfile(ofile):
118 118 return None
119 119 else:
120 120 # Print only text files, not extension binaries. Note that
121 121 # getsourcelines returns lineno with 1-offset and page() uses
122 122 # 0-offset, so we must adjust.
123 123 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
124 124 encoding, lines = openpy.detect_encoding(buffer.readline)
125 125 return encoding
126 126
127 127 def getdoc(obj):
128 128 """Stable wrapper around inspect.getdoc.
129 129
130 130 This can't crash because of attribute problems.
131 131
132 132 It also attempts to call a getdoc() method on the given object. This
133 133 allows objects which provide their docstrings via non-standard mechanisms
134 134 (like Pyro proxies) to still be inspected by ipython's ? system."""
135 135 # Allow objects to offer customized documentation via a getdoc method:
136 136 try:
137 137 ds = obj.getdoc()
138 138 except Exception:
139 139 pass
140 140 else:
141 141 # if we get extra info, we add it to the normal docstring.
142 142 if isinstance(ds, string_types):
143 143 return inspect.cleandoc(ds)
144 144
145 145 try:
146 146 docstr = inspect.getdoc(obj)
147 147 encoding = get_encoding(obj)
148 148 return py3compat.cast_unicode(docstr, encoding=encoding)
149 149 except Exception:
150 150 # Harden against an inspect failure, which can occur with
151 151 # SWIG-wrapped extensions.
152 152 raise
153 153 return None
154 154
155 155
156 156 def getsource(obj,is_binary=False):
157 157 """Wrapper around inspect.getsource.
158 158
159 159 This can be modified by other projects to provide customized source
160 160 extraction.
161 161
162 162 Inputs:
163 163
164 164 - obj: an object whose source code we will attempt to extract.
165 165
166 166 Optional inputs:
167 167
168 168 - is_binary: whether the object is known to come from a binary source.
169 169 This implementation will skip returning any output for binary objects, but
170 170 custom extractors may know how to meaningfully process them."""
171 171
172 172 if is_binary:
173 173 return None
174 174 else:
175 175 # get source if obj was decorated with @decorator
176 176 if hasattr(obj,"__wrapped__"):
177 177 obj = obj.__wrapped__
178 178 try:
179 179 src = inspect.getsource(obj)
180 180 except TypeError:
181 181 if hasattr(obj,'__class__'):
182 182 src = inspect.getsource(obj.__class__)
183 183 encoding = get_encoding(obj)
184 184 return cast_unicode(src, encoding=encoding)
185 185
186 186
187 187 def is_simple_callable(obj):
188 188 """True if obj is a function ()"""
189 189 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
190 190 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
191 191
192 192
193 193 def getargspec(obj):
194 194 """Wrapper around :func:`inspect.getfullargspec` on Python 3, and
195 195 :func:inspect.getargspec` on Python 2.
196 196
197 197 In addition to functions and methods, this can also handle objects with a
198 198 ``__call__`` attribute.
199 199 """
200 200 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
201 201 obj = obj.__call__
202 202
203 203 return inspect.getfullargspec(obj) if PY3 else inspect.getargspec(obj)
204 204
205 205
206 206 def format_argspec(argspec):
207 207 """Format argspect, convenience wrapper around inspect's.
208 208
209 209 This takes a dict instead of ordered arguments and calls
210 210 inspect.format_argspec with the arguments in the necessary order.
211 211 """
212 212 return inspect.formatargspec(argspec['args'], argspec['varargs'],
213 213 argspec['varkw'], argspec['defaults'])
214 214
215 215
216 216 def call_tip(oinfo, format_call=True):
217 217 """Extract call tip data from an oinfo dict.
218 218
219 219 Parameters
220 220 ----------
221 221 oinfo : dict
222 222
223 223 format_call : bool, optional
224 224 If True, the call line is formatted and returned as a string. If not, a
225 225 tuple of (name, argspec) is returned.
226 226
227 227 Returns
228 228 -------
229 229 call_info : None, str or (str, dict) tuple.
230 230 When format_call is True, the whole call information is formattted as a
231 231 single string. Otherwise, the object's name and its argspec dict are
232 232 returned. If no call information is available, None is returned.
233 233
234 234 docstring : str or None
235 235 The most relevant docstring for calling purposes is returned, if
236 236 available. The priority is: call docstring for callable instances, then
237 237 constructor docstring for classes, then main object's docstring otherwise
238 238 (regular functions).
239 239 """
240 240 # Get call definition
241 241 argspec = oinfo.get('argspec')
242 242 if argspec is None:
243 243 call_line = None
244 244 else:
245 245 # Callable objects will have 'self' as their first argument, prune
246 246 # it out if it's there for clarity (since users do *not* pass an
247 247 # extra first argument explicitly).
248 248 try:
249 249 has_self = argspec['args'][0] == 'self'
250 250 except (KeyError, IndexError):
251 251 pass
252 252 else:
253 253 if has_self:
254 254 argspec['args'] = argspec['args'][1:]
255 255
256 256 call_line = oinfo['name']+format_argspec(argspec)
257 257
258 258 # Now get docstring.
259 259 # The priority is: call docstring, constructor docstring, main one.
260 260 doc = oinfo.get('call_docstring')
261 261 if doc is None:
262 262 doc = oinfo.get('init_docstring')
263 263 if doc is None:
264 264 doc = oinfo.get('docstring','')
265 265
266 266 return call_line, doc
267 267
268 268
269 269 def find_file(obj):
270 270 """Find the absolute path to the file where an object was defined.
271 271
272 272 This is essentially a robust wrapper around `inspect.getabsfile`.
273 273
274 274 Returns None if no file can be found.
275 275
276 276 Parameters
277 277 ----------
278 278 obj : any Python object
279 279
280 280 Returns
281 281 -------
282 282 fname : str
283 283 The absolute path to the file where the object was defined.
284 284 """
285 285 # get source if obj was decorated with @decorator
286 286 if safe_hasattr(obj, '__wrapped__'):
287 287 obj = obj.__wrapped__
288 288
289 289 fname = None
290 290 try:
291 291 fname = inspect.getabsfile(obj)
292 292 except TypeError:
293 293 # For an instance, the file that matters is where its class was
294 294 # declared.
295 295 if hasattr(obj, '__class__'):
296 296 try:
297 297 fname = inspect.getabsfile(obj.__class__)
298 298 except TypeError:
299 299 # Can happen for builtins
300 300 pass
301 301 except:
302 302 pass
303 303 return cast_unicode(fname)
304 304
305 305
306 306 def find_source_lines(obj):
307 307 """Find the line number in a file where an object was defined.
308 308
309 309 This is essentially a robust wrapper around `inspect.getsourcelines`.
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 lineno : int
320 320 The line number where the object definition starts.
321 321 """
322 322 # get source if obj was decorated with @decorator
323 323 if safe_hasattr(obj, '__wrapped__'):
324 324 obj = obj.__wrapped__
325 325
326 326 try:
327 327 try:
328 328 lineno = inspect.getsourcelines(obj)[1]
329 329 except TypeError:
330 330 # For instances, try the class object like getsource() does
331 331 if hasattr(obj, '__class__'):
332 332 lineno = inspect.getsourcelines(obj.__class__)[1]
333 333 else:
334 334 lineno = None
335 335 except:
336 336 return None
337 337
338 338 return lineno
339 339
340 340
341 341 class Inspector:
342 342 def __init__(self, color_table=InspectColors,
343 343 code_color_table=PyColorize.ANSICodeColors,
344 344 scheme='NoColor',
345 345 str_detail_level=0):
346 346 self.color_table = color_table
347 347 self.parser = PyColorize.Parser(code_color_table,out='str')
348 348 self.format = self.parser.format
349 349 self.str_detail_level = str_detail_level
350 350 self.set_active_scheme(scheme)
351 351
352 352 def _getdef(self,obj,oname=''):
353 353 """Return the call signature for any callable object.
354 354
355 355 If any exception is generated, None is returned instead and the
356 356 exception is suppressed."""
357 357 try:
358 358 hdef = oname + inspect.formatargspec(*getargspec(obj))
359 359 return cast_unicode(hdef)
360 360 except:
361 361 return None
362 362
363 363 def __head(self,h):
364 364 """Return a header string with proper colors."""
365 365 return '%s%s%s' % (self.color_table.active_colors.header,h,
366 366 self.color_table.active_colors.normal)
367 367
368 368 def set_active_scheme(self, scheme):
369 369 self.color_table.set_active_scheme(scheme)
370 370 self.parser.color_table.set_active_scheme(scheme)
371 371
372 372 def noinfo(self, msg, oname):
373 373 """Generic message when no information is found."""
374 374 print('No %s found' % msg, end=' ')
375 375 if oname:
376 376 print('for %s' % oname)
377 377 else:
378 378 print()
379 379
380 380 def pdef(self, obj, oname=''):
381 381 """Print the call signature for any callable object.
382 382
383 383 If the object is a class, print the constructor information."""
384 384
385 385 if not callable(obj):
386 386 print('Object is not callable.')
387 387 return
388 388
389 389 header = ''
390 390
391 391 if inspect.isclass(obj):
392 392 header = self.__head('Class constructor information:\n')
393 393 obj = obj.__init__
394 394 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
395 395 obj = obj.__call__
396 396
397 397 output = self._getdef(obj,oname)
398 398 if output is None:
399 399 self.noinfo('definition header',oname)
400 400 else:
401 401 print(header,self.format(output), end=' ', file=io.stdout)
402 402
403 403 # In Python 3, all classes are new-style, so they all have __init__.
404 404 @skip_doctest_py3
405 405 def pdoc(self,obj,oname='',formatter = None):
406 406 """Print the docstring for any object.
407 407
408 408 Optional:
409 409 -formatter: a function to run the docstring through for specially
410 410 formatted docstrings.
411 411
412 412 Examples
413 413 --------
414 414
415 415 In [1]: class NoInit:
416 416 ...: pass
417 417
418 418 In [2]: class NoDoc:
419 419 ...: def __init__(self):
420 420 ...: pass
421 421
422 422 In [3]: %pdoc NoDoc
423 423 No documentation found for NoDoc
424 424
425 425 In [4]: %pdoc NoInit
426 426 No documentation found for NoInit
427 427
428 428 In [5]: obj = NoInit()
429 429
430 430 In [6]: %pdoc obj
431 431 No documentation found for obj
432 432
433 433 In [5]: obj2 = NoDoc()
434 434
435 435 In [6]: %pdoc obj2
436 436 No documentation found for obj2
437 437 """
438 438
439 439 head = self.__head # For convenience
440 440 lines = []
441 441 ds = getdoc(obj)
442 442 if formatter:
443 443 ds = formatter(ds)
444 444 if ds:
445 445 lines.append(head("Class docstring:"))
446 446 lines.append(indent(ds))
447 447 if inspect.isclass(obj) and hasattr(obj, '__init__'):
448 448 init_ds = getdoc(obj.__init__)
449 449 if init_ds is not None:
450 450 lines.append(head("Init docstring:"))
451 451 lines.append(indent(init_ds))
452 452 elif hasattr(obj,'__call__'):
453 453 call_ds = getdoc(obj.__call__)
454 454 if call_ds:
455 455 lines.append(head("Call docstring:"))
456 456 lines.append(indent(call_ds))
457 457
458 458 if not lines:
459 459 self.noinfo('documentation',oname)
460 460 else:
461 461 page.page('\n'.join(lines))
462 462
463 463 def psource(self,obj,oname=''):
464 464 """Print the source code for an object."""
465 465
466 466 # Flush the source cache because inspect can return out-of-date source
467 467 linecache.checkcache()
468 468 try:
469 469 src = getsource(obj)
470 470 except:
471 471 self.noinfo('source',oname)
472 472 else:
473 473 page.page(self.format(src))
474 474
475 475 def pfile(self, obj, oname=''):
476 476 """Show the whole file where an object was defined."""
477 477
478 478 lineno = find_source_lines(obj)
479 479 if lineno is None:
480 480 self.noinfo('file', oname)
481 481 return
482 482
483 483 ofile = find_file(obj)
484 484 # run contents of file through pager starting at line where the object
485 485 # is defined, as long as the file isn't binary and is actually on the
486 486 # filesystem.
487 487 if ofile.endswith(('.so', '.dll', '.pyd')):
488 488 print('File %r is binary, not printing.' % ofile)
489 489 elif not os.path.isfile(ofile):
490 490 print('File %r does not exist, not printing.' % ofile)
491 491 else:
492 492 # Print only text files, not extension binaries. Note that
493 493 # getsourcelines returns lineno with 1-offset and page() uses
494 494 # 0-offset, so we must adjust.
495 495 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
496 496
497 497 def _format_fields(self, fields, title_width=0):
498 498 """Formats a list of fields for display.
499 499
500 500 Parameters
501 501 ----------
502 502 fields : list
503 503 A list of 2-tuples: (field_title, field_content)
504 504 title_width : int
505 505 How many characters to pad titles to. Default to longest title.
506 506 """
507 507 out = []
508 508 header = self.__head
509 509 if title_width == 0:
510 for title, _ in fields:
511 title_width = max(len(title) + 2, title_width)
510 title_width = max(len(title) + 2 for title, _ in fields)
512 511 for title, content in fields:
513 512 if len(content.splitlines()) > 1:
514 513 title = header(title + ":") + "\n"
515 514 else:
516 515 title = header((title+":").ljust(title_width))
517 516 out.append(cast_unicode(title) + cast_unicode(content))
518 517 return "\n".join(out)
519 518
520 519 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
521 520 pinfo_fields1 = [("Type", "type_name"),
522 521 ]
523 522
524 523 pinfo_fields2 = [("String form", "string_form"),
525 524 ]
526 525
527 526 pinfo_fields3 = [("Length", "length"),
528 527 ("File", "file"),
529 528 ("Definition", "definition"),
530 529 ]
531 530
532 531 pinfo_fields_obj = [("Class docstring", "class_docstring"),
533 532 ("Init docstring", "init_docstring"),
534 533 ("Call def", "call_def"),
535 534 ("Call docstring", "call_docstring")]
536 535
537 536 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
538 537 """Show detailed information about an object.
539 538
540 539 Optional arguments:
541 540
542 541 - oname: name of the variable pointing to the object.
543 542
544 543 - formatter: special formatter for docstrings (see pdoc)
545 544
546 545 - info: a structure with some information fields which may have been
547 546 precomputed already.
548 547
549 548 - detail_level: if set to 1, more information is given.
550 549 """
551 550 info = self.info(obj, oname=oname, formatter=formatter,
552 551 info=info, detail_level=detail_level)
553 552 displayfields = []
554 553 def add_fields(fields):
555 554 for title, key in fields:
556 555 field = info[key]
557 556 if field is not None:
558 557 displayfields.append((title, field.rstrip()))
559 558
560 559 add_fields(self.pinfo_fields1)
561 560
562 561 # Base class for old-style instances
563 562 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
564 563 displayfields.append(("Base Class", info['base_class'].rstrip()))
565 564
566 565 add_fields(self.pinfo_fields2)
567 566
568 567 # Namespace
569 568 if info['namespace'] != 'Interactive':
570 569 displayfields.append(("Namespace", info['namespace'].rstrip()))
571 570
572 571 add_fields(self.pinfo_fields3)
573 572 if info['isclass'] and info['init_definition']:
574 573 displayfields.append(("Init definition",
575 574 info['init_definition'].rstrip()))
576 575
577 576 # Source or docstring, depending on detail level and whether
578 577 # source found.
579 578 if detail_level > 0 and info['source'] is not None:
580 579 displayfields.append(("Source",
581 580 self.format(cast_unicode(info['source']))))
582 581 elif info['docstring'] is not None:
583 582 displayfields.append(("Docstring", info["docstring"]))
584 583
585 584 # Constructor info for classes
586 585 if info['isclass']:
587 586 if info['init_docstring'] is not None:
588 587 displayfields.append(("Init docstring",
589 588 info['init_docstring']))
590 589
591 590 # Info for objects:
592 591 else:
593 592 add_fields(self.pinfo_fields_obj)
594 593
595 594 # Finally send to printer/pager:
596 595 if displayfields:
597 596 page.page(self._format_fields(displayfields))
598 597
599 598 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
600 599 """Compute a dict with detailed information about an object.
601 600
602 601 Optional arguments:
603 602
604 603 - oname: name of the variable pointing to the object.
605 604
606 605 - formatter: special formatter for docstrings (see pdoc)
607 606
608 607 - info: a structure with some information fields which may have been
609 608 precomputed already.
610 609
611 610 - detail_level: if set to 1, more information is given.
612 611 """
613 612
614 613 obj_type = type(obj)
615 614
616 615 if info is None:
617 616 ismagic = 0
618 617 isalias = 0
619 618 ospace = ''
620 619 else:
621 620 ismagic = info.ismagic
622 621 isalias = info.isalias
623 622 ospace = info.namespace
624 623
625 624 # Get docstring, special-casing aliases:
626 625 if isalias:
627 626 if not callable(obj):
628 627 try:
629 628 ds = "Alias to the system command:\n %s" % obj[1]
630 629 except:
631 630 ds = "Alias: " + str(obj)
632 631 else:
633 632 ds = "Alias to " + str(obj)
634 633 if obj.__doc__:
635 634 ds += "\nDocstring:\n" + obj.__doc__
636 635 else:
637 636 ds = getdoc(obj)
638 637 if ds is None:
639 638 ds = '<no docstring>'
640 639 if formatter is not None:
641 640 ds = formatter(ds)
642 641
643 642 # store output in a dict, we initialize it here and fill it as we go
644 643 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
645 644
646 645 string_max = 200 # max size of strings to show (snipped if longer)
647 646 shalf = int((string_max -5)/2)
648 647
649 648 if ismagic:
650 649 obj_type_name = 'Magic function'
651 650 elif isalias:
652 651 obj_type_name = 'System alias'
653 652 else:
654 653 obj_type_name = obj_type.__name__
655 654 out['type_name'] = obj_type_name
656 655
657 656 try:
658 657 bclass = obj.__class__
659 658 out['base_class'] = str(bclass)
660 659 except: pass
661 660
662 661 # String form, but snip if too long in ? form (full in ??)
663 662 if detail_level >= self.str_detail_level:
664 663 try:
665 664 ostr = str(obj)
666 665 str_head = 'string_form'
667 666 if not detail_level and len(ostr)>string_max:
668 667 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
669 668 ostr = ("\n" + " " * len(str_head.expandtabs())).\
670 669 join(q.strip() for q in ostr.split("\n"))
671 670 out[str_head] = ostr
672 671 except:
673 672 pass
674 673
675 674 if ospace:
676 675 out['namespace'] = ospace
677 676
678 677 # Length (for strings and lists)
679 678 try:
680 679 out['length'] = str(len(obj))
681 680 except: pass
682 681
683 682 # Filename where object was defined
684 683 binary_file = False
685 684 fname = find_file(obj)
686 685 if fname is None:
687 686 # if anything goes wrong, we don't want to show source, so it's as
688 687 # if the file was binary
689 688 binary_file = True
690 689 else:
691 690 if fname.endswith(('.so', '.dll', '.pyd')):
692 691 binary_file = True
693 692 elif fname.endswith('<string>'):
694 693 fname = 'Dynamically generated function. No source code available.'
695 694 out['file'] = fname
696 695
697 696 # Docstrings only in detail 0 mode, since source contains them (we
698 697 # avoid repetitions). If source fails, we add them back, see below.
699 698 if ds and detail_level == 0:
700 699 out['docstring'] = ds
701 700
702 701 # Original source code for any callable
703 702 if detail_level:
704 703 # Flush the source cache because inspect can return out-of-date
705 704 # source
706 705 linecache.checkcache()
707 706 source = None
708 707 try:
709 708 try:
710 709 source = getsource(obj, binary_file)
711 710 except TypeError:
712 711 if hasattr(obj, '__class__'):
713 712 source = getsource(obj.__class__, binary_file)
714 713 if source is not None:
715 714 out['source'] = source.rstrip()
716 715 except Exception:
717 716 pass
718 717
719 718 if ds and source is None:
720 719 out['docstring'] = ds
721 720
722 721
723 722 # Constructor docstring for classes
724 723 if inspect.isclass(obj):
725 724 out['isclass'] = True
726 725 # reconstruct the function definition and print it:
727 726 try:
728 727 obj_init = obj.__init__
729 728 except AttributeError:
730 729 init_def = init_ds = None
731 730 else:
732 731 init_def = self._getdef(obj_init,oname)
733 732 init_ds = getdoc(obj_init)
734 733 # Skip Python's auto-generated docstrings
735 734 if init_ds == _object_init_docstring:
736 735 init_ds = None
737 736
738 737 if init_def or init_ds:
739 738 if init_def:
740 739 out['init_definition'] = self.format(init_def)
741 740 if init_ds:
742 741 out['init_docstring'] = init_ds
743 742
744 743 # and class docstring for instances:
745 744 else:
746 745 # reconstruct the function definition and print it:
747 746 defln = self._getdef(obj, oname)
748 747 if defln:
749 748 out['definition'] = self.format(defln)
750 749
751 750 # First, check whether the instance docstring is identical to the
752 751 # class one, and print it separately if they don't coincide. In
753 752 # most cases they will, but it's nice to print all the info for
754 753 # objects which use instance-customized docstrings.
755 754 if ds:
756 755 try:
757 756 cls = getattr(obj,'__class__')
758 757 except:
759 758 class_ds = None
760 759 else:
761 760 class_ds = getdoc(cls)
762 761 # Skip Python's auto-generated docstrings
763 762 if class_ds in _builtin_type_docstrings:
764 763 class_ds = None
765 764 if class_ds and ds != class_ds:
766 765 out['class_docstring'] = class_ds
767 766
768 767 # Next, try to show constructor docstrings
769 768 try:
770 769 init_ds = getdoc(obj.__init__)
771 770 # Skip Python's auto-generated docstrings
772 771 if init_ds == _object_init_docstring:
773 772 init_ds = None
774 773 except AttributeError:
775 774 init_ds = None
776 775 if init_ds:
777 776 out['init_docstring'] = init_ds
778 777
779 778 # Call form docstring for callable instances
780 779 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
781 780 call_def = self._getdef(obj.__call__, oname)
782 781 if call_def:
783 782 call_def = self.format(call_def)
784 783 # it may never be the case that call def and definition differ,
785 784 # but don't include the same signature twice
786 785 if call_def != out.get('definition'):
787 786 out['call_def'] = call_def
788 787 call_ds = getdoc(obj.__call__)
789 788 # Skip Python's auto-generated docstrings
790 789 if call_ds == _func_call_docstring:
791 790 call_ds = None
792 791 if call_ds:
793 792 out['call_docstring'] = call_ds
794 793
795 794 # Compute the object's argspec as a callable. The key is to decide
796 795 # whether to pull it from the object itself, from its __init__ or
797 796 # from its __call__ method.
798 797
799 798 if inspect.isclass(obj):
800 799 # Old-style classes need not have an __init__
801 800 callable_obj = getattr(obj, "__init__", None)
802 801 elif callable(obj):
803 802 callable_obj = obj
804 803 else:
805 804 callable_obj = None
806 805
807 806 if callable_obj:
808 807 try:
809 808 argspec = getargspec(callable_obj)
810 809 except (TypeError, AttributeError):
811 810 # For extensions/builtins we can't retrieve the argspec
812 811 pass
813 812 else:
814 813 # named tuples' _asdict() method returns an OrderedDict, but we
815 814 # we want a normal
816 815 out['argspec'] = argspec_dict = dict(argspec._asdict())
817 816 # We called this varkw before argspec became a named tuple.
818 817 # With getfullargspec it's also called varkw.
819 818 if 'varkw' not in argspec_dict:
820 819 argspec_dict['varkw'] = argspec_dict.pop('keywords')
821 820
822 821 return object_info(**out)
823 822
824 823
825 824 def psearch(self,pattern,ns_table,ns_search=[],
826 825 ignore_case=False,show_all=False):
827 826 """Search namespaces with wildcards for objects.
828 827
829 828 Arguments:
830 829
831 830 - pattern: string containing shell-like wildcards to use in namespace
832 831 searches and optionally a type specification to narrow the search to
833 832 objects of that type.
834 833
835 834 - ns_table: dict of name->namespaces for search.
836 835
837 836 Optional arguments:
838 837
839 838 - ns_search: list of namespace names to include in search.
840 839
841 840 - ignore_case(False): make the search case-insensitive.
842 841
843 842 - show_all(False): show all names, including those starting with
844 843 underscores.
845 844 """
846 845 #print 'ps pattern:<%r>' % pattern # dbg
847 846
848 847 # defaults
849 848 type_pattern = 'all'
850 849 filter = ''
851 850
852 851 cmds = pattern.split()
853 852 len_cmds = len(cmds)
854 853 if len_cmds == 1:
855 854 # Only filter pattern given
856 855 filter = cmds[0]
857 856 elif len_cmds == 2:
858 857 # Both filter and type specified
859 858 filter,type_pattern = cmds
860 859 else:
861 860 raise ValueError('invalid argument string for psearch: <%s>' %
862 861 pattern)
863 862
864 863 # filter search namespaces
865 864 for name in ns_search:
866 865 if name not in ns_table:
867 866 raise ValueError('invalid namespace <%s>. Valid names: %s' %
868 867 (name,ns_table.keys()))
869 868
870 869 #print 'type_pattern:',type_pattern # dbg
871 870 search_result, namespaces_seen = set(), set()
872 871 for ns_name in ns_search:
873 872 ns = ns_table[ns_name]
874 873 # Normally, locals and globals are the same, so we just check one.
875 874 if id(ns) in namespaces_seen:
876 875 continue
877 876 namespaces_seen.add(id(ns))
878 877 tmp_res = list_namespace(ns, type_pattern, filter,
879 878 ignore_case=ignore_case, show_all=show_all)
880 879 search_result.update(tmp_res)
881 880
882 881 page.page('\n'.join(sorted(search_result)))
General Comments 0
You need to be logged in to leave comments. Login now