# epydoc -- API Documentation Classes
#
# Copyright (C) 2005 Edward Loper
# Author: Edward Loper <edloper@loper.org>
# URL: <http://epydoc.sf.net>
#
# $Id: apidoc.py 1675 2008-01-29 17:12:56Z edloper $

"""
Classes for encoding API documentation about Python programs.
These classes are used as a common representation for combining
information derived from introspection and from parsing.

The API documentation for a Python program is encoded using a graph of
L{APIDoc} objects, each of which encodes information about a single
Python variable or value.  C{APIDoc} has two direct subclasses:
L{VariableDoc}, for documenting variables; and L{ValueDoc}, for
documenting values.  The C{ValueDoc} class is subclassed further, to
define the different pieces of information that should be recorded
about each value type:

G{classtree: APIDoc}

The distinction between variables and values is intentionally made
explicit.  This allows us to distinguish information about a variable
itself (such as whether it should be considered 'public' in its
containing namespace) from information about the value it contains
(such as what type the value has).  This distinction is also important
because several variables can contain the same value: each variable
should be described by a separate C{VariableDoc}; but we only need one
C{ValueDoc}, since they share a single value.

@todo: Add a cache to canonical name lookup?
"""
__docformat__ = 'epytext en'

######################################################################
## Imports
######################################################################

import types, re, os.path, pickle
from epydoc import log
import epydoc
import __builtin__
from epydoc.compat import * # Backwards compatibility
from epydoc.util import decode_with_backslashreplace, py_src_filename
import epydoc.markup.pyval_repr

######################################################################
# Dotted Names
######################################################################

class DottedName:
    """
    A sequence of identifiers, separated by periods, used to name a
    Python variable, value, or argument.  The identifiers that make up
    a dotted name can be accessed using the indexing operator:

        >>> name = DottedName('epydoc', 'api_doc', 'DottedName')
        >>> print name
        epydoc.apidoc.DottedName
        >>> name[1]
        'api_doc'
    """
    UNREACHABLE = "??"
    _IDENTIFIER_RE = re.compile("""(?x)
        (%s |             # UNREACHABLE marker, or..
         (script-)?       #   Prefix: script (not a module)
         \w+              #   Identifier (yes, identifiers starting with a
                          #   digit are allowed. See SF bug #1649347)
         '?)              #   Suffix: submodule that is shadowed by a var
        (-\d+)?           # Suffix: unreachable vals with the same name
        $"""
        % re.escape(UNREACHABLE))

    class InvalidDottedName(ValueError):
        """
        An exception raised by the DottedName constructor when one of
        its arguments is not a valid dotted name.
        """

    _ok_identifiers = set()
    """A cache of identifier strings that have been checked against
    _IDENTIFIER_RE and found to be acceptable."""
    
    def __init__(self, *pieces, **options):
        """
        Construct a new dotted name from the given sequence of pieces,
        each of which can be either a C{string} or a C{DottedName}.
        Each piece is divided into a sequence of identifiers, and
        these sequences are combined together (in order) to form the
        identifier sequence for the new C{DottedName}.  If a piece
        contains a string, then it is divided into substrings by
        splitting on periods, and each substring is checked to see if
        it is a valid identifier.

        As an optimization, C{pieces} may also contain a single tuple
        of values.  In that case, that tuple will be used as the
        C{DottedName}'s identifiers; it will I{not} be checked to
        see if it's valid.

        @kwparam strict: if true, then raise an L{InvalidDottedName}
        if the given name is invalid.
        """
        if len(pieces) == 1 and isinstance(pieces[0], tuple):
            self._identifiers = pieces[0] # Optimization
            return
        if len(pieces) == 0:
            raise DottedName.InvalidDottedName('Empty DottedName')
        self._identifiers = []
        for piece in pieces:
            if isinstance(piece, DottedName):
                self._identifiers += piece._identifiers
            elif isinstance(piece, basestring):
                for subpiece in piece.split('.'):
                    if piece not in self._ok_identifiers:
                        if not self._IDENTIFIER_RE.match(subpiece):
                            if options.get('strict'):
                                raise DottedName.InvalidDottedName(
                                    'Bad identifier %r' % (piece,))
                            else:
                                log.warning("Identifier %r looks suspicious; "
                                            "using it anyway." % piece)
                        self._ok_identifiers.add(piece)
                    self._identifiers.append(subpiece)
            else:
                raise TypeError('Bad identifier %r: expected '
                                'DottedName or str' % (piece,))
        self._identifiers = tuple(self._identifiers)

    def __repr__(self):
        idents = [`ident` for ident in self._identifiers]
        return 'DottedName(' + ', '.join(idents) + ')'

    def __str__(self):
        """
        Return the dotted name as a string formed by joining its
        identifiers with periods:

            >>> print DottedName('epydoc', 'api_doc', DottedName')
            epydoc.apidoc.DottedName
        """
        return '.'.join(self._identifiers)

    def __add__(self, other):
        """
        Return a new C{DottedName} whose identifier sequence is formed
        by adding C{other}'s identifier sequence to C{self}'s.
        """
        if isinstance(other, (basestring, DottedName)):
            return DottedName(self, other)
        else:
            return DottedName(self, *other)

    def __radd__(self, other):
        """
        Return a new C{DottedName} whose identifier sequence is formed
        by adding C{self}'s identifier sequence to C{other}'s.
        """
        if isinstance(other, (basestring, DottedName)):
            return DottedName(other, self)
        else:
            return DottedName(*(list(other)+[self]))

    def __getitem__(self, i):
        """
        Return the C{i}th identifier in this C{DottedName}.  If C{i} is
        a non-empty slice, then return a C{DottedName} built from the
        identifiers selected by the slice.  If C{i} is an empty slice,
        return an empty list (since empty C{DottedName}s are not valid).
        """
        if isinstance(i, types.SliceType):
            pieces = self._identifiers[i.start:i.stop]
            if pieces: return DottedName(pieces)
            else: return []
        else:
            return self._identifiers[i]

    def __hash__(self):
        return hash(self._identifiers)

    def __cmp__(self, other):
        """
        Compare this dotted name to C{other}.  Two dotted names are
        considered equal if their identifier subsequences are equal.
        Ordering between dotted names is lexicographic, in order of
        identifier from left to right.
        """
        if not isinstance(other, DottedName):
            return -1
        return cmp(self._identifiers, other._identifiers)

    def __len__(self):
        """
        Return the number of identifiers in this dotted name.
        """
        return len(self._identifiers)

    def container(self):
        """
        Return the DottedName formed by removing the last identifier
        from this dotted name's identifier sequence.  If this dotted
        name only has one name in its identifier sequence, return
        C{None} instead.
        """
        if len(self._identifiers) == 1:
            return None
        else:
            return DottedName(*self._identifiers[:-1])

    def dominates(self, name, strict=False):
        """
        Return true if this dotted name is equal to a prefix of
        C{name}.  If C{strict} is true, then also require that
        C{self!=name}.

            >>> DottedName('a.b').dominates(DottedName('a.b.c.d'))
            True
        """
        len_self = len(self._identifiers)
        len_name = len(name._identifiers)

        if (len_self > len_name) or (strict and len_self == len_name):
            return False
        # The following is redundant (the first clause is implied by
        # the second), but is done as an optimization.
        return ((self._identifiers[0] == name._identifiers[0]) and
                self._identifiers == name._identifiers[:len_self])

    def contextualize(self, context):
        """
        If C{self} and C{context} share a common ancestor, then return
        a name for C{self}, relative to that ancestor.  If they do not
        share a common ancestor (or if C{context} is C{UNKNOWN}), then
        simply return C{self}.

        This is used to generate shorter versions of dotted names in
        cases where users can infer the intended target from the
        context.
        
        @type context: L{DottedName}
        @rtype: L{DottedName}
        """
        if context is UNKNOWN or not context or len(self) <= 1:
            return self
        if self[0] == context[0]:
            return self[1:].contextualize(context[1:])
        else:
            return self

        # Find the first index where self & context differ.
        for i in range(min(len(context), len(self))):
            if self._identifiers[i] != context._identifiers[i]:
                first_difference = i
                break
        else:
            first_difference = i+1
            
        # Strip off anything before that index.
        if first_difference == 0:
            return self
        elif first_difference == len(self):
            return self[-1:]
        else:
            return self[first_difference:]

######################################################################
# UNKNOWN Value
######################################################################

class _Sentinel:
    """
    A unique value that won't compare equal to any other value.  This
    class is used to create L{UNKNOWN}.
    """
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return '<%s>' % self.name
    def __nonzero__(self):
        raise ValueError('Sentinel value <%s> can not be used as a boolean' %
                         self.name)

UNKNOWN = _Sentinel('UNKNOWN')
"""A special value used to indicate that a given piece of
information about an object is unknown.  This is used as the
default value for all instance variables."""

######################################################################
# API Documentation Objects: Abstract Base Classes
######################################################################

