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