コード例 #1
0
def get_file(obj):
    if hasattr(obj, "__file__"):
        return obj.__file__
    if hasattr(obj, "__module__") and obj.__module__ is not None:
        _, module, _, _ = import_by_name(obj.__module__)
        return get_file(module)
    return None
コード例 #2
0
ファイル: test_ext_autosummary.py プロジェクト: LFYG/sphinx
def test_import_by_name():
    import sphinx
    import sphinx.ext.autosummary

    prefixed_name, obj, parent, modname = import_by_name('sphinx')
    assert prefixed_name == 'sphinx'
    assert obj is sphinx
    assert parent is None
    assert modname == 'sphinx'

    prefixed_name, obj, parent, modname = import_by_name('sphinx.ext.autosummary.__name__')
    assert prefixed_name == 'sphinx.ext.autosummary.__name__'
    assert obj is sphinx.ext.autosummary.__name__
    assert parent is sphinx.ext.autosummary
    assert modname == 'sphinx.ext.autosummary'

    prefixed_name, obj, parent, modname = import_by_name('sphinx.ext.autosummary.Autosummary.get_items')
    assert prefixed_name == 'sphinx.ext.autosummary.Autosummary.get_items'
    assert obj == sphinx.ext.autosummary.Autosummary.get_items
    assert parent is sphinx.ext.autosummary.Autosummary
    assert modname == 'sphinx.ext.autosummary'
コード例 #3
0
ファイル: apisummary.py プロジェクト: deti/boss
def autolink_role(typ, rawtext, etext, lineno, inliner,
                  options=None, content=None):
    """Smart linking role.

    Expands to ':obj:`text`' if `text` is an object that can be imported;
    otherwise expands to '*text*'.
    """
    options = options or {}
    content = content or []
    env = inliner.document.settings.env
    r = env.get_domain('py').role('obj')(
        'obj', rawtext, etext, lineno, inliner, options, content)
    pnode = r[0][0]

    prefixes = get_import_prefixes_from_env(env)
    try:
        import_by_name(pnode['reftarget'], prefixes)
    except ImportError:
        content = pnode[0]
        r[0][0] = nodes.emphasis(rawtext, content[0].astext(),
                                 classes=content['classes'])
    return r
コード例 #4
0
ファイル: conf.py プロジェクト: moyogo/fontparts
 def get_items(self, names):
     """
     Subclass get items
     to get support for all methods in an given object
     """
     env = self.state.document.settings.env
     prefixes = get_import_prefixes_from_env(env)
     methodNames = []
     for name in names:
         methodNames.append(name)
         _, obj, _, _ = import_by_name(name, prefixes=prefixes)
         methodNames.extend(["%s.%s" % (name, method) for method in dir(obj) if not method.startswith("_")])
     return super(AutosummaryMethodList, self).get_items(methodNames)
コード例 #5
0
ファイル: generate.py プロジェクト: SurfasJones/icecream-info
def find_autosummary_in_docstring(name, module=None, filename=None):
    """Find out what items are documented in the given object's docstring.

    See `find_autosummary_in_lines`.
    """
    try:
        real_name, obj, parent = import_by_name(name)
        lines = pydoc.getdoc(obj).splitlines()
        return find_autosummary_in_lines(lines, module=name, filename=filename)
    except AttributeError:
        pass
    except ImportError, e:
        print "Failed to import '%s': %s" % (name, e)
コード例 #6
0
    def get_items(self, names):
        env = self.state.document.settings.env
        prefixes = get_import_prefixes_from_env(env)

        items = []
        prefix = ''
        shorten = ''

        def _get_items(name):
            _items = super(AutoMemberSummary, self).get_items([shorten + name])
            if self.result.data and ".. deprecated::" in self.result.data[0]:
                # don't show deprecated classes / functions in summary
                return
            for dn, sig, summary, rn in _items:
                if ".. deprecated::" in summary:
                    # don't show deprecated methods in summary
                    continue
                items.append(('%s%s' % (prefix, dn), sig, summary, rn))

        for name in names:
            if '~' in name:
                prefix, name = name.split('~')
                shorten = '~'
            else:
                prefix = ''
                shorten = ''

            try:
                real_name, obj, parent, _ = import_by_name(name, prefixes=prefixes)
            except ImportError:
                self.warn('failed to import %s' % name)
                continue

            if not inspect.ismodule(obj):
                _get_items(name)
                continue

            for member in dir(obj):
                if member.startswith('_'):
                    continue
                mobj = getattr(obj, member)
                if hasattr(mobj, '__module__'):
                    if not mobj.__module__.startswith(real_name):
                        continue  # skip imported classes & functions
                elif hasattr(mobj, '__name__'):
                    continue  # skip imported modules
                else:
                    continue  # skip instances
                _get_items('%s.%s' % (mobj.__module__, member))

        return items
コード例 #7
0
ファイル: gendoc.py プロジェクト: AWhetter/jinjaapidoc
def import_name(app, name):
    """Import the given name and return name, obj, parent, mod_name

    :param name: name to import
    :type name: str
    :returns: the imported object or None
    :rtype: object | None
    :raises: None
    """
    try:
        app.debug2('Importing %r', name)
        name, obj = autosummary.import_by_name(name)[:2]
        app.debug2('Imported %s', obj)
        return obj
    except ImportError as e:
        app.warn("Jinjapidoc failed to import %r: %s", name, e)
コード例 #8
0
ファイル: generate.py プロジェクト: goujou/sphinx-repaired
def find_autosummary_in_docstring(name, module=None, filename=None):
    """Find out what items are documented in the given object's docstring.

    See `find_autosummary_in_lines`.
    """
    try:
        real_name, obj, parent, modname = import_by_name(name)
        lines = pydoc.getdoc(obj).splitlines()
        return find_autosummary_in_lines(lines, module=name, filename=filename)
    except AttributeError:
        pass
    except ImportError as e:
        print("Failed to import '%s': %s" % (name, e))
    except SystemExit as e:
        print("Failed to import '%s'; the module executes module level "
              "statement and it might call sys.exit()." % name)
    return []
コード例 #9
0
ファイル: autoautosummary.py プロジェクト: Syfaro/weasyl
 def find_automembers(self):
     env = self.state.document.settings.env
     prefixes = get_import_prefixes_from_env(env)
     objects = [import_by_name(p) for p in prefixes if p is not None]
     new_names = []
     for name, obj, _, _ in objects:
         for attr, child in inspect.getmembers(obj):
             if getattr(child, '__module__', None) != name:
                 continue
             if inspect.isfunction(child):
                 new_names.append(attr)
             elif inspect.isclass(child):
                 for childattr, grandchild in inspect.getmembers(child, inspect.isfunction):
                     if grandchild.__module__ != name:
                         continue
                     new_names.append('%s.%s' % (attr, childattr))
     new_names.sort(key=lambda s: s.lower())
     return new_names
コード例 #10
0
ファイル: check_api_doc.py プロジェクト: liam2/larray
def get_autosummary_api():
    import shutil
    from sphinx.ext.autosummary import import_by_name
    from sphinx.ext.autosummary.generate import DummyApplication, setup_documenters, generate_autosummary_docs

    sources = ['api.rst']
    output_dir = './tmp_generated'
    app = DummyApplication()
    setup_documenters(app)
    generate_autosummary_docs(sources, output_dir, app=app)

    autosummary_api = {}
    for module_name in _modules:
        try:
            module = importlib.import_module(module_name)
            module_item = ModuleItem(module)
            autosummary_api[module_name] = module_item
        except ImportError as err:
            print('module {} could not be imported: {}'.format(module_name, err))
            autosummary_api[module_name] = err

    for generated_rst_file in os.listdir(output_dir):
        qualname, ext = os.path.splitext(generated_rst_file)
        qualname, obj, parent, module_name = import_by_name(qualname)
        module_item = autosummary_api[module_name]
        name = qualname.split('.')[-1]
        if inspect.isclass(obj) and name in module_item.classes:
            continue
        if inspect.isclass(parent):
            class_name = parent.__name__
            if class_name not in module_item.classes:
                module_item.insert_element(class_name, parent)
            class_item = module_item.classes[class_name]
            class_item.insert_element(name, obj)
        else:
            module_item.insert_element(name, obj)

    if os.path.exists(output_dir):
        shutil.rmtree(output_dir)

    return autosummary_api