class APIDoc(object):
    """
    API documentation information for a single element of a Python
    program.  C{APIDoc} itself is an abstract base class; subclasses
    are used to specify what information should be recorded about each
    type of program element.  In particular, C{APIDoc} has two direct
    subclasses, C{VariableDoc} for documenting variables and
    C{ValueDoc} for documenting values; and the C{ValueDoc} class is
    subclassed further for different value types.

    Each C{APIDoc} subclass specifies the set of attributes that
    should be used to record information about the corresponding
    program element type.  The default value for each attribute is
    stored in the class; these default values can then be overridden
    with instance variables.  Most attributes use the special value
    L{UNKNOWN} as their default value, to indicate that the correct
    value for that attribute has not yet been determined.  This makes
    it easier to merge two C{APIDoc} objects that are documenting the
    same element (in particular, to merge information about an element
    that was derived from parsing with information that was derived
    from introspection).

    For all attributes with boolean values, use only the constants
    C{True} and C{False} to designate true and false.  In particular,
    do I{not} use other values that evaluate as true or false, such as
    C{2} or C{()}.  This restriction makes it easier to handle
    C{UNKNOWN} values.  For example, to test if a boolean attribute is
    C{True} or C{UNKNOWN}, use 'C{attrib in (True, UNKNOWN)}' or
    'C{attrib is not False}'.

    Two C{APIDoc} objects describing the same object can be X{merged},
    using the method L{merge_and_overwrite(other)}.  After two
    C{APIDoc}s are merged, any changes to one will be reflected in the
    other.  This is accomplished by setting the two C{APIDoc} objects
    to use a shared instance dictionary.  See the documentation for
    L{merge_and_overwrite} for more information, and some important
    caveats about hashing.
    """
    #{ Docstrings
    docstring = UNKNOWN
    """@ivar: The documented item's docstring.
       @type: C{string} or C{None}"""
    
    docstring_lineno = UNKNOWN
    """@ivar: The line number on which the documented item's docstring
       begins.
       @type: C{int}"""
    #} end of "docstrings" group

    #{ Information Extracted from Docstrings
    descr = UNKNOWN
    """@ivar: A description of the documented item, extracted from its
       docstring.
       @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
    
    summary = UNKNOWN
    """@ivar: A summary description of the documented item, extracted from
       its docstring.
       @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
    
    other_docs = UNKNOWN
    """@ivar: A flag indicating if the entire L{docstring} body (except tags
       if any) is entirely included in the L{summary}.
       @type: C{bool}"""
    
    metadata = UNKNOWN
    """@ivar: Metadata about the documented item, extracted from fields in
       its docstring.  I{Currently} this is encoded as a list of tuples
       C{(field, arg, descr)}.  But that may change.
       @type: C{(str, str, L{ParsedDocstring<markup.ParsedDocstring>})}"""
    
    extra_docstring_fields = UNKNOWN
    """@ivar: A list of new docstring fields tags that are defined by the
       documented item's docstring.  These new field tags can be used by
       this item or by any item it contains.
       @type: L{DocstringField <epydoc.docstringparser.DocstringField>}"""
    #} end of "information extracted from docstrings" group

    #{ Source Information
    docs_extracted_by = UNKNOWN # 'parser' or 'introspecter' or 'both'
    """@ivar: Information about where the information contained by this
       C{APIDoc} came from.  Can be one of C{'parser'},
       C{'introspector'}, or C{'both'}.
       @type: C{str}"""
    #} end of "source information" group

    def __init__(self, **kwargs):
        """
        Construct a new C{APIDoc} object.  Keyword arguments may be
        used to initialize the new C{APIDoc}'s attributes.
        
        @raise TypeError: If a keyword argument is specified that does
            not correspond to a valid attribute for this (sub)class of
            C{APIDoc}.
        """
        if epydoc.DEBUG:
            for key in kwargs:
                if key[0] != '_' and not hasattr(self.__class__, key):
                    raise TypeError('%s got unexpected arg %r' %
                                    (self.__class__.__name__, key))
        self.__dict__.update(kwargs)

    def _debug_setattr(self, attr, val):
        """
        Modify an C{APIDoc}'s attribute.  This is used when
        L{epydoc.DEBUG} is true, to make sure we don't accidentally
        set any inappropriate attributes on C{APIDoc} objects.

        @raise AttributeError: If C{attr} is not a valid attribute for
            this (sub)class of C{APIDoc}.  (C{attr} is considered a
            valid attribute iff C{self.__class__} defines an attribute
            with that name.)
        """
        # Don't intercept special assignments like __class__, or
        # assignments to private variables.
        if attr.startswith('_'):
            return object.__setattr__(self, attr, val)
        if not hasattr(self, attr):
            raise AttributeError('%s does not define attribute %r' %
                            (self.__class__.__name__, attr))
        self.__dict__[attr] = val

    if epydoc.DEBUG:
        __setattr__ = _debug_setattr

    def __repr__(self):
       return '<%s>' % self.__class__.__name__
    
    def pp(self, doublespace=0, depth=5, exclude=(), include=()):
        """
        Return a pretty-printed string representation for the
        information contained in this C{APIDoc}.
        """
        return pp_apidoc(self, doublespace, depth, exclude, include)
    __str__ = pp

    def specialize_to(self, cls):
        """
        Change C{self}'s class to C{cls}.  C{cls} must be a subclass
        of C{self}'s current class.  For example, if a generic
        C{ValueDoc} was created for a value, and it is determined that
        the value is a routine, you can update its class with:
        
            >>> valdoc.specialize_to(RoutineDoc)
        """
        if not issubclass(cls, self.__class__):
            raise ValueError('Can not specialize to %r' % cls)
        # Update the class.
        self.__class__ = cls
        # Update the class of any other apidoc's in the mergeset.
        if self.__mergeset is not None:
            for apidoc in self.__mergeset:
                apidoc.__class__ = cls
        # Re-initialize self, in case the subclass constructor does
        # any special processing on its arguments.
        self.__init__(**self.__dict__)

    __has_been_hashed = False
    """True iff L{self.__hash__()} has ever been called."""
    
    def __hash__(self):
        self.__has_been_hashed = True
        return id(self.__dict__)

    def __cmp__(self, other):
        if not isinstance(other, APIDoc): return -1
        if self.__dict__ is other.__dict__: return 0
        name_cmp = cmp(self.canonical_name, other.canonical_name)
        if name_cmp == 0: return -1
        else: return name_cmp

    def is_detailed(self):
        """
        Does this object deserve a box with extra details?

        @return: True if the object needs extra details, else False.
        @rtype: C{bool}
        """
        if self.other_docs is True:
            return True

        if self.metadata is not UNKNOWN:
            return bool(self.metadata)

    __mergeset = None
    """The set of all C{APIDoc} objects that have been merged with
    this C{APIDoc} (using L{merge_and_overwrite()}).  Each C{APIDoc}
    in this set shares a common instance dictionary (C{__dict__})."""
    
    def merge_and_overwrite(self, other, ignore_hash_conflict=False):
        """
        Combine C{self} and C{other} into a X{merged object}, such
        that any changes made to one will affect the other.  Any
        attributes that C{other} had before merging will be discarded.
        This is accomplished by copying C{self.__dict__} over
        C{other.__dict__} and C{self.__class__} over C{other.__class__}.

        Care must be taken with this method, since it modifies the
        hash value of C{other}.  To help avoid the problems that this
        can cause, C{merge_and_overwrite} will raise an exception if
        C{other} has ever been hashed, unless C{ignore_hash_conflict}
        is True.  Note that adding C{other} to a dictionary, set, or
        similar data structure will implicitly cause it to be hashed.
        If you do set C{ignore_hash_conflict} to True, then any
        existing data structures that rely on C{other}'s hash staying
        constant may become corrupted.

        @return: C{self}
        @raise ValueError: If C{other} has ever been hashed.
        """
        # If we're already merged, then there's nothing to do.
        if (self.__dict__ is other.__dict__ and
            self.__class__ is other.__class__): return self
            
        if other.__has_been_hashed and not ignore_hash_conflict:
            raise ValueError("%r has already been hashed!  Merging it "
                             "would cause its has value to change." % other)

        # If other was itself already merged with anything,
        # then we need to merge those too.
        a,b = (self.__mergeset, other.__mergeset)
        mergeset = (self.__mergeset or [self]) + (other.__mergeset or [other])
        other.__dict__.clear()
        for apidoc in mergeset:
            #if apidoc is self: pass
            apidoc.__class__ = self.__class__
            apidoc.__dict__ = self.__dict__
        self.__mergeset = mergeset
        # Sanity chacks.
        assert self in mergeset and other in mergeset
        for apidoc in mergeset:
            assert apidoc.__dict__ is self.__dict__
        # Return self.
        return self

    def apidoc_links(self, **filters):
        """
        Return a list of all C{APIDoc}s that are directly linked from
        this C{APIDoc} (i.e., are contained or pointed to by one or
        more of this C{APIDoc}'s attributes.)

        Keyword argument C{filters} can be used to selectively exclude
        certain categories of attribute value.  For example, using
        C{includes=False} will exclude variables that were imported
        from other modules; and C{subclasses=False} will exclude
        subclasses.  The filter categories currently supported by
        epydoc are:
          - C{imports}: Imported variables.
          - C{packages}: Containing packages for modules.
          - C{submodules}: Contained submodules for packages.
          - C{bases}: Bases for classes.
          - C{subclasses}: Subclasses for classes.
          - C{variables}: All variables.
          - C{private}: Private variables.
          - C{overrides}: Points from class variables to the variables
            they override.  This filter is False by default.
        """
        return []

def reachable_valdocs(root, **filters):
    """
    Return a list of all C{ValueDoc}s that can be reached, directly or
    indirectly from the given root list of C{ValueDoc}s.

    @param filters: A set of filters that can be used to prevent
        C{reachable_valdocs} from following specific link types when
        looking for C{ValueDoc}s that can be reached from the root
        set.  See C{APIDoc.apidoc_links} for a more complete
        description.
    """
    apidoc_queue = list(root)
    val_set = set()
    var_set = set()
    while apidoc_queue:
        api_doc = apidoc_queue.pop()
        if isinstance(api_doc, ValueDoc):
            val_set.add(api_doc)
        else:
            var_set.add(api_doc)
        apidoc_queue.extend([v for v in api_doc.apidoc_links(**filters)
                             if v not in val_set and v not in var_set])
    return val_set

######################################################################
# Variable Documentation Objects
######################################################################

