Package epydoc :: Module docintrospecter
[hide private]
[frames] | no frames]

Source Code for Module epydoc.docintrospecter

   1  # epydoc -- Introspection 
   2  # 
   3  # Copyright (C) 2005 Edward Loper 
   4  # Author: Edward Loper <edloper@loper.org> 
   5  # URL: <http://epydoc.sf.net> 
   6  # 
   7  # $Id: docintrospecter.py 1678 2008-01-29 17:21:29Z edloper $ 
   8   
   9  """ 
  10  Extract API documentation about python objects by directly introspecting 
  11  their values. 
  12   
  13  The function L{introspect_docs()}, which provides the main interface 
  14  of this module, examines a Python objects via introspection, and uses 
  15  the information it finds to create an L{APIDoc} objects containing the 
  16  API documentation for that objects. 
  17   
  18  The L{register_introspecter()} method can be used to extend the 
  19  functionality of C{docintrospector}, by providing methods that handle 
  20  special value types. 
  21  """ 
  22  __docformat__ = 'epytext en' 
  23   
  24  ###################################################################### 
  25  ## Imports 
  26  ###################################################################### 
  27   
  28  import inspect, re, sys, os.path, imp 
  29  # API documentation encoding: 
  30  from epydoc.apidoc import * 
  31  # Type comparisons: 
  32  from types import * 
  33  # Error reporting: 
  34  from epydoc import log 
  35  # Helper functions: 
  36  from epydoc.util import * 
  37  # For extracting encoding for docstrings: 
  38  import epydoc.docparser 
  39  # Builtin values 
  40  import __builtin__ 
  41  # Backwards compatibility 
  42  from epydoc.compat import *  
  43   
  44  ###################################################################### 
  45  ## Caches 
  46  ###################################################################### 
  47   
  48  _valuedoc_cache = {} 
  49  """A cache containing the API documentation for values that we've 
  50  already seen.  This cache is implemented as a dictionary that maps a 
  51  value's pyid to its L{ValueDoc}. 
  52   
  53  Note that if we encounter a value but decide not to introspect it 
  54  (because it's imported from another module), then C{_valuedoc_cache} 
  55  will contain an entry for the value, but the value will not be listed 
  56  in L{_introspected_values}.""" 
  57   
  58  _introspected_values = {} 
  59  """A record which values we've introspected, encoded as a dictionary from 
  60  pyid to C{bool}.""" 
  61   
