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