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