コード例 #11
0
def format_directive(module, package=None):
    """Create the automodule directive and add the options."""
    _, obj, _, _ = import_by_name(makename(package, module))
    functions = get_public_members(obj, 'function')
    classes = get_public_members(obj, 'class')
    exceptions = get_public_members(obj, 'exception')

    if len(functions) == 0 and len(classes) == 0 and len(exceptions) == 0:
        return None

    directive = '.. automodule:: %s\n\n' % makename(package, module)

    directive += '.. currentmodule:: %s\n\n' % makename(package, module)

    directive += get_summary(functions, "Functions", "")

    directive += get_summary(exceptions, "Exceptions", "", min_items=1)

    directive += get_summary(classes, "Classes", "", min_items=1)

    for function in functions:
        directive += '.. autofunction:: %s\n' % function

    for exception in exceptions:
        directive += '.. autoexception:: %s\n' % exception

    for cls in classes:
        directive += '.. autoclass:: %s\n' % cls
        directive += '    :show-inheritance:\n\n'

        _, cls_obj, _, _ = import_by_name(makename(package,
                                                   "%s.%s" % (module, cls)))
        attributes = get_public_members(cls_obj, 'attribute')
        methods = get_public_members(cls_obj, 'method')
        subclasses = get_public_members(cls_obj, 'class')
        attributes.extend(get_private_superclass_public_members(cls_obj,
                                                                'attribute'))
        methods.extend(get_private_superclass_public_members(cls_obj,
                                                             'method'))

        abstract_attrs, real_attrs = split_into_abstract_and_non_abstract(
                cls_obj, attributes, "__isabstractattribute__")
        abstract_methods, real_methods = split_into_abstract_and_non_abstract(
                cls_obj, methods, "__isabstractmethod__")

        directive += get_summary(abstract_attrs, "Abstract Attributes", "    ")

        directive += get_summary(real_attrs, "Attributes", "    ")

        directive += get_summary(abstract_methods, "Abstract Methods", "    ")

        directive += get_summary(real_methods, "Methods", "    ")

        if len(subclasses) > 0:
            directive += '    .. rubric:: Detailed Types\n\n'
            for subcls in subclasses:
                directive += '    .. autoattribute:: %s\n' % subcls

        if len(methods) > 0:
            directive += '    .. rubric:: Detailed Methods\n\n'
            for method in methods:
                directive += '    .. automethod:: %s\n' % method
            directive += '\n'

    return directive
コード例 #12
0
def generate_autosummary_docs(sources: List[str], output_dir: str = None,
                              suffix: str = '.rst', base_path: str = None,
                              builder: Builder = None, template_dir: str = None,
                              imported_members: bool = False, app: Any = None,
                              overwrite: bool = True) -> None:
    if builder:
        warnings.warn('builder argument for generate_autosummary_docs() is deprecated.',
                      RemovedInSphinx50Warning)

    if template_dir:
        warnings.warn('template_dir argument for generate_autosummary_docs() is deprecated.',
                      RemovedInSphinx50Warning)

    showed_sources = list(sorted(sources))
    if len(showed_sources) > 20:
        showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:]
    logger.info(__('[autosummary] generating autosummary for: %s') %
                ', '.join(showed_sources))

    if output_dir:
        logger.info(__('[autosummary] writing to %s') % output_dir)

    if base_path is not None:
        sources = [os.path.join(base_path, filename) for filename in sources]

    template = AutosummaryRenderer(app)

    # read
    items = find_autosummary_in_files(sources)

    # keep track of new files
    new_files = []

    # write
    for entry in sorted(set(items), key=str):
        if entry.path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = output_dir or os.path.abspath(entry.path)
        ensuredir(path)

        try:
            name, obj, parent, mod_name = import_by_name(entry.name)
        except ImportError as e:
            logger.warning(__('[autosummary] failed to import %r: %s') % (entry.name, e))
            continue

        context = {}
        if app:
            context.update(app.config.autosummary_context)

        content = generate_autosummary_content(name, obj, parent, template, entry.template,
                                               imported_members, app, entry.recursive, context)

        filename = os.path.join(path, name + suffix)
        if os.path.isfile(filename):
            with open(filename) as f:
                old_content = f.read()

            if content == old_content:
                continue
            elif overwrite:  # content has changed
                with open(filename, 'w') as f:
                    f.write(content)
                new_files.append(filename)
        else:
            with open(filename, 'w') as f:
                f.write(content)
            new_files.append(filename)

    # descend recursively to new files
    if new_files:
        generate_autosummary_docs(new_files, output_dir=output_dir,
                                  suffix=suffix, base_path=base_path,
                                  builder=builder, template_dir=template_dir,
                                  imported_members=imported_members, app=app,
                                  overwrite=overwrite)
コード例 #13
0
ファイル: generate.py プロジェクト: zhengphou/sphinx
def generate_autosummary_docs(sources,
                              output_dir=None,
                              suffix='.rst',
                              warn=None,
                              info=None,
                              base_path=None,
                              builder=None,
                              template_dir=None,
                              imported_members=False,
                              app=None):
    # type: (List[str], str, str, Callable, Callable, str, Builder, str, bool, Any) -> None
    if info:
        warnings.warn(
            'info argument for generate_autosummary_docs() is deprecated.',
            RemovedInSphinx40Warning)
        _info = info
    else:
        _info = logger.info

    if warn:
        warnings.warn(
            'warn argument for generate_autosummary_docs() is deprecated.',
            RemovedInSphinx40Warning)
        _warn = warn
    else:
        _warn = logger.warning

    showed_sources = list(sorted(sources))
    if len(showed_sources) > 20:
        showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:]
    _info(
        __('[autosummary] generating autosummary for: %s') %
        ', '.join(showed_sources))

    if output_dir:
        _info(__('[autosummary] writing to %s') % output_dir)

    if base_path is not None:
        sources = [os.path.join(base_path, filename) for filename in sources]

    template = AutosummaryRenderer(builder, template_dir)

    # read
    items = find_autosummary_in_files(sources)

    # keep track of new files
    new_files = []

    # write
    for name, path, template_name in sorted(set(items), key=str):
        if path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = output_dir or os.path.abspath(path)
        ensuredir(path)

        try:
            name, obj, parent, mod_name = import_by_name(name)
        except ImportError as e:
            _warn('[autosummary] failed to import %r: %s' % (name, e))
            continue

        fn = os.path.join(path, name + suffix)

        # skip it if it exists
        if os.path.isfile(fn):
            continue

        new_files.append(fn)

        with open(fn, 'w') as f:
            rendered = generate_autosummary_content(name, obj, parent,
                                                    template, template_name,
                                                    imported_members, app)
            f.write(rendered)

    # descend recursively to new files
    if new_files:
        generate_autosummary_docs(new_files,
                                  output_dir=output_dir,
                                  suffix=suffix,
                                  warn=warn,
                                  info=info,
                                  base_path=base_path,
                                  builder=builder,
                                  template_dir=template_dir,
                                  app=app)
コード例 #14
0
    def get_items(self,
                  names: List[str]) -> List[Tuple[str, str, str, str, str]]:
        """Try to import the given names, and return a list of
        ``[(name, signature, summary_string, real_name, env_summary), ...]``.
        """
        prefixes = get_import_prefixes_from_env(self.env)
        items = []  # type: List[Tuple[str, str, str, str, str]]
        max_item_chars = 50

        for name in names:
            display_name = name
            if name.startswith('~'):
                name = name[1:]
                display_name = name.split('.')[-1]
            try:
                with mock(self.config.autosummary_mock_imports):
                    real_name, obj, parent, modname = import_by_name(
                        name, prefixes=prefixes)
            except ImportError:
                logger.warning(__('failed to import %s'), name)
                items.append((name, '', '', name, ''))
                continue

            self.bridge.result = StringList()  # initialize for each documenter
            full_name = real_name
            if not isinstance(obj, ModuleType):
                # give explicitly separated module name, so that members
                # of inner classes can be documented
                full_name = modname + '::' + full_name[len(modname) + 1:]
            # NB. using full_name here is important, since Documenters
            #     handle module prefixes slightly differently
            doccls = get_documenter(self.env.app, obj, parent)
            documenter = doccls(self.bridge, full_name)

            if not documenter.parse_name():
                logger.warning(__('failed to parse name %s'), real_name)
                items.append((display_name, '', '', real_name, ''))
                continue
            if not documenter.import_object():
                logger.warning(__('failed to import object %s'), real_name)
                items.append((display_name, '', '', real_name, ''))
                continue
            if documenter.options.members and not documenter.check_module():
                continue

            # try to also get a source code analyzer for attribute docs
            try:
                documenter.analyzer = ModuleAnalyzer.for_module(
                    documenter.get_real_modname())
                # parse right now, to get PycodeErrors on parsing (results will
                # be cached anyway)
                documenter.analyzer.find_attr_docs()
            except PycodeError as err:
                logger.debug('[autodoc] module analyzer failed: %s', err)
                # no source file -- e.g. for builtin and C modules
                documenter.analyzer = None

            # -- Grab the signature

            try:
                sig = documenter.format_signature(show_annotation=False)
            except TypeError:
                # the documenter does not support ``show_annotation`` option
                sig = documenter.format_signature()

            if not sig:
                sig = ''
            else:
                max_chars = max(10, max_item_chars - len(display_name))
                sig = mangle_signature(sig, max_chars=max_chars)

            # -- Grab the summary

            documenter.add_content(None)
            summary = extract_summary(self.bridge.result.data[:],
                                      self.state.document)
            env_sum = self.extract_env_summary(self.bridge.result.data[:])
            items.append((display_name, sig, summary, real_name, env_sum))

        return items
コード例 #15
0
ファイル: hacks.py プロジェクト: franzinc/agraph-python
 def process_obj(name, typ, include_public=None):
     obj_name = name[name.index(':') + 1:]
     full_name, obj, _, _ = import_by_name(obj_name, prefixes=prefixes)
     members, _ = self.get_members(env.app, obj, typ, include_public)
     ext_names.extend(['~%s.%s' % (full_name, member) for member in members])