class VariableDoc(APIDoc):
    """
    API documentation information about a single Python variable.

    @note: The only time a C{VariableDoc} will have its own docstring
    is if that variable was created using an assignment statement, and
    that assignment statement had a docstring-comment or was followed
    by a pseudo-docstring.
    """
    #{ Basic Variable Information
    name = UNKNOWN
    """@ivar: The name of this variable in its containing namespace.
       @type: C{str}"""
    
    container = UNKNOWN
    """@ivar: API documentation for the namespace that contains this
       variable.
       @type: L{ValueDoc}"""
    
    canonical_name = UNKNOWN
    """@ivar: A dotted name that serves as a unique identifier for
       this C{VariableDoc}.  It should be formed by concatenating
       the C{VariableDoc}'s C{container} with its C{name}.
       @type: L{DottedName}"""

    value = UNKNOWN
    """@ivar: The API documentation for this variable's value.
       @type: L{ValueDoc}"""
    #}

    #{ Information Extracted from Docstrings
    type_descr = UNKNOWN 
    """@ivar: A description of the variable's expected type, extracted from
       its docstring.
       @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
    #} end of "information extracted from docstrings" group
    
    #{ Information about Imported Variables
    imported_from = UNKNOWN
    """@ivar: The fully qualified dotted name of the variable that this
       variable's value was imported from.  This attribute should only
       be defined if C{is_instvar} is true.
       @type: L{DottedName}"""

    is_imported = UNKNOWN
    """@ivar: Was this variable's value imported from another module?
       (Exception: variables that are explicitly included in __all__ have
       C{is_imported} set to C{False}, even if they are in fact
       imported.)
       @type: C{bool}"""
    #} end of "information about imported variables" group

    #{ Information about Variables in Classes
    is_instvar = UNKNOWN
    """@ivar: If true, then this variable is an instance variable; if false,
       then this variable is a class variable.  This attribute should
       only be defined if the containing namespace is a class    
       @type: C{bool}"""
    
    overrides = UNKNOWN # [XXX] rename -- don't use a verb.
    """@ivar: The API documentation for the variable that is overridden by
       this variable.  This attribute should only be defined if the
       containing namespace is a class.
       @type: L{VariableDoc}"""
    #} end of "information about variables in classes" group

    #{ Flags
    is_alias = UNKNOWN
    """@ivar: Is this variable an alias for another variable with the same
       value?  If so, then this variable will be dispreferred when
       assigning canonical names.
       @type: C{bool}"""
    
    is_public = UNKNOWN
    """@ivar: Is this variable part of its container's public API?
       @type: C{bool}"""
    #} end of "flags" group

    def __init__(self, **kwargs):
        APIDoc.__init__(self, **kwargs)
        if self.is_public is UNKNOWN and self.name is not UNKNOWN:
            self.is_public = (not self.name.startswith('_') or
                              self.name.endswith('_'))
        
    def __repr__(self):
        if self.canonical_name is not UNKNOWN:
            return '<%s %s>' % (self.__class__.__name__, self.canonical_name)
        if self.name is not UNKNOWN:
            return '<%s %s>' % (self.__class__.__name__, self.name)
        else:                     
            return '<%s>' % self.__class__.__name__

    def _get_defining_module(self):
        if self.container is UNKNOWN:
            return UNKNOWN
        return self.container.defining_module
    defining_module = property(_get_defining_module, doc="""
    A read-only property that can be used to get the variable's
    defining module.  This is defined as the defining module
    of the variable's container.""")

    def apidoc_links(self, **filters):
        # nb: overrides filter is *False* by default.
        if (filters.get('overrides', False) and
            (self.overrides not in (None, UNKNOWN))):
            overrides = [self.overrides]
        else:
            overrides = []
        if self.value in (None, UNKNOWN):
            return []+overrides
        else:
            return [self.value]+overrides

    def is_detailed(self):
        pval = super(VariableDoc, self).is_detailed()
        if pval or self.value in (None, UNKNOWN):
            return pval

        if (self.overrides not in (None, UNKNOWN) and
            isinstance(self.value, RoutineDoc)):
            return True

        if isinstance(self.value, GenericValueDoc):
            # [XX] This is a little hackish -- we assume that the
            # summary lines will have SUMMARY_REPR_LINELEN chars,
            # that len(name) of those will be taken up by the name,
            # and that 3 of those will be taken up by " = " between
            # the name & val.  Note that if any docwriter uses a
            # different formula for maxlen for this, then it will
            # not get the right value for is_detailed().
            maxlen = self.value.SUMMARY_REPR_LINELEN-3-len(self.name)
            return (not self.value.summary_pyval_repr(maxlen).is_complete)
        else:
            return self.value.is_detailed()

######################################################################
# Value Documentation Objects
######################################################################

class ValueDoc(APIDoc):
    """
    API documentation information about a single Python value.
    """
    canonical_name = UNKNOWN
    """@ivar: A dotted name that serves as a unique identifier for
       this C{ValueDoc}'s value.  If the value can be reached using a
       single sequence of identifiers (given the appropriate imports),
       then that sequence of identifiers is used as its canonical name.
       If the value can be reached by multiple sequences of identifiers
       (i.e., if it has multiple aliases), then one of those sequences of
       identifiers is used.  If the value cannot be reached by any
       sequence of identifiers (e.g., if it was used as a base class but
       then its variable was deleted), then its canonical name will start
       with C{'??'}.  If necessary, a dash followed by a number will be
       appended to the end of a non-reachable identifier to make its
       canonical name unique.

       When possible, canonical names are chosen when new C{ValueDoc}s
       are created.  However, this is sometimes not possible.  If a
       canonical name can not be chosen when the C{ValueDoc} is created,
       then one will be assigned by L{assign_canonical_names()
       <docbuilder.assign_canonical_names>}.
       
       @type: L{DottedName}"""

    #{ Value Representation
    pyval = UNKNOWN
    """@ivar: A pointer to the actual Python object described by this
       C{ValueDoc}.  This is used to display the value (e.g., when
       describing a variable.)  Use L{pyval_repr()} to generate a
       plaintext string representation of this value.
       @type: Python object"""

    parse_repr = UNKNOWN
    """@ivar: A text representation of this value, extracted from 
       parsing its source code.  This representation may not accurately
       reflect the actual value (e.g., if the value was modified after
       the initial assignment).
       @type: C{unicode}"""

    REPR_MAXLINES = 5
    """@cvar: The maximum number of lines of text that should be
    generated by L{pyval_repr()}.  If the string representation does
    not fit in this number of lines, an ellpsis marker (...) will
    be placed at the end of the formatted representation."""

    REPR_LINELEN = 75
    """@cvar: The maximum number of characters for lines of text that
    should be generated by L{pyval_repr()}.  Any lines that exceed
    this number of characters will be line-wrappped; The S{crarr}
    symbol will be used to indicate that the line was wrapped."""

    SUMMARY_REPR_LINELEN = 75
    """@cvar: The maximum number of characters for the single-line
    text representation generated by L{summary_pyval_repr()}.  If
    the value's representation does not fit in this number of
    characters, an ellipsis marker (...) will be placed at the end
    of the formatted representation."""

    REPR_MIN_SCORE = 0
    """@cvar: The minimum score that a value representation based on
    L{pyval} should have in order to be used instead of L{parse_repr}
    as the canonical representation for this C{ValueDoc}'s value.
    @see: L{epydoc.markup.pyval_repr}"""
    #} end of "value representation" group

    #{ Context
    defining_module = UNKNOWN
    """@ivar: The documentation for the module that defines this
       value.  This is used, e.g., to lookup the appropriate markup
       language for docstrings.  For a C{ModuleDoc},
       C{defining_module} should be C{self}.
       @type: L{ModuleDoc}"""
    #} end of "context group"

    #{ Information about Imported Variables
    proxy_for = None # [xx] in progress.
    """@ivar: If C{proxy_for} is not None, then this value was
       imported from another file.  C{proxy_for} is the dotted name of
       the variable that this value was imported from.  If that
       variable is documented, then its C{value} may contain more
       complete API documentation about this value.  The C{proxy_for}
       attribute is used by the source code parser to link imported
       values to their source values (in particular, for base
       classes).  When possible, these proxy C{ValueDoc}s are replaced
       by the imported value's C{ValueDoc} by
       L{link_imports()<docbuilder.link_imports>}.
       @type: L{DottedName}"""
    #} end of "information about imported variables" group

    #: @ivar:
    #: This is currently used to extract values from __all__, etc, in
    #: the docparser module; maybe I should specialize
    #: process_assignment and extract it there?  Although, for __all__,
    #: it's not clear where I'd put the value, since I just use it to
    #: set private/public/imported attribs on other vars (that might not
    #: exist yet at the time.)
    toktree = UNKNOWN

    def __repr__(self):
        if self.canonical_name is not UNKNOWN:
            return '<%s %s>' % (self.__class__.__name__, self.canonical_name)
        else:
            return '<%s %s>' % (self.__class__.__name__,
                                self.summary_pyval_repr().to_plaintext(None))

    def __setstate__(self, state):
        self.__dict__ = state

    def __getstate__(self):
        """
        State serializer for the pickle module.  This is necessary
        because sometimes the C{pyval} attribute contains an
        un-pickleable value.
        """
        # Construct our pickled dictionary.  Maintain this dictionary
        # as a private attribute, so we can reuse it later, since
        # merged objects need to share a single dictionary.
        if not hasattr(self, '_ValueDoc__pickle_state'):
            # Make sure __pyval_repr & __summary_pyval_repr are cached:
            self.pyval_repr(), self.summary_pyval_repr()
            # Construct the dictionary; leave out 'pyval'.
            self.__pickle_state = self.__dict__.copy()
            self.__pickle_state['pyval'] = UNKNOWN

        if not isinstance(self, GenericValueDoc):
            assert self.__pickle_state != {}
        # Return the pickle state.
        return self.__pickle_state

    #{ Value Representation
    def pyval_repr(self):
        """
        Return a formatted representation of the Python object
        described by this C{ValueDoc}.  This representation may
        include data from introspection or parsing, and is authorative
        as 'the best way to represent a Python value.'  Any lines that
        go beyond L{REPR_LINELEN} characters will be wrapped; and if
        the representation as a whole takes more than L{REPR_MAXLINES}
        lines, then it will be truncated (with an ellipsis marker).
        This function will never return L{UNKNOWN} or C{None}.
    
        @rtype: L{ColorizedPyvalRepr}
        """
        # Use self.__pyval_repr to cache the result.
        if not hasattr(self, '_ValueDoc__pyval_repr'):
            self.__pyval_repr = epydoc.markup.pyval_repr.colorize_pyval(
                self.pyval, self.parse_repr, self.REPR_MIN_SCORE,
                self.REPR_LINELEN, self.REPR_MAXLINES, linebreakok=True)
        return self.__pyval_repr

    def summary_pyval_repr(self, max_len=None):
        """
        Return a single-line formatted representation of the Python
        object described by this C{ValueDoc}.  This representation may
        include data from introspection or parsing, and is authorative
        as 'the best way to summarize a Python value.'  If the
        representation takes more then L{SUMMARY_REPR_LINELEN}
        characters, then it will be truncated (with an ellipsis
        marker).  This function will never return L{UNKNOWN} or
        C{None}.
    
        @rtype: L{ColorizedPyvalRepr}
        """
        # If max_len is specified, then do *not* cache the result.
        if max_len is not None:
            return epydoc.markup.pyval_repr.colorize_pyval(
                self.pyval, self.parse_repr, self.REPR_MIN_SCORE,
                max_len, maxlines=1, linebreakok=False)
            
        # Use self.__summary_pyval_repr to cache the result.
        if not hasattr(self, '_ValueDoc__summary_pyval_repr'):
            self.__summary_pyval_repr = epydoc.markup.pyval_repr.colorize_pyval(
                self.pyval, self.parse_repr, self.REPR_MIN_SCORE,
                self.SUMMARY_REPR_LINELEN, maxlines=1, linebreakok=False)
        return self.__summary_pyval_repr
    #} end of "value representation" group

    def apidoc_links(self, **filters):
        return []

