From 3863256cb6e04730a1ed9897415f0aeff9e2a515 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Wed, 28 Nov 2018 01:53:00 +0900 Subject: [PATCH] Add SphinxTranslator as an abstract class --- sphinx/ext/graphviz.py | 5 +-- sphinx/util/docutils.py | 27 ++++++++++++++ sphinx/writers/html.py | 28 ++++++++------- sphinx/writers/html5.py | 30 ++++++++-------- sphinx/writers/latex.py | 76 +++++++++++++++++++-------------------- sphinx/writers/manpage.py | 35 +++++++++--------- sphinx/writers/texinfo.py | 16 ++++----- sphinx/writers/text.py | 15 ++++---- tests/test_markup.py | 1 + 9 files changed, 134 insertions(+), 99 deletions(-) diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index e073d63b8..a926bef6e 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -33,8 +33,9 @@ from sphinx.util.osutil import ensuredir, ENOENT, EPIPE, EINVAL if False: # For type annotation from docutils.parsers.rst import Directive # NOQA - from typing import Any, Dict, List, Tuple, Union # NOQA + from typing import Any, Dict, List, Tuple # NOQA from sphinx.application import Sphinx # NOQA + from sphinx.util.docutils import SphinxTranslator # NOQA from sphinx.util.typing import unicode # NOQA from sphinx.writers.html import HTMLTranslator # NOQA from sphinx.writers.latex import LaTeXTranslator # NOQA @@ -219,7 +220,7 @@ class GraphvizSimple(SphinxDirective): def render_dot(self, code, options, format, prefix='graphviz'): - # type: (Union[HTMLTranslator, LaTeXTranslator, TexinfoTranslator], unicode, Dict, unicode, unicode) -> Tuple[unicode, unicode] # NOQA + # type: (SphinxTranslator, unicode, Dict, unicode, unicode) -> Tuple[unicode, unicode] # NOQA """Render graphviz code into a PNG or PDF output file.""" graphviz_dot = options.get('graphviz_dot', self.builder.config.graphviz_dot) hashkey = (code + str(options) + str(graphviz_dot) + diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py index 7b1edfc34..6b2247dbd 100644 --- a/sphinx/util/docutils.py +++ b/sphinx/util/docutils.py @@ -39,6 +39,7 @@ if False: from types import ModuleType # NOQA from typing import Any, Callable, Generator, List, Set, Tuple, Type # NOQA from docutils.statemachine import State, ViewList # NOQA + from sphinx.builders import Builder # NOQA from sphinx.config import Config # NOQA from sphinx.environment import BuildEnvironment # NOQA from sphinx.io import SphinxFileInput # NOQA @@ -383,6 +384,32 @@ class SphinxDirective(Directive): return self.env.config +class SphinxTranslator(nodes.NodeVisitor): + """A base class for Sphinx translators. + + This class provides helper methods for Sphinx translators. + + .. note:: The subclasses of this class might not work with docutils. + This class is strongly coupled with Sphinx. + """ + + def __init__(self, builder, document): + # type: (Builder, nodes.document) -> None + super(SphinxTranslator, self).__init__(document) + self.builder = builder + self.config = builder.config + + def get_settings(self): + # type: () -> Any + """Get settings object with type safe. + + .. note:: It is hard to check types for settings object because it's attributes + are added dynamically. This method avoids the type errors through + imitating it's type as Any. + """ + return self.document.settings + + # cache a vanilla instance of nodes.document # Used in new_document() function __document_cache__ = None # type: nodes.document diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 8589da2b1..e4c4bca07 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -23,6 +23,7 @@ from sphinx import addnodes from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.locale import admonitionlabels, _, __ from sphinx.util import logging +from sphinx.util.docutils import SphinxTranslator from sphinx.util.images import get_image_size if False: @@ -67,25 +68,26 @@ class HTMLWriter(Writer): self.clean_meta = ''.join(self.visitor.meta[2:]) -class HTMLTranslator(BaseTranslator): +class HTMLTranslator(SphinxTranslator, BaseTranslator): """ Our custom HTML translator. """ - def __init__(self, builder, *args, **kwds): - # type: (StandaloneHTMLBuilder, Any, Any) -> None - super(HTMLTranslator, self).__init__(*args, **kwds) - self.highlighter = builder.highlighter - self.builder = builder - self.docnames = [builder.current_docname] # for singlehtml builder - self.manpages_url = builder.config.manpages_url + builder = None # type: StandaloneHTMLBuilder + + def __init__(self, builder, document): + # type: (StandaloneHTMLBuilder, nodes.document) -> None + super(HTMLTranslator, self).__init__(builder, document) + self.highlighter = self.builder.highlighter + self.docnames = [self.builder.current_docname] # for singlehtml builder + self.manpages_url = self.config.manpages_url self.protect_literal_text = 0 - self.permalink_text = builder.config.html_add_permalinks + self.permalink_text = self.config.html_add_permalinks # support backwards-compatible setting to a bool if not isinstance(self.permalink_text, str): self.permalink_text = self.permalink_text and u'\u00B6' or '' self.permalink_text = self.encode(self.permalink_text) - self.secnumber_suffix = builder.config.html_secnumber_suffix + self.secnumber_suffix = self.config.html_secnumber_suffix self.param_separator = '' self.optional_param_level = 0 self._table_row_index = 0 @@ -250,8 +252,8 @@ class HTMLTranslator(BaseTranslator): atts['class'] += ' external' if 'refuri' in node: atts['href'] = node['refuri'] or '#' - if self.settings.cloak_email_addresses and \ - atts['href'].startswith('mailto:'): + if (self.get_settings().cloak_email_addresses and + atts['href'].startswith('mailto:')): atts['href'] = self.cloak_mailto(atts['href']) self.in_mailto = True else: @@ -708,7 +710,7 @@ class HTMLTranslator(BaseTranslator): # protect runs of multiple spaces; the last one can wrap self.body.append(' ' * (len(token) - 1) + ' ') else: - if self.in_mailto and self.settings.cloak_email_addresses: + if self.in_mailto and self.get_settings().cloak_email_addresses: encoded = self.cloak_email(encoded) self.body.append(encoded) diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index 6524baadc..133cd6b71 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -22,6 +22,7 @@ from sphinx import addnodes from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.locale import admonitionlabels, _, __ from sphinx.util import logging +from sphinx.util.docutils import SphinxTranslator from sphinx.util.images import get_image_size if False: @@ -37,25 +38,26 @@ logger = logging.getLogger(__name__) # http://www.arnebrodowski.de/blog/write-your-own-restructuredtext-writer.html -class HTML5Translator(BaseTranslator): +class HTML5Translator(SphinxTranslator, BaseTranslator): """ Our custom HTML translator. """ - def __init__(self, builder, *args, **kwds): - # type: (StandaloneHTMLBuilder, Any, Any) -> None - super(HTML5Translator, self).__init__(*args, **kwds) - self.highlighter = builder.highlighter - self.builder = builder - self.docnames = [builder.current_docname] # for singlehtml builder - self.manpages_url = builder.config.manpages_url + builder = None # type: StandaloneHTMLBuilder + + def __init__(self, builder, document): + # type: (StandaloneHTMLBuilder, nodes.document) -> None + super(HTML5Translator, self).__init__(builder, document) + self.highlighter = self.builder.highlighter + self.docnames = [self.builder.current_docname] # for singlehtml builder + self.manpages_url = self.config.manpages_url self.protect_literal_text = 0 - self.permalink_text = builder.config.html_add_permalinks + self.permalink_text = self.config.html_add_permalinks # support backwards-compatible setting to a bool if not isinstance(self.permalink_text, str): self.permalink_text = self.permalink_text and u'\u00B6' or '' self.permalink_text = self.encode(self.permalink_text) - self.secnumber_suffix = builder.config.html_secnumber_suffix + self.secnumber_suffix = self.config.html_secnumber_suffix self.param_separator = '' self.optional_param_level = 0 self._table_row_index = 0 @@ -219,8 +221,8 @@ class HTML5Translator(BaseTranslator): atts['class'] += ' external' if 'refuri' in node: atts['href'] = node['refuri'] or '#' - if self.settings.cloak_email_addresses and \ - atts['href'].startswith('mailto:'): + if (self.get_settings().cloak_email_addresses and + atts['href'].startswith('mailto:')): atts['href'] = self.cloak_mailto(atts['href']) self.in_mailto = True else: @@ -649,7 +651,7 @@ class HTML5Translator(BaseTranslator): # protect runs of multiple spaces; the last one can wrap self.body.append(' ' * (len(token) - 1) + ' ') else: - if self.in_mailto and self.settings.cloak_email_addresses: + if self.in_mailto and self.get_settings().cloak_email_addresses: encoded = self.cloak_email(encoded) self.body.append(encoded) @@ -788,7 +790,7 @@ class HTML5Translator(BaseTranslator): self._table_row_index = 0 classes = [cls.strip(u' \t\n') - for cls in self.settings.table_style.split(',')] + for cls in self.get_settings().table_style.split(',')] classes.insert(0, "docutils") # compat if 'align' in node: classes.append('align-%s' % node['align']) diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 14fa2bdd3..69663c334 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -29,6 +29,7 @@ from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warnin from sphinx.errors import SphinxError from sphinx.locale import admonitionlabels, _, __ from sphinx.util import split_into, logging +from sphinx.util.docutils import SphinxTranslator from sphinx.util.i18n import format_date from sphinx.util.nodes import clean_astext from sphinx.util.template import LaTeXRenderer @@ -497,7 +498,8 @@ def rstdim_to_latexdim(width_str): return res -class LaTeXTranslator(nodes.NodeVisitor): +class LaTeXTranslator(SphinxTranslator): + builder = None # type: LaTeXBuilder secnumdepth = 2 # legacy sphinxhowto.cls uses this, whereas article.cls # default is originally 3. For book/report, 2 is already LaTeX default. @@ -508,8 +510,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def __init__(self, document, builder): # type: (nodes.document, LaTeXBuilder) -> None - super(LaTeXTranslator, self).__init__(document) - self.builder = builder + super(LaTeXTranslator, self).__init__(builder, document) self.body = [] # type: List[unicode] # flags @@ -529,42 +530,42 @@ class LaTeXTranslator(nodes.NodeVisitor): self.first_param = 0 # sort out some elements - self.elements = builder.context.copy() + self.elements = self.builder.context.copy() # but some have other interface in config file - self.elements['wrapperclass'] = self.format_docclass(document.settings.docclass) + self.elements['wrapperclass'] = self.format_docclass(self.get_settings().docclass) # we assume LaTeX class provides \chapter command except in case # of non-Japanese 'howto' case self.sectionnames = LATEXSECTIONNAMES[:] - if document.settings.docclass == 'howto': - docclass = builder.config.latex_docclass.get('howto', 'article') + if self.get_settings().docclass == 'howto': + docclass = self.config.latex_docclass.get('howto', 'article') if docclass[0] == 'j': # Japanese class... pass else: self.sectionnames.remove('chapter') else: - docclass = builder.config.latex_docclass.get('manual', 'report') + docclass = self.config.latex_docclass.get('manual', 'report') self.elements['docclass'] = docclass # determine top section level self.top_sectionlevel = 1 - if builder.config.latex_toplevel_sectioning: + if self.config.latex_toplevel_sectioning: try: self.top_sectionlevel = \ - self.sectionnames.index(builder.config.latex_toplevel_sectioning) + self.sectionnames.index(self.config.latex_toplevel_sectioning) except ValueError: logger.warning(__('unknown %r toplevel_sectioning for class %r') % - (builder.config.latex_toplevel_sectioning, docclass)) + (self.config.latex_toplevel_sectioning, docclass)) - if builder.config.today: - self.elements['date'] = builder.config.today + if self.config.today: + self.elements['date'] = self.config.today else: - self.elements['date'] = format_date(builder.config.today_fmt or _('%b %d, %Y'), - language=builder.config.language) + self.elements['date'] = format_date(self.config.today_fmt or _('%b %d, %Y'), + language=self.config.language) - if builder.config.numfig: - self.numfig_secnum_depth = builder.config.numfig_secnum_depth + if self.config.numfig: + self.numfig_secnum_depth = self.config.numfig_secnum_depth if self.numfig_secnum_depth > 0: # default is 1 # numfig_secnum_depth as passed to sphinx.sty indices same names as in # LATEXSECTIONNAMES but with -1 for part, 0 for chapter, 1 for section... @@ -582,31 +583,31 @@ class LaTeXTranslator(nodes.NodeVisitor): else: self.elements['sphinxpkgoptions'] += ',nonumfigreset' try: - if builder.config.math_numfig: + if self.config.math_numfig: self.elements['sphinxpkgoptions'] += ',mathnumfig' except AttributeError: pass - if builder.config.latex_logo: + if self.config.latex_logo: # no need for \\noindent here, used in flushright self.elements['logo'] = '\\sphinxincludegraphics{%s}\\par' % \ - path.basename(builder.config.latex_logo) + path.basename(self.config.latex_logo) - if (builder.config.language and builder.config.language != 'ja' and - 'fncychap' not in builder.config.latex_elements): + if (self.config.language and self.config.language != 'ja' and + 'fncychap' not in self.config.latex_elements): # use Sonny style if any language specified self.elements['fncychap'] = ('\\usepackage[Sonny]{fncychap}\n' '\\ChNameVar{\\Large\\normalfont' '\\sffamily}\n\\ChTitleVar{\\Large' '\\normalfont\\sffamily}') - self.babel = ExtBabel(builder.config.language, + self.babel = ExtBabel(self.config.language, not self.elements['babel']) - if builder.config.language and not self.babel.is_supported_language(): + if self.config.language and not self.babel.is_supported_language(): # emit warning if specified language is invalid # (only emitting, nothing changed to processing) logger.warning(__('no Babel option known for language %r'), - builder.config.language) + self.config.language) # set up multilingual module... if self.elements['latex_engine'] == 'pdflatex': @@ -628,12 +629,11 @@ class LaTeXTranslator(nodes.NodeVisitor): self.elements['classoptions'] += ',' + self.babel.get_language() # this branch is not taken for xelatex/lualatex if default settings self.elements['multilingual'] = self.elements['babel'] - if builder.config.language: + if self.config.language: self.elements['shorthandoff'] = SHORTHANDOFF # Times fonts don't work with Cyrillic languages - if self.babel.uses_cyrillic() \ - and 'fontpkg' not in builder.config.latex_elements: + if self.babel.uses_cyrillic() and 'fontpkg' not in self.config.latex_elements: self.elements['fontpkg'] = '' elif self.elements['polyglossia']: self.elements['classoptions'] += ',' + self.babel.get_language() @@ -647,25 +647,25 @@ class LaTeXTranslator(nodes.NodeVisitor): self.elements['multilingual'] = '%s\n%s' % (self.elements['polyglossia'], mainlanguage) - if getattr(builder, 'usepackages', None): + if getattr(self.builder, 'usepackages', None): def declare_package(packagename, options=None): # type:(unicode, unicode) -> unicode if options: return '\\usepackage[%s]{%s}' % (options, packagename) else: return '\\usepackage{%s}' % (packagename,) - usepackages = (declare_package(*p) for p in builder.usepackages) + usepackages = (declare_package(*p) for p in self.builder.usepackages) self.elements['usepackages'] += "\n".join(usepackages) minsecnumdepth = self.secnumdepth # 2 from legacy sphinx manual/howto - if document.get('tocdepth'): + if self.document.get('tocdepth'): # reduce tocdepth if `part` or `chapter` is used for top_sectionlevel # tocdepth = -1: show only parts # tocdepth = 0: show parts and chapters # tocdepth = 1: show parts, chapters and sections # tocdepth = 2: show parts, chapters, sections and subsections # ... - tocdepth = document['tocdepth'] + self.top_sectionlevel - 2 + tocdepth = self.document['tocdepth'] + self.top_sectionlevel - 2 if len(self.sectionnames) < len(LATEXSECTIONNAMES) and \ self.top_sectionlevel > 0: tocdepth += 1 # because top_sectionlevel is shifted by -1 @@ -676,16 +676,16 @@ class LaTeXTranslator(nodes.NodeVisitor): self.elements['tocdepth'] = '\\setcounter{tocdepth}{%d}' % tocdepth minsecnumdepth = max(minsecnumdepth, tocdepth) - if builder.config.numfig and (builder.config.numfig_secnum_depth > 0): + if self.config.numfig and (self.config.numfig_secnum_depth > 0): minsecnumdepth = max(minsecnumdepth, self.numfig_secnum_depth - 1) if minsecnumdepth > self.secnumdepth: self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' %\ minsecnumdepth - if getattr(document.settings, 'contentsname', None): - self.elements['contentsname'] = \ - self.babel_renewcommand('\\contentsname', document.settings.contentsname) + contentsname = self.get_settings().contentsname + self.elements['contentsname'] = self.babel_renewcommand('\\contentsname', + contentsname) if self.elements['maxlistdepth']: self.elements['sphinxpkgoptions'] += (',maxlistdepth=%s' % @@ -699,9 +699,9 @@ class LaTeXTranslator(nodes.NodeVisitor): if self.elements['extraclassoptions']: self.elements['classoptions'] += ',' + \ self.elements['extraclassoptions'] - self.elements['numfig_format'] = self.generate_numfig_format(builder) + self.elements['numfig_format'] = self.generate_numfig_format(self.builder) - self.highlighter = highlighting.PygmentsBridge('latex', builder.config.pygments_style) + self.highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style) self.context = [] # type: List[Any] self.descstack = [] # type: List[unicode] self.table = None # type: Table diff --git a/sphinx/writers/manpage.py b/sphinx/writers/manpage.py index 850b23c3b..9ad5919fe 100644 --- a/sphinx/writers/manpage.py +++ b/sphinx/writers/manpage.py @@ -20,6 +20,7 @@ from docutils.writers.manpage import ( from sphinx import addnodes from sphinx.locale import admonitionlabels, _ from sphinx.util import logging +from sphinx.util.docutils import SphinxTranslator from sphinx.util.i18n import format_date from sphinx.util.nodes import NodeMatcher @@ -78,17 +79,16 @@ class NestedInlineTransform: node.parent.insert(pos + 1, newnode) -class ManualPageTranslator(BaseTranslator): +class ManualPageTranslator(SphinxTranslator, BaseTranslator): """ Custom translator. """ _docinfo = {} # type: Dict[unicode, Any] - def __init__(self, builder, *args, **kwds): - # type: (Builder, Any, Any) -> None - super(ManualPageTranslator, self).__init__(*args, **kwds) - self.builder = builder + def __init__(self, builder, document): + # type: (Builder, nodes.document) -> None + super(ManualPageTranslator, self).__init__(builder, document) self.in_productionlist = 0 @@ -96,23 +96,24 @@ class ManualPageTranslator(BaseTranslator): self.section_level = -1 # docinfo set by man_pages config value - self._docinfo['title'] = self.document.settings.title - self._docinfo['subtitle'] = self.document.settings.subtitle - if self.document.settings.authors: + settings = self.get_settings() + self._docinfo['title'] = settings.title + self._docinfo['subtitle'] = settings.subtitle + if settings.authors: # don't set it if no author given - self._docinfo['author'] = self.document.settings.authors - self._docinfo['manual_section'] = self.document.settings.section + self._docinfo['author'] = settings.authors + self._docinfo['manual_section'] = settings.section # docinfo set by other config values self._docinfo['title_upper'] = self._docinfo['title'].upper() - if builder.config.today: - self._docinfo['date'] = builder.config.today + if self.config.today: + self._docinfo['date'] = self.config.today else: - self._docinfo['date'] = format_date(builder.config.today_fmt or _('%b %d, %Y'), - language=builder.config.language) - self._docinfo['copyright'] = builder.config.copyright - self._docinfo['version'] = builder.config.version - self._docinfo['manual_group'] = builder.config.project + self._docinfo['date'] = format_date(self.config.today_fmt or _('%b %d, %Y'), + language=self.config.language) + self._docinfo['copyright'] = self.config.copyright + self._docinfo['version'] = self.config.version + self._docinfo['manual_group'] = self.config.project # Overwrite admonition label translations with our own for label, translation in admonitionlabels.items(): diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 6544d742f..1132d893c 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -20,6 +20,7 @@ from sphinx import addnodes, __display_version__ from sphinx.errors import ExtensionError from sphinx.locale import admonitionlabels, _, __ from sphinx.util import logging +from sphinx.util.docutils import SphinxTranslator from sphinx.util.i18n import format_date from sphinx.writers.latex import collected_footnote @@ -144,8 +145,9 @@ class TexinfoWriter(writers.Writer): setattr(self, attr, getattr(self.visitor, attr)) -class TexinfoTranslator(nodes.NodeVisitor): +class TexinfoTranslator(SphinxTranslator): + builder = None # type: TexinfoBuilder ignore_missing_images = False default_elements = { @@ -165,8 +167,7 @@ class TexinfoTranslator(nodes.NodeVisitor): def __init__(self, document, builder): # type: (nodes.document, TexinfoBuilder) -> None - super(TexinfoTranslator, self).__init__(document) - self.builder = builder + super(TexinfoTranslator, self).__init__(builder, document) self.init_settings() self.written_ids = set() # type: Set[unicode] @@ -227,7 +228,7 @@ class TexinfoTranslator(nodes.NodeVisitor): def init_settings(self): # type: () -> None - settings = self.settings = self.document.settings + self.settings = settings = self.get_settings() elements = self.elements = self.default_elements.copy() elements.update({ # if empty, the title is set to the first section title @@ -243,11 +244,10 @@ class TexinfoTranslator(nodes.NodeVisitor): language=self.builder.config.language)) }) # title - title = None # type: unicode - title = elements['title'] # type: ignore + title = settings.title # type: unicode if not title: - title = self.document.next_node(nodes.title) - title = (title and title.astext()) or '' # type: ignore + title_node = self.document.next_node(nodes.title) + title = (title and title_node.astext()) or '' elements['title'] = self.escape_id(title) or '' # filename if not elements['filename']: diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py index 3e5961753..9bad2c10e 100644 --- a/sphinx/writers/text.py +++ b/sphinx/writers/text.py @@ -20,6 +20,7 @@ from docutils.utils import column_width from sphinx import addnodes from sphinx.locale import admonitionlabels, _ +from sphinx.util.docutils import SphinxTranslator if False: # For type annotation @@ -391,23 +392,23 @@ class TextWriter(writers.Writer): self.output = cast(TextTranslator, visitor).body -class TextTranslator(nodes.NodeVisitor): +class TextTranslator(SphinxTranslator): + builder = None # type: TextBuilder def __init__(self, document, builder): # type: (nodes.document, TextBuilder) -> None - super(TextTranslator, self).__init__(document) - self.builder = builder + super(TextTranslator, self).__init__(builder, document) - newlines = builder.config.text_newlines + newlines = self.config.text_newlines if newlines == 'windows': self.nl = '\r\n' elif newlines == 'native': self.nl = os.linesep else: self.nl = '\n' - self.sectionchars = builder.config.text_sectionchars - self.add_secnumbers = builder.config.text_add_secnumbers - self.secnumber_suffix = builder.config.text_secnumber_suffix + self.sectionchars = self.config.text_sectionchars + self.add_secnumbers = self.config.text_add_secnumbers + self.secnumber_suffix = self.config.text_secnumber_suffix self.states = [[]] # type: List[List[Tuple[int, Union[unicode, List[unicode]]]]] self.stateindent = [0] self.list_counter = [] # type: List[int] diff --git a/tests/test_markup.py b/tests/test_markup.py index 0c376d041..c2f10298f 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -35,6 +35,7 @@ def settings(app): settings.smart_quotes = True settings.env = app.builder.env settings.env.temp_data['docname'] = 'dummy' + settings.contentsname = 'dummy' domain_context = sphinx_domains(settings.env) domain_context.enable() yield settings