コード例 #16
0
    def get_items(self, names):
        """Try to import the given names, and return a list of
        ``[(name, signature, summary_string, real_name), ...]``.
        """
        from sphinx.ext.autosummary import (get_import_prefixes_from_env,
            import_by_name, get_documenter, mangle_signature)

        env = self.state.document.settings.env

        prefixes = get_import_prefixes_from_env(env)

        items = []

        max_item_chars = 50

        for name in names:
            display_name = name
            if name.startswith('~'):
                name = name[1:]
                display_name = name.split('.')[-1]

            try:
                import_by_name_values = import_by_name(name, prefixes=prefixes)
            except ImportError:
                self.warn('[astropyautosummary] failed to import %s' % name)
                items.append((name, '', '', name))
                continue

            # to accommodate Sphinx v1.2.2 and v1.2.3
            if len(import_by_name_values) == 3:
                real_name, obj, parent = import_by_name_values
            elif len(import_by_name_values) == 4:
                real_name, obj, parent, module_name = import_by_name_values

            # NB. using real_name here is important, since Documenters
            #     handle module prefixes slightly differently
            documenter = get_documenter(obj, parent)(self, real_name)
            if not documenter.parse_name():
                self.warn('[astropyautosummary] failed to parse name %s' % real_name)
                items.append((display_name, '', '', real_name))
                continue
            if not documenter.import_object():
                self.warn('[astropyautosummary] failed to import object %s' % real_name)
                items.append((display_name, '', '', real_name))
                continue

            # -- Grab the signature

            sig = documenter.format_signature()
            if not sig:
                sig = ''
            else:
                max_chars = max(10, max_item_chars - len(display_name))
                sig = mangle_signature(sig, max_chars=max_chars)
                sig = sig.replace('*', r'\*')

            # -- Grab the summary

            doc = list(documenter.process_doc(documenter.get_doc()))

            while doc and not doc[0].strip():
                doc.pop(0)
            m = _itemsummrex.search(" ".join(doc).strip())
            if m:
                summary = m.group(1).strip()
            elif doc:
                summary = doc[0].strip()
            else:
                summary = ''

            items.append((display_name, sig, summary, real_name))

        return items
コード例 #17
0
def generate_autosummary_docs(sources,
                              output_dir=None,
                              suffix='.rst',
                              warn=_simple_warn,
                              info=_simple_info,
                              base_path=None,
                              builder=None,
                              template_dir=None,
                              app=None):
    showed_sources = list(sorted(sources))
    if len(showed_sources) > 20:
        showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:]
    info('[autosummary] generating autosummary for: %s' %
         ', '.join(showed_sources))

    if output_dir:
        info('[autosummary] writing to %s' % output_dir)

    if base_path is not None:
        sources = [osp.join(base_path, filename) for filename in sources]

    # create our own templating environment
    template_dirs = [osp.join(package_dir, 'ext', 'autosummary', 'templates')]
    if builder is not None:
        # allow the user to override the templates
        template_loader = BuiltinTemplateLoader()
        template_loader.init(builder, dirs=template_dirs)
    else:
        if template_dir:
            template_dirs.insert(0, template_dir)
        template_loader = FileSystemLoader(template_dirs)
    template_env = SandboxedEnvironment(loader=template_loader)

    # read
    items = find_autosummary_in_files(sources)

    # remove possible duplicates
    items = list(dict([(item, True) for item in items]).keys())

    # keep track of new files
    new_files = []

    # write
    # noinspection PyTypeChecker
    for name, path, template_name in sorted(items, key=str):
        if path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = output_dir or osp.abspath(path)
        ensuredir(path)

        try:
            name, obj, parent, mod_name = import_by_name(name)
        except ImportError as e:
            warn('[autosummary] failed to import %r: %s' % (name, e))
            continue

        fn = osp.join(path, name + suffix)

        # skip it if it exists
        if osp.isfile(fn):
            continue

        new_files.append(fn)

        f = open(fn, 'w')

        try:
            try:
                doc = get_documenter(app, obj, parent)
            except TypeError:
                doc = get_documenter(obj, parent)

            if template_name is not None:
                template = template_env.get_template(template_name)
            else:
                try:
                    template = template_env.get_template('autosummary/%s.rst' %
                                                         doc.objtype)
                except TemplateNotFound:
                    template = template_env.get_template(
                        'autosummary/base.rst')

            ns = {}

            if doc.objtype == 'module':
                ns['members'] = dir(obj)
                ns['functions'], ns['all_functions'] = \
                    get_members(app, obj, 'function')
                ns['classes'], ns['all_classes'] = \
                    get_members(app, obj, 'class')
                ns['exceptions'], ns['all_exceptions'] = \
                    get_members(app, obj, 'exception')
                ns['data'], ns['all_data'] = \
                    get_members(app, obj, 'data', imported=True)

                ns['data'] = ', '.join(ns['data'])
                ns['all_data'] = ', '.join(ns['all_data'])

                ns['dispatchers'], ns['all_dispatchers'] = \
                    get_members(app, obj, 'dispatcher', imported=True)
            elif doc.objtype == 'class':
                ns['members'] = dir(obj)
                ns['methods'], ns['all_methods'] = \
                    get_members(app, obj, 'method', ['__init__'], True)
                ns['attributes'], ns['all_attributes'] = \
                    get_members(app, obj, 'attribute')

            parts = name.split('.')
            if doc.objtype in ('method', 'attribute'):
                mod_name = '.'.join(parts[:-2])
                cls_name = parts[-2]
                obj_name = '.'.join(parts[-2:])
                ns['class'] = cls_name
            else:
                mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]

            ns['fullname'] = name
            ns['module'] = mod_name
            ns['objname'] = obj_name
            ns['name'] = parts[-1]

            ns['objtype'] = doc.objtype
            ns['underline'] = len(name) * '='

            rendered = template.render(**ns)
            f.write(rendered)
        finally:
            f.close()

    # descend recursively to new files
    if new_files:
        generate_autosummary_docs(new_files,
                                  output_dir=output_dir,
                                  suffix=suffix,
                                  warn=warn,
                                  info=info,
                                  base_path=base_path,
                                  builder=builder,
                                  template_dir=template_dir,
                                  app=app)
コード例 #18
0
ファイル: apisummary.py プロジェクト: omarabdalhamid/boss
    def get_items(self, modules):
        """Try to import the given names, and return a list of
        ``[(name, signature, summary_string, real_name), ...]``.
        """
        env = self.state.document.settings.env

        prefixes = get_import_prefixes_from_env(env)

        items = {}

        max_item_chars = 80
        callbacks_already_met = set()

        for name in modules:
            try:
                real_name, obj, parent, modename = import_by_name(name, prefixes=prefixes)
            except ImportError:
                self.warn("import name failed: %s" % name)
                continue
            try:
                routes = obj().routes
            except Exception:
                continue

            for r in routes:
                callback = r.callback
                if not hasattr(callback, "_mapped_to") or callback in callbacks_already_met:
                    continue
                callbacks_already_met.add(callback)

                rule = r.rule
                method = r.method
                clas = callback.__self__.__class__.__name__
                display_name = "%s %s" % (method, rule)
                documenter = get_documenter(callback, parent)(self, display_name)
                documenter.object = callback

                # -- Grab the signature
                sig = documenter.format_signature()
                if not sig:
                    sig = ''
                else:
                    max_chars = max(10, max_item_chars - len(display_name))
                    sig = mangle_signature(sig, max_chars=max_chars)

                # -- Grab the summary

                doc = list(documenter.process_doc(documenter.get_doc()))

                while doc and not doc[0].strip():
                    doc.pop(0)
                m = re.search(r"^([A-Z][^A-Z]*?\.\s)", " ".join(doc).strip())
                if m:
                    summary = m.group(1).strip()
                elif doc:
                    summary = doc[0].strip()
                else:
                    summary = ''

                items.setdefault(clas, []).append((escape_rst(display_name), escape_rst(sig),
                                                   summary, display_name))

        return items
コード例 #19
0
ファイル: automodsumm.py プロジェクト: bnaul/gatspy
def generate_automodsumm_docs(lines, srcfn, suffix='.rst', warn=None,
                              info=None, base_path=None, builder=None,
                              template_dir=None):
    """
    This function is adapted from
    `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to
    generate source for the automodsumm directives that should be
    autosummarized. Unlike generate_autosummary_docs, this function is
    called one file at a time.
    """

    from sphinx.jinja2glue import BuiltinTemplateLoader
    from sphinx.ext.autosummary import import_by_name, get_documenter
    from sphinx.ext.autosummary.generate import (find_autosummary_in_lines,
                                                 _simple_info, _simple_warn)
    from sphinx.util.osutil import ensuredir
    from sphinx.util.inspect import safe_getattr
    from jinja2 import FileSystemLoader, TemplateNotFound
    from jinja2.sandbox import SandboxedEnvironment

    if info is None:
        info = _simple_info
    if warn is None:
        warn = _simple_warn

    #info('[automodsumm] generating automodsumm for: ' + srcfn)

    # Create our own templating environment - here we use Astropy's
    # templates rather than the default autosummary templates, in order to
    # allow docstrings to be shown for methods.
    template_dirs = [os.path.join(os.path.dirname(__file__), 'templates'),
                     os.path.join(base_path, '_templates')]
    if builder is not None:
        # allow the user to override the templates
        template_loader = BuiltinTemplateLoader()
        template_loader.init(builder, dirs=template_dirs)
    else:
        if template_dir:
            template_dirs.insert(0, template_dir)
        template_loader = FileSystemLoader(template_dirs)
    template_env = SandboxedEnvironment(loader=template_loader)

    # read
    #items = find_autosummary_in_files(sources)
    items = find_autosummary_in_lines(lines, filename=srcfn)
    if len(items) > 0:
        msg = '[automodsumm] {1}: found {0} automodsumm entries to generate'
        info(msg.format(len(items), srcfn))

