##// END OF EJS Templates
remove accidentally committed print statement
MinRK -
Show More
@@ -1,875 +1,874 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 *
43 43 from IPython.utils.py3compat import cast_unicode, string_types
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 color schemes
53 53
54 54 Colors = TermColors # just a shorthand
55 55
56 56 # Build a few color schemes
57 57 NoColor = ColorScheme(
58 58 'NoColor',{
59 59 'header' : Colors.NoColor,
60 60 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
61 61 } )
62 62
63 63 LinuxColors = ColorScheme(
64 64 'Linux',{
65 65 'header' : Colors.LightRed,
66 66 'normal' : Colors.Normal # color off (usu. Colors.Normal)
67 67 } )
68 68
69 69 LightBGColors = ColorScheme(
70 70 'LightBG',{
71 71 'header' : Colors.Red,
72 72 'normal' : Colors.Normal # color off (usu. Colors.Normal)
73 73 } )
74 74
75 75 # Build table of color schemes (needed by the parser)
76 76 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
77 77 'Linux')
78 78
79 79 #****************************************************************************
80 80 # Auxiliary functions and objects
81 81
82 82 # See the messaging spec for the definition of all these fields. This list
83 83 # effectively defines the order of display
84 84 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
85 85 'length', 'file', 'definition', 'docstring', 'source',
86 86 'init_definition', 'class_docstring', 'init_docstring',
87 87 'call_def', 'call_docstring',
88 88 # These won't be printed but will be used to determine how to
89 89 # format the object
90 90 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
91 91 ]
92 92
93 93
94 94 def object_info(**kw):
95 95 """Make an object info dict with all fields present."""
96 96 infodict = dict(izip_longest(info_fields, [None]))
97 97 infodict.update(kw)
98 98 return infodict
99 99
100 100
101 101 def get_encoding(obj):
102 102 """Get encoding for python source file defining obj
103 103
104 104 Returns None if obj is not defined in a sourcefile.
105 105 """
106 106 ofile = find_file(obj)
107 107 # run contents of file through pager starting at line where the object
108 108 # is defined, as long as the file isn't binary and is actually on the
109 109 # filesystem.
110 110 if ofile is None:
111 111 return None
112 112 elif ofile.endswith(('.so', '.dll', '.pyd')):
113 113 return None
114 114 elif not os.path.isfile(ofile):
115 115 return None
116 116 else:
117 117 # Print only text files, not extension binaries. Note that
118 118 # getsourcelines returns lineno with 1-offset and page() uses
119 119 # 0-offset, so we must adjust.
120 120 buffer = stdlib_io.open(ofile, 'rb') # Tweaked to use io.open for Python 2
121 121 encoding, lines = openpy.detect_encoding(buffer.readline)
122 122 return encoding
123 123
124 124 def getdoc(obj):
125 125 """Stable wrapper around inspect.getdoc.
126 126
127 127 This can't crash because of attribute problems.
128 128
129 129 It also attempts to call a getdoc() method on the given object. This
130 130 allows objects which provide their docstrings via non-standard mechanisms
131 131 (like Pyro proxies) to still be inspected by ipython's ? system."""
132 132 # Allow objects to offer customized documentation via a getdoc method:
133 133 try:
134 134 ds = obj.getdoc()
135 135 except Exception:
136 136 pass
137 137 else:
138 138 # if we get extra info, we add it to the normal docstring.
139 139 if isinstance(ds, string_types):
140 140 return inspect.cleandoc(ds)
141 141
142 142 try:
143 143 docstr = inspect.getdoc(obj)
144 144 encoding = get_encoding(obj)
145 145 return py3compat.cast_unicode(docstr, encoding=encoding)
146 146 except Exception:
147 147 # Harden against an inspect failure, which can occur with
148 148 # SWIG-wrapped extensions.
149 149 raise
150 150 return None
151 151
152 152
153 153 def getsource(obj,is_binary=False):
154 154 """Wrapper around inspect.getsource.
155 155
156 156 This can be modified by other projects to provide customized source
157 157 extraction.
158 158
159 159 Inputs:
160 160
161 161 - obj: an object whose source code we will attempt to extract.
162 162
163 163 Optional inputs:
164 164
165 165 - is_binary: whether the object is known to come from a binary source.
166 166 This implementation will skip returning any output for binary objects, but
167 167 custom extractors may know how to meaningfully process them."""
168 168
169 169 if is_binary:
170 170 return None
171 171 else:
172 172 # get source if obj was decorated with @decorator
173 173 if hasattr(obj,"__wrapped__"):
174 174 obj = obj.__wrapped__
175 175 try:
176 176 src = inspect.getsource(obj)
177 177 except TypeError:
178 178 if hasattr(obj,'__class__'):
179 179 src = inspect.getsource(obj.__class__)
180 180 encoding = get_encoding(obj)
181 181 return cast_unicode(src, encoding=encoding)
182 182
183 183 def getargspec(obj):
184 184 """Get the names and default values of a function's arguments.
185 185
186 186 A tuple of four things is returned: (args, varargs, varkw, defaults).
187 187 'args' is a list of the argument names (it may contain nested lists).
188 188 'varargs' and 'varkw' are the names of the * and ** arguments or None.
189 189 'defaults' is an n-tuple of the default values of the last n arguments.
190 190
191 191 Modified version of inspect.getargspec from the Python Standard
192 192 Library."""
193 193
194 194 if inspect.isfunction(obj):
195 195 func_obj = obj
196 196 elif inspect.ismethod(obj):
197 197 func_obj = obj.__func__
198 198 elif hasattr(obj, '__call__'):
199 199 func_obj = obj.__call__
200 200 else:
201 201 raise TypeError('arg is not a Python function')
202 202 args, varargs, varkw = inspect.getargs(func_obj.__code__)
203 203 return args, varargs, varkw, func_obj.__defaults__
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
358 358 try:
359 359 hdef = oname + inspect.formatargspec(*getargspec(obj))
360 360 return cast_unicode(hdef)
361 361 except:
362 362 return None
363 363
364 364 def __head(self,h):
365 365 """Return a header string with proper colors."""
366 366 return '%s%s%s' % (self.color_table.active_colors.header,h,
367 367 self.color_table.active_colors.normal)
368 368
369 369 def set_active_scheme(self, scheme):
370 370 self.color_table.set_active_scheme(scheme)
371 371 self.parser.color_table.set_active_scheme(scheme)
372 372
373 373 def noinfo(self, msg, oname):
374 374 """Generic message when no information is found."""
375 375 print('No %s found' % msg, end=' ')
376 376 if oname:
377 377 print('for %s' % oname)
378 378 else:
379 379 print()
380 380
381 381 def pdef(self, obj, oname=''):
382 382 """Print the call signature for any callable object.
383 383
384 384 If the object is a class, print the constructor information."""
385 385
386 386 if not callable(obj):
387 387 print('Object is not callable.')
388 388 return
389 389
390 390 header = ''
391 391
392 392 if inspect.isclass(obj):
393 393 header = self.__head('Class constructor information:\n')
394 394 obj = obj.__init__
395 395 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
396 396 obj = obj.__call__
397 397
398 398 output = self._getdef(obj,oname)
399 399 if output is None:
400 400 self.noinfo('definition header',oname)
401 401 else:
402 402 print(header,self.format(output), end=' ', file=io.stdout)
403 403
404 404 # In Python 3, all classes are new-style, so they all have __init__.
405 405 @skip_doctest_py3
406 406 def pdoc(self,obj,oname='',formatter = None):
407 407 """Print the docstring for any object.
408 408
409 409 Optional:
410 410 -formatter: a function to run the docstring through for specially
411 411 formatted docstrings.
412 412
413 413 Examples
414 414 --------
415 415
416 416 In [1]: class NoInit:
417 417 ...: pass
418 418
419 419 In [2]: class NoDoc:
420 420 ...: def __init__(self):
421 421 ...: pass
422 422
423 423 In [3]: %pdoc NoDoc
424 424 No documentation found for NoDoc
425 425
426 426 In [4]: %pdoc NoInit
427 427 No documentation found for NoInit
428 428
429 429 In [5]: obj = NoInit()
430 430
431 431 In [6]: %pdoc obj
432 432 No documentation found for obj
433 433
434 434 In [5]: obj2 = NoDoc()
435 435
436 436 In [6]: %pdoc obj2
437 437 No documentation found for obj2
438 438 """
439 439
440 440 head = self.__head # For convenience
441 441 lines = []
442 442 ds = getdoc(obj)
443 443 if formatter:
444 444 ds = formatter(ds)
445 445 if ds:
446 446 lines.append(head("Class Docstring:"))
447 447 lines.append(indent(ds))
448 448 if inspect.isclass(obj) and hasattr(obj, '__init__'):
449 449 init_ds = getdoc(obj.__init__)
450 450 if init_ds is not None:
451 451 lines.append(head("Constructor Docstring:"))
452 452 lines.append(indent(init_ds))
453 453 elif hasattr(obj,'__call__'):
454 454 call_ds = getdoc(obj.__call__)
455 455 if call_ds:
456 456 lines.append(head("Calling Docstring:"))
457 457 lines.append(indent(call_ds))
458 458
459 459 if not lines:
460 460 self.noinfo('documentation',oname)
461 461 else:
462 462 page.page('\n'.join(lines))
463 463
464 464 def psource(self,obj,oname=''):
465 465 """Print the source code for an object."""
466 466
467 467 # Flush the source cache because inspect can return out-of-date source
468 468 linecache.checkcache()
469 469 try:
470 470 src = getsource(obj)
471 471 except:
472 472 self.noinfo('source',oname)
473 473 else:
474 474 page.page(self.format(src))
475 475
476 476 def pfile(self, obj, oname=''):
477 477 """Show the whole file where an object was defined."""
478 478
479 479 lineno = find_source_lines(obj)
480 480 if lineno is None:
481 481 self.noinfo('file', oname)
482 482 return
483 483
484 484 ofile = find_file(obj)
485 485 # run contents of file through pager starting at line where the object
486 486 # is defined, as long as the file isn't binary and is actually on the
487 487 # filesystem.
488 488 if ofile.endswith(('.so', '.dll', '.pyd')):
489 489 print('File %r is binary, not printing.' % ofile)
490 490 elif not os.path.isfile(ofile):
491 491 print('File %r does not exist, not printing.' % ofile)
492 492 else:
493 493 # Print only text files, not extension binaries. Note that
494 494 # getsourcelines returns lineno with 1-offset and page() uses
495 495 # 0-offset, so we must adjust.
496 496 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
497 497
498 498 def _format_fields(self, fields, title_width=12):
499 499 """Formats a list of fields for display.
500 500
501 501 Parameters
502 502 ----------
503 503 fields : list
504 504 A list of 2-tuples: (field_title, field_content)
505 505 title_width : int
506 506 How many characters to pad titles to. Default 12.
507 507 """
508 508 out = []
509 509 header = self.__head
510 510 for title, content in fields:
511 511 if len(content.splitlines()) > 1:
512 512 title = header(title + ":") + "\n"
513 513 else:
514 514 title = header((title+":").ljust(title_width))
515 515 out.append(cast_unicode(title) + cast_unicode(content))
516 516 return "\n".join(out)
517 517
518 518 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
519 519 pinfo_fields1 = [("Type", "type_name"),
520 520 ]
521 521
522 522 pinfo_fields2 = [("String Form", "string_form"),
523 523 ]
524 524
525 525 pinfo_fields3 = [("Length", "length"),
526 526 ("File", "file"),
527 527 ("Definition", "definition"),
528 528 ]
529 529
530 530 pinfo_fields_obj = [("Class Docstring", "class_docstring"),
531 531 ("Constructor Docstring","init_docstring"),
532 532 ("Call def", "call_def"),
533 533 ("Call docstring", "call_docstring")]
534 534
535 535 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
536 536 """Show detailed information about an object.
537 537
538 538 Optional arguments:
539 539
540 540 - oname: name of the variable pointing to the object.
541 541
542 542 - formatter: special formatter for docstrings (see pdoc)
543 543
544 544 - info: a structure with some information fields which may have been
545 545 precomputed already.
546 546
547 547 - detail_level: if set to 1, more information is given.
548 548 """
549 549 info = self.info(obj, oname=oname, formatter=formatter,
550 550 info=info, detail_level=detail_level)
551 551 displayfields = []
552 552 def add_fields(fields):
553 553 for title, key in fields:
554 554 field = info[key]
555 555 if field is not None:
556 556 displayfields.append((title, field.rstrip()))
557 557
558 558 add_fields(self.pinfo_fields1)
559 559
560 560 # Base class for old-style instances
561 561 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
562 562 displayfields.append(("Base Class", info['base_class'].rstrip()))
563 563
564 564 add_fields(self.pinfo_fields2)
565 565
566 566 # Namespace
567 567 if info['namespace'] != 'Interactive':
568 568 displayfields.append(("Namespace", info['namespace'].rstrip()))
569 569
570 570 add_fields(self.pinfo_fields3)
571 571
572 572 # Source or docstring, depending on detail level and whether
573 573 # source found.
574 574 if detail_level > 0 and info['source'] is not None:
575 575 displayfields.append(("Source",
576 576 self.format(cast_unicode(info['source']))))
577 577 elif info['docstring'] is not None:
578 578 displayfields.append(("Docstring", info["docstring"]))
579 579
580 580 # Constructor info for classes
581 581 if info['isclass']:
582 582 if info['init_definition'] or info['init_docstring']:
583 583 displayfields.append(("Constructor information", ""))
584 584 if info['init_definition'] is not None:
585 585 displayfields.append((" Definition",
586 586 info['init_definition'].rstrip()))
587 587 if info['init_docstring'] is not None:
588 588 displayfields.append((" Docstring",
589 589 indent(info['init_docstring'])))
590 590
591 591 # Info for objects:
592 592 else:
593 593 add_fields(self.pinfo_fields_obj)
594 594
595 595 # Finally send to printer/pager:
596 596 if displayfields:
597 597 page.page(self._format_fields(displayfields))
598 598
599 599 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
600 600 """Compute a dict with detailed information about an object.
601 601
602 602 Optional arguments:
603 603
604 604 - oname: name of the variable pointing to the object.
605 605
606 606 - formatter: special formatter for docstrings (see pdoc)
607 607
608 608 - info: a structure with some information fields which may have been
609 609 precomputed already.
610 610
611 611 - detail_level: if set to 1, more information is given.
612 612 """
613 613
614 614 obj_type = type(obj)
615 615
616 616 header = self.__head
617 617 if info is None:
618 618 ismagic = 0
619 619 isalias = 0
620 620 ospace = ''
621 621 else:
622 622 ismagic = info.ismagic
623 623 isalias = info.isalias
624 624 ospace = info.namespace
625 625
626 626 # Get docstring, special-casing aliases:
627 627 if isalias:
628 628 if not callable(obj):
629 629 try:
630 630 ds = "Alias to the system command:\n %s" % obj[1]
631 631 except:
632 632 ds = "Alias: " + str(obj)
633 633 else:
634 634 ds = "Alias to " + str(obj)
635 635 if obj.__doc__:
636 636 ds += "\nDocstring:\n" + obj.__doc__
637 637 else:
638 638 ds = getdoc(obj)
639 639 if ds is None:
640 640 ds = '<no docstring>'
641 641 if formatter is not None:
642 642 ds = formatter(ds)
643 643
644 644 # store output in a dict, we initialize it here and fill it as we go
645 645 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
646 646
647 647 string_max = 200 # max size of strings to show (snipped if longer)
648 648 shalf = int((string_max -5)/2)
649 649
650 650 if ismagic:
651 651 obj_type_name = 'Magic function'
652 652 elif isalias:
653 653 obj_type_name = 'System alias'
654 654 else:
655 655 obj_type_name = obj_type.__name__
656 656 out['type_name'] = obj_type_name
657 657
658 658 try:
659 659 bclass = obj.__class__
660 660 out['base_class'] = str(bclass)
661 661 except: pass
662 662
663 663 # String form, but snip if too long in ? form (full in ??)
664 664 if detail_level >= self.str_detail_level:
665 665 try:
666 666 ostr = str(obj)
667 667 str_head = 'string_form'
668 668 if not detail_level and len(ostr)>string_max:
669 669 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
670 670 ostr = ("\n" + " " * len(str_head.expandtabs())).\
671 671 join(q.strip() for q in ostr.split("\n"))
672 672 out[str_head] = ostr
673 673 except:
674 674 pass
675 675
676 676 if ospace:
677 677 out['namespace'] = ospace
678 678
679 679 # Length (for strings and lists)
680 680 try:
681 681 out['length'] = str(len(obj))
682 682 except: pass
683 683
684 684 # Filename where object was defined
685 685 binary_file = False
686 686 fname = find_file(obj)
687 687 if fname is None:
688 688 # if anything goes wrong, we don't want to show source, so it's as
689 689 # if the file was binary
690 690 binary_file = True
691 691 else:
692 692 if fname.endswith(('.so', '.dll', '.pyd')):
693 693 binary_file = True
694 694 elif fname.endswith('<string>'):
695 695 fname = 'Dynamically generated function. No source code available.'
696 696 out['file'] = fname
697 697
698 698 # reconstruct the function definition and print it:
699 699 defln = self._getdef(obj, oname)
700 700 if defln:
701 701 out['definition'] = self.format(defln)
702 702
703 703 # Docstrings only in detail 0 mode, since source contains them (we
704 704 # avoid repetitions). If source fails, we add them back, see below.
705 705 if ds and detail_level == 0:
706 706 out['docstring'] = ds
707 707
708 708 # Original source code for any callable
709 709 if detail_level:
710 710 # Flush the source cache because inspect can return out-of-date
711 711 # source
712 712 linecache.checkcache()
713 713 source = None
714 714 try:
715 715 try:
716 716 source = getsource(obj, binary_file)
717 717 except TypeError:
718 718 if hasattr(obj, '__class__'):
719 719 source = getsource(obj.__class__, binary_file)
720 720 if source is not None:
721 721 out['source'] = source.rstrip()
722 722 except Exception:
723 723 pass
724 724
725 725 if ds and source is None:
726 726 out['docstring'] = ds
727 727
728 728
729 729 # Constructor docstring for classes
730 730 if inspect.isclass(obj):
731 731 out['isclass'] = True
732 732 # reconstruct the function definition and print it:
733 733 try:
734 734 obj_init = obj.__init__
735 735 except AttributeError:
736 736 init_def = init_ds = None
737 737 else:
738 738 init_def = self._getdef(obj_init,oname)
739 739 init_ds = getdoc(obj_init)
740 740 # Skip Python's auto-generated docstrings
741 print(init_ds)
742 741 if init_ds == _object_init_docstring:
743 742 init_ds = None
744 743
745 744 if init_def or init_ds:
746 745 if init_def:
747 746 out['init_definition'] = self.format(init_def)
748 747 if init_ds:
749 748 out['init_docstring'] = init_ds
750 749
751 750 # and class docstring for instances:
752 751 else:
753 752 # First, check whether the instance docstring is identical to the
754 753 # class one, and print it separately if they don't coincide. In
755 754 # most cases they will, but it's nice to print all the info for
756 755 # objects which use instance-customized docstrings.
757 756 if ds:
758 757 try:
759 758 cls = getattr(obj,'__class__')
760 759 except:
761 760 class_ds = None
762 761 else:
763 762 class_ds = getdoc(cls)
764 763 # Skip Python's auto-generated docstrings
765 764 if class_ds in _builtin_type_docstrings:
766 765 class_ds = None
767 766 if class_ds and ds != class_ds:
768 767 out['class_docstring'] = class_ds
769 768
770 769 # Next, try to show constructor docstrings
771 770 try:
772 771 init_ds = getdoc(obj.__init__)
773 772 # Skip Python's auto-generated docstrings
774 773 if init_ds == _object_init_docstring:
775 774 init_ds = None
776 775 except AttributeError:
777 776 init_ds = None
778 777 if init_ds:
779 778 out['init_docstring'] = init_ds
780 779
781 780 # Call form docstring for callable instances
782 781 if safe_hasattr(obj, '__call__'):
783 782 call_def = self._getdef(obj.__call__, oname)
784 783 if call_def is not None:
785 784 out['call_def'] = self.format(call_def)
786 785 call_ds = getdoc(obj.__call__)
787 786 # Skip Python's auto-generated docstrings
788 787 if call_ds == _func_call_docstring:
789 788 call_ds = None
790 789 if call_ds:
791 790 out['call_docstring'] = call_ds
792 791
793 792 # Compute the object's argspec as a callable. The key is to decide
794 793 # whether to pull it from the object itself, from its __init__ or
795 794 # from its __call__ method.
796 795
797 796 if inspect.isclass(obj):
798 797 # Old-style classes need not have an __init__
799 798 callable_obj = getattr(obj, "__init__", None)
800 799 elif callable(obj):
801 800 callable_obj = obj
802 801 else:
803 802 callable_obj = None
804 803
805 804 if callable_obj:
806 805 try:
807 806 args, varargs, varkw, defaults = getargspec(callable_obj)
808 807 except (TypeError, AttributeError):
809 808 # For extensions/builtins we can't retrieve the argspec
810 809 pass
811 810 else:
812 811 out['argspec'] = dict(args=args, varargs=varargs,
813 812 varkw=varkw, defaults=defaults)
814 813
815 814 return object_info(**out)
816 815
817 816
818 817 def psearch(self,pattern,ns_table,ns_search=[],
819 818 ignore_case=False,show_all=False):
820 819 """Search namespaces with wildcards for objects.
821 820
822 821 Arguments:
823 822
824 823 - pattern: string containing shell-like wildcards to use in namespace
825 824 searches and optionally a type specification to narrow the search to
826 825 objects of that type.
827 826
828 827 - ns_table: dict of name->namespaces for search.
829 828
830 829 Optional arguments:
831 830
832 831 - ns_search: list of namespace names to include in search.
833 832
834 833 - ignore_case(False): make the search case-insensitive.
835 834
836 835 - show_all(False): show all names, including those starting with
837 836 underscores.
838 837 """
839 838 #print 'ps pattern:<%r>' % pattern # dbg
840 839
841 840 # defaults
842 841 type_pattern = 'all'
843 842 filter = ''
844 843
845 844 cmds = pattern.split()
846 845 len_cmds = len(cmds)
847 846 if len_cmds == 1:
848 847 # Only filter pattern given
849 848 filter = cmds[0]
850 849 elif len_cmds == 2:
851 850 # Both filter and type specified
852 851 filter,type_pattern = cmds
853 852 else:
854 853 raise ValueError('invalid argument string for psearch: <%s>' %
855 854 pattern)
856 855
857 856 # filter search namespaces
858 857 for name in ns_search:
859 858 if name not in ns_table:
860 859 raise ValueError('invalid namespace <%s>. Valid names: %s' %
861 860 (name,ns_table.keys()))
862 861
863 862 #print 'type_pattern:',type_pattern # dbg
864 863 search_result, namespaces_seen = set(), set()
865 864 for ns_name in ns_search:
866 865 ns = ns_table[ns_name]
867 866 # Normally, locals and globals are the same, so we just check one.
868 867 if id(ns) in namespaces_seen:
869 868 continue
870 869 namespaces_seen.add(id(ns))
871 870 tmp_res = list_namespace(ns, type_pattern, filter,
872 871 ignore_case=ignore_case, show_all=show_all)
873 872 search_result.update(tmp_res)
874 873
875 874 page.page('\n'.join(sorted(search_result)))
General Comments 0
You need to be logged in to leave comments. Login now