예제 #1
0
def test_autosummary_generate_content_for_module_imported_members(app):
    import autosummary_dummy_module
    template = Mock()

    generate_autosummary_content('autosummary_dummy_module',
                                 autosummary_dummy_module, None, template,
                                 None, True, app, False, {})
    assert template.render.call_args[0][0] == 'module'

    context = template.render.call_args[0][1]
    assert context['members'] == [
        'CONSTANT1', 'CONSTANT2', 'Exc', 'Foo', 'Union', '_Baz', '_Exc',
        '__builtins__', '__cached__', '__doc__', '__file__', '__loader__',
        '__name__', '__package__', '__spec__', '_quux', 'bar', 'path', 'qux'
    ]
    assert context['functions'] == ['bar']
    assert context['all_functions'] == ['_quux', 'bar']
    assert context['classes'] == ['Foo']
    assert context['all_classes'] == ['Foo', '_Baz']
    assert context['exceptions'] == ['Exc']
    assert context['all_exceptions'] == ['Exc', '_Exc']
    assert context['attributes'] == ['CONSTANT1', 'qux']
    assert context['all_attributes'] == ['CONSTANT1', 'qux']
    assert context['fullname'] == 'autosummary_dummy_module'
    assert context['module'] == 'autosummary_dummy_module'
    assert context['objname'] == ''
    assert context['name'] == ''
    assert context['objtype'] == 'module'
예제 #2
0
def test_autosummary_generate_content_for_module___all__(app):
    import autosummary_dummy_module
    template = Mock()
    app.config.autosummary_ignore_module_all = False

    generate_autosummary_content('autosummary_dummy_module',
                                 autosummary_dummy_module, None, template,
                                 None, False, app, False, {})
    assert template.render.call_args[0][0] == 'module'

    context = template.render.call_args[0][1]
    assert context['members'] == [
        'CONSTANT1', 'Exc', 'Foo', '_Baz', 'bar', 'qux', 'path'
    ]
    assert context['functions'] == ['bar']
    assert context['all_functions'] == ['bar']
    assert context['classes'] == ['Foo']
    assert context['all_classes'] == ['Foo', '_Baz']
    assert context['exceptions'] == ['Exc']
    assert context['all_exceptions'] == ['Exc']
    assert context['attributes'] == ['CONSTANT1', 'qux']
    assert context['all_attributes'] == ['CONSTANT1', 'qux']
    assert context['fullname'] == 'autosummary_dummy_module'
    assert context['module'] == 'autosummary_dummy_module'
    assert context['objname'] == ''
    assert context['name'] == ''
    assert context['objtype'] == 'module'
예제 #3
0
def create_documenter_from_template(autosummary, app, obj, parent, full_name):
    real_name = ".".join(full_name.split("::"))

    options = autosummary.options.copy()
    template_name = options.pop("template", None)
    if template_name is None:
        return original_create_documenter(autosummary, app, obj, parent,
                                          full_name)

    options.pop("toctree", None)
    options["imported_members"] = options.get("imported_members", False)
    options["recursive"] = options.get("recursive", False)

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

    rendered = generate.generate_autosummary_content(
        real_name,
        obj,
        parent,
        template=generate.AutosummaryRenderer(app),
        template_name=template_name,
        app=app,
        context=context,
        **options,
    )

    documenter_name, real_name = extract_documenter(rendered)
    doccls = app.registry.documenters.get(documenter_name)
    documenter = doccls(autosummary.bridge, real_name)

    return documenter
예제 #4
0
def test_autosummary_generate_content_for_module_skipped(app):
    import autosummary_dummy_module
    template = Mock()

    def skip_member(app, what, name, obj, skip, options):
        if name in ('Foo', 'bar', 'Exc'):
            return True

    app.connect('autodoc-skip-member', skip_member)
    generate_autosummary_content('autosummary_dummy_module', autosummary_dummy_module, None,
                                 template, None, False, app, False, {})
    context = template.render.call_args[0][1]
    assert context['members'] == ['_Baz', '_Exc', '__builtins__', '__cached__', '__doc__',
                                  '__file__', '__name__', '__package__', '_quux', 'qux']
    assert context['functions'] == []
    assert context['classes'] == []
    assert context['exceptions'] == []
예제 #5
0
    def generate_docs(
        self,
        source_filenames: List[str],
        output_dir: str = None,
        suffix: str = ".rst",
        base_path: str = None,
        imported_members: bool = False,
        overwrite: bool = True,
        encoding: str = "utf-8",
    ) -> None:
        """
        Generate and write stub files for objects defined in the :rst:dir:`automodapi`
        and :rst:dir:`automodsumm` directives.

        Parameters
        ----------

        source_filenames : List[str]
            A list of all filenames for with the :rst:dir:`automodapi` and
            :rst:dir:`automodsumm` directives will be searched for.

        output_dir : `str`
            Directory for which the stub files will be written to.

        suffix : `str`
            (Default ``".rst"``) Suffix given to the written stub files.

        base_path : `str`
            The common base path for the filenames listed in ``source_filenames``.
            This is typically the source directory of the Sphinx application.

        imported_members : `bool`
            (Default `False`) Set `True` to include imported members in the
            stub file documentation for *module* object types.

        overwrite : `bool`
            (Default `True`)  Will cause existing stub files to be overwritten.

        encoding : `str`
            (Default: ``"utf-8"``) Encoding for the written stub files.


        .. note::  Adapted from
                   :func:`sphinx.ext.autosummary.generate.generate_autosummary_docs`.
        """
        app = self.app

        _info = self.logger.info
        _warn = self.logger.warning

        showed_sources = list(sorted(source_filenames))
        _info(
            __(f"[automodsumm] generating stub files for {len(showed_sources)} sources"
               ))

        if output_dir:
            _info(__(f"[automodsumm] writing to {output_dir}"))

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

        template = AutomodsummRenderer(app)

        # read
        items = self.find_in_files(source_filenames)

        # 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 automodsumm:: 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 import as an instance attribute
                    name, obj, parent, modname = import_ivar_by_name(
                        entry.name)
                    qualname = name.replace(modname + ".", "")
                except ImportError:
                    _warn(
                        __(f"[automodsumm] failed to import {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:
            self.generate_docs(
                new_files,
                output_dir=output_dir,
                suffix=suffix,
                base_path=base_path,
                imported_members=imported_members,
                overwrite=overwrite,
            )