#    gennms = [item[0] for item in items]
#    if len(gennms) > 20:
#        gennms = gennms[:10] + ['...'] + gennms[-10:]
#    info('[automodsumm] generating autosummary for: ' + ', '.join(gennms))

    # remove possible duplicates
    items = dict([(item, True) for item in items]).keys()

    # keep track of new files
    new_files = []

    # write
    for name, path, template_name in sorted(items):
        if path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = os.path.abspath(path)
        ensuredir(path)

        try:
            import_by_name_values = import_by_name(name)
        except ImportError as e:
            warn('[automodsumm] failed to import %r: %s' % (name, e))
            continue

        # if block to accommodate Sphinx's v1.2.2 and v1.2.3 respectively
        if len(import_by_name_values) == 3:
            name, obj, parent = import_by_name_values
        elif len(import_by_name_values) == 4:
            name, obj, parent, module_name = import_by_name_values

        fn = os.path.join(path, name + suffix)

        # skip it if it exists
        if os.path.isfile(fn):
            continue

        new_files.append(fn)

        f = open(fn, 'w')

        try:
            doc = get_documenter(obj, parent)

            if template_name is not None:
                template = template_env.get_template(template_name)
            else:
                tmplstr = 'autosummary/%s.rst'
                try:
                    template = template_env.get_template(tmplstr % doc.objtype)
                except TemplateNotFound:
                    template = template_env.get_template(tmplstr % 'base')

            def get_members_mod(obj, typ, include_public=[]):
                """
                typ = None -> all
                """
                items = []
                for name in dir(obj):
                    try:
                        documenter = get_documenter(safe_getattr(obj, name),
                                                    obj)
                    except AttributeError:
                        continue
                    if typ is None or documenter.objtype == typ:
                        items.append(name)
                public = [x for x in items
                          if x in include_public or not x.startswith('_')]
                return public, items

            def get_members_class(obj, typ, include_public=[],
                                  include_base=False):
                """
                typ = None -> all
                include_base -> include attrs that are from a base class
                """
                items = []

                # using dir gets all of the attributes, including the elements
                # from the base class, otherwise use __slots__ or __dict__
                if include_base:
                    names = dir(obj)
                else:
                    if hasattr(obj, '__slots__'):
                        names = tuple(getattr(obj, '__slots__'))
                    else:
                        names = getattr(obj, '__dict__').keys()

                for name in names:
                    try:
                        documenter = get_documenter(safe_getattr(obj, name),
                                                    obj)
                    except AttributeError:
                        continue
                    if typ is None or documenter.objtype == typ:
                        items.append(name)
                public = [x for x in items
                          if x in include_public or not x.startswith('_')]
                return public, items

            ns = {}

            if doc.objtype == 'module':
                ns['members'] = get_members_mod(obj, None)
                ns['functions'], ns['all_functions'] = \
                                   get_members_mod(obj, 'function')
                ns['classes'], ns['all_classes'] = \
                                 get_members_mod(obj, 'class')
                ns['exceptions'], ns['all_exceptions'] = \
                                   get_members_mod(obj, 'exception')
            elif doc.objtype == 'class':
                api_class_methods = ['__init__', '__call__']
                ns['members'] = get_members_class(obj, None)
                ns['methods'], ns['all_methods'] = \
                                 get_members_class(obj, 'method', api_class_methods)
                ns['attributes'], ns['all_attributes'] = \
                                 get_members_class(obj, 'attribute')
                ns['methods'].sort()
                ns['attributes'].sort()

            parts = name.split('.')
            if doc.objtype in ('method', 'attribute'):
                mod_name = '.'.join(parts[:-2])
                cls_name = parts[-2]
                obj_name = '.'.join(parts[-2:])
                ns['class'] = cls_name
            else:
                mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]

            ns['fullname'] = name
            ns['module'] = mod_name
            ns['objname'] = obj_name
            ns['name'] = parts[-1]

            ns['objtype'] = doc.objtype
            ns['underline'] = len(name) * '='

            # We now check whether a file for reference footnotes exists for
            # the module being documented. We first check if the
            # current module is a file or a directory, as this will give a
            # different path for the reference file. For example, if
            # documenting astropy.wcs then the reference file is at
            # ../wcs/references.txt, while if we are documenting
            # astropy.config.logging_helper (which is at
            # astropy/config/logging_helper.py) then the reference file is set
            # to ../config/references.txt
            if '.' in mod_name:
                mod_name_dir = mod_name.replace('.', '/').split('/', 1)[1]
            else:
                mod_name_dir = mod_name
            if not os.path.isdir(os.path.join(base_path, mod_name_dir)) \
               and os.path.isdir(os.path.join(base_path, mod_name_dir.rsplit('/', 1)[0])):
                mod_name_dir = mod_name_dir.rsplit('/', 1)[0]

            # We then have to check whether it exists, and if so, we pass it
            # to the template.
            if os.path.exists(os.path.join(base_path, mod_name_dir, 'references.txt')):
                # An important subtlety here is that the path we pass in has
                # to be relative to the file being generated, so we have to
                # figure out the right number of '..'s
                ndirsback = path.replace(base_path, '').count('/')
                ref_file_rel_segments = ['..'] * ndirsback
                ref_file_rel_segments.append(mod_name_dir)
                ref_file_rel_segments.append('references.txt')
                ns['referencefile'] = os.path.join(*ref_file_rel_segments)

            rendered = template.render(**ns)
            f.write(rendered)
        finally:
            f.close()
コード例 #20
0
def generate_autosummary_docs(sources: List[str],
                              output_dir: str = None,
                              suffix: str = '.rst',
                              warn: Callable = None,
                              info: Callable = None,
                              base_path: str = None,
                              builder: Builder = None,
                              template_dir: str = None,
                              imported_members: bool = False,
                              app: Any = None,
                              overwrite: bool = True,
                              encoding: str = 'utf-8') -> None:
    if info:
        warnings.warn(
            'info argument for generate_autosummary_docs() is deprecated.',
            RemovedInSphinx40Warning,
            stacklevel=2)
        _info = info
    else:
        _info = logger.info

    if warn:
        warnings.warn(
            'warn argument for generate_autosummary_docs() is deprecated.',
            RemovedInSphinx40Warning,
            stacklevel=2)
        _warn = warn
    else:
        _warn = logger.warning

    if builder:
        warnings.warn(
            'builder argument for generate_autosummary_docs() is deprecated.',
            RemovedInSphinx50Warning,
            stacklevel=2)

    if template_dir:
        warnings.warn(
            'template_dir argument for generate_autosummary_docs() is deprecated.',
            RemovedInSphinx50Warning,
            stacklevel=2)

    showed_sources = list(sorted(sources))
    if len(showed_sources) > 20:
        showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:]
    _info(
        __('[autosummary] generating autosummary for: %s') %
        ', '.join(showed_sources))

    if output_dir:
        _info(__('[autosummary] writing to %s') % output_dir)

    if base_path is not None:
        sources = [os.path.join(base_path, filename) for filename in sources]

    template = AutosummaryRenderer(app)

    # read
    items = find_autosummary_in_files(sources)

    # keep track of new files
    new_files = []

    if app:
        filename_map = app.config.autosummary_filename_map
    else:
        filename_map = {}

    # write
    for entry in sorted(set(items), key=str):
        if entry.path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = output_dir or os.path.abspath(entry.path)
        ensuredir(path)

        try:
            name, obj, parent, modname = import_by_name(entry.name)
            qualname = name.replace(modname + ".", "")
        except ImportError as e:
            try:
                # try to importl as an instance attribute
                name, obj, parent, modname = import_ivar_by_name(entry.name)
                qualname = name.replace(modname + ".", "")
            except ImportError:
                _warn(
                    __('[autosummary] failed to import %r: %s') %
                    (entry.name, e))
                continue

        context = {}
        if app:
            context.update(app.config.autosummary_context)

        content = generate_autosummary_content(name, obj, parent, template,
                                               entry.template,
                                               imported_members, app,
                                               entry.recursive, context,
                                               modname, qualname)

        filename = os.path.join(path, filename_map.get(name, name) + suffix)
        if os.path.isfile(filename):
            with open(filename, encoding=encoding) as f:
                old_content = f.read()

            if content == old_content:
                continue
            elif overwrite:  # content has changed
                with open(filename, 'w', encoding=encoding) as f:
                    f.write(content)
                new_files.append(filename)
        else:
            with open(filename, 'w', encoding=encoding) as f:
                f.write(content)
            new_files.append(filename)

    # descend recursively to new files
    if new_files:
        generate_autosummary_docs(new_files,
                                  output_dir=output_dir,
                                  suffix=suffix,
                                  warn=warn,
                                  info=info,
                                  base_path=base_path,
                                  imported_members=imported_members,
                                  app=app,
                                  overwrite=overwrite)