62 -def clear_cache():
63 """ 64 Discard any cached C{APIDoc} values that have been computed for 65 introspected values. 66 """ 67 _valuedoc_cache.clear() 68 _introspected_values.clear()
69 70 ###################################################################### 71 ## Introspection 72 ###################################################################### 73
74 -def introspect_docs(value=None, name=None, filename=None, context=None, 75 is_script=False, module_name=None):
76 """ 77 Generate the API documentation for a specified object by 78 introspecting Python values, and return it as a L{ValueDoc}. The 79 object to generate documentation for may be specified using 80 the C{value} parameter, the C{filename} parameter, I{or} the 81 C{name} parameter. (It is an error to specify more than one 82 of these three parameters, or to not specify any of them.) 83 84 @param value: The python object that should be documented. 85 @param filename: The name of the file that contains the python 86 source code for a package, module, or script. If 87 C{filename} is specified, then C{introspect} will return a 88 C{ModuleDoc} describing its contents. 89 @param name: The fully-qualified python dotted name of any 90 value (including packages, modules, classes, and 91 functions). C{DocParser} will automatically figure out 92 which module(s) it needs to import in order to find the 93 documentation for the specified object. 94 @param context: The API documentation for the class of module 95 that contains C{value} (if available). 96 @param module_name: The name of the module where the value is defined. 97 Useful to retrieve the docstring encoding if there is no way to 98 detect the module by introspection (such as in properties) 99 """ 100 if value is None and name is not None and filename is None: 101 value = get_value_from_name(DottedName(name)) 102 elif value is None and name is None and filename is not None: 103 if is_script: 104 value = get_value_from_scriptname(filename) 105 else: 106 value = get_value_from_filename(filename, context) 107 elif name is None and filename is None: 108 # it's ok if value is None -- that's a value, after all. 109 pass 110 else: 111 raise ValueError("Expected exactly one of the following " 112 "arguments: value, name, filename") 113 114 pyid = id(value) 115 116 # If we've already introspected this value, then simply return 117 # its ValueDoc from our cache. 118 if pyid in _introspected_values: 119 # If the file is a script, then adjust its name. 120 if is_script and filename is not None: 121 _valuedoc_cache[pyid].canonical_name = DottedName( 122 munge_script_name(str(filename))) 123 return _valuedoc_cache[pyid] 124 125 # Create an initial value doc for this value & add it to the cache. 126 val_doc = _get_valuedoc(value) 127 128 # Introspect the value. 129 _introspected_values[pyid] = True 130 introspect_func = _get_introspecter(value) 131 introspect_func(value, val_doc, module_name=module_name) 132 133 # Set canonical name, if it was given 134 if val_doc.canonical_name is UNKNOWN and name is not None: 135 val_doc.canonical_name = DottedName(name) 136 137 # If the file is a script, then adjust its name. 138 if is_script and filename is not None: 139 val_doc.canonical_name = DottedName(munge_script_name(str(filename))) 140 141 if val_doc.canonical_name is UNKNOWN and filename is not None: 142 shadowed_name = DottedName(value.__name__) 143 log.warning("Module %s is shadowed by a variable with " 144 "the same name." % shadowed_name) 145 val_doc.canonical_name = DottedName(str(shadowed_name)+"'") 146 147 return val_doc
148
149 -def _get_valuedoc(value):
150 """ 151 If a C{ValueDoc} for the given value exists in the valuedoc 152 cache, then return it; otherwise, create a new C{ValueDoc}, 153 add it to the cache, and return it. When possible, the new 154 C{ValueDoc}'s C{pyval}, C{repr}, and C{canonical_name} 155 attributes will be set appropriately. 156 """ 157 pyid = id(value) 158 val_doc = _valuedoc_cache.get(pyid) 159 if val_doc is None: 160 try: canonical_name = get_canonical_name(value, strict=True) 161 except DottedName.InvalidDottedName: canonical_name = UNKNOWN 162 val_doc = ValueDoc(pyval=value, canonical_name = canonical_name, 163 docs_extracted_by='introspecter') 164 _valuedoc_cache[pyid] = val_doc 165 166 # If it's a module, then do some preliminary introspection. 167 # Otherwise, check what the containing module is (used e.g. 168 # to decide what markup language should be used for docstrings) 169 if inspect.ismodule(value): 170 introspect_module(value, val_doc, preliminary=True) 171 val_doc.defining_module = val_doc 172 else: 173 module_name = str(get_containing_module(value)) 174 module = sys.modules.get(module_name) 175 if module is not None and inspect.ismodule(module): 176 val_doc.defining_module = _get_valuedoc(module) 177 178 return val_doc
179 180 #//////////////////////////////////////////////////////////// 181 # Module Introspection 182 #//////////////////////////////////////////////////////////// 183 184 #: A list of module variables that should not be included in a 185 #: module's API documentation. 186 UNDOCUMENTED_MODULE_VARS = ( 187 '__builtins__', '__doc__', '__all__', '__file__', '__path__', 188 '__name__', '__extra_epydoc_fields__', '__docformat__') 189
190 -def introspect_module(module, module_doc, module_name=None, preliminary=False):
191 """ 192 Add API documentation information about the module C{module} 193 to C{module_doc}. 194 """ 195 module_doc.specialize_to(ModuleDoc) 196 197 # Record the module's docformat 198 if hasattr(module, '__docformat__'): 199 module_doc.docformat = unicode(module.__docformat__) 200 201 # Record the module's filename 202 if hasattr(module, '__file__'): 203 try: module_doc.filename = unicode(module.__file__) 204 except KeyboardInterrupt: raise 205 except: pass 206 if module_doc.filename is not UNKNOWN: 207 try: module_doc.filename = py_src_filename(module_doc.filename) 208 except ValueError: pass 209 210 # If this is just a preliminary introspection, then don't do 211 # anything else. (Typically this is true if this module was 212 # imported, but is not included in the set of modules we're 213 # documenting.) 214 module_doc.variables = {} 215 if preliminary: return 216 217 # Record the module's docstring 218 if hasattr(module, '__doc__'): 219 module_doc.docstring = get_docstring(module) 220 221 # If the module has a __path__, then it's (probably) a 222 # package; so set is_package=True and record its __path__. 223 if hasattr(module, '__path__'): 224 module_doc.is_package = True 225 try: module_doc.path = [unicode(p) for p in module.__path__] 226 except KeyboardInterrupt: raise 227 except: pass 228 else: 229 module_doc.is_package = False 230 231 # Make sure we have a name for the package. 232 dotted_name = module_doc.canonical_name 233 if dotted_name is UNKNOWN: 234 dotted_name = DottedName(module.__name__) 235 name_without_primes = DottedName(str(dotted_name).replace("'", "")) 236 237 # Record the module's parent package, if it has one. 238 if len(dotted_name) > 1: 239 package_name = str(dotted_name.container()) 240 package = sys.modules.get(package_name) 241 if package is not None: 242 module_doc.package = introspect_docs(package) 243 else: 244 module_doc.package = None 245 246 # Initialize the submodules property 247 module_doc.submodules = [] 248 249 # Add the module to its parent package's submodules list. 250 if module_doc.package not in (None, UNKNOWN): 251 module_doc.package.submodules.append(module_doc) 252 253 # Look up the module's __all__ attribute (public names). 254 public_names = None 255 if hasattr(module, '__all__'): 256 try: 257 public_names = set([str(name) for name in module.__all__]) 258 except KeyboardInterrupt: raise 259 except: pass 260 261 # Record the module's variables. 262 module_doc.variables = {} 263 for child_name in dir(module): 264 if child_name in UNDOCUMENTED_MODULE_VARS: continue 265 child = getattr(module, child_name) 266 267 # Create a VariableDoc for the child, and introspect its 268 # value if it's defined in this module. 269 container = get_containing_module(child) 270 if ((container is not None and 271 container == name_without_primes) or 272 (public_names is not None and 273 child_name in public_names)): 274 # Local variable. 275 child_val_doc = introspect_docs(child, context=module_doc, 276 module_name=dotted_name) 277 child_var_doc = VariableDoc(name=child_name, 278 value=child_val_doc, 279 is_imported=False, 280 container=module_doc, 281 docs_extracted_by='introspecter') 282 elif container is None or module_doc.canonical_name is UNKNOWN: 283 284 # Don't introspect stuff "from __future__" 285 if is_future_feature(child): continue 286 287 # Possibly imported variable. 288 child_val_doc = introspect_docs(child, context=module_doc) 289 child_var_doc = VariableDoc(name=child_name, 290 value=child_val_doc, 291 container=module_doc, 292 docs_extracted_by='introspecter') 293 else: 294 # Imported variable. 295 child_val_doc = _get_valuedoc(child) 296 child_var_doc = VariableDoc(name=child_name, 297 value=child_val_doc, 298 is_imported=True, 299 container=module_doc, 300 docs_extracted_by='introspecter') 301 302 # If the module's __all__ attribute is set, use it to set the 303 # variables public/private status and imported status. 304 if public_names is not None: 305 if child_name in public_names: 306 child_var_doc.is_public = True 307 if not isinstance(child_var_doc, ModuleDoc): 308 child_var_doc.is_imported = False 309 else: 310 child_var_doc.is_public = False 311 312 module_doc.variables[child_name] = child_var_doc 313 314 return module_doc
315 316 #//////////////////////////////////////////////////////////// 317 # Class Introspection 318 #//////////////////////////////////////////////////////////// 319 320 #: A list of class variables that should not be included in a 321 #: class's API documentation. 322 UNDOCUMENTED_CLASS_VARS = ( 323 '__doc__', '__module__', '__dict__', '__weakref__', '__slots__', 324 '__pyx_vtable__') 325
326 -def introspect_class(cls, class_doc, module_name=None):
327 """ 328 Add API documentation information about the class C{cls} 329 to C{class_doc}. 330 """ 331 class_doc.specialize_to(ClassDoc) 332 333 # Record the class's docstring. 334 class_doc.docstring = get_docstring(cls) 335 336 # Record the class's __all__ attribute (public names). 337 public_names = None 338 if hasattr(cls, '__all__'): 339 try: 340 public_names = set([str(name) for name in cls.__all__]) 341 except KeyboardInterrupt: raise 342 except: pass 343 344 # Start a list of subclasses. 345 class_doc.subclasses = [] 346 347 # Sometimes users will define a __metaclass__ that copies all 348 # class attributes from bases directly into the derived class's 349 # __dict__ when the class is created. (This saves the lookup time 350 # needed to search the base tree for an attribute.) But for the 351 # docs, we only want to list these copied attributes in the 352 # parent. So only add an attribute if it is not identical to an 353 # attribute of a base class. (Unfortunately, this can sometimes 354 # cause an attribute to look like it was inherited, even though it 355 # wasn't, if it happens to have the exact same value as the 356 # corresponding base's attribute.) An example of a case where 357 # this helps is PyQt -- subclasses of QWidget get about 300 358 # methods injected into them. 359 base_children = {} 360 361 # Record the class's base classes; and add the class to its 362 # base class's subclass lists. 363 if hasattr(cls, '__bases__'): 364 try: bases = list(cls.__bases__) 365 except: 366 bases = None 367 log.warning("Class '%s' defines __bases__, but it does not " 368 "contain an iterable; ignoring base list." 369 % getattr(cls, '__name__', '??')) 370 if bases is not None: 371 class_doc.bases = [] 372 for base in bases: 373 basedoc = introspect_docs(base) 374 class_doc.bases.append(basedoc) 375 basedoc.subclasses.append(class_doc) 376 377 bases.reverse() 378 for base in bases: 379 if hasattr(base, '__dict__'): 380 base_children.update(base.__dict__) 381 382 # The module name is not defined if the class is being introspected 383 # as another class base. 384 if module_name is None and class_doc.defining_module not in (None, UNKNOWN): 385 module_name = class_doc.defining_module.canonical_name 386 387 # Record the class's local variables. 388 class_doc.variables = {} 389 if hasattr(cls, '__dict__'): 390 private_prefix = '_%s__' % getattr(cls, '__name__', '<none>') 391 for child_name, child in cls.__dict__.items(): 392 if (child_name in base_children 393 and base_children[child_name] == child): 394 continue 395 396 if child_name.startswith(private_prefix): 397 child_name = child_name[len(private_prefix)-2:] 398 if child_name in UNDOCUMENTED_CLASS_VARS: continue 399 val_doc = introspect_docs(child, context=class_doc, 400 module_name=module_name) 401 var_doc = VariableDoc(name=child_name, value=val_doc, 402 container=class_doc, 403 docs_extracted_by='introspecter') 404 if public_names is not None: 405 var_doc.is_public = (child_name in public_names) 406 class_doc.variables[child_name] = var_doc 407 408 return class_doc
409 410 #//////////////////////////////////////////////////////////// 411 # Routine Introspection 412 #//////////////////////////////////////////////////////////// 413
414 -def introspect_routine(routine, routine_doc, module_name=None):
415 """Add API documentation information about the function 416 C{routine} to C{routine_doc} (specializing it to C{Routine_doc}).""" 417 routine_doc.specialize_to(RoutineDoc) 418 419 # Extract the underying function 420 if isinstance(routine, MethodType): 421 func = routine.im_func 422 elif isinstance(routine, staticmethod): 423 func = routine.__get__(0) 424 elif isinstance(routine, classmethod): 425 func = routine.__get__(0).im_func 426 else: 427 func = routine 428 429 # Record the function's docstring. 430 routine_doc.docstring = get_docstring(func) 431 432 # Record the function's signature. 433 if isinstance(func, FunctionType): 434 (args, vararg, kwarg, defaults) = inspect.getargspec(func) 435 436 # Add the arguments. 437 routine_doc.posargs = args 438 routine_doc.vararg = vararg 439 routine_doc.kwarg = kwarg 440 441 # Set default values for positional arguments. 442 routine_doc.posarg_defaults = [None]*len(args) 443 if defaults is not None: 444 offset = len(args)-len(defaults) 445 for i in range(len(defaults)): 446 default_val = introspect_docs(defaults[i]) 447 routine_doc.posarg_defaults[i+offset] = default_val 448 449 # If it's a bound method, then strip off the first argument. 450 if isinstance(routine, MethodType) and routine.im_self is not None: 451 routine_doc.posargs = routine_doc.posargs[1:] 452 routine_doc.posarg_defaults = routine_doc.posarg_defaults[1:] 453 454 # Set the routine's line number. 455 if hasattr(func, 'func_code'): 456 routine_doc.lineno = func.func_code.co_firstlineno 457 458 else: 459 # [XX] I should probably use UNKNOWN here?? 460 # dvarrazzo: if '...' is to be changed, also check that 461 # `docstringparser.process_arg_field()` works correctly. 462 # See SF bug #1556024. 463 routine_doc.posargs = ['...'] 464 routine_doc.posarg_defaults = [None] 465 routine_doc.kwarg = None 466 routine_doc.vararg = None 467 468 # Change type, if appropriate. 469 if isinstance(routine, staticmethod): 470 routine_doc.specialize_to(StaticMethodDoc) 471 if isinstance(routine, classmethod): 472 routine_doc.specialize_to(ClassMethodDoc) 473 474 return routine_doc
475 476 #//////////////////////////////////////////////////////////// 477 # Property Introspection 478 #//////////////////////////////////////////////////////////// 479
480 -def introspect_property(prop, prop_doc, module_name=None):
481 """Add API documentation information about the property 482 C{prop} to C{prop_doc} (specializing it to C{PropertyDoc}).""" 483 prop_doc.specialize_to(PropertyDoc) 484 485 # Record the property's docstring. 486 prop_doc.docstring = get_docstring(prop, module_name=module_name) 487 488 # Record the property's access functions. 489 if hasattr(prop, 'fget'): 490 prop_doc.fget = introspect_docs(prop.fget) 491 prop_doc.fset = introspect_docs(prop.fset) 492 prop_doc.fdel = introspect_docs(prop.fdel) 493 494 return prop_doc
495 496 #//////////////////////////////////////////////////////////// 497 # Generic Value Introspection 498 #//////////////////////////////////////////////////////////// 499
500 -def introspect_other(val, val_doc, module_name=None):
501 """Specialize val_doc to a C{GenericValueDoc} and return it.""" 502 val_doc.specialize_to(GenericValueDoc) 503 return val_doc
504 505 #//////////////////////////////////////////////////////////// 506 # Helper functions 507 #//////////////////////////////////////////////////////////// 508
509 -def isclass(object):
510 """ 511 Return true if the given object is a class. In particular, return 512 true if object is an instance of C{types.TypeType} or of 513 C{types.ClassType}. This is used instead of C{inspect.isclass()}, 514 because the latter returns true for objects that are not classes 515 (in particular, it returns true for any object that has a 516 C{__bases__} attribute, including objects that define 517 C{__getattr__} to always return a value). 518 """ 519 return isinstance(object, tuple(_CLASS_TYPES))
520 521 _CLASS_TYPES = set([TypeType, ClassType]) 522 """A list of types that should be treated as classes.""" 523
524 -def register_class_type(typ):
525 """Add a type to the lists of types that should be treated as 526 classes. By default, this list contains C{TypeType} and 527 C{ClassType}.""" 528 _CLASS_TYPES.add(typ)
529 530 __future_check_works = None 531
532 -def is_future_feature(object):
533 """ 534 Return True if C{object} results from a C{from __future__ import feature} 535 statement. 536 """ 537 # Guard from unexpected implementation changes of the __future__ module. 538 global __future_check_works 539 if __future_check_works is not None: 540 if __future_check_works: 541 import __future__ 542 return isinstance(object, __future__._Feature) 543 else: 544 return False 545 else: 546 __future_check_works = True 547 try: 548 return is_future_feature(object) 549 except: 550 __future_check_works = False 551 log.warning("Troubles inspecting __future__. Python implementation" 552 " may have been changed.") 553 return False
554
555 -def get_docstring(value, module_name=None):
556 """ 557 Return the docstring for the given value; or C{None} if it 558 does not have a docstring. 559 @rtype: C{unicode} 560 """ 561 docstring = getattr(value, '__doc__', None) 562 if docstring is None: 563 return None 564 elif isinstance(docstring, unicode): 565 return docstring 566 elif isinstance(docstring, str): 567 try: return unicode(docstring, 'ascii') 568 except UnicodeDecodeError: 569 if module_name is None: 570 module_name = get_containing_module(value) 571 if module_name is not None: 572 try: 573 module = get_value_from_name(module_name) 574 filename = py_src_filename(module.__file__) 575 encoding = epydoc.docparser.get_module_encoding(filename) 576 return unicode(docstring, encoding) 577 except KeyboardInterrupt: raise 578 except Exception: pass 579 if hasattr(value, '__name__'): name = value.__name__ 580 else: name = repr(value) 581 log.warning("%s's docstring is not a unicode string, but it " 582 "contains non-ascii data -- treating it as " 583 "latin-1." % name) 584 return unicode(docstring, 'latin-1') 585 return None 586 elif value is BuiltinMethodType: 587 # Don't issue a warning for this special case. 588 return None 589 else: 590 if hasattr(value, '__name__'): name = value.__name__ 591 else: name = repr(value) 592 log.warning("%s's docstring is not a string -- ignoring it." % 593 name) 594 return None
595
596 -def get_canonical_name(value, strict=False):
597 """ 598 @return: the canonical name for C{value}, or C{UNKNOWN} if no 599 canonical name can be found. Currently, C{get_canonical_name} 600 can find canonical names for: modules; functions; non-nested 601 classes; methods of non-nested classes; and some class methods 602 of non-nested classes. 603 604 @rtype: L{DottedName} or C{UNKNOWN} 605 """ 606 if not hasattr(value, '__name__'): return UNKNOWN 607 608 # Get the name via introspection. 609 if isinstance(value, ModuleType): 610 try: 611 dotted_name = DottedName(value.__name__, strict=strict) 612 # If the module is shadowed by a variable in its parent 613 # package(s), then add a prime mark to the end, to 614 # differentiate it from the variable that shadows it. 615 if verify_name(value, dotted_name) is UNKNOWN: 616 log.warning("Module %s is shadowed by a variable with " 617 "the same name." % dotted_name) 618 # Note -- this return bypasses verify_name check: 619 return DottedName(value.__name__+"'") 620 except DottedName.InvalidDottedName: 621 # Name is not a valid Python identifier -- treat as script. 622 if hasattr(value, '__file__'): 623 filename = '%s' % value.__str__ 624 dotted_name = DottedName(munge_script_name(filename)) 625 626 elif isclass(value): 627 if value.__module__ == '__builtin__': 628 dotted_name = DottedName(value.__name__, strict=strict) 629 else: 630 dotted_name = DottedName(value.__module__, value.__name__, 631 strict=strict) 632 633 elif (inspect.ismethod(value) and value.im_self is not None and 634 value.im_class is ClassType and 635 not value.__name__.startswith('<')): # class method. 636 class_name = get_canonical_name(value.im_self) 637 if class_name is UNKNOWN: return UNKNOWN 638 dotted_name = DottedName(class_name, value.__name__, strict=strict) 639 elif (inspect.ismethod(value) and 640 not value.__name__.startswith('<')): 641 class_name = get_canonical_name(value.im_class) 642 if class_name is UNKNOWN: return UNKNOWN 643 dotted_name = DottedName(class_name, value.__name__, strict=strict) 644 elif (isinstance(value, FunctionType) and 645 not value.__name__.startswith('<')): 646 module_name = _find_function_module(value) 647 if module_name is None: return UNKNOWN 648 dotted_name = DottedName(module_name, value.__name__, strict=strict) 649 else: 650 return UNKNOWN 651 652 return verify_name(value, dotted_name)
653
654 -def verify_name(value, dotted_name):
655 """ 656 Verify the name. E.g., if it's a nested class, then we won't be 657 able to find it with the name we constructed. 658 """ 659 if dotted_name is UNKNOWN: return UNKNOWN 660 if len(dotted_name) == 1 and hasattr(__builtin__, dotted_name[0]): 661 return dotted_name 662 named_value = sys.modules.get(dotted_name[0]) 663 if named_value is None: return UNKNOWN 664 for identifier in dotted_name[1:]: 665 try: named_value = getattr(named_value, identifier) 666 except: return UNKNOWN 667 if value is named_value: 668 return dotted_name 669 else: 670 return UNKNOWN
671 672 # [xx] not used:
673 -def value_repr(value):
674 try: 675 s = '%r' % value 676 if isinstance(s, str): 677 s = decode_with_backslashreplace(s) 678 return s 679 except: 680 return UNKNOWN
681
682 -def get_containing_module(value):
683 """ 684 Return the name of the module containing the given value, or 685 C{None} if the module name can't be determined. 686 @rtype: L{DottedName} 687 """ 688 if inspect.ismodule(value): 689 return DottedName(value.__name__) 690 elif isclass(value): 691 return DottedName(value.__module__) 692 elif (inspect.ismethod(value) and value.im_self is not None and 693 value.im_class is ClassType): # class method. 694 return DottedName(value.im_self.__module__) 695 elif inspect.ismethod(value): 696 return DottedName(value.im_class.__module__) 697 elif inspect.isroutine(value): 698 module = _find_function_module(value) 699 if module is None: return None 700 return DottedName(module) 701 else: 702 return None
703
704 -def _find_function_module(func):
705 """ 706 @return: The module that defines the given function. 707 @rtype: C{module} 708 @param func: The function whose module should be found. 709 @type func: C{function} 710 """ 711 if hasattr(func, '__module__'): 712 return func.__module__ 713 try: 714 module = inspect.getmodule(func) 715 if module: return module.__name__ 716 except KeyboardInterrupt: raise 717 except: pass 718 719 # This fallback shouldn't usually be needed. But it is needed in 720 # a couple special cases (including using epydoc to document 721 # itself). In particular, if a module gets loaded twice, using 722 # two different names for the same file, then this helps. 723 for module in sys.modules.values(): 724 if (hasattr(module, '__dict__') and 725 hasattr(func, 'func_globals') and 726 func.func_globals is module.__dict__): 727 return module.__name__ 728 return None
729 730 #//////////////////////////////////////////////////////////// 731 # Introspection Dispatch Table 732 #//////////////////////////////////////////////////////////// 733 734 _introspecter_registry = []
735 -def register_introspecter(applicability_test, introspecter, priority=10):
736 """ 737 Register an introspecter function. Introspecter functions take 738 two arguments, a python value and a C{ValueDoc} object, and should 739 add information about the given value to the the C{ValueDoc}. 740 Usually, the first line of an inspecter function will specialize 741 it to a sublass of C{ValueDoc}, using L{ValueDoc.specialize_to()}: 742 743 >>> def typical_introspecter(value, value_doc): 744 ... value_doc.specialize_to(SomeSubclassOfValueDoc) 745 ... <add info to value_doc> 746 747 @param priority: The priority of this introspecter, which determines 748 the order in which introspecters are tried -- introspecters with lower 749 numbers are tried first. The standard introspecters have priorities 750 ranging from 20 to 30. The default priority (10) will place new 751 introspecters before standard introspecters. 752 """ 753 _introspecter_registry.append( (priority, applicability_test, 754 introspecter) ) 755 _introspecter_registry.sort()
756
757 -def _get_introspecter(value):
758 for (priority, applicability_test, introspecter) in _introspecter_registry: 759 if applicability_test(value): 760 return introspecter 761 else: 762 return introspect_other
763 764 # Register the standard introspecter functions.
765 -def is_classmethod(v): return isinstance(v, classmethod)
766 -def is_staticmethod(v): return isinstance(v, staticmethod)
767 -def is_property(v): return isinstance(v, property)
768 register_introspecter(inspect.ismodule, introspect_module, priority=20) 769 register_introspecter(isclass, introspect_class, priority=24) 770 register_introspecter(inspect.isroutine, introspect_routine, priority=28) 771 register_introspecter(is_property, introspect_property, priority=30) 772 773 # Register getset_descriptor as a property 774 try: 775 import array 776 getset_type = type(array.array.typecode) 777 del array
778 - def is_getset(v): return isinstance(v, getset_type)
779 register_introspecter(is_getset, introspect_property, priority=32) 780 except: 781 pass 782 783 # Register member_descriptor as a property 784 try: 785 import datetime 786 member_type = type(datetime.timedelta.days) 787 del datetime
788 - def is_member(v): return isinstance(v, member_type)
789 register_introspecter(is_member, introspect_property, priority=34) 790 except: 791 pass 792 793 #//////////////////////////////////////////////////////////// 794 # Import support 795 #//////////////////////////////////////////////////////////// 796
797 -def get_value_from_filename(filename, context=None):
798 # Normalize the filename. 799 filename = os.path.normpath(os.path.abspath(filename)) 800 801 # Divide the filename into a base directory and a name. (For 802 # packages, use the package's parent directory as the base, and 803 # the directory name as its name). 804 basedir = os.path.split(filename)[0] 805 name = os.path.splitext(os.path.split(filename)[1])[0] 806 if name == '__init__': 807 basedir, name = os.path.split(basedir) 808 name = DottedName(name) 809 810 # If the context wasn't provided, then check if the file is in a 811 # package directory. If so, then update basedir & name to contain 812 # the topmost package's directory and the fully qualified name for 813 # this file. (This update assume the default value of __path__ 814 # for the parent packages; if the parent packages override their 815 # __path__s, then this can cause us not to find the value.) 816 if context is None: 817 while is_package_dir(basedir): 818 basedir, pkg_name = os.path.split(basedir) 819 name = DottedName(pkg_name, name) 820 821 # If a parent package was specified, then find the directory of 822 # the topmost package, and the fully qualified name for this file. 823 if context is not None: 824 # Combine the name. 825 name = DottedName(context.canonical_name, name) 826 # Find the directory of the base package. 827 while context not in (None, UNKNOWN): 828 pkg_dir = os.path.split(context.filename)[0] 829 basedir = os.path.split(pkg_dir)[0] 830 context = context.package 831 832 # Import the module. (basedir is the directory of the module's 833 # topmost package, or its own directory if it's not in a package; 834 # and name is the fully qualified dotted name for the module.) 835 old_sys_path = sys.path[:] 836 try: 837 sys.path.insert(0, basedir) 838 # This will make sure that we get the module itself, even 839 # if it is shadowed by a variable. (E.g., curses.wrapper): 840 _import(str(name)) 841 if str(name) in sys.modules: 842 return sys.modules[str(name)] 843 else: 844 # Use this as a fallback -- it *shouldn't* ever be needed. 845 return get_value_from_name(name) 846 finally: 847 sys.path = old_sys_path
848
849 -def get_value_from_scriptname(filename):
850 name = munge_script_name(filename) 851 return _import(name, filename)
852
853 -def get_value_from_name(name, globs=None):
854 """ 855 Given a name, return the corresponding value. 856 857 @param globs: A namespace to check for the value, if there is no 858 module containing the named value. Defaults to __builtin__. 859 """ 860 name = DottedName(name) 861 862 # Import the topmost module/package. If we fail, then check if 863 # the requested name refers to a builtin. 864 try: 865 module = _import(name[0]) 866 except ImportError, e: 867 if globs is None: globs = __builtin__.__dict__ 868 if name[0] in globs: 869 try: return _lookup(globs[name[0]], name[1:]) 870 except: raise e 871 else: 872 raise 873 874 # Find the requested value in the module/package or its submodules. 875 for i in range(1, len(name)): 876 try: return _lookup(module, name[i:]) 877 except ImportError: pass 878 module = _import('.'.join(name[:i+1])) 879 module = _lookup(module, name[1:i+1]) 880 return module
881
882 -def _lookup(module, name):
883 val = module 884 for i, identifier in enumerate(name): 885 try: val = getattr(val, identifier) 886 except AttributeError: 887 exc_msg = ('no variable named %s in %s' % 888 (identifier, '.'.join(name[:1+i]))) 889 raise ImportError(exc_msg) 890 return val
891
892 -def _import(name, filename=None):
893 """ 894 Run the given callable in a 'sandboxed' environment. 895 Currently, this includes saving and restoring the contents of 896 sys and __builtins__; and suppressing stdin, stdout, and stderr. 897 """ 898 # Note that we just do a shallow copy of sys. In particular, 899 # any changes made to sys.modules will be kept. But we do 900 # explicitly store sys.path. 901 old_sys = sys.__dict__.copy() 902 old_sys_path = sys.path[:] 903 old_builtins = __builtin__.__dict__.copy() 904 905 # Add the current directory to sys.path, in case they're trying to 906 # import a module by name that resides in the current directory. 907 # But add it to the end -- otherwise, the explicit directory added 908 # in get_value_from_filename might get overwritten 909 sys.path.append('') 910 911 # Suppress input and output. (These get restored when we restore 912 # sys to old_sys). 913 sys.stdin = sys.stdout = sys.stderr = _dev_null 914 sys.__stdin__ = sys.__stdout__ = sys.__stderr__ = _dev_null 915 916 # Remove any command-line arguments 917 sys.argv = ['(imported)'] 918 919 try: 920 try: 921 if filename is None: 922 return __import__(name) 923 else: 924 # For importing scripts: 925 return imp.load_source(name, filename) 926 except KeyboardInterrupt: raise 927 except: 928 exc_typ, exc_val, exc_tb = sys.exc_info() 929 if exc_val is None: 930 estr = '%s' % (exc_typ,) 931 else: 932 estr = '%s: %s' % (exc_typ.__name__, exc_val) 933 if exc_tb.tb_next is not None: 934 estr += ' (line %d)' % (exc_tb.tb_next.tb_lineno,) 935 raise ImportError(estr) 936 finally: 937 # Restore the important values that we saved. 938 __builtin__.__dict__.clear() 939 __builtin__.__dict__.update(old_builtins) 940 sys.__dict__.clear() 941 sys.__dict__.update(old_sys) 942 sys.path = old_sys_path
943
944 -def introspect_docstring_lineno(api_doc):
945 """ 946 Try to determine the line number on which the given item's 947 docstring begins. Return the line number, or C{None} if the line 948 number can't be determined. The line number of the first line in 949 the file is 1. 950 """ 951 if api_doc.docstring_lineno is not UNKNOWN: 952 return api_doc.docstring_lineno 953 if isinstance(api_doc, ValueDoc) and api_doc.pyval is not UNKNOWN: 954 try: 955 lines, lineno = inspect.findsource(api_doc.pyval) 956 if not isinstance(api_doc, ModuleDoc): lineno += 1 957 for lineno in range(lineno, len(lines)): 958 if lines[lineno].split('#', 1)[0].strip(): 959 api_doc.docstring_lineno = lineno + 1 960 return lineno + 1 961 except IOError: pass 962 except TypeError: pass 963 except IndexError: 964 log.warning('inspect.findsource(%s) raised IndexError' 965 % api_doc.canonical_name) 966 return None
967
968 -class _DevNull:
969 """ 970 A "file-like" object that discards anything that is written and 971 always reports end-of-file when read. C{_DevNull} is used by 972 L{_import()} to discard output when importing modules; and to 973 ensure that stdin appears closed. 974 """
975 - def __init__(self):
976 self.closed = 1 977 self.mode = 'r+' 978 self.softspace = 0 979 self.name='</dev/null>'
980 - def close(self): pass
981 - def flush(self): pass
982 - def read(self, size=0): return ''
983 - def readline(self, size=0): return ''
984 - def readlines(self, sizehint=0): return []
985 - def seek(self, offset, whence=0): pass
986 - def tell(self): return 0L
987 - def truncate(self, size=0): pass
988 - def write(self, str): pass
989 - def writelines(self, sequence): pass
990 xreadlines = readlines
991 _dev_null = _DevNull() 992 993 ###################################################################### 994 ## Zope InterfaceClass 995 ###################################################################### 996 997 try: 998 from zope.interface.interface import InterfaceClass as _ZopeInterfaceClass 999 register_class_type(_ZopeInterfaceClass) 1000 except: 1001 pass 1002 1003 ###################################################################### 1004 ## Zope Extension classes 1005 ###################################################################### 1006 1007 try: 1008 # Register type(ExtensionClass.ExtensionClass) 1009 from ExtensionClass import ExtensionClass as _ExtensionClass 1010 _ZopeType = type(_ExtensionClass)
1011 - def _is_zope_type(val):
1012 return isinstance(val, _ZopeType)
1013 register_introspecter(_is_zope_type, introspect_class) 1014 1015 # Register ExtensionClass.*MethodType 1016 from ExtensionClass import PythonMethodType as _ZopeMethodType 1017 from ExtensionClass import ExtensionMethodType as _ZopeCMethodType
1018 - def _is_zope_method(val):
1019 return isinstance(val, (_ZopeMethodType, _ZopeCMethodType))
1020 register_introspecter(_is_zope_method, introspect_routine) 1021 except: 1022 pass 1023 1024 1025 1026 1027 # [xx] 1028 0 # hm.. otherwise the following gets treated as a docstring! ouch! 1029 """ 1030 ###################################################################### 1031 ## Zope Extension... 1032 ###################################################################### 1033 class ZopeIntrospecter(Introspecter): 1034 VALUEDOC_CLASSES = Introspecter.VALUEDOC_CLASSES.copy() 1035 VALUEDOC_CLASSES.update({ 1036 'module': ZopeModuleDoc, 1037 'class': ZopeClassDoc, 1038 'interface': ZopeInterfaceDoc, 1039 'attribute': ZopeAttributeDoc, 1040 }) 1041 1042 def add_module_child(self, child, child_name, module_doc): 1043 if isinstance(child, zope.interfaces.Interface): 1044 module_doc.add_zope_interface(child_name) 1045 else: 1046 Introspecter.add_module_child(self, child, child_name, module_doc) 1047 1048 def add_class_child(self, child, child_name, class_doc): 1049 if isinstance(child, zope.interfaces.Interface): 1050 class_doc.add_zope_interface(child_name) 1051 else: 1052 Introspecter.add_class_child(self, child, child_name, class_doc) 1053 1054 def introspect_zope_interface(self, interface, interfacename): 1055 pass # etc... 1056 """ 1057