Beispiel #1
0
    def resolve_name(self, what, name):
        """
        Determine what module to import and what attribute to document.

        Returns a tuple of: the full name, the module name, a path of
        names to get via getattr, the signature and return annotation.
        """
        # first, parse the definition -- auto directives for classes and functions
        # can contain a signature which is then used instead of an autogenerated one
        try:
            path, base, args, retann = py_sig_re.match(name).groups()
        except:
            self.warn('invalid signature for auto%s (%r)' % (what, name))
            return
        # fullname is the fully qualified name, base the name after the last dot
        fullname = (path or '') + base

        if what == 'module':
            if args or retann:
                self.warn('ignoring signature arguments and return annotation '
                          'for automodule %s' % fullname)
            return fullname, fullname, [], None, None

        elif what in ('class', 'exception', 'function'):
            if path:
                mod = path.rstrip('.')
            else:
                mod = None
                # if documenting a toplevel object without explicit module, it can
                # be contained in another auto directive ...
                if hasattr(self.env, 'autodoc_current_module'):
                    mod = self.env.autodoc_current_module
                # ... or in the scope of a module directive
                if not mod:
                    mod = self.env.currmodule
            return fullname, mod, [base], args, retann

        else:
            if path:
                mod_cls = path.rstrip('.')
            else:
                mod_cls = None
                # if documenting a class-level object without path, there must be a
                # current class, either from a parent auto directive ...
                if hasattr(self.env, 'autodoc_current_class'):
                    mod_cls = self.env.autodoc_current_class
                # ... or from a class directive
                if mod_cls is None:
                    mod_cls = self.env.currclass
                # ... if still None, there's no way to know
                if mod_cls is None:
                    return fullname, None, [], args, retann
            mod, cls = rpartition(mod_cls, '.')
            # if the module name is still missing, get it like above
            if not mod and hasattr(self.env, 'autodoc_current_module'):
                mod = self.env.autodoc_current_module
            if not mod:
                mod = self.env.currmodule
            return fullname, mod, [cls, base], args, retann
Beispiel #2
0
    def resolve_name(self, what, name):
        """
        Determine what module to import and what attribute to document.

        Returns a tuple of: the full name, the module name, a path of
        names to get via getattr, the signature and return annotation.
        """
        # first, parse the definition -- auto directives for classes and functions
        # can contain a signature which is then used instead of an autogenerated one
        try:
            path, base, args, retann = py_sig_re.match(name).groups()
        except:
            self.warn('invalid signature for auto%s (%r)' % (what, name))
            return
        # fullname is the fully qualified name, base the name after the last dot
        fullname = (path or '') + base

        if what == 'module':
            if args or retann:
                self.warn('ignoring signature arguments and return annotation '
                          'for automodule %s' % fullname)
            return fullname, fullname, [], None, None

        elif what in ('class', 'exception', 'function'):
            if path:
                mod = path.rstrip('.')
            else:
                mod = None
                # if documenting a toplevel object without explicit module, it can
                # be contained in another auto directive ...
                if hasattr(self.env, 'autodoc_current_module'):
                    mod = self.env.autodoc_current_module
                # ... or in the scope of a module directive
                if not mod:
                    mod = self.env.currmodule
            return fullname, mod, [base], args, retann

        else:
            if path:
                mod_cls = path.rstrip('.')
            else:
                mod_cls = None
                # if documenting a class-level object without path, there must be a
                # current class, either from a parent auto directive ...
                if hasattr(self.env, 'autodoc_current_class'):
                    mod_cls = self.env.autodoc_current_class
                # ... or from a class directive
                if mod_cls is None:
                    mod_cls = self.env.currclass
            mod, cls = rpartition(mod_cls, '.')
            # if the module name is still missing, get it like above
            if not mod and hasattr(self.env, 'autodoc_current_module'):
                mod = self.env.autodoc_current_module
            if not mod:
                mod = self.env.currmodule
            return fullname, mod, [cls, base], args, retann
Beispiel #3
0
    def _import_class_or_module(self, name):
        """
        Import a class using its fully-qualified *name*.
        """
        try:
            path, base, signature = py_sig_re.match(name).groups()
        except:
            raise ValueError(
                "Invalid class or module '%s' specified for inheritance diagram"
                % name)
        fullname = (path or '') + base
        path = path and path.rstrip('.')
        if not path:
            raise ValueError(
                "Invalid class or module '%s' specified for inheritance diagram"
                % name)
        try:
            module = __import__(path, None, None, [])
        except ImportError:
            raise ValueError(
                "Could not import class or module '%s' specified for inheritance diagram"
                % name)

        try:
            todoc = module
            for comp in fullname.split('.')[1:]:
                todoc = getattr(todoc, comp)
        except AttributeError:
            raise ValueError(
                "Could not find class or module '%s' specified for inheritance diagram"
                % name)

        # If a class, just return it
        if inspect.isclass(todoc):
            return [todoc]
        elif inspect.ismodule(todoc):
            classes = []
            for cls in todoc.__dict__.values():
                if inspect.isclass(cls) and cls.__module__ == todoc.__name__:
                    classes.append(cls)
            return classes
        raise ValueError("'%s' does not resolve to a class or module" % name)