コード例 #21
0
def generate_automodsumm_docs(lines,
                              srcfn,
                              app=None,
                              suffix='.rst',
                              warn=None,
                              info=None,
                              base_path=None,
                              builder=None,
                              template_dir=None,
                              inherited_members=False):
    """
    This function is adapted from
    `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to
    generate source for the automodsumm directives that should be
    autosummarized. Unlike generate_autosummary_docs, this function is
    called one file at a time.
    """

    from sphinx.jinja2glue import BuiltinTemplateLoader
    from sphinx.ext.autosummary import import_by_name, get_documenter
    from sphinx.ext.autosummary.generate import (_simple_info, _simple_warn)
    from sphinx.util.osutil import ensuredir
    from sphinx.util.inspect import safe_getattr
    from jinja2 import FileSystemLoader, TemplateNotFound
    from jinja2.sandbox import SandboxedEnvironment

    from .utils import find_autosummary_in_lines_for_automodsumm as find_autosummary_in_lines

    if info is None:
        info = _simple_info
    if warn is None:
        warn = _simple_warn

    # info('[automodsumm] generating automodsumm for: ' + srcfn)

    # Create our own templating environment - here we use Astropy's
    # templates rather than the default autosummary templates, in order to
    # allow docstrings to be shown for methods.
    template_dirs = [
        os.path.join(os.path.dirname(__file__), 'templates'),
        os.path.join(base_path, '_templates')
    ]
    if builder is not None:
        # allow the user to override the templates
        template_loader = BuiltinTemplateLoader()
        template_loader.init(builder, dirs=template_dirs)
    else:
        if template_dir:
            template_dirs.insert(0, template_dir)
        template_loader = FileSystemLoader(template_dirs)
    template_env = SandboxedEnvironment(loader=template_loader)

    # read
    # items = find_autosummary_in_files(sources)
    items = find_autosummary_in_lines(lines, filename=srcfn)
    if len(items) > 0:
        msg = '[automodsumm] {1}: found {0} automodsumm entries to generate'
        info(msg.format(len(items), srcfn))


#    gennms = [item[0] for item in items]
#    if len(gennms) > 20:
#        gennms = gennms[:10] + ['...'] + gennms[-10:]
#    info('[automodsumm] generating autosummary for: ' + ', '.join(gennms))

# remove possible duplicates
    items = list(set(items))

    # keep track of new files
    new_files = []

    # write
    for name, path, template_name, inherited_mem in sorted(items):

        if path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = os.path.abspath(os.path.join(base_path, path))
        ensuredir(path)

        try:
            import_by_name_values = import_by_name(name)
        except ImportError as e:
            warn('[automodsumm] failed to import %r: %s' % (name, e))
            continue

        # if block to accommodate Sphinx's v1.2.2 and v1.2.3 respectively
        if len(import_by_name_values) == 3:
            name, obj, parent = import_by_name_values
        elif len(import_by_name_values) == 4:
            name, obj, parent, module_name = import_by_name_values

        fn = os.path.join(path, name + suffix)

        # skip it if it exists
        if os.path.isfile(fn):
            continue

        new_files.append(fn)

        f = open(fn, 'w')

        try:

            if SPHINX_LT_17:
                doc = get_documenter(obj, parent)
            else:
                doc = get_documenter(app, obj, parent)

            if template_name is not None:
                template = template_env.get_template(template_name)
            else:
                tmplstr = 'autosummary_core/%s.rst'
                try:
                    template = template_env.get_template(tmplstr % doc.objtype)
                except TemplateNotFound:
                    template = template_env.get_template(tmplstr % 'base')

            def get_members_mod(obj, typ, include_public=[]):
                """
                typ = None -> all
                """
                items = []
                for name in dir(obj):
                    try:
                        if SPHINX_LT_17:
                            documenter = get_documenter(
                                safe_getattr(obj, name), obj)
                        else:
                            documenter = get_documenter(
                                app, safe_getattr(obj, name), obj)
                    except AttributeError:
                        continue
                    if typ is None or documenter.objtype == typ:
                        items.append(name)
                public = [
                    x for x in items
                    if x in include_public or not x.startswith('_')
                ]
                return public, items

            def get_members_class(obj,
                                  typ,
                                  include_public=[],
                                  include_base=False):
                """
                typ = None -> all
                include_base -> include attrs that are from a base class
                """
                items = []

                # using dir gets all of the attributes, including the elements
                # from the base class, otherwise use __slots__ or __dict__
                if include_base:
                    names = dir(obj)
                else:
                    if hasattr(obj, '__slots__'):
                        names = tuple(getattr(obj, '__slots__'))
                    else:
                        names = getattr(obj, '__dict__').keys()

                for name in names:
                    try:
                        if SPHINX_LT_17:
                            documenter = get_documenter(
                                safe_getattr(obj, name), obj)
                        else:
                            documenter = get_documenter(
                                app, safe_getattr(obj, name), obj)
                    except AttributeError:
                        continue
                    if typ is None or documenter.objtype == typ:
                        items.append(name)
                public = [
                    x for x in items
                    if x in include_public or not x.startswith('_')
                ]
                return public, items

            ns = {}

            if doc.objtype == 'module':
                ns['members'] = get_members_mod(obj, None)
                ns['functions'], ns['all_functions'] = \
                    get_members_mod(obj, 'function')
                ns['classes'], ns['all_classes'] = \
                    get_members_mod(obj, 'class')
                ns['exceptions'], ns['all_exceptions'] = \
                    get_members_mod(obj, 'exception')
            elif doc.objtype == 'class':
                if inherited_mem is not None:
                    # option set in this specifc directive
                    include_base = inherited_mem
                else:
                    # use default value
                    include_base = inherited_members

                api_class_methods = ['__init__', '__call__']
                ns['members'] = get_members_class(obj,
                                                  None,
                                                  include_base=include_base)
                ns['methods'], ns['all_methods'] = \
                    get_members_class(obj, 'method', api_class_methods,
                                      include_base=include_base)
                ns['attributes'], ns['all_attributes'] = \
                    get_members_class(obj, 'attribute',
                                      include_base=include_base)
                ns['methods'].sort()
                ns['attributes'].sort()

            parts = name.split('.')
            if doc.objtype in ('method', 'attribute'):
                mod_name = '.'.join(parts[:-2])
                cls_name = parts[-2]
                obj_name = '.'.join(parts[-2:])
                ns['class'] = cls_name
            else:
                mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]

            ns['fullname'] = name
            ns['module'] = mod_name
            ns['objname'] = obj_name
            ns['name'] = parts[-1]

            ns['objtype'] = doc.objtype
            ns['underline'] = len(obj_name) * '='

            # We now check whether a file for reference footnotes exists for
            # the module being documented. We first check if the
            # current module is a file or a directory, as this will give a
            # different path for the reference file. For example, if
            # documenting astropy.wcs then the reference file is at
            # ../wcs/references.txt, while if we are documenting
            # astropy.config.logging_helper (which is at
            # astropy/config/logging_helper.py) then the reference file is set
            # to ../config/references.txt
            if '.' in mod_name:
                mod_name_dir = mod_name.replace('.', '/').split('/', 1)[1]
            else:
                mod_name_dir = mod_name
            if not os.path.isdir(os.path.join(base_path, mod_name_dir)) \
               and os.path.isdir(os.path.join(base_path, mod_name_dir.rsplit('/', 1)[0])):
                mod_name_dir = mod_name_dir.rsplit('/', 1)[0]

            # We then have to check whether it exists, and if so, we pass it
            # to the template.
            if os.path.exists(
                    os.path.join(base_path, mod_name_dir, 'references.txt')):
                # An important subtlety here is that the path we pass in has
                # to be relative to the file being generated, so we have to
                # figure out the right number of '..'s
                ndirsback = path.replace(base_path, '').count('/')
                ref_file_rel_segments = ['..'] * ndirsback
                ref_file_rel_segments.append(mod_name_dir)
                ref_file_rel_segments.append('references.txt')
                ns['referencefile'] = os.path.join(*ref_file_rel_segments)

            rendered = template.render(**ns)
            f.write(cleanup_whitespace(rendered))
        finally:
            f.close()
