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