class GenericValueDoc(ValueDoc):
    """
    API documentation about a 'generic' value, i.e., one that does not
    have its own docstring or any information other than its value and
    parse representation.  C{GenericValueDoc}s do not get assigned
    cannonical names.
    """
    canonical_name = None
    
    def is_detailed(self):
        return (not self.summary_pyval_repr().is_complete)

class NamespaceDoc(ValueDoc):
    """
    API documentation information about a singe Python namespace
    value.  (I.e., a module or a class).
    """
    #{ Information about Variables
    variables = UNKNOWN
    """@ivar: The contents of the namespace, encoded as a
        dictionary mapping from identifiers to C{VariableDoc}s.  This
        dictionary contains all names defined by the namespace,
        including imported variables, aliased variables, and variables
        inherited from base classes (once L{inherit_docs()
        <epydoc.docbuilder.inherit_docs>} has added them).
       @type: C{dict} from C{string} to L{VariableDoc}"""
    sorted_variables = UNKNOWN
    """@ivar: A list of all variables defined by this
       namespace, in sorted order.  The elements of this list should
       exactly match the values of L{variables}.  The sort order for
       this list is defined as follows:
          - Any variables listed in a C{@sort} docstring field are
            listed in the order given by that field.
          - These are followed by any variables that were found while
            parsing the source code, in the order in which they were
            defined in the source file.
          - Finally, any remaining variables are listed in
            alphabetical order.
       @type: C{list} of L{VariableDoc}"""
    sort_spec = UNKNOWN
    """@ivar: The order in which variables should be listed,
       encoded as a list of names.  Any variables whose names are not
       included in this list should be listed alphabetically,
       following the variables that are included.
       @type: C{list} of C{str}"""
    group_specs = UNKNOWN
    """@ivar: The groups that are defined by this namespace's
       docstrings.  C{group_specs} is encoded as an ordered list of
       tuples C{(group_name, elt_names)}, where C{group_name} is the
        
       name of a group and C{elt_names} is a list of element names in
       that group.  (An element can be a variable or a submodule.)  A
       '*' in an element name will match any string of characters.
       @type: C{list} of C{(str,list)}"""
    variable_groups = UNKNOWN
    """@ivar: A dictionary specifying what group each
       variable belongs to.  The keys of the dictionary are group
       names, and the values are lists of C{VariableDoc}s.  The order
       that groups should be listed in should be taken from
       L{group_specs}.
       @type: C{dict} from C{str} to C{list} of L{VariableDoc}"""
    #} end of group "information about variables"

    def __init__(self, **kwargs):
        kwargs.setdefault('variables', {})
        APIDoc.__init__(self, **kwargs)
        assert self.variables is not UNKNOWN

    def is_detailed(self):
        return True

    def apidoc_links(self, **filters):
        variables = filters.get('variables', True)
        imports = filters.get('imports', True)
        private = filters.get('private', True)
        if variables and imports and private:
            return self.variables.values() # list the common case first.
        elif not variables:
            return []
        elif not imports and not private:
            return [v for v in self.variables.values() if
                    v.is_imported != True and v.is_public != False]
        elif not private:
            return [v for v in self.variables.values() if
                    v.is_public != False]
        elif not imports:
            return [v for v in self.variables.values() if
                    v.is_imported != True]
        assert 0, 'this line should be unreachable'

    def init_sorted_variables(self):
        """
        Initialize the L{sorted_variables} attribute, based on the
        L{variables} and L{sort_spec} attributes.  This should usually
        be called after all variables have been added to C{variables}
        (including any inherited variables for classes).  
        """
        unsorted = self.variables.copy()
        self.sorted_variables = []
    
        # Add any variables that are listed in sort_spec
        if self.sort_spec is not UNKNOWN:
            unused_idents = set(self.sort_spec)
            for ident in self.sort_spec:
                if ident in unsorted:
                    self.sorted_variables.append(unsorted.pop(ident))
                    unused_idents.discard(ident)
                elif '*' in ident:
                    regexp = re.compile('^%s$' % ident.replace('*', '(.*)'))
                    # sort within matching group?
                    for name, var_doc in unsorted.items():
                        if regexp.match(name):
                            self.sorted_variables.append(unsorted.pop(name))
                            unused_idents.discard(ident)
            for ident in unused_idents:
                if ident not in ['__all__', '__docformat__', '__path__']:
                    log.warning("@sort: %s.%s not found" %
                                (self.canonical_name, ident))
                    
    
        # Add any remaining variables in alphabetical order.
        var_docs = unsorted.items()
        var_docs.sort()
        for name, var_doc in var_docs:
            self.sorted_variables.append(var_doc)

    def init_variable_groups(self):
        """
        Initialize the L{variable_groups} attribute, based on the
        L{sorted_variables} and L{group_specs} attributes.
        """
        if self.sorted_variables is UNKNOWN:
            self.init_sorted_variables()
        assert len(self.sorted_variables) == len(self.variables)

        elts = [(v.name, v) for v in self.sorted_variables]
        self._unused_groups = dict([(n,set(i)) for (n,i) in self.group_specs])
        self.variable_groups = self._init_grouping(elts)

    def group_names(self):
        """
        Return a list of the group names defined by this namespace, in
        the order in which they should be listed, with no duplicates.
        """
        name_list = ['']
        name_set = set()
        for name, spec in self.group_specs:
            if name not in name_set:
                name_set.add(name)
                name_list.append(name)
        return name_list

    def _init_grouping(self, elts):
        """
        Divide a given a list of APIDoc objects into groups, as
        specified by L{self.group_specs}.

        @param elts: A list of tuples C{(name, apidoc)}.
        
        @return: A list of tuples C{(groupname, elts)}, where
        C{groupname} is the name of a group and C{elts} is a list of
        C{APIDoc}s in that group.  The first tuple has name C{''}, and
        is used for ungrouped elements.  The remaining tuples are
        listed in the order that they appear in C{self.group_specs}.
        Within each tuple, the elements are listed in the order that
        they appear in C{api_docs}.
        """
        # Make the common case fast.
        if len(self.group_specs) == 0:
            return {'': [elt[1] for elt in elts]}

        ungrouped = set([elt_doc for (elt_name, elt_doc) in elts])

        ungrouped = dict(elts)
        groups = {}
        for elt_name, elt_doc in elts:
            for (group_name, idents) in self.group_specs:
                group = groups.setdefault(group_name, [])
                unused_groups = self._unused_groups[group_name]
                for ident in idents:
                    if re.match('^%s$' % ident.replace('*', '(.*)'), elt_name):
                        unused_groups.discard(ident)
                        if elt_name in ungrouped:
                            group.append(ungrouped.pop(elt_name))
                        else:
                            log.warning("%s.%s in multiple groups" %
                                        (self.canonical_name, elt_name))

        # Convert ungrouped from an unordered set to an ordered list.
        groups[''] = [elt_doc for (elt_name, elt_doc) in elts
                      if elt_name in ungrouped]
        return groups
    
    def report_unused_groups(self):
        """
        Issue a warning for any @group items that were not used by
        L{_init_grouping()}.
        """
        for (group, unused_idents) in self._unused_groups.items():
            for ident in unused_idents:
                log.warning("@group %s: %s.%s not found" %
                            (group, self.canonical_name, ident))
                        