コード例 #22
0
    def get_items(self, names):
        """Try to import the given names, and return a list of
        ``[(name, signature, summary_string, real_name), ...]``.
        """
        from sphinx.ext.autosummary import (get_import_prefixes_from_env,
                                            import_by_name, get_documenter,
                                            mangle_signature)

        env = self.state.document.settings.env

        prefixes = get_import_prefixes_from_env(env)

        items = []

        max_item_chars = 50

        for name in names:
            display_name = name
            if name.startswith('~'):
                name = name[1:]
                display_name = name.split('.')[-1]

            try:
                real_name, obj, parent = import_by_name(name,
                                                        prefixes=prefixes)
            except ImportError:
                self.warn('[astropyautosummary] failed to import %s' % name)
                items.append((name, '', '', name))
                continue

            # NB. using real_name here is important, since Documenters
            #     handle module prefixes slightly differently
            documenter = get_documenter(obj, parent)(self, real_name)
            if not documenter.parse_name():
                self.warn('[astropyautosummary] failed to parse name %s' %
                          real_name)
                items.append((display_name, '', '', real_name))
                continue
            if not documenter.import_object():
                self.warn('[astropyautosummary] failed to import object %s' %
                          real_name)
                items.append((display_name, '', '', real_name))
                continue

            # -- Grab the signature

            sig = documenter.format_signature()
            if not sig:
                sig = ''
            else:
                max_chars = max(10, max_item_chars - len(display_name))
                sig = mangle_signature(sig, max_chars=max_chars)
                sig = sig.replace('*', r'\*')

            # -- Grab the summary

            doc = list(documenter.process_doc(documenter.get_doc()))

            while doc and not doc[0].strip():
                doc.pop(0)
            m = _itemsummrex.search(" ".join(doc).strip())
            if m:
                summary = m.group(1).strip()
            elif doc:
                summary = doc[0].strip()
            else:
                summary = ''

            items.append((display_name, sig, summary, real_name))

        return items
コード例 #23
0
ファイル: automodsumm.py プロジェクト: henrysting/astropy
def generate_automodsumm_docs(lines, srcfn, suffix='.rst', warn=None,
                              info=None, base_path=None, builder=None,
                              template_dir=None):
    """
    This function is adapted from
    `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to
    generate source for the automodsumm directives that should be
    autosummarized. Unlike generate_autosummary_docs, this function is
    called one file at a time.
    """
    import os

    from sphinx import package_dir
    from sphinx.jinja2glue import BuiltinTemplateLoader
    from sphinx.ext.autosummary import import_by_name, get_documenter
    from sphinx.ext.autosummary.generate import (find_autosummary_in_lines,
                                                 _simple_info, _simple_warn)
    from sphinx.util.osutil import ensuredir
    from sphinx.util.inspect import safe_getattr
    from jinja2 import FileSystemLoader, TemplateNotFound
    from jinja2.sandbox import SandboxedEnvironment

    if info is None:
        info = _simple_info
    if warn is None:
        warn = _simple_warn

    #info('[automodsumm] generating automodsumm for: ' + srcfn)

    # create our own templating environment
    template_dirs = [os.path.join(package_dir, 'ext',
                                  'autosummary', 'templates')]
    if builder is not None:
        # allow the user to override the templates
        template_loader = BuiltinTemplateLoader()
        template_loader.init(builder, dirs=template_dirs)
    else:
        if template_dir:
            template_dirs.insert(0, template_dir)
        template_loader = FileSystemLoader(template_dirs)
    template_env = SandboxedEnvironment(loader=template_loader)

    # read
    #items = find_autosummary_in_files(sources)
    items = find_autosummary_in_lines(lines, filename=srcfn)
    if len(items) > 0:
        msg = '[automodsumm] {1}: found {0} automodsumm entries to generate'
        info(msg.format(len(items), srcfn))

#    gennms = [item[0] for item in items]
#    if len(gennms) > 20:
#        gennms = gennms[:10] + ['...'] + gennms[-10:]
#    info('[automodsumm] generating autosummary for: ' + ', '.join(gennms))

    # remove possible duplicates
    items = dict([(item, True) for item in items]).keys()

    # keep track of new files
    new_files = []

    # write
    for name, path, template_name in sorted(items):
        if path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = os.path.abspath(path)
        ensuredir(path)

        try:
            name, obj, parent = import_by_name(name)
        except ImportError, e:
            warn('[automodapi] failed to import %r: %s' % (name, e))
            continue

        fn = os.path.join(path, name + suffix)

        # skip it if it exists
        if os.path.isfile(fn):
            continue

        new_files.append(fn)

        f = open(fn, 'w')

        try:
            doc = get_documenter(obj, parent)

            if template_name is not None:
                template = template_env.get_template(template_name)
            else:
                tmplstr = 'autosummary/%s.rst'
                try:
                    template = template_env.get_template(tmplstr % doc.objtype)
                except TemplateNotFound:
                    template = template_env.get_template(tmplstr % 'base')

            def get_members(obj, typ, include_public=[]):
                items = []
                for name in dir(obj):
                    try:
                        documenter = get_documenter(safe_getattr(obj, name),
                                                    obj)
                    except AttributeError:
                        continue
                    if documenter.objtype == typ:
                        items.append(name)
                public = [x for x in items
                          if x in include_public or not x.startswith('_')]
                return public, items

            ns = {}

            if doc.objtype == 'module':
                ns['members'] = dir(obj)
                ns['functions'], ns['all_functions'] = \
                                   get_members(obj, 'function')
                ns['classes'], ns['all_classes'] = \
                                 get_members(obj, 'class')
                ns['exceptions'], ns['all_exceptions'] = \
                                   get_members(obj, 'exception')
            elif doc.objtype == 'class':
                ns['members'] = dir(obj)
                ns['methods'], ns['all_methods'] = \
                                 get_members(obj, 'method', ['__init__'])
                ns['attributes'], ns['all_attributes'] = \
                                 get_members(obj, 'attribute')

            parts = name.split('.')
            if doc.objtype in ('method', 'attribute'):
                mod_name = '.'.join(parts[:-2])
                cls_name = parts[-2]
                obj_name = '.'.join(parts[-2:])
                ns['class'] = cls_name
            else:
                mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]

            ns['fullname'] = name
            ns['module'] = mod_name
            ns['objname'] = obj_name
            ns['name'] = parts[-1]

            ns['objtype'] = doc.objtype
            ns['underline'] = len(name) * '='

            rendered = template.render(**ns)
            f.write(rendered)
        finally:
            f.close()
コード例 #24
0
def generate_autosummary_docs(sources,
                              output_dir=None,
                              suffix='.rst',
                              warn=_simple_warn,
                              info=_simple_info,
                              base_path=None,
                              builder=None,
                              template_dir=None,
                              imported_members=False,
                              app=None):
    # type: (List[unicode], unicode, unicode, Callable, Callable, unicode, Builder, unicode, bool, Any) -> None  # NOQA

    showed_sources = list(sorted(sources))
    if len(showed_sources) > 20:
        showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:]
    info('[autosummary] generating autosummary for: %s' %
         ', '.join(showed_sources))

    if output_dir:
        info('[autosummary] writing to %s' % output_dir)

    if base_path is not None:
        sources = [os.path.join(base_path, filename) for filename in sources]

    # create our own templating environment
    template_dirs = None  # type: List[unicode]
    template_dirs = [
        os.path.join(package_dir, 'ext', 'autosummary', 'templates')
    ]

    template_loader = None  # type: BaseLoader
    if builder is not None:
        # allow the user to override the templates
        template_loader = BuiltinTemplateLoader()
        template_loader.init(builder, dirs=template_dirs)
    else:
        if template_dir:
            template_dirs.insert(0, template_dir)
        template_loader = FileSystemLoader(template_dirs)  # type: ignore
    template_env = SandboxedEnvironment(loader=template_loader)
    template_env.filters['underline'] = _underline

    # replace the builtin html filters
    template_env.filters['escape'] = rst_escape
    template_env.filters['e'] = rst_escape

    # read
    items = find_autosummary_in_files(sources)

    # keep track of new files
    new_files = []

    # write
    for name, path, template_name in sorted(set(items), key=str):
        if path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = output_dir or os.path.abspath(path)
        ensuredir(path)

        try:
            name, obj, parent, mod_name = import_by_name(name)
        except ImportError as e:
            warn('[autosummary] failed to import %r: %s' % (name, e))
            continue

        fn = os.path.join(path, name + suffix)

        # skip it if it exists
        if os.path.isfile(fn):
            continue

        new_files.append(fn)

        with open(fn, 'w') as f:
            doc = get_documenter(app, obj, parent)

            if template_name is not None:
                template = template_env.get_template(template_name)
            else:
                try:
                    template = template_env.get_template('autosummary/%s.rst' %
                                                         doc.objtype)
                except TemplateNotFound:
                    template = template_env.get_template(
                        'autosummary/base.rst')

            def get_members(obj, typ, include_public=[], imported=False):
                # type: (Any, unicode, List[unicode], bool) -> Tuple[List[unicode], List[unicode]]  # NOQA
                items = []  # type: List[unicode]
                for name in dir(obj):
                    try:
                        value = safe_getattr(obj, name)
                    except AttributeError:
                        continue
                    documenter = get_documenter(app, value, obj)
                    if documenter.objtype == typ:
                        if typ == 'method':
                            items.append(name)
                        elif imported or getattr(value, '__module__',
                                                 None) == obj.__name__:
                            # skip imported members if expected
                            items.append(name)
                public = [
                    x for x in items
                    if x in include_public or not x.startswith('_')
                ]
                return public, items

            ns = {}  # type: Dict[unicode, Any]

            if doc.objtype == 'module':
                ns['members'] = dir(obj)
                ns['functions'], ns['all_functions'] = \
                    get_members(obj, 'function', imported=imported_members)
                ns['classes'], ns['all_classes'] = \
                    get_members(obj, 'class', imported=imported_members)
                ns['exceptions'], ns['all_exceptions'] = \
                    get_members(obj, 'exception', imported=imported_members)
            elif doc.objtype == 'class':
                ns['members'] = dir(obj)
                ns['methods'], ns['all_methods'] = \
                    get_members(obj, 'method', ['__init__'], imported=imported_members)
                ns['attributes'], ns['all_attributes'] = \
                    get_members(obj, 'attribute', imported=imported_members)

            parts = name.split('.')
            if doc.objtype in ('method', 'attribute'):
                mod_name = '.'.join(parts[:-2])
                cls_name = parts[-2]
                obj_name = '.'.join(parts[-2:])
                ns['class'] = cls_name
            else:
                mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]

            ns['fullname'] = name
            ns['module'] = mod_name
            ns['objname'] = obj_name
            ns['name'] = parts[-1]

            ns['objtype'] = doc.objtype
            ns['underline'] = len(name) * '='

            rendered = template.render(**ns)
            f.write(rendered)  # type: ignore

    # descend recursively to new files
    if new_files:
        generate_autosummary_docs(new_files,
                                  output_dir=output_dir,
                                  suffix=suffix,
                                  warn=warn,
                                  info=info,
                                  base_path=base_path,
                                  builder=builder,
                                  template_dir=template_dir)
