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