class ModuleDoc(NamespaceDoc):
    """
    API documentation information about a single module.
    """
    #{ Information about the Module
    filename = UNKNOWN
    """@ivar: The name of the file that defines the module.
       @type: C{string}"""
    docformat = UNKNOWN
    """@ivar: The markup language used by docstrings in this module.
       @type: C{string}"""
    #{ Information about Submodules
    submodules = UNKNOWN
    """@ivar: Modules contained by this module (if this module
       is a package).  (Note: on rare occasions, a module may have a
       submodule that is shadowed by a variable with the same name.)
       @type: C{list} of L{ModuleDoc}"""
    submodule_groups = UNKNOWN
    """@ivar: A dictionary specifying what group each
       submodule belongs to.  The keys of the dictionary are group
       names, and the values are lists of C{ModuleDoc}s.  The order
       that groups should be listed in should be taken from
       L{group_specs}.
       @type: C{dict} from C{str} to C{list} of L{ModuleDoc}"""
    #{ Information about Packages
    package = UNKNOWN
    """@ivar: API documentation for the module's containing package.
       @type: L{ModuleDoc}"""
    is_package = UNKNOWN
    """@ivar: True if this C{ModuleDoc} describes a package.
       @type: C{bool}"""
    path = UNKNOWN
    """@ivar: If this C{ModuleDoc} describes a package, then C{path}
       contains a list of directories that constitute its path (i.e.,
       the value of its C{__path__} variable).
       @type: C{list} of C{str}"""
    #{ Information about Imported Variables
    imports = UNKNOWN
    """@ivar: A list of the source names of variables imported into
       this module.  This is used to construct import graphs.
       @type: C{list} of L{DottedName}"""
    #}

    def apidoc_links(self, **filters):
        val_docs = NamespaceDoc.apidoc_links(self, **filters)
        if (filters.get('packages', True) and
            self.package not in (None, UNKNOWN)):
            val_docs.append(self.package)
        if (filters.get('submodules', True) and
            self.submodules not in (None, UNKNOWN)):
            val_docs += self.submodules
        return val_docs

    def init_submodule_groups(self):
        """
        Initialize the L{submodule_groups} attribute, based on the
        L{submodules} and L{group_specs} attributes.
        """
        if self.submodules in (None, UNKNOWN):
            return
        self.submodules = sorted(self.submodules,
                                 key=lambda m:m.canonical_name)
        elts = [(m.canonical_name[-1], m) for m in self.submodules]
        self.submodule_groups = self._init_grouping(elts)

    def select_variables(self, group=None, value_type=None, public=None,
                         imported=None, detailed=None):
        """
        Return a specified subset of this module's L{sorted_variables}
        list.  If C{value_type} is given, then only return variables
        whose values have the specified type.  If C{group} is given,
        then only return variables that belong to the specified group.

        @require: The L{sorted_variables}, L{variable_groups}, and
            L{submodule_groups} attributes must be initialized before
            this method can be used.  See L{init_sorted_variables()},
            L{init_variable_groups()}, and L{init_submodule_groups()}.

        @param value_type: A string specifying the value type for
            which variables should be returned.  Valid values are:
              - 'class' - variables whose values are classes or types.
              - 'function' - variables whose values are functions.
              - 'other' - variables whose values are not classes,
                 exceptions, types, or functions.
        @type value_type: C{string}
        
        @param group: The name of the group for which variables should
            be returned.  A complete list of the groups defined by
            this C{ModuleDoc} is available in the L{group_names}
            instance variable.  The first element of this list is
            always the special group name C{''}, which is used for
            variables that do not belong to any group.
        @type group: C{string}

        @param detailed: If True (False), return only the variables
            deserving (not deserving) a detailed informative box.
            If C{None}, don't care.
        @type detailed: C{bool}
        """
        if (self.sorted_variables is UNKNOWN or 
            self.variable_groups is UNKNOWN):
            raise ValueError('sorted_variables and variable_groups '
                             'must be initialized first.')
        
        if group is None: var_list = self.sorted_variables
        else:
            var_list = self.variable_groups.get(group, self.sorted_variables)

        # Public/private filter (Count UNKNOWN as public)
        if public is True:
            var_list = [v for v in var_list if v.is_public is not False]
        elif public is False:
            var_list = [v for v in var_list if v.is_public is False]

        # Imported filter (Count UNKNOWN as non-imported)
        if imported is True:
            var_list = [v for v in var_list if v.is_imported is True]
        elif imported is False:
            var_list = [v for v in var_list if v.is_imported is not True]

        # Detailed filter
        if detailed is True:
            var_list = [v for v in var_list if v.is_detailed() is True]
        elif detailed is False:
            var_list = [v for v in var_list if v.is_detailed() is not True]

        # [xx] Modules are not currently included in any of these
        # value types.
        if value_type is None:
            return var_list
        elif value_type == 'class':
            return [var_doc for var_doc in var_list
                    if (isinstance(var_doc.value, ClassDoc))]
        elif value_type == 'function':
            return [var_doc for var_doc in var_list
                    if isinstance(var_doc.value, RoutineDoc)]
        elif value_type == 'other':
            return [var_doc for var_doc in var_list
                    if not isinstance(var_doc.value,
                                      (ClassDoc, RoutineDoc, ModuleDoc))]
        else:
            raise ValueError('Bad value type %r' % value_type)

class ClassDoc(NamespaceDoc):
    """
    API documentation information about a single class.
    """
    #{ Information about Base Classes
    bases = UNKNOWN
    """@ivar: API documentation for the class's base classes.
    @type: C{list} of L{ClassDoc}"""
    #{ Information about Subclasses
    subclasses = UNKNOWN
    """@ivar: API documentation for the class's known subclasses.
    @type: C{list} of L{ClassDoc}"""
    #}

    def apidoc_links(self, **filters):
        val_docs = NamespaceDoc.apidoc_links(self, **filters)
        if (filters.get('bases', True) and 
            self.bases not in (None, UNKNOWN)):
            val_docs += self.bases
        if (filters.get('subclasses', True) and
            self.subclasses not in (None, UNKNOWN)):
            val_docs += self.subclasses
        return val_docs
    
    def is_type(self):
        if self.canonical_name == DottedName('type'): return True
        if self.bases is UNKNOWN: return False
        for base in self.bases:
            if isinstance(base, ClassDoc) and base.is_type():
                return True
        return False
    
    def is_exception(self):
        if self.canonical_name == DottedName('Exception'): return True
        if self.bases is UNKNOWN: return False
        for base in self.bases:
            if isinstance(base, ClassDoc) and base.is_exception():
                return True
        return False
    
    def is_newstyle_class(self):
        if self.canonical_name == DottedName('object'): return True
        if self.bases is UNKNOWN: return False
        for base in self.bases:
            if isinstance(base, ClassDoc) and base.is_newstyle_class():
                return True
        return False

    def mro(self, warn_about_bad_bases=False):
        if self.is_newstyle_class():
            return self._c3_mro(warn_about_bad_bases)
        else:
            return self._dfs_bases([], set(), warn_about_bad_bases)
                
    def _dfs_bases(self, mro, seen, warn_about_bad_bases):
        if self in seen: return mro
        mro.append(self)
        seen.add(self)
        if self.bases is not UNKNOWN:
            for base in self.bases:
                if isinstance(base, ClassDoc) and base.proxy_for is None:
                    base._dfs_bases(mro, seen, warn_about_bad_bases)
                elif warn_about_bad_bases:
                    self._report_bad_base(base)
        return mro

    def _c3_mro(self, warn_about_bad_bases):
        """
        Compute the class precedence list (mro) according to C3.
        @seealso: U{http://www.python.org/2.3/mro.html}
        """
        bases = [base for base in self.bases if isinstance(base, ClassDoc)]
        if len(bases) != len(self.bases) and warn_about_bad_bases:
            for base in self.bases:
                if (not isinstance(base, ClassDoc) or
                    base.proxy_for is not None):
                    self._report_bad_base(base)
        w = [warn_about_bad_bases]*len(bases)
        return self._c3_merge([[self]] + map(ClassDoc._c3_mro, bases, w) +
                              [list(bases)])

    def _report_bad_base(self, base):
        if not isinstance(base, ClassDoc):
            if not isinstance(base, GenericValueDoc):
                base_name = base.canonical_name
            elif base.parse_repr is not UNKNOWN:
                base_name = base.parse_repr
            else:
                base_name = '%r' % base
            log.warning("%s's base %s is not a class" %
                        (self.canonical_name, base_name))
        elif base.proxy_for is not None:
            log.warning("No information available for %s's base %s" %
                        (self.canonical_name, base.proxy_for))

    def _c3_merge(self, seqs):
        """
        Helper function for L{_c3_mro}.
        """
        res = []
        while 1:
          nonemptyseqs=[seq for seq in seqs if seq]
          if not nonemptyseqs: return res
          for seq in nonemptyseqs: # find merge candidates among seq heads
              cand = seq[0]
              nothead=[s for s in nonemptyseqs if cand in s[1:]]
              if nothead: cand=None #reject candidate
              else: break
          if not cand: raise "Inconsistent hierarchy"
          res.append(cand)
          for seq in nonemptyseqs: # remove cand
              if seq[0] == cand: del seq[0]
    
    def select_variables(self, group=None, value_type=None, inherited=None,
                         public=None, imported=None, detailed=None):
        """
        Return a specified subset of this class's L{sorted_variables}
        list.  If C{value_type} is given, then only return variables
        whose values have the specified type.  If C{group} is given,
        then only return variables that belong to the specified group.
        If C{inherited} is True, then only return inherited variables;
        if C{inherited} is False, then only return local variables.

        @require: The L{sorted_variables} and L{variable_groups}
            attributes must be initialized before this method can be
            used.  See L{init_sorted_variables()} and
            L{init_variable_groups()}.

        @param value_type: A string specifying the value type for
            which variables should be returned.  Valid values are:
              - 'instancemethod' - variables whose values are
                instance methods.
              - 'classmethod' - variables whose values are class
                methods.
              - 'staticmethod' - variables whose values are static
                methods.
              - 'properties' - variables whose values are properties.
              - 'class' - variables whose values are nested classes
                (including exceptions and types).
              - 'instancevariable' - instance variables.  This includes
                any variables that are explicitly marked as instance
                variables with docstring fields; and variables with
                docstrings that are initialized in the constructor.
              - 'classvariable' - class variables.  This includes any
                variables that are not included in any of the above
                categories.
        @type value_type: C{string}
        
        @param group: The name of the group for which variables should
            be returned.  A complete list of the groups defined by
            this C{ClassDoc} is available in the L{group_names}
            instance variable.  The first element of this list is
            always the special group name C{''}, which is used for
            variables that do not belong to any group.
        @type group: C{string}

        @param inherited: If C{None}, then return both inherited and
            local variables; if C{True}, then return only inherited
            variables; if C{False}, then return only local variables.

        @param detailed: If True (False), return only the variables
            deserving (not deserving) a detailed informative box.
            If C{None}, don't care.
        @type detailed: C{bool}
        """
        if (self.sorted_variables is UNKNOWN or 
            self.variable_groups is UNKNOWN):
            raise ValueError('sorted_variables and variable_groups '
                             'must be initialized first.')
        
        if group is None: var_list = self.sorted_variables
        else: var_list = self.variable_groups[group]

        # Public/private filter (Count UNKNOWN as public)
        if public is True:
            var_list = [v for v in var_list if v.is_public is not False]
        elif public is False:
            var_list = [v for v in var_list if v.is_public is False]

        # Inherited filter (Count UNKNOWN as non-inherited)
        if inherited is None: pass
        elif inherited:
            var_list = [v for v in var_list if v.container != self]
        else:
            var_list = [v for v in var_list if v.container == self ]

        # Imported filter (Count UNKNOWN as non-imported)
        if imported is True:
            var_list = [v for v in var_list if v.is_imported is True]
        elif imported is False:
            var_list = [v for v in var_list if v.is_imported is not True]

        # Detailed filter
        if detailed is True:
            var_list = [v for v in var_list if v.is_detailed() is True]
        elif detailed is False:
            var_list = [v for v in var_list if v.is_detailed() is not True]

        if value_type is None:
            return var_list
        elif value_type == 'method':
            return [var_doc for var_doc in var_list
                    if (isinstance(var_doc.value, RoutineDoc) and
                        var_doc.is_instvar in (False, UNKNOWN))]
        elif value_type == 'instancemethod':
            return [var_doc for var_doc in var_list
                    if (isinstance(var_doc.value, RoutineDoc) and
                        not isinstance(var_doc.value, ClassMethodDoc) and
                        not isinstance(var_doc.value, StaticMethodDoc) and
                        var_doc.is_instvar in (False, UNKNOWN))]
        elif value_type == 'classmethod':
            return [var_doc for var_doc in var_list
                    if (isinstance(var_doc.value, ClassMethodDoc) and
                        var_doc.is_instvar in (False, UNKNOWN))]
        elif value_type == 'staticmethod':
            return [var_doc for var_doc in var_list
                    if (isinstance(var_doc.value, StaticMethodDoc) and
                        var_doc.is_instvar in (False, UNKNOWN))]
        elif value_type == 'property':
            return [var_doc for var_doc in var_list
                    if (isinstance(var_doc.value, PropertyDoc) and
                        var_doc.is_instvar in (False, UNKNOWN))]
        elif value_type == 'class':
            return [var_doc for var_doc in var_list
                    if (isinstance(var_doc.value, ClassDoc) and
                        var_doc.is_instvar in (False, UNKNOWN))]
        elif value_type == 'instancevariable':
            return [var_doc for var_doc in var_list
                    if var_doc.is_instvar is True]
        elif value_type == 'classvariable':
            return [var_doc for var_doc in var_list
                    if (var_doc.is_instvar in (False, UNKNOWN) and
                        not isinstance(var_doc.value,
                                       (RoutineDoc, ClassDoc, PropertyDoc)))]
        else:
            raise ValueError('Bad value type %r' % value_type)

