mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #7535: sphinx-autogen: crashes when custom template uses inheritance
This commit is contained in:
parent
fd0a55223f
commit
b15e3f6639
1
CHANGES
1
CHANGES
@ -30,6 +30,7 @@ Features added
|
||||
caption to the toctree
|
||||
* #248, #6040: autosummary: Add ``:recursive:`` option to autosummary directive
|
||||
to generate stub files recursively
|
||||
* #7535: sphinx-autogen: crashes when custom template uses inheritance
|
||||
* #7481: html theme: Add right margin to footnote/citation labels
|
||||
* #7482: html theme: CSS spacing for code blocks with captions and line numbers
|
||||
* #7443: html theme: Add new options :confval:`globaltoc_collapse` and
|
||||
|
@ -25,25 +25,27 @@ import pydoc
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
from os import path
|
||||
from typing import Any, Callable, Dict, List, NamedTuple, Set, Tuple
|
||||
|
||||
from jinja2 import BaseLoader, FileSystemLoader, TemplateNotFound
|
||||
from jinja2 import TemplateNotFound
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
|
||||
import sphinx.locale
|
||||
from sphinx import __display_version__
|
||||
from sphinx import package_dir
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.config import Config
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning
|
||||
from sphinx.ext.autodoc import Documenter
|
||||
from sphinx.ext.autosummary import import_by_name, get_documenter
|
||||
from sphinx.jinja2glue import BuiltinTemplateLoader
|
||||
from sphinx.locale import __
|
||||
from sphinx.registry import SphinxComponentRegistry
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import rst
|
||||
from sphinx.util.inspect import safe_getattr
|
||||
from sphinx.util.osutil import ensuredir
|
||||
from sphinx.util.template import SphinxTemplateLoader
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
@ -59,6 +61,7 @@ class DummyApplication:
|
||||
def __init__(self) -> None:
|
||||
self.registry = SphinxComponentRegistry()
|
||||
self.messagelog = [] # type: List[str]
|
||||
self.translator = None
|
||||
self.verbosity = 0
|
||||
self._warncount = 0
|
||||
self.warningiserror = False
|
||||
@ -67,6 +70,21 @@ class DummyApplication:
|
||||
pass
|
||||
|
||||
|
||||
class DummyBuilder:
|
||||
"""Dummy builder class for sphinx-autogen command."""
|
||||
|
||||
def __init__(self, app: DummyApplication, template_path: str) -> None:
|
||||
if template_path:
|
||||
templates_path = [path.abspath(template_path)]
|
||||
else:
|
||||
templates_path = []
|
||||
|
||||
self.app = app
|
||||
self.srcdir = "/"
|
||||
self.config = Config(overrides={'templates_path': templates_path})
|
||||
self.config.init_values()
|
||||
|
||||
|
||||
AutosummaryEntry = NamedTuple('AutosummaryEntry', [('name', str),
|
||||
('path', str),
|
||||
('template', str),
|
||||
@ -110,16 +128,10 @@ class AutosummaryRenderer:
|
||||
"""A helper class for rendering."""
|
||||
|
||||
def __init__(self, builder: Builder, template_dir: str) -> None:
|
||||
loader = None # type: BaseLoader
|
||||
template_dirs = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')]
|
||||
if builder is None:
|
||||
if template_dir:
|
||||
template_dirs.insert(0, template_dir)
|
||||
loader = FileSystemLoader(template_dirs)
|
||||
else:
|
||||
# allow the user to override the templates
|
||||
loader = BuiltinTemplateLoader()
|
||||
loader.init(builder, dirs=template_dirs)
|
||||
system_templates_path = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')]
|
||||
loader = SphinxTemplateLoader(builder.srcdir,
|
||||
builder.config.templates_path,
|
||||
system_templates_path)
|
||||
|
||||
self.env = SandboxedEnvironment(loader=loader)
|
||||
self.env.filters['escape'] = rst.escape
|
||||
@ -514,9 +526,9 @@ def main(argv: List[str] = sys.argv[1:]) -> None:
|
||||
logging.setup(app, sys.stdout, sys.stderr) # type: ignore
|
||||
setup_documenters(app)
|
||||
args = get_parser().parse_args(argv)
|
||||
builder = DummyBuilder(app, args.templates)
|
||||
generate_autosummary_docs(args.source_file, args.output_dir,
|
||||
'.' + args.suffix,
|
||||
template_dir=args.templates,
|
||||
'.' + args.suffix, builder=builder, # type: ignore
|
||||
imported_members=args.imported_members,
|
||||
app=app)
|
||||
|
||||
|
@ -10,8 +10,11 @@
|
||||
|
||||
import os
|
||||
from functools import partial
|
||||
from typing import Dict, List, Union
|
||||
from os import path
|
||||
from typing import Callable, Dict, List, Tuple, Union
|
||||
|
||||
from jinja2 import TemplateNotFound
|
||||
from jinja2.environment import Environment
|
||||
from jinja2.loaders import BaseLoader
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
|
||||
@ -94,3 +97,36 @@ class ReSTRenderer(SphinxRenderer):
|
||||
self.env.filters['e'] = rst.escape
|
||||
self.env.filters['escape'] = rst.escape
|
||||
self.env.filters['heading'] = rst.heading
|
||||
|
||||
|
||||
class SphinxTemplateLoader(BaseLoader):
|
||||
"""A loader supporting template inheritance"""
|
||||
|
||||
def __init__(self, confdir: str, templates_paths: List[str],
|
||||
system_templates_paths: List[str]) -> None:
|
||||
self.loaders = []
|
||||
self.sysloaders = []
|
||||
|
||||
for templates_path in templates_paths:
|
||||
loader = SphinxFileSystemLoader(path.join(confdir, templates_path))
|
||||
self.loaders.append(loader)
|
||||
|
||||
for templates_path in system_templates_paths:
|
||||
loader = SphinxFileSystemLoader(templates_path)
|
||||
self.loaders.append(loader)
|
||||
self.sysloaders.append(loader)
|
||||
|
||||
def get_source(self, environment: Environment, template: str) -> Tuple[str, str, Callable]:
|
||||
if template.startswith('!'):
|
||||
# search a template from ``system_templates_paths``
|
||||
loaders = self.sysloaders
|
||||
template = template[1:]
|
||||
else:
|
||||
loaders = self.loaders
|
||||
|
||||
for loader in loaders:
|
||||
try:
|
||||
return loader.get_source(environment, template)
|
||||
except TemplateNotFound:
|
||||
pass
|
||||
raise TemplateNotFound(template)
|
||||
|
Loading…
Reference in New Issue
Block a user