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