Beispiel #4
0
    def _import_class_or_module(self, name):
        """
        Import a class using its fully-qualified *name*.
        """
        try:
            path, base, signature = py_sig_re.match(name).groups()
        except:
            raise ValueError(
                "Invalid class or module '%s' specified for inheritance diagram" % name)
        fullname = (path or '') + base
        path = path and path.rstrip('.')
        if not path:
            raise ValueError(
                "Invalid class or module '%s' specified for inheritance diagram" % name)
        try:
            module = __import__(path, None, None, [])
        except ImportError:
            raise ValueError(
                "Could not import class or module '%s' specified for inheritance diagram" % name)

        try:
            todoc = module
            for comp in fullname.split('.')[1:]:
                todoc = getattr(todoc, comp)
        except AttributeError:
            raise ValueError(
                "Could not find class or module '%s' specified for inheritance diagram" % name)

        # If a class, just return it
        if inspect.isclass(todoc):
            return [todoc]
        elif inspect.ismodule(todoc):
            classes = []
            for cls in todoc.__dict__.values():
                if inspect.isclass(cls) and cls.__module__ == todoc.__name__:
                    classes.append(cls)
            return classes
        raise ValueError(
            "'%s' does not resolve to a class or module" % name)
Beispiel #5
0
def generate_rst(what,
                 name,
                 members,
                 options,
                 add_content,
                 document,
                 lineno,
                 indent=u'',
                 filename_set=None,
                 check_module=False):
    env = document.settings.env

    result = None

    # first, parse the definition -- auto directives for classes and functions
    # can contain a signature which is then used instead of an autogenerated one
    try:
        path, base, signature, retann = py_sig_re.match(name).groups()
    except:
        warning = document.reporter.warning(
            'invalid signature for auto%s (%r)' % (what, name), line=lineno)
        return [warning], result
    # fullname is the fully qualified name, base the name after the last dot
    fullname = (path or '') + base
    # path is the name up to the last dot
    path = path and path.rstrip('.')

    warnings = []

    # determine what module to import -- mod is the module name, objpath the
    # path of names to get via getattr
    mod = None
    if what == 'module':
        mod = fullname
        if signature:
            warnings.append(
                document.reporter.warning(
                    'ignoring arguments for automodule %s' % mod, line=lineno))
        objpath = []
    elif what in ('class', 'exception', 'function'):
        if path:
            mod = path
        else:
            # if documenting a toplevel object without explicit module, it can
            # be contained in another auto directive ...
            if hasattr(env, 'autodoc_current_module'):
                mod = env.autodoc_current_module
            # ... or in the scope of a module directive
            if not mod:
                mod = env.currmodule
        objpath = [base]
    else:
        if path:
            mod_cls = path
        else:
            # if documenting a class-level object without path, there must be a
            # current class, either from a parent auto directive ...
            if hasattr(env, 'autodoc_current_class'):
                mod_cls = env.autodoc_current_class
            # ... or from a class directive
            if not mod_cls:
                mod_cls = env.currclass
        mod, cls = rpartition(mod_cls, '.')
        # if the module name is still missing, get it like above
        if not mod and hasattr(env, 'autodoc_current_module'):
            mod = env.autodoc_current_module
        if not mod:
            mod = env.currmodule
        objpath = [cls, base]

    # by this time, a module *must* be determined
    if mod is None:
        warnings.append(
            document.reporter.warning(
                'don\'t know which module to import for autodocumenting %r '
                '(try placing a "module" or "currentmodule" directive in the document, '
                'or giving an explicit module name)' % fullname,
                line=lineno))
        return warnings, result

    # the name to put into the generated directive -- doesn't contain the module
    name_in_directive = '.'.join(objpath) or mod

    # now, import the module and get docstring(s) of object to document
    try:
        todoc = module = __import__(mod, None, None, ['foo'])
        if hasattr(module, '__file__') and module.__file__:
            modfile = module.__file__
            if modfile[-4:].lower() in ('.pyc', '.pyo'):
                modfile = modfile[:-1]
            if filename_set is not None:
                filename_set.add(modfile)
        else:
            modfile = None  # e.g. for builtin and C modules
        for part in objpath:
            todoc = getattr(todoc, part)
    except (ImportError, AttributeError):
        warnings.append(
            document.reporter.warning(
                'autodoc can\'t import/find %s %r, check your spelling '
                'and sys.path' % (what, str(fullname)),
                line=lineno))
        return warnings, result

    # check __module__ of object if wanted (for members not given explicitly)
    if check_module:
        if hasattr(todoc, '__module__'):
            if todoc.__module__ != mod:
                return warnings, result

    # format the object's signature, if any
    if signature is not None:
        # signature given explicitly -- the parentheses were stripped by the regex
        args = '(%s)' % signature
        if retann:
            args += retann
    else:
        try:
            args = format_signature(what, todoc)
        except Exception, err:
            warnings.append(
                document.reporter.warning(
                    'error while formatting signature for %s: %s' %
                    (fullname, err),
                    line=lineno))
            args = ''