class RoutineDoc(ValueDoc):
    """
    API documentation information about a single routine.
    """
    #{ Signature
    posargs = UNKNOWN
    """@ivar: The names of the routine's positional arguments.
       If an argument list contains \"unpacking\" arguments, then
       their names will be specified using nested lists.  E.g., if
       a function's argument list is C{((x1,y1), (x2,y2))}, then
       posargs will be C{[['x1','y1'], ['x2','y2']]}.
       @type: C{list}"""
    posarg_defaults = UNKNOWN
    """@ivar: API documentation for the positional arguments'
       default values.  This list has the same length as C{posargs}, and
       each element of C{posarg_defaults} describes the corresponding
       argument in C{posargs}.  For positional arguments with no default,
       C{posargs_defaults} will contain None.
       @type: C{list} of C{ValueDoc} or C{None}"""
    vararg = UNKNOWN
    """@ivar: The name of the routine's vararg argument, or C{None} if
       it has no vararg argument.
       @type: C{string} or C{None}"""
    kwarg = UNKNOWN
    """@ivar: The name of the routine's keyword argument, or C{None} if
       it has no keyword argument.
       @type: C{string} or C{None}"""
    lineno = UNKNOWN # used to look up profiling info from pstats.
    """@ivar: The line number of the first line of the function's
       signature.  For Python functions, this is equal to
       C{func.func_code.co_firstlineno}.  The first line of a file
       is considered line 1.
       @type: C{int}"""
    #} end of "signature" group

    #{ Decorators
    decorators = UNKNOWN
    """@ivar: A list of names of decorators that were applied to this
       routine, in the order that they are listed in the source code.
       (I.e., in the reverse of the order that they were applied in.)
       @type: C{list} of C{string}"""
    #} end of "decorators" group

    #{ Information Extracted from Docstrings
    arg_descrs = UNKNOWN
    """@ivar: A list of descriptions of the routine's
       arguments.  Each element of this list is a tuple C{(args,
       descr)}, where C{args} is a list of argument names; and
       C{descr} is a L{ParsedDocstring
       <epydoc.markup.ParsedDocstring>} describing the argument(s)
       specified by C{arg}.
       @type: C{list}"""
    arg_types = UNKNOWN
    """@ivar: Descriptions of the expected types for the
       routine's arguments, encoded as a dictionary mapping from
       argument names to type descriptions.
       @type: C{dict} from C{string} to L{ParsedDocstring
       <epydoc.markup.ParsedDocstring>}"""
    return_descr = UNKNOWN
    """@ivar: A description of the value returned by this routine.
       @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
    return_type = UNKNOWN
    """@ivar: A description of expected type for the value
       returned by this routine.
       @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
    exception_descrs = UNKNOWN
    """@ivar: A list of descriptions of exceptions
       that the routine might raise.  Each element of this list is a
       tuple C{(exc, descr)}, where C{exc} is a string contianing the
       exception name; and C{descr} is a L{ParsedDocstring
       <epydoc.markup.ParsedDocstring>} describing the circumstances
       under which the exception specified by C{exc} is raised.
       @type: C{list}"""
    #} end of "information extracted from docstrings" group
    callgraph_uid = None
    """@ivar: L{DotGraph}.uid of the call graph for the function.
       @type: C{str}"""

    def is_detailed(self):
        if super(RoutineDoc, self).is_detailed():
            return True

        if self.arg_descrs not in (None, UNKNOWN) and self.arg_descrs:
            return True

        if self.arg_types not in (None, UNKNOWN) and self.arg_types:
            return True

        if self.return_descr not in (None, UNKNOWN):
            return True

        if self.exception_descrs not in (None, UNKNOWN) and self.exception_descrs:
            return True

        if (self.decorators not in (None, UNKNOWN)
            and [ d for d in self.decorators
                 if d not in ('classmethod', 'staticmethod') ]):
            return True

        return False

    def all_args(self):
        """
        @return: A list of the names of all arguments (positional,
        vararg, and keyword), in order.  If a positional argument
        consists of a tuple of names, then that tuple will be
        flattened.
        """
        if self.posargs is UNKNOWN:
            return UNKNOWN
            
        all_args = _flatten(self.posargs)
        if self.vararg not in (None, UNKNOWN):
            all_args.append(self.vararg)
        if self.kwarg not in (None, UNKNOWN):
            all_args.append(self.kwarg)
        return all_args

def _flatten(lst, out=None):
    """
    Return a flattened version of C{lst}.
    """
    if out is None: out = []
    for elt in lst:
        if isinstance(elt, (list,tuple)):
            _flatten(elt, out)
        else:
            out.append(elt)
    return out

class ClassMethodDoc(RoutineDoc): pass
class StaticMethodDoc(RoutineDoc): pass

