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 1810 2008-03-31 03:22:51Z 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 and not inspect.ismodule(child)): 275 # Local variable. 276 child_val_doc = introspect_docs(child, context=module_doc, 277 module_name=dotted_name) 278 child_var_doc = VariableDoc(name=child_name, 279 value=child_val_doc, 280 is_imported=False, 281 container=module_doc, 282 docs_extracted_by='introspecter') 283 elif ((container is None or module_doc.canonical_name is UNKNOWN) 284 and not inspect.ismodule(child)): 285 286 # Don't introspect stuff "from __future__" 287 if is_future_feature(child): continue 288 289 # Possibly imported variable. 290 child_val_doc = introspect_docs(child, context=module_doc) 291 child_var_doc = VariableDoc(name=child_name, 292 value=child_val_doc, 293 container=module_doc, 294 docs_extracted_by='introspecter') 295 else: 296 # Imported variable. 297 child_val_doc = _get_valuedoc(child) 298 child_var_doc = VariableDoc(name=child_name, 299 value=child_val_doc, 300 is_imported=True, 301 container=module_doc, 302 docs_extracted_by='introspecter') 303 304 # If the module's __all__ attribute is set, use it to set the 305 # variables public/private status and imported status. 306 if public_names is not None: 307 if child_name in public_names: 308 child_var_doc.is_public = True 309 if not isinstance(child_var_doc, ModuleDoc): 310 child_var_doc.is_imported = False 311 else: 312 child_var_doc.is_public = False 313 314 module_doc.variables[child_name] = child_var_doc 315 316 return module_doc
317 318 #//////////////////////////////////////////////////////////// 319 # Class Introspection 320 #//////////////////////////////////////////////////////////// 321 322 #: A list of class variables that should not be included in a 323 #: class's API documentation. 324 UNDOCUMENTED_CLASS_VARS = ( 325 '__doc__', '__module__', '__dict__', '__weakref__', '__slots__', 326 '__pyx_vtable__', '__metaclass__') 327
328 -def introspect_class(cls, class_doc, module_name=None):
329 """ 330 Add API documentation information about the class C{cls} 331 to C{class_doc}. 332 """ 333 class_doc.specialize_to(ClassDoc) 334 335 # Record the class's docstring. 336 class_doc.docstring = get_docstring(cls) 337 338 # Record the class's __all__ attribute (public names). 339 public_names = None 340 if hasattr(cls, '__all__'): 341 try: 342 public_names = set([str(name) for name in cls.__all__]) 343 except KeyboardInterrupt: raise 344 except: pass 345 346 # Record the class's metaclass 347 class_doc.metaclass = introspect_docs(type(cls)) 348 349 # Start a list of subclasses. 350 class_doc.subclasses = [] 351 352 # Sometimes users will define a __metaclass__ that copies all 353 # class attributes from bases directly into the derived class's 354 # __dict__ when the class is created. (This saves the lookup time 355 # needed to search the base tree for an attribute.) But for the 356 # docs, we only want to list these copied attributes in the 357 # parent. So only add an attribute if it is not identical to an 358 # attribute of a base class. (Unfortunately, this can sometimes 359 # cause an attribute to look like it was inherited, even though it 360 # wasn't, if it happens to have the exact same value as the 361 # corresponding base's attribute.) An example of a case where 362 # this helps is PyQt -- subclasses of QWidget get about 300 363 # methods injected into them. 364 base_children = {} 365 366 # Record the class's base classes; and add the class to its 367 # base class's subclass lists. 368 if hasattr(cls, '__bases__'): 369 try: bases = list(cls.__bases__) 370 except: 371 bases = None 372 log.warning("Class '%s' defines __bases__, but it does not " 373 "contain an iterable; ignoring base list." 374 % getattr(cls, '__name__', '??')) 375 if bases is not None: 376 class_doc.bases = [] 377 for base in bases: 378 basedoc = introspect_docs(base) 379 class_doc.bases.append(basedoc) 380 basedoc.subclasses.append(class_doc) 381 382 bases.reverse() 383 for base in bases: 384 if hasattr(base, '__dict__'): 385 base_children.update(base.__dict__) 386 387 # The module name is not defined if the class is being introspected 388 # as another class base. 389 if module_name is None and class_doc.defining_module not in (None, UNKNOWN): 390 module_name = class_doc.defining_module.canonical_name 391 392 # Record the class's local variables. 393 class_doc.variables = {} 394 if hasattr(cls, '__dict__'): 395 private_prefix = '_%s__' % getattr(cls, '__name__', '<none>') 396 for child_name, child in cls.__dict__.items(): 397 if (child_name in base_children 398 and base_children[child_name] == child): 399 continue 400 401 if child_name.startswith(private_prefix): 402 child_name = child_name[len(private_prefix)-2:] 403 if child_name in UNDOCUMENTED_CLASS_VARS: continue 404 val_doc = introspect_docs(child, context=class_doc, 405 module_name=module_name) 406 var_doc = VariableDoc(name=child_name, value=val_doc, 407 container=class_doc, 408 docs_extracted_by='introspecter') 409 if public_names is not None: 410 var_doc.is_public = (child_name in public_names) 411 class_doc.variables[child_name] = var_doc 412 413 return class_doc
414 415 #//////////////////////////////////////////////////////////// 416 # Routine Introspection 417 #//////////////////////////////////////////////////////////// 418
419 -def introspect_routine(routine, routine_doc, module_name=None):
420 """Add API documentation information about the function 421 C{routine} to C{routine_doc} (specializing it to C{Routine_doc}).""" 422 routine_doc.specialize_to(RoutineDoc) 423 424 # Extract the underying function 425 if isinstance(routine, MethodType): 426 func = routine.im_func 427 elif isinstance(routine, staticmethod): 428 func = routine.__get__(0) 429 elif isinstance(routine, classmethod): 430 func = routine.__get__(0).im_func 431 else: 432 func = routine 433 434 # Record the function's docstring. 435 routine_doc.docstring = get_docstring(func) 436 437 # Record the function's signature. 438 if isinstance(func, FunctionType): 439 (args, vararg, kwarg, defaults) = inspect.getargspec(func) 440 441 # Add the arguments. 442 routine_doc.posargs = args 443 routine_doc.vararg = vararg 444 routine_doc.kwarg = kwarg 445 446 # Set default values for positional arguments. 447 routine_doc.posarg_defaults = [None]*len(args) 448 if defaults is not None: 449 offset = len(args)-len(defaults) 450 for i in range(len(defaults)): 451 default_val = introspect_docs(defaults[i]) 452 routine_doc.posarg_defaults[i+offset] = default_val 453 454 # If it's a bound method, then strip off the first argument. 455 if isinstance(routine, MethodType) and routine.im_self is not None: 456 routine_doc.posargs = routine_doc.posargs[1:] 457 routine_doc.posarg_defaults = routine_doc.posarg_defaults[1:] 458 459 # Set the routine's line number. 460 if hasattr(func, 'func_code'): 461 routine_doc.lineno = func.func_code.co_firstlineno 462 463 else: 464 # [XX] I should probably use UNKNOWN here?? 465 # dvarrazzo: if '...' is to be changed, also check that 466 # `docstringparser.process_arg_field()` works correctly. 467 # See SF bug #1556024. 468 routine_doc.posargs = ['...'] 469 routine_doc.posarg_defaults = [None] 470 routine_doc.kwarg = None 471 routine_doc.vararg = None 472 473 # Change type, if appropriate. 474 if isinstance(routine, staticmethod): 475 routine_doc.specialize_to(StaticMethodDoc) 476 if isinstance(routine, classmethod): 477 routine_doc.specialize_to(ClassMethodDoc) 478 479 return routine_doc
480 481 #//////////////////////////////////////////////////////////// 482 # Property Introspection 483 #//////////////////////////////////////////////////////////// 484
485 -def introspect_property(prop, prop_doc, module_name=None):
486 """Add API documentation information about the property 487 C{prop} to C{prop_doc} (specializing it to C{PropertyDoc}).""" 488 prop_doc.specialize_to(PropertyDoc) 489 490 # Record the property's docstring. 491 prop_doc.docstring = get_docstring(prop, module_name=module_name) 492 493 # Record the property's access functions. 494 if hasattr(prop, 'fget'): 495 prop_doc.fget = introspect_docs(prop.fget) 496 prop_doc.fset = introspect_docs(prop.fset) 497 prop_doc.fdel = introspect_docs(prop.fdel) 498 499 return prop_doc
500 501 #//////////////////////////////////////////////////////////// 502 # Generic Value Introspection 503 #//////////////////////////////////////////////////////////// 504
505 -def introspect_other(val, val_doc, module_name=None):
506 """Specialize val_doc to a C{GenericValueDoc} and return it.""" 507 val_doc.specialize_to(GenericValueDoc) 508 return val_doc
509 510 #//////////////////////////////////////////////////////////// 511 # Helper functions 512 #//////////////////////////////////////////////////////////// 513
514 -def isclass(object):
515 """ 516 Return true if the given object is a class. In particular, return 517 true if object is an instance of C{types.TypeType} or of 518 C{types.ClassType}. This is used instead of C{inspect.isclass()}, 519 because the latter returns true for objects that are not classes 520 (in particular, it returns true for any object that has a 521 C{__bases__} attribute, including objects that define 522 C{__getattr__} to always return a value). 523 """ 524 return isinstance(object, tuple(_CLASS_TYPES))
525 526 _CLASS_TYPES = set([TypeType, ClassType]) 527 """A list of types that should be treated as classes.""" 528
529 -def register_class_type(typ):
530 """Add a type to the lists of types that should be treated as 531 classes. By default, this list contains C{TypeType} and 532 C{ClassType}.""" 533 _CLASS_TYPES.add(typ)
534 535 __future_check_works = None 536
537 -def is_future_feature(object):
538 """ 539 Return True if C{object} results from a C{from __future__ import feature} 540 statement. 541 """ 542 # Guard from unexpected implementation changes of the __future__ module. 543 global __future_check_works 544 if __future_check_works is not None: 545 if __future_check_works: 546 import __future__ 547 return isinstance(object, __future__._Feature) 548 else: 549 return False 550 else: 551 __future_check_works = True 552 try: 553 return is_future_feature(object) 554 except: 555 __future_check_works = False 556 log.warning("Troubles inspecting __future__. Python implementation" 557 " may have been changed.") 558 return False
559
560 -def get_docstring(value, module_name=None):
561 """ 562 Return the docstring for the given value; or C{None} if it 563 does not have a docstring. 564 @rtype: C{unicode} 565 """ 566 docstring = getattr(value, '__doc__', None) 567 if docstring is None: 568 return None 569 elif isinstance(docstring, unicode): 570 return docstring 571 elif isinstance(docstring, str): 572 try: return unicode(docstring, 'ascii') 573 except UnicodeDecodeError: 574 if module_name is None: 575 module_name = get_containing_module(value) 576 if module_name is not None: 577 try: 578 module = get_value_from_name(module_name) 579 filename = py_src_filename(module.__file__) 580 encoding = epydoc.docparser.get_module_encoding(filename) 581 return unicode(docstring, encoding) 582 except KeyboardInterrupt: raise 583 except Exception: pass 584 if hasattr(value, '__name__'): name = value.__name__ 585 else: name = repr(value) 586 log.warning("%s's docstring is not a unicode string, but it " 587 "contains non-ascii data -- treating it as " 588 "latin-1." % name) 589 return unicode(docstring, 'latin-1') 590 return None 591 elif value is BuiltinMethodType: 592 # Don't issue a warning for this special case. 593 return None 594 else: 595 if hasattr(value, '__name__'): name = value.__name__ 596 else: name = repr(value) 597 log.warning("%s's docstring is not a string -- ignoring it." % 598 name) 599 return None
600
601 -def get_canonical_name(value, strict=False):
602 """ 603 @return: the canonical name for C{value}, or C{UNKNOWN} if no 604 canonical name can be found. Currently, C{get_canonical_name} 605 can find canonical names for: modules; functions; non-nested 606 classes; methods of non-nested classes; and some class methods 607 of non-nested classes. 608 609 @rtype: L{DottedName} or C{UNKNOWN} 610 """ 611 if not hasattr(value, '__name__'): return UNKNOWN 612 613 # Get the name via introspection. 614 if isinstance(value, ModuleType): 615 try: 616 dotted_name = DottedName(value.__name__, strict=strict) 617 # If the module is shadowed by a variable in its parent 618 # package(s), then add a prime mark to the end, to 619 # differentiate it from the variable that shadows it. 620 if verify_name(value, dotted_name) is UNKNOWN: 621 log.warning("Module %s is shadowed by a variable with " 622 "the same name." % dotted_name) 623 # Note -- this return bypasses verify_name check: 624 return DottedName(value.__name__+"'") 625 except DottedName.InvalidDottedName: 626 # Name is not a valid Python identifier -- treat as script. 627 if hasattr(value, '__file__'): 628 filename = '%s' % value.__str__ 629 dotted_name = DottedName(munge_script_name(filename)) 630 631 elif isclass(value): 632 if value.__module__ == '__builtin__': 633 dotted_name = DottedName(value.__name__, strict=strict) 634 else: 635 dotted_name = DottedName(value.__module__, value.__name__, 636 strict=strict) 637 638 elif (inspect.ismethod(value) and value.im_self is not None and 639 value.im_class is ClassType and 640 not value.__name__.startswith('<')): # class method. 641 class_name = get_canonical_name(value.im_self) 642 if class_name is UNKNOWN: return UNKNOWN 643 dotted_name = DottedName(class_name, value.__name__, strict=strict) 644 elif (inspect.ismethod(value) and 645 not value.__name__.startswith('<')): 646 class_name = get_canonical_name(value.im_class) 647 if class_name is UNKNOWN: return UNKNOWN 648 dotted_name = DottedName(class_name, value.__name__, strict=strict) 649 elif (isinstance(value, FunctionType) and 650 not value.__name__.startswith('<')): 651 module_name = _find_function_module(value) 652 if module_name is None: return UNKNOWN 653 dotted_name = DottedName(module_name, value.__name__, strict=strict) 654 else: 655 return UNKNOWN 656 657 return verify_name(value, dotted_name)
658
659 -def verify_name(value, dotted_name):
660 """ 661 Verify the name. E.g., if it's a nested class, then we won't be 662 able to find it with the name we constructed. 663 """ 664 if dotted_name is UNKNOWN: return UNKNOWN 665 if len(dotted_name) == 1 and hasattr(__builtin__, dotted_name[0]): 666 return dotted_name 667 named_value = sys.modules.get(dotted_name[0]) 668 if named_value is None: return UNKNOWN 669 for identifier in dotted_name[1:]: 670 try: named_value = getattr(named_value, identifier) 671 except: return UNKNOWN 672 if value is named_value: 673 return dotted_name 674 else: 675 return UNKNOWN
676 677 # [xx] not used:
678 -def value_repr(value):
679 try: 680 s = '%r' % value 681 if isinstance(s, str): 682 s = decode_with_backslashreplace(s) 683 return s 684 except: 685 return UNKNOWN
686
687 -def get_containing_module(value):
688 """ 689 Return the name of the module containing the given value, or 690 C{None} if the module name can't be determined. 691 @rtype: L{DottedName} 692 """ 693 if inspect.ismodule(value): 694 return DottedName(value.__name__) 695 elif isclass(value): 696 return DottedName(value.__module__) 697 elif (inspect.ismethod(value) and value.im_self is not None and 698 value.im_class is ClassType): # class method. 699 return DottedName(value.im_self.__module__) 700 elif inspect.ismethod(value): 701 return DottedName(value.im_class.__module__) 702 elif inspect.isroutine(value): 703 module = _find_function_module(value) 704 if module is None: return None 705 return DottedName(module) 706 else: 707 return None
708
709 -def _find_function_module(func):
710 """ 711 @return: The module that defines the given function. 712 @rtype: C{module} 713 @param func: The function whose module should be found. 714 @type func: C{function} 715 """ 716 if hasattr(func, '__module__'): 717 return func.__module__ 718 try: 719 module = inspect.getmodule(func) 720 if module: return module.__name__ 721 except KeyboardInterrupt: raise 722 except: pass 723 724 # This fallback shouldn't usually be needed. But it is needed in 725 # a couple special cases (including using epydoc to document 726 # itself). In particular, if a module gets loaded twice, using 727 # two different names for the same file, then this helps. 728 for module in sys.modules.values(): 729 if (hasattr(module, '__dict__') and 730 hasattr(func, 'func_globals') and 731 func.func_globals is module.__dict__): 732 return module.__name__ 733 return None
734 735 #//////////////////////////////////////////////////////////// 736 # Introspection Dispatch Table 737 #//////////////////////////////////////////////////////////// 738 739 _introspecter_registry = []
740 -def register_introspecter(applicability_test, introspecter, priority=10):
741 """ 742 Register an introspecter function. Introspecter functions take 743 two arguments, a python value and a C{ValueDoc} object, and should 744 add information about the given value to the the C{ValueDoc}. 745 Usually, the first line of an inspecter function will specialize 746 it to a sublass of C{ValueDoc}, using L{ValueDoc.specialize_to()}: 747 748 >>> def typical_introspecter(value, value_doc): 749 ... value_doc.specialize_to(SomeSubclassOfValueDoc) 750 ... <add info to value_doc> 751 752 @param priority: The priority of this introspecter, which determines 753 the order in which introspecters are tried -- introspecters with lower 754 numbers are tried first. The standard introspecters have priorities 755 ranging from 20 to 30. The default priority (10) will place new 756 introspecters before standard introspecters. 757 """ 758 _introspecter_registry.append( (priority, applicability_test, 759 introspecter) ) 760 _introspecter_registry.sort()
761
762 -def _get_introspecter(value):
763 for (priority, applicability_test, introspecter) in _introspecter_registry: 764 if applicability_test(value): 765 return introspecter 766 else: 767 return introspect_other
768 769 # Register the standard introspecter functions.
770 -def is_classmethod(v): return isinstance(v, classmethod)
771 -def is_staticmethod(v): return isinstance(v, staticmethod)
772 -def is_property(v): return isinstance(v, property)
773 register_introspecter(inspect.ismodule, introspect_module, priority=20) 774 register_introspecter(isclass, introspect_class, priority=24) 775 register_introspecter(inspect.isroutine, introspect_routine, priority=28) 776 register_introspecter(is_property, introspect_property, priority=30) 777 778 # Register getset_descriptor as a property 779 try: 780 import array 781 getset_type = type(array.array.typecode) 782 del array
783 - def is_getset(v): return isinstance(v, getset_type)
784 register_introspecter(is_getset, introspect_property, priority=32) 785 except: 786 pass 787 788 # Register member_descriptor as a property 789 try: 790 import datetime 791 member_type = type(datetime.timedelta.days) 792 del datetime
793 - def is_member(v): return isinstance(v, member_type)
794 register_introspecter(is_member, introspect_property, priority=34) 795 except: 796 pass 797 798 #//////////////////////////////////////////////////////////// 799 # Import support 800 #//////////////////////////////////////////////////////////// 801
802 -def get_value_from_filename(filename, context=None):
803 # Normalize the filename. 804 filename = os.path.normpath(os.path.abspath(filename)) 805 806 # Divide the filename into a base directory and a name. (For 807 # packages, use the package's parent directory as the base, and 808 # the directory name as its name). 809 basedir = os.path.split(filename)[0] 810 name = os.path.splitext(os.path.split(filename)[1])[0] 811 if name == '__init__': 812 basedir, name = os.path.split(basedir) 813 name = DottedName(name) 814 815 # If the context wasn't provided, then check if the file is in a 816 # package directory. If so, then update basedir & name to contain 817 # the topmost package's directory and the fully qualified name for 818 # this file. (This update assume the default value of __path__ 819 # for the parent packages; if the parent packages override their 820 # __path__s, then this can cause us not to find the value.) 821 if context is None: 822 while is_package_dir(basedir): 823 basedir, pkg_name = os.path.split(basedir) 824 name = DottedName(pkg_name, name) 825 826 # If a parent package was specified, then find the directory of 827 # the topmost package, and the fully qualified name for this file. 828 if context is not None: 829 # Combine the name. 830 name = DottedName(context.canonical_name, name) 831 # Find the directory of the base package. 832 while context not in (None, UNKNOWN): 833 pkg_dir = os.path.split(context.filename)[0] 834 basedir = os.path.split(pkg_dir)[0] 835 context = context.package 836 837 # Import the module. (basedir is the directory of the module's 838 # topmost package, or its own directory if it's not in a package; 839 # and name is the fully qualified dotted name for the module.) 840 old_sys_path = sys.path[:] 841 try: 842 sys.path.insert(0, basedir) 843 # This will make sure that we get the module itself, even 844 # if it is shadowed by a variable. (E.g., curses.wrapper): 845 _import(str(name)) 846 if str(name) in sys.modules: 847 return sys.modules[str(name)] 848 else: 849 # Use this as a fallback -- it *shouldn't* ever be needed. 850 return get_value_from_name(name) 851 finally: 852 sys.path = old_sys_path
853
854 -def get_value_from_scriptname(filename):
855 name = munge_script_name(filename) 856 return _import(name, filename)
857
858 -def get_value_from_name(name, globs=None):
859 """ 860 Given a name, return the corresponding value. 861 862 @param globs: A namespace to check for the value, if there is no 863 module containing the named value. Defaults to __builtin__. 864 """ 865 name = DottedName(name) 866 867 # Import the topmost module/package. If we fail, then check if 868 # the requested name refers to a builtin. 869 try: 870 module = _import(name[0]) 871 except ImportError, e: 872 if globs is None: globs = __builtin__.__dict__ 873 if name[0] in globs: 874 try: return _lookup(globs[name[0]], name[1:]) 875 except: raise e 876 else: 877 raise 878 879 # Find the requested value in the module/package or its submodules. 880 for i in range(1, len(name)): 881 try: return _lookup(module, name[i:]) 882 except ImportError: pass 883 module = _import('.'.join(name[:i+1])) 884 module = _lookup(module, name[1:i+1]) 885 return module
886
887 -def _lookup(module, name):
888 val = module 889 for i, identifier in enumerate(name): 890 try: val = getattr(val, identifier) 891 except AttributeError: 892 exc_msg = ('no variable named %s in %s' % 893 (identifier, '.'.join(name[:1+i]))) 894 raise ImportError(exc_msg) 895 return val
896
897 -def _import(name, filename=None):
898 """ 899 Run the given callable in a 'sandboxed' environment. 900 Currently, this includes saving and restoring the contents of 901 sys and __builtins__; and suppressing stdin, stdout, and stderr. 902 """ 903 # Note that we just do a shallow copy of sys. In particular, 904 # any changes made to sys.modules will be kept. But we do 905 # explicitly store sys.path. 906 old_sys = sys.__dict__.copy() 907 old_sys_path = sys.path[:] 908 old_builtins = __builtin__.__dict__.copy() 909 910 # Add the current directory to sys.path, in case they're trying to 911 # import a module by name that resides in the current directory. 912 # But add it to the end -- otherwise, the explicit directory added 913 # in get_value_from_filename might get overwritten 914 sys.path.append('') 915 916 # Suppress input and output. (These get restored when we restore 917 # sys to old_sys). 918 sys.stdin = sys.stdout = sys.stderr = _dev_null 919 sys.__stdin__ = sys.__stdout__ = sys.__stderr__ = _dev_null 920 921 # Remove any command-line arguments 922 sys.argv = ['(imported)'] 923 924 try: 925 try: 926 if filename is None: 927 return __import__(name) 928 else: 929 # For importing scripts: 930 return imp.load_source(name, filename) 931 except KeyboardInterrupt: raise 932 except: 933 exc_typ, exc_val, exc_tb = sys.exc_info() 934 if exc_val is None: 935 estr = '%s' % (exc_typ,) 936 else: 937 estr = '%s: %s' % (exc_typ.__name__, exc_val) 938 if exc_tb.tb_next is not None: 939 estr += ' (line %d)' % (exc_tb.tb_next.tb_lineno,) 940 raise ImportError(estr) 941 finally: 942 # Restore the important values that we saved. 943 __builtin__.__dict__.clear() 944 __builtin__.__dict__.update(old_builtins) 945 sys.__dict__.clear() 946 sys.__dict__.update(old_sys) 947 sys.path = old_sys_path
948
949 -def introspect_docstring_lineno(api_doc):
950 """ 951 Try to determine the line number on which the given item's 952 docstring begins. Return the line number, or C{None} if the line 953 number can't be determined. The line number of the first line in 954 the file is 1. 955 """ 956 if api_doc.docstring_lineno is not UNKNOWN: 957 return api_doc.docstring_lineno 958 if isinstance(api_doc, ValueDoc) and api_doc.pyval is not UNKNOWN: 959 try: 960 lines, lineno = inspect.findsource(api_doc.pyval) 961 if not isinstance(api_doc, ModuleDoc): lineno += 1 962 for lineno in range(lineno, len(lines)): 963 if lines[lineno].split('#', 1)[0].strip(): 964 api_doc.docstring_lineno = lineno + 1 965 return lineno + 1 966 except IOError: pass 967 except TypeError: pass 968 except IndexError: 969 log.warning('inspect.findsource(%s) raised IndexError' 970 % api_doc.canonical_name) 971 return None
972
973 -class _DevNull:
974 """ 975 A "file-like" object that discards anything that is written and 976 always reports end-of-file when read. C{_DevNull} is used by 977 L{_import()} to discard output when importing modules; and to 978 ensure that stdin appears closed. 979 """
980 - def __init__(self):
981 self.closed = 1 982 self.mode = 'r+' 983 self.softspace = 0 984 self.name='</dev/null>'
985 - def close(self): pass
986 - def flush(self): pass
987 - def read(self, size=0): return ''
988 - def readline(self, size=0): return ''
989 - def readlines(self, sizehint=0): return []
990 - def seek(self, offset, whence=0): pass
991 - def tell(self): return 0L
992 - def truncate(self, size=0): pass
993 - def write(self, str): pass
994 - def writelines(self, sequence): pass
995 xreadlines = readlines
996 _dev_null = _DevNull() 997 998 ###################################################################### 999 ## Zope InterfaceClass 1000 ###################################################################### 1001 1002 try: 1003 from zope.interface.interface import InterfaceClass as _ZopeInterfaceClass 1004 register_class_type(_ZopeInterfaceClass) 1005 except: 1006 pass 1007 1008 ###################################################################### 1009 ## Zope Extension classes 1010 ###################################################################### 1011 1012 try: 1013 # Register type(ExtensionClass.ExtensionClass) 1014 from ExtensionClass import ExtensionClass as _ExtensionClass 1015 _ZopeType = type(_ExtensionClass)
1016 - def _is_zope_type(val):
1017 return isinstance(val, _ZopeType)
1018 register_introspecter(_is_zope_type, introspect_class) 1019 1020 # Register ExtensionClass.*MethodType 1021 from ExtensionClass import PythonMethodType as _ZopeMethodType 1022 from ExtensionClass import ExtensionMethodType as _ZopeCMethodType
1023 - def _is_zope_method(val):
1024 return isinstance(val, (_ZopeMethodType, _ZopeCMethodType))
1025 register_introspecter(_is_zope_method, introspect_routine) 1026 except: 1027 pass 1028 1029 1030 1031 1032 # [xx] 1033 0 # hm.. otherwise the following gets treated as a docstring! ouch! 1034 """ 1035 ###################################################################### 1036 ## Zope Extension... 1037 ###################################################################### 1038 class ZopeIntrospecter(Introspecter): 1039 VALUEDOC_CLASSES = Introspecter.VALUEDOC_CLASSES.copy() 1040 VALUEDOC_CLASSES.update({ 1041 'module': ZopeModuleDoc, 1042 'class': ZopeClassDoc, 1043 'interface': ZopeInterfaceDoc, 1044 'attribute': ZopeAttributeDoc, 1045 }) 1046 1047 def add_module_child(self, child, child_name, module_doc): 1048 if isinstance(child, zope.interfaces.Interface): 1049 module_doc.add_zope_interface(child_name) 1050 else: 1051 Introspecter.add_module_child(self, child, child_name, module_doc) 1052 1053 def add_class_child(self, child, child_name, class_doc): 1054 if isinstance(child, zope.interfaces.Interface): 1055 class_doc.add_zope_interface(child_name) 1056 else: 1057 Introspecter.add_class_child(self, child, child_name, class_doc) 1058 1059 def introspect_zope_interface(self, interface, interfacename): 1060 pass # etc... 1061 """ 1062