Beispiel #6
0
def generate_rst(what, name, members, options, add_content, document, lineno,
                 indent=u'', filename_set=None, check_module=False):
    env = document.settings.env

    result = None

    # first, parse the definition -- auto directives for classes and functions
    # can contain a signature which is then used instead of an autogenerated one
    try:
        path, base, signature, retann = py_sig_re.match(name).groups()
    except:
        warning = document.reporter.warning(
            'invalid signature for auto%s (%r)' % (what, name), line=lineno)
        return [warning], result
    # fullname is the fully qualified name, base the name after the last dot
    fullname = (path or '') + base
    # path is the name up to the last dot
    path = path and path.rstrip('.')

    warnings = []

    # determine what module to import -- mod is the module name, objpath the
    # path of names to get via getattr
    mod = None
    if what == 'module':
        mod = fullname
        if signature:
            warnings.append(document.reporter.warning(
                'ignoring arguments for automodule %s' % mod, line=lineno))
        objpath = []
    elif what in ('class', 'exception', 'function'):
        if path:
            mod = path
        else:
            # if documenting a toplevel object without explicit module, it can
            # be contained in another auto directive ...
            if hasattr(env, 'autodoc_current_module'):
                mod = env.autodoc_current_module
            # ... or in the scope of a module directive
            if not mod:
                mod = env.currmodule
        objpath = [base]
    else:
        if path:
            mod_cls = path
        else:
            # if documenting a class-level object without path, there must be a
            # current class, either from a parent auto directive ...
            if hasattr(env, 'autodoc_current_class'):
                mod_cls = env.autodoc_current_class
            # ... or from a class directive
            if not mod_cls:
                mod_cls = env.currclass
        mod, cls = rpartition(mod_cls, '.')
        # if the module name is still missing, get it like above
        if not mod and hasattr(env, 'autodoc_current_module'):
            mod = env.autodoc_current_module
        if not mod:
            mod = env.currmodule
        objpath = [cls, base]

    # by this time, a module *must* be determined
    if mod is None:
        warnings.append(document.reporter.warning(
            'don\'t know which module to import for autodocumenting %r '
            '(try placing a "module" or "currentmodule" directive in the document, '
            'or giving an explicit module name)' % fullname, line=lineno))
        return warnings, result

    # the name to put into the generated directive -- doesn't contain the module
    name_in_directive = '.'.join(objpath) or mod

    # now, import the module and get docstring(s) of object to document
    try:
        todoc = module = __import__(mod, None, None, ['foo'])
        if hasattr(module, '__file__') and module.__file__:
            modfile = module.__file__
            if modfile[-4:].lower() in ('.pyc', '.pyo'):
                modfile = modfile[:-1]
            if filename_set is not None:
                filename_set.add(modfile)
        else:
            modfile = None  # e.g. for builtin and C modules
        for part in objpath:
            todoc = getattr(todoc, part)
    except (ImportError, AttributeError):
        warnings.append(document.reporter.warning(
            'autodoc can\'t import/find %s %r, check your spelling '
            'and sys.path' % (what, str(fullname)), line=lineno))
        return warnings, result

    # check __module__ of object if wanted (for members not given explicitly)
    if check_module:
        if hasattr(todoc, '__module__'):
            if todoc.__module__ != mod:
                return warnings, result

    # format the object's signature, if any
    if signature is not None:
        # signature given explicitly -- the parentheses were stripped by the regex
        args = '(%s)' % signature
        if retann:
            args += retann
    else:
        try:
            args = format_signature(what, todoc)
        except Exception, err:
            warnings.append(document.reporter.warning(
                'error while formatting signature for %s: %s' %
                (fullname, err), line=lineno))
            args = ''