class PropertyDoc(ValueDoc):
    """
    API documentation information about a single property.
    """
    #{ Property Access Functions
    fget = UNKNOWN
    """@ivar: API documentation for the property's get function.
       @type: L{RoutineDoc}"""
    fset = UNKNOWN
    """@ivar: API documentation for the property's set function.
       @type: L{RoutineDoc}"""
    fdel = UNKNOWN
    """@ivar: API documentation for the property's delete function.
       @type: L{RoutineDoc}"""
    #}
    #{ Information Extracted from Docstrings
    type_descr = UNKNOWN
    """@ivar: A description of the property's expected type, extracted
       from its docstring.
       @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
    #} end of "information extracted from docstrings" group

    def apidoc_links(self, **filters):
        val_docs = []
        if self.fget not in (None, UNKNOWN): val_docs.append(self.fget)
        if self.fset not in (None, UNKNOWN): val_docs.append(self.fset)
        if self.fdel not in (None, UNKNOWN): val_docs.append(self.fdel)
        return val_docs

    def is_detailed(self):
        if super(PropertyDoc, self).is_detailed():
            return True

        if self.fget not in (None, UNKNOWN) and self.fget.pyval is not None:
             return True
        if self.fset not in (None, UNKNOWN) and self.fset.pyval is not None:
             return True
        if self.fdel not in (None, UNKNOWN) and self.fdel.pyval is not None:
             return True

        return False

######################################################################
## Index
######################################################################

class DocIndex:
    """
    [xx] out of date.
    
    An index that .. hmm...  it *can't* be used to access some things,
    cuz they're not at the root level.  Do I want to add them or what?
    And if so, then I have a sort of a new top level.  hmm..  so
    basically the question is what to do with a name that's not in the
    root var's name space.  2 types:
      - entirely outside (eg os.path)
      - inside but not known (eg a submodule that we didn't look at?)
      - container of current thing not examined?
    
    An index of all the C{APIDoc} objects that can be reached from a
    root set of C{ValueDoc}s.  
    
    The members of this index can be accessed by dotted name.  In
    particular, C{DocIndex} defines two mappings, accessed via the
    L{get_vardoc()} and L{get_valdoc()} methods, which can be used to
    access C{VariableDoc}s or C{ValueDoc}s respectively by name.  (Two
    separate mappings are necessary because a single name can be used
    to refer to both a variable and to the value contained by that
    variable.)

    Additionally, the index defines two sets of C{ValueDoc}s:
    \"reachable C{ValueDoc}s\" and \"contained C{ValueDoc}s\".  The
    X{reachable C{ValueDoc}s} are defined as the set of all
    C{ValueDoc}s that can be reached from the root set by following
    I{any} sequence of pointers to C{ValueDoc}s or C{VariableDoc}s.
    The X{contained C{ValueDoc}s} are defined as the set of all
    C{ValueDoc}s that can be reached from the root set by following
    only the C{ValueDoc} pointers defined by non-imported
    C{VariableDoc}s.  For example, if the root set contains a module
    C{m}, then the contained C{ValueDoc}s includes the C{ValueDoc}s
    for any functions, variables, or classes defined in that module,
    as well as methods and variables defined in classes defined in the
    module.  The reachable C{ValueDoc}s includes all of those
    C{ValueDoc}s, as well as C{ValueDoc}s for any values imported into
    the module, and base classes for classes defined in the module.
    """

    def __init__(self, root):
        """
        Create a new documentation index, based on the given root set
        of C{ValueDoc}s.  If any C{APIDoc}s reachable from the root
        set does not have a canonical name, then it will be assigned
        one.  etc.
        
        @param root: A list of C{ValueDoc}s.
        """
        for apidoc in root:
            if apidoc.canonical_name in (None, UNKNOWN):
                raise ValueError("All APIdocs passed to DocIndexer "
                                 "must already have canonical names.")
        
        # Initialize the root items list.  We sort them by length in
        # ascending order.  (This ensures that variables will shadow
        # submodules when appropriate.)
        # When the elements name is the same, list in alphabetical order:
        # this is needed by the check for duplicates below.
        self.root = sorted(root,
            key=lambda d: (len(d.canonical_name), d.canonical_name))
        """The list of C{ValueDoc}s to document.
            @type: C{list}"""

        # Drop duplicated modules
        # [xx] maybe what causes duplicates should be fixed instead.
        #      If fixed, adjust the sort here above: sorting by names will not
        #      be required anymore
        i = 1
        while i < len(self.root):
            if self.root[i-1] is self.root[i]:
                del self.root[i]
            else:
                i += 1

        self.mlclasses = self._get_module_classes(self.root)
        """A mapping from class names to L{ClassDoc}. Contains
           classes defined at module level for modules in L{root}
           and which can be used as fallback by L{find()} if looking
           in containing namespaces fails.
           @type: C{dict} from C{str} to L{ClassDoc} or C{list}"""

        self.callers = None
        """A dictionary mapping from C{RoutineDoc}s in this index
           to lists of C{RoutineDoc}s for the routine's callers.
           This dictionary is initialized by calling
           L{read_profiling_info()}.
           @type: C{list} of L{RoutineDoc}"""
        
        self.callees = None
        """A dictionary mapping from C{RoutineDoc}s in this index
           to lists of C{RoutineDoc}s for the routine's callees.
           This dictionary is initialized by calling
           L{read_profiling_info()}.
           @type: C{list} of L{RoutineDoc}"""

        self._funcid_to_doc = {}
        """A mapping from C{profile} function ids to corresponding
           C{APIDoc} objects.  A function id is a tuple of the form
           C{(filename, lineno, funcname)}.  This is used to update
           the L{callers} and L{callees} variables."""

        self._container_cache = {}
        """A cache for the L{container()} method, to increase speed."""

        self._get_cache = {}
        """A cache for the L{get_vardoc()} and L{get_valdoc()} methods,
        to increase speed."""

    #////////////////////////////////////////////////////////////
    # Lookup methods
    #////////////////////////////////////////////////////////////
    # [xx]
    # Currently these only work for things reachable from the
    # root... :-/  I might want to change this so that imported
    # values can be accessed even if they're not contained.  
    # Also, I might want canonical names to not start with ??
    # if the thing is a top-level imported module..?

    def get_vardoc(self, name):
        """
        Return the C{VariableDoc} with the given name, or C{None} if this
        index does not contain a C{VariableDoc} with the given name.
        """
        var, val = self._get(name)
        return var

    def get_valdoc(self, name):
        """
        Return the C{ValueDoc} with the given name, or C{None} if this
        index does not contain a C{ValueDoc} with the given name.
        """
        var, val = self._get(name)
        return val

    def _get(self, name):
        """
        A helper function that's used to implement L{get_vardoc()}
        and L{get_valdoc()}.
        """
        # Convert name to a DottedName, if necessary.
        if not isinstance(name, DottedName):
            name = DottedName(name)

        # Check if the result is cached.
        val = self._get_cache.get(name)
        if val is not None: return val

        # Look for an element in the root set whose name is a prefix
        # of `name`.  If we can't find one, then return None.
        for root_valdoc in self.root:
            if root_valdoc.canonical_name.dominates(name):
                # Starting at the root valdoc, walk down the variable/
                # submodule chain until we find the requested item.
                var_doc = None
                val_doc = root_valdoc
                for identifier in name[len(root_valdoc.canonical_name):]:
                    if val_doc is None: break
                    var_doc, val_doc = self._get_from(val_doc, identifier)
                else:
                    # If we found it, then return.
                    if var_doc is not None or val_doc is not None:
                        self._get_cache[name] = (var_doc, val_doc)
                        return var_doc, val_doc

        # We didn't find it.
        self._get_cache[name] = (None, None)
        return None, None

    def _get_from(self, val_doc, identifier):
        if isinstance(val_doc, NamespaceDoc):
            child_var = val_doc.variables.get(identifier)
            if child_var is not None:
                child_val = child_var.value
                if child_val is UNKNOWN: child_val = None
                return child_var, child_val

        # If that fails, then see if it's a submodule.
        if (isinstance(val_doc, ModuleDoc) and
            val_doc.submodules is not UNKNOWN):
            for submodule in val_doc.submodules:
                if submodule.canonical_name[-1] == identifier:
                    var_doc = None
                    val_doc = submodule
                    if val_doc is UNKNOWN: val_doc = None
                    return var_doc, val_doc

        return None, None

    def find(self, name, context):
        """
        Look for an C{APIDoc} named C{name}, relative to C{context}.
        Return the C{APIDoc} if one is found; otherwise, return
        C{None}.  C{find} looks in the following places, in order:
          - Function parameters (if one matches, return C{None})
          - All enclosing namespaces, from closest to furthest.
          - If C{name} starts with C{'self'}, then strip it off and
            look for the remaining part of the name using C{find}
          - Builtins
          - Parameter attributes
          - Classes at module level (if the name is not ambiguous)
        
        @type name: C{str} or L{DottedName}
        @type context: L{APIDoc}
        """
        if isinstance(name, basestring):
            name = re.sub(r'\(.*\)$', '', name.strip())
            if re.match('^([a-zA-Z_]\w*)(\.[a-zA-Z_]\w*)*$', name):
                name = DottedName(name)
            else:
                return None
        elif not isinstance(name, DottedName):
            raise TypeError("'name' should be a string or DottedName")
        
        if context is None or context.canonical_name is None:
            container_name = []
        else:
            container_name = context.canonical_name

        # Check for the name in all containing namespaces, starting
        # with the closest one.
        for i in range(len(container_name), -1, -1):
            relative_name = container_name[:i]+name
            # Is `name` the absolute name of a documented value?
            # (excepting GenericValueDoc values.)
            val_doc = self.get_valdoc(relative_name)
            if (val_doc is not None and
                not isinstance(val_doc, GenericValueDoc)):
                return val_doc
            # Is `name` the absolute name of a documented variable?
            var_doc = self.get_vardoc(relative_name)
            if var_doc is not None: return var_doc

        # If the name begins with 'self', then try stripping that off
        # and see if we can find the variable.
        if name[0] == 'self':
            doc = self.find('.'.join(name[1:]), context)
            if doc is not None: return doc

        # Is it the name of a builtin?
        if len(name)==1 and hasattr(__builtin__, name[0]):
            return None
        
        # Is it a parameter's name or an attribute of a parameter?
        if isinstance(context, RoutineDoc):
            all_args = context.all_args()
            if all_args is not UNKNOWN and name[0] in all_args:
                return None

        # Is this an object directly contained by any module?
        doc = self.mlclasses.get(name[-1])
        if isinstance(doc, APIDoc):
            return doc
        elif isinstance(doc, list):
            log.warning("%s is an ambiguous name: it may be %s" % (
                name[-1],
                ", ".join([ "'%s'" % d.canonical_name for d in doc ])))

            # Drop this item so that the warning is reported only once.
            # fail() will fail anyway.
            del self.mlclasses[name[-1]]

    def _get_module_classes(self, docs):
        """
        Gather all the classes defined in a list of modules.

        Very often people refers to classes only by class name,
        even if they are not imported in the namespace. Linking
        to such classes will fail if we look for them only in nested
        namespaces. Allow them to retrieve only by name.

        @param docs: containers of the objects to collect
        @type docs: C{list} of C{APIDoc}
        @return: mapping from objects name to the object(s) with that name
        @rtype: C{dict} from C{str} to L{ClassDoc} or C{list}
        """
        classes = {}
        for doc in docs:
            if not isinstance(doc, ModuleDoc):
                continue

            for var in doc.variables.values():
                if not isinstance(var.value, ClassDoc):
                    continue

                val = var.value
                if val in (None, UNKNOWN) or val.defining_module is not doc:
                    continue
                if val.canonical_name in (None, UNKNOWN):
                    continue

                name = val.canonical_name[-1]
                vals = classes.get(name)
                if vals is None:
                    classes[name] = val
                elif not isinstance(vals, list):
                    classes[name] = [ vals, val ]
                else:
                    vals.append(val)

        return classes

    #////////////////////////////////////////////////////////////
    # etc
    #////////////////////////////////////////////////////////////

    def reachable_valdocs(self, **filters):
        """
        Return a list of all C{ValueDoc}s that can be reached,
        directly or indirectly from this C{DocIndex}'s root set.
        
        @param filters: A set of filters that can be used to prevent
            C{reachable_valdocs} from following specific link types
            when looking for C{ValueDoc}s that can be reached from the
            root set.  See C{APIDoc.apidoc_links} for a more complete
            description.
        """
        return reachable_valdocs(self.root, **filters)

    def container(self, api_doc):
        """
        Return the C{ValueDoc} that contains the given C{APIDoc}, or
        C{None} if its container is not in the index.
        """
        # Check if the result is cached.
        val = self._container_cache.get(api_doc)
        if val is not None: return val
        
        if isinstance(api_doc, GenericValueDoc):
            self._container_cache[api_doc] = None
            return None # [xx] unknown.
        if isinstance(api_doc, VariableDoc):
            self._container_cache[api_doc] = api_doc.container
            return api_doc.container
        if len(api_doc.canonical_name) == 1:
            self._container_cache[api_doc] = None
            return None
        elif isinstance(api_doc, ModuleDoc) and api_doc.package is not UNKNOWN:
            self._container_cache[api_doc] = api_doc.package
            return api_doc.package
        else:
            parent = self.get_valdoc(api_doc.canonical_name.container())
            self._container_cache[api_doc] = parent
            return parent

    #////////////////////////////////////////////////////////////
    # Profiling information
    #////////////////////////////////////////////////////////////

    def read_profiling_info(self, profile_stats):
        """
        Initialize the L{callers} and L{callees} variables, given a
        C{Stat} object from the C{pstats} module.
        
        @warning: This method uses undocumented data structures inside
            of C{profile_stats}.
        """
        if self.callers is None: self.callers = {}
        if self.callees is None: self.callees = {}
        
        # The Stat object encodes functions using `funcid`s, or
        # tuples of (filename, lineno, funcname).  Create a mapping
        # from these `funcid`s to `RoutineDoc`s.
        self._update_funcid_to_doc(profile_stats)
        
        for callee, (cc, nc, tt, ct, callers) in profile_stats.stats.items():
            callee = self._funcid_to_doc.get(callee)
            if callee is None: continue
            for caller in callers:
                caller = self._funcid_to_doc.get(caller)
                if caller is None: continue
                self.callers.setdefault(callee, []).append(caller)
                self.callees.setdefault(caller, []).append(callee)

    def _update_funcid_to_doc(self, profile_stats):
        """
        Update the dictionary mapping from C{pstat.Stat} funciton ids to
        C{RoutineDoc}s.  C{pstat.Stat} function ids are tuples of
        C{(filename, lineno, funcname)}.
        """
        # Maps (filename, lineno, funcname) -> RoutineDoc
        for val_doc in self.reachable_valdocs():
            # We only care about routines.
            if not isinstance(val_doc, RoutineDoc): continue
            # Get the filename from the defining module.
            module = val_doc.defining_module
            if module is UNKNOWN or module.filename is UNKNOWN: continue
            # Normalize the filename.
            filename = os.path.abspath(module.filename)
            try: filename = py_src_filename(filename)
            except: pass
            # Look up the stat_func_id
            funcid = (filename, val_doc.lineno, val_doc.canonical_name[-1])
            if funcid in profile_stats.stats:
                self._funcid_to_doc[funcid] = val_doc

######################################################################
## Pretty Printing
######################################################################

def pp_apidoc(api_doc, doublespace=0, depth=5, exclude=(), include=(),
              backpointers=None):
    """
    @return: A multiline pretty-printed string representation for the
        given C{APIDoc}.
    @param doublespace: If true, then extra lines will be
        inserted to make the output more readable.
    @param depth: The maximum depth that pp_apidoc will descend
        into descendent VarDocs.  To put no limit on
        depth, use C{depth=-1}.
    @param exclude: A list of names of attributes whose values should
        not be shown.
    @param backpointers: For internal use.
    """
    pyid = id(api_doc.__dict__)
    if backpointers is None: backpointers = {}
    if (hasattr(api_doc, 'canonical_name') and
        api_doc.canonical_name not in (None, UNKNOWN)):
        name = '%s for %s' % (api_doc.__class__.__name__,
                              api_doc.canonical_name)
    elif getattr(api_doc, 'name', None) not in (UNKNOWN, None):
        if (getattr(api_doc, 'container', None) not in (UNKNOWN, None) and
            getattr(api_doc.container, 'canonical_name', None)
            not in (UNKNOWN, None)):
            name ='%s for %s' % (api_doc.__class__.__name__,
                                 api_doc.container.canonical_name+
                                 api_doc.name)
        else:
            name = '%s for %s' % (api_doc.__class__.__name__, api_doc.name)
    else:
        name = api_doc.__class__.__name__
        
    if pyid in backpointers:
        return '%s [%s] (defined above)' % (name, backpointers[pyid])
    
    if depth == 0:
        if hasattr(api_doc, 'name') and api_doc.name is not None:
            return '%s...' % api_doc.name
        else:
            return '...'

    backpointers[pyid] = len(backpointers)
    s = '%s [%s]' % (name, backpointers[pyid])

    # Only print non-empty fields:
    fields = [field for field in api_doc.__dict__.keys()
              if (field in include or
                  (getattr(api_doc, field) is not UNKNOWN
                   and field not in exclude))]
    if include:
        fields = [field for field in dir(api_doc)
                  if field in include]
    else:
        fields = [field for field in api_doc.__dict__.keys()
                  if (getattr(api_doc, field) is not UNKNOWN
                      and field not in exclude)]
    fields.sort()
    
    for field in fields:
        fieldval = getattr(api_doc, field)
        if doublespace: s += '\n |'
        s += '\n +- %s' % field

        if (isinstance(fieldval, types.ListType) and
            len(fieldval)>0 and
            isinstance(fieldval[0], APIDoc)):
            s += _pp_list(api_doc, fieldval, doublespace, depth,
                          exclude, include, backpointers,
                          (field is fields[-1]))
        elif (isinstance(fieldval, types.DictType) and
              len(fieldval)>0 and 
              isinstance(fieldval.values()[0], APIDoc)):
            s += _pp_dict(api_doc, fieldval, doublespace, 
                          depth, exclude, include, backpointers,
                          (field is fields[-1]))
        elif isinstance(fieldval, APIDoc):
            s += _pp_apidoc(api_doc, fieldval, doublespace, depth,
                            exclude, include, backpointers,
                            (field is fields[-1]))
        else:
            s += ' = ' + _pp_val(api_doc, fieldval, doublespace,
                                 depth, exclude, include, backpointers)
                
    return s

def _pp_list(api_doc, items, doublespace, depth, exclude, include,
              backpointers, is_last):
    line1 = (is_last and ' ') or '|'
    s = ''
    for item in items:
        line2 = ((item is items[-1]) and ' ') or '|'
        joiner = '\n %s  %s ' % (line1, line2)
        if doublespace: s += '\n %s  |' % line1
        s += '\n %s  +- ' % line1
        valstr = _pp_val(api_doc, item, doublespace, depth, exclude, include,
                         backpointers)
        s += joiner.join(valstr.split('\n'))
    return s

def _pp_dict(api_doc, dict, doublespace, depth, exclude, include,
              backpointers, is_last):
    items = dict.items()
    items.sort()
    line1 = (is_last and ' ') or '|'
    s = ''
    for item in items:
        line2 = ((item is items[-1]) and ' ') or '|'
        joiner = '\n %s  %s ' % (line1, line2)
        if doublespace: s += '\n %s  |' % line1
        s += '\n %s  +- ' % line1
        valstr = _pp_val(api_doc, item[1], doublespace, depth, exclude,
                         include, backpointers)
        s += joiner.join(('%s => %s' % (item[0], valstr)).split('\n'))
    return s

def _pp_apidoc(api_doc, val, doublespace, depth, exclude, include,
                backpointers, is_last):
    line1 = (is_last and ' ') or '|'
    s = ''
    if doublespace: s += '\n %s  |  ' % line1
    s += '\n %s  +- ' % line1
    joiner = '\n %s    ' % line1
    childstr = pp_apidoc(val, doublespace, depth-1, exclude,
                         include, backpointers)
    return s + joiner.join(childstr.split('\n'))
    
def _pp_val(api_doc, val, doublespace, depth, exclude, include, backpointers):
    from epydoc import markup
    if isinstance(val, APIDoc):
        return pp_apidoc(val, doublespace, depth-1, exclude,
                         include, backpointers)
    elif isinstance(val, markup.ParsedDocstring):
        valrepr = `val.to_plaintext(None)`
        if len(valrepr) < 40: return valrepr
        else: return valrepr[:37]+'...'
    else:
        valrepr = repr(val)
        if len(valrepr) < 40: return valrepr
        else: return valrepr[:37]+'...'