コード例 #25
0
ファイル: generate.py プロジェクト: 89sos98/main
def generate_autosummary_docs(sources, output_dir=None, suffix=None,
                              warn=_simple_warn, info=_simple_info):
    info('generating autosummary for: %s' % ', '.join(sources))
    if output_dir:
        info('writing to %s' % output_dir)
    # read
    names = {}
    for name, loc in get_documented(sources).items():
        for (filename, sec_title, keyword, toctree) in loc:
            if toctree is not None:
                path = os.path.join(os.path.dirname(filename), toctree)
                names[name] = os.path.abspath(path)

    # write
    for name, path in sorted(names.items()):
        path = output_dir or path
        ensuredir(path)

        try:
            obj, name = import_by_name(name)
        except ImportError, e:
            warn('failed to import %r: %s' % (name, e))
            continue

        fn = os.path.join(path, name + (suffix or '.rst'))
        # skip it if it exists
        if os.path.isfile(fn):
            continue

        f = open(fn, 'w')

        try:
            if inspect.ismodule(obj):
                # XXX replace this with autodoc's API?
                tmpl = env.get_template('module')
                functions = [getattr(obj, item).__name__
                             for item in dir(obj)
                             if inspect.isfunction(getattr(obj, item))]
                classes = [getattr(obj, item).__name__
                           for item in dir(obj)
                           if inspect.isclass(getattr(obj, item))
                           and not issubclass(getattr(obj, item), Exception)]
                exceptions = [getattr(obj, item).__name__
                              for item in dir(obj)
                              if inspect.isclass(getattr(obj, item))
                              and issubclass(getattr(obj, item), Exception)]
                rendered = tmpl.render(name=name,
                                       underline='='*len(name),
                                       functions=functions,
                                       classes=classes,
                                       exceptions=exceptions,
                                       len_functions=len(functions),
                                       len_classes=len(classes),
                                       len_exceptions=len(exceptions))
                f.write(rendered)
            else:
                f.write('%s\n%s\n\n' % (name, '='*len(name)))

                if inspect.isclass(obj):
                    if issubclass(obj, Exception):
                        f.write(format_modulemember(name, 'autoexception'))
                    else:
                        f.write(format_modulemember(name, 'autoclass'))
                elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj):
                    f.write(format_classmember(name, 'automethod'))
                elif callable(obj):
                    f.write(format_modulemember(name, 'autofunction'))
                elif hasattr(obj, '__get__'):
                    f.write(format_classmember(name, 'autoattribute'))
                else:
                    f.write(format_modulemember(name, 'autofunction'))
        finally:
            f.close()
コード例 #26
0
ファイル: generate.py プロジェクト: alfonsodiecko/PYTHON_DIST
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
                              warn=_simple_warn, info=_simple_info,
                              base_path=None, builder=None, template_dir=None):

    showed_sources = list(sorted(sources))
    if len(showed_sources) > 20:
        showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:]
    info('[autosummary] generating autosummary for: %s' %
         ', '.join(showed_sources))

    if output_dir:
        info('[autosummary] writing to %s' % output_dir)

    if base_path is not None:
        sources = [os.path.join(base_path, filename) for filename in sources]

    # create our own templating environment
    template_dirs = [os.path.join(package_dir, 'ext',
                                  'autosummary', 'templates')]
    if builder is not None:
        # allow the user to override the templates
        template_loader = BuiltinTemplateLoader()
        template_loader.init(builder, dirs=template_dirs)
    else:
        if template_dir:
            template_dirs.insert(0, template_dir)
        template_loader = FileSystemLoader(template_dirs)
    template_env = SandboxedEnvironment(loader=template_loader)

    # read
    items = find_autosummary_in_files(sources)

    # remove possible duplicates
    items = list(dict([(item, True) for item in items]).keys())

    # keep track of new files
    new_files = []

    # write
    for name, path, template_name in sorted(items, key=str):
        if path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = output_dir or os.path.abspath(path)
        ensuredir(path)

        try:
            name, obj, parent = import_by_name(name)
        except ImportError as e:
            warn('[autosummary] failed to import %r: %s' % (name, e))
            continue

        fn = os.path.join(path, name + suffix)

        # skip it if it exists
        if os.path.isfile(fn):
            continue

        new_files.append(fn)

        f = open(fn, 'w')

        try:
            doc = get_documenter(obj, parent)

            if template_name is not None:
                template = template_env.get_template(template_name)
            else:
                try:
                    template = template_env.get_template('autosummary/%s.rst'
                                                         % doc.objtype)
                except TemplateNotFound:
                    template = template_env.get_template('autosummary/base.rst')

            def get_members(obj, typ, include_public=[]):
                items = []
                for name in dir(obj):
                    try:
                        documenter = get_documenter(safe_getattr(obj, name),
                                                    obj)
                    except AttributeError:
                        continue
                    if documenter.objtype == typ:
                        items.append(name)
                public = [x for x in items
                          if x in include_public or not x.startswith('_')]
                return public, items

            ns = {}

            if doc.objtype == 'module':
                ns['members'] = dir(obj)
                ns['functions'], ns['all_functions'] = \
                                   get_members(obj, 'function')
                ns['classes'], ns['all_classes'] = \
                                 get_members(obj, 'class')
                ns['exceptions'], ns['all_exceptions'] = \
                                   get_members(obj, 'exception')
            elif doc.objtype == 'class':
                ns['members'] = dir(obj)
                ns['methods'], ns['all_methods'] = \
                                 get_members(obj, 'method', ['__init__'])
                ns['attributes'], ns['all_attributes'] = \
                                 get_members(obj, 'attribute')

            parts = name.split('.')
            if doc.objtype in ('method', 'attribute'):
                mod_name = '.'.join(parts[:-2])
                cls_name = parts[-2]
                obj_name = '.'.join(parts[-2:])
                ns['class'] = cls_name
            else:
                mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]

            ns['fullname'] = name
            ns['module'] = mod_name
            ns['objname'] = obj_name
            ns['name'] = parts[-1]

            ns['objtype'] = doc.objtype
            ns['underline'] = len(name) * '='

            rendered = template.render(**ns)
            f.write(rendered)
        finally:
            f.close()

    # descend recursively to new files
    if new_files:
        generate_autosummary_docs(new_files, output_dir=output_dir,
                                  suffix=suffix, warn=warn, info=info,
                                  base_path=base_path, builder=builder,
                                  template_dir=template_dir)
