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