# Buggy code
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,
) -> 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 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:
            _warn(__("[autosummary] failed to import %r: %s") % (entry.name, e))
            continue

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

        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,
            warn=warn,
            info=info,
            base_path=base_path,
            builder=builder,
            template_dir=template_dir,
            imported_members=imported_members,
            app=app,
            overwrite=overwrite,
        )


# Traceback (jinja2.exceptions.TemplateNotFound)
$ sphinx-autogen -t . example.py
[autosummary] example.py の autosummary を生成中
Traceback (most recent call last):
File "/Users/tkomiya/work/tmp/bin/sphinx-autogen", line 11, in <module>
load_entry_point('Sphinx', 'console_scripts', 'sphinx-autogen')()
File "/Users/tkomiya/work/sphinx/sphinx/ext/autosummary/generate.py", line 495, in main
generate_autosummary_docs(args.source_file, args.output_dir,
File "/Users/tkomiya/work/sphinx/sphinx/ext/autosummary/generate.py", line 290, in generate_autosummary_docs
content = generate_autosummary_content(name, obj, parent, template, entry.template,
File "/Users/tkomiya/work/sphinx/sphinx/ext/autosummary/generate.py", line 231, in generate_autosummary_content
return template.render(template_name, ns)
File "/Users/tkomiya/work/sphinx/sphinx/ext/autosummary/generate.py", line 142, in render
return self.env.get_template(template_name).render(context)
File "/Users/tkomiya/.pyenv/versions/3.8.1/lib/python3.8/site-packages/Jinja2-3.0.0a1-py3.8.egg/jinja2/environment.py", line 1045, in render
self.environment.handle_exception()
File "/Users/tkomiya/.pyenv/versions/3.8.1/lib/python3.8/site-packages/Jinja2-3.0.0a1-py3.8.egg/jinja2/environment.py", line 787, in handle_exception
raise rewrite_traceback_stack(source=source)
File "./autosummary/module.rst", line 1, in top-level template code
{% extends "!autosummary/module.rst" %}
File "/Users/tkomiya/.pyenv/versions/3.8.1/lib/python3.8/site-packages/Jinja2-3.0.0a1-py3.8.egg/jinja2/loaders.py", line 189, in get_source
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: !autosummary/module.rst

# Fixed code
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,
) -> 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

    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:]
    _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)

    # 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:
            _warn(__("[autosummary] failed to import %r: %s") % (entry.name, e))
            continue

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

        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,
            warn=warn,
            info=info,
            base_path=base_path,
            builder=builder,
            imported_members=imported_members,
            app=app,
            overwrite=overwrite,
        )