コード例 #27
0
ファイル: generate.py プロジェクト: QuLogic/sphinx
def generate_autosummary_docs(
    sources,
    output_dir=None,
    suffix=".rst",
    warn=_simple_warn,
    info=_simple_info,
    base_path=None,
    builder=None,
    template_dir=None,
):

    showed_sources = list(sorted(sources))
    if len(showed_sources) > 20:
        showed_sources = showed_sources[:10] + ["..."] + showed_sources[-10:]
    info("[autosummary] generating autosummary for: %s" % ", ".join(showed_sources))

    if output_dir:
        info("[autosummary] writing to %s" % output_dir)

    if base_path is not None:
        sources = [os.path.join(base_path, filename) for filename in sources]

    # create our own templating environment
    template_dirs = [os.path.join(package_dir, "ext", "autosummary", "templates")]
    if builder is not None:
        # allow the user to override the templates
        template_loader = BuiltinTemplateLoader()
        template_loader.init(builder, dirs=template_dirs)
    else:
        if template_dir:
            template_dirs.insert(0, template_dir)
        template_loader = FileSystemLoader(template_dirs)
    template_env = SandboxedEnvironment(loader=template_loader)

    # read
    items = find_autosummary_in_files(sources)

    # keep track of new files
    new_files = []

    # write
    for name, path, template_name in sorted(set(items), key=str):
        if path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = output_dir or os.path.abspath(path)
        ensuredir(path)

        try:
            name, obj, parent, mod_name = import_by_name(name)
        except ImportError as e:
            warn("[autosummary] failed to import %r: %s" % (name, e))
            continue

        fn = os.path.join(path, name + suffix)

        # skip it if it exists
        if os.path.isfile(fn):
            continue

        new_files.append(fn)

        with open(fn, "w") as f:
            doc = get_documenter(obj, parent)

            if template_name is not None:
                template = template_env.get_template(template_name)
            else:
                try:
                    template = template_env.get_template("autosummary/%s.rst" % doc.objtype)
                except TemplateNotFound:
                    template = template_env.get_template("autosummary/base.rst")

            def get_members(obj, typ, include_public=[]):
                items = []
                for name in dir(obj):
                    try:
                        documenter = get_documenter(safe_getattr(obj, name), obj)
                    except AttributeError:
                        continue
                    if documenter.objtype == typ:
                        items.append(name)
                public = [x for x in items if x in include_public or not x.startswith("_")]
                return public, items

            ns = {}

            if doc.objtype == "module":
                ns["members"] = dir(obj)
                ns["functions"], ns["all_functions"] = get_members(obj, "function")
                ns["classes"], ns["all_classes"] = get_members(obj, "class")
                ns["exceptions"], ns["all_exceptions"] = get_members(obj, "exception")
            elif doc.objtype == "class":
                ns["members"] = dir(obj)
                ns["methods"], ns["all_methods"] = get_members(obj, "method", ["__init__"])
                ns["attributes"], ns["all_attributes"] = get_members(obj, "attribute")

            parts = name.split(".")
            if doc.objtype in ("method", "attribute"):
                mod_name = ".".join(parts[:-2])
                cls_name = parts[-2]
                obj_name = ".".join(parts[-2:])
                ns["class"] = cls_name
            else:
                mod_name, obj_name = ".".join(parts[:-1]), parts[-1]

            ns["fullname"] = name
            ns["module"] = mod_name
            ns["objname"] = obj_name
            ns["name"] = parts[-1]

            ns["objtype"] = doc.objtype
            ns["underline"] = len(name) * "="

            rendered = template.render(**ns)
            f.write(rendered)

    # descend recursively to new files
    if new_files:
        generate_autosummary_docs(
            new_files,
            output_dir=output_dir,
            suffix=suffix,
            warn=warn,
            info=info,
            base_path=base_path,
            builder=builder,
            template_dir=template_dir,
        )
コード例 #28
0
ファイル: generate.py プロジェクト: marcosptf/fedora
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
                              warn=_simple_warn, info=_simple_info,
                              base_path=None, builder=None, template_dir=None,
                              imported_members=False):
    # type: (List[unicode], unicode, unicode, Callable, Callable, unicode, Builder, unicode, bool) -> None  # NOQA

    showed_sources = list(sorted(sources))
    if len(showed_sources) > 20:
        showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:]
    info('[autosummary] generating autosummary for: %s' %
         ', '.join(showed_sources))

    if output_dir:
        info('[autosummary] writing to %s' % output_dir)

    if base_path is not None:
        sources = [os.path.join(base_path, filename) for filename in sources]

    # create our own templating environment
    template_dirs = None  # type: List[unicode]
    template_dirs = [os.path.join(package_dir, 'ext',
                                  'autosummary', 'templates')]

    template_loader = None  # type: BaseLoader
    if builder is not None:
        # allow the user to override the templates
        template_loader = BuiltinTemplateLoader()
        template_loader.init(builder, dirs=template_dirs)
    else:
        if template_dir:
            template_dirs.insert(0, template_dir)
        template_loader = FileSystemLoader(template_dirs)  # type: ignore
    template_env = SandboxedEnvironment(loader=template_loader)
    template_env.filters['underline'] = _underline

    # replace the builtin html filters
    template_env.filters['escape'] = rst_escape
    template_env.filters['e'] = rst_escape

    # read
    items = find_autosummary_in_files(sources)

    # keep track of new files
    new_files = []

    # write
    for name, path, template_name in sorted(set(items), key=str):
        if path is None:
            # The corresponding autosummary:: directive did not have
            # a :toctree: option
            continue

        path = output_dir or os.path.abspath(path)
        ensuredir(path)

        try:
            name, obj, parent, mod_name = import_by_name(name)
        except ImportError as e:
            warn('[autosummary] failed to import %r: %s' % (name, e))
            continue

        fn = os.path.join(path, name + suffix)

        # skip it if it exists
        if os.path.isfile(fn):
            continue

        new_files.append(fn)

        with open(fn, 'w') as f:
            doc = get_documenter(obj, parent)

            if template_name is not None:
                template = template_env.get_template(template_name)
            else:
                try:
                    template = template_env.get_template('autosummary/%s.rst'
                                                         % doc.objtype)
                except TemplateNotFound:
                    template = template_env.get_template('autosummary/base.rst')

            def get_members(obj, typ, include_public=[], imported=False):
                # type: (Any, unicode, List[unicode], bool) -> Tuple[List[unicode], List[unicode]]  # NOQA
                items = []  # type: List[unicode]
                for name in dir(obj):
                    try:
                        value = safe_getattr(obj, name)
                    except AttributeError:
                        continue
                    documenter = get_documenter(value, obj)
                    if documenter.objtype == typ:
                        if typ == 'method':
                            items.append(name)
                        elif imported or getattr(value, '__module__', None) == obj.__name__:
                            # skip imported members if expected
                            items.append(name)
                public = [x for x in items
                          if x in include_public or not x.startswith('_')]
                return public, items

            ns = {}  # type: Dict[unicode, Any]

            if doc.objtype == 'module':
                ns['members'] = dir(obj)
                ns['functions'], ns['all_functions'] = \
                    get_members(obj, 'function', imported=imported_members)
                ns['classes'], ns['all_classes'] = \
                    get_members(obj, 'class', imported=imported_members)
                ns['exceptions'], ns['all_exceptions'] = \
                    get_members(obj, 'exception', imported=imported_members)
            elif doc.objtype == 'class':
                ns['members'] = dir(obj)
                ns['methods'], ns['all_methods'] = \
                    get_members(obj, 'method', ['__init__'], imported=imported_members)
                ns['attributes'], ns['all_attributes'] = \
                    get_members(obj, 'attribute', imported=imported_members)

            parts = name.split('.')
            if doc.objtype in ('method', 'attribute'):
                mod_name = '.'.join(parts[:-2])
                cls_name = parts[-2]
                obj_name = '.'.join(parts[-2:])
                ns['class'] = cls_name
            else:
                mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]

            ns['fullname'] = name
            ns['module'] = mod_name
            ns['objname'] = obj_name
            ns['name'] = parts[-1]

            ns['objtype'] = doc.objtype
            ns['underline'] = len(name) * '='

            rendered = template.render(**ns)
            f.write(rendered)  # type: ignore

    # descend recursively to new files
    if new_files:
        generate_autosummary_docs(new_files, output_dir=output_dir,
                                  suffix=suffix, warn=warn, info=info,
                                  base_path=base_path, builder=builder,
                                  template_dir=template_dir)
コード例 #29
0
def generate_autosummary_docs(sources,
                              output_dir=None,
                              suffix=None,
                              warn=_simple_warn,
                              info=_simple_info):
    info('generating autosummary for: %s' % ', '.join(sources))
    if output_dir:
        info('writing to %s' % output_dir)
    # read
    names = {}
    for name, loc in get_documented(sources).items():
        for (filename, sec_title, keyword, toctree) in loc:
            if toctree is not None:
                path = os.path.join(os.path.dirname(filename), toctree)
                names[name] = os.path.abspath(path)

    # write
    for name, path in sorted(names.items()):
        path = output_dir or path
        ensuredir(path)

        try:
            obj, name = import_by_name(name)
        except ImportError, e:
            warn('failed to import %r: %s' % (name, e))
            continue

        fn = os.path.join(path, name + (suffix or '.rst'))
        # skip it if it exists
        if os.path.isfile(fn):
            continue

        f = open(fn, 'w')

        try:
            if inspect.ismodule(obj):
                # XXX replace this with autodoc's API?
                tmpl = env.get_template('module')
                functions = [
                    getattr(obj, item).__name__ for item in dir(obj)
                    if inspect.isfunction(getattr(obj, item))
                ]
                classes = [
                    getattr(obj, item).__name__ for item in dir(obj)
                    if inspect.isclass(getattr(obj, item))
                    and not issubclass(getattr(obj, item), Exception)
                ]
                exceptions = [
                    getattr(obj, item).__name__ for item in dir(obj)
                    if inspect.isclass(getattr(obj, item))
                    and issubclass(getattr(obj, item), Exception)
                ]
                rendered = tmpl.render(name=name,
                                       underline='=' * len(name),
                                       functions=functions,
                                       classes=classes,
                                       exceptions=exceptions,
                                       len_functions=len(functions),
                                       len_classes=len(classes),
                                       len_exceptions=len(exceptions))
                f.write(rendered)
            else:
                f.write('%s\n%s\n\n' % (name, '=' * len(name)))

                if inspect.isclass(obj):
                    if issubclass(obj, Exception):
                        f.write(format_modulemember(name, 'autoexception'))
                    else:
                        f.write(format_modulemember(name, 'autoclass'))
                elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj):
                    f.write(format_classmember(name, 'automethod'))
                elif callable(obj):
                    f.write(format_modulemember(name, 'autofunction'))
                elif hasattr(obj, '__get__'):
                    f.write(format_classmember(name, 'autoattribute'))
                else:
                    f.write(format_modulemember(name, 'autofunction'))
        finally:
            f.close()