Revert "Support and prefer `.jinja to _t` for static templates (#11165)" (#11329)

This reverts commit 5d13215b58.
This commit is contained in:
James Addison 2023-04-23 19:06:44 +01:00 committed by GitHub
parent aee3c0ab75
commit 59de8d5202
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 59 additions and 298 deletions

View File

@ -23,11 +23,6 @@ Deprecated
---------- ----------
* #11247: Deprecate the legacy ``intersphinx_mapping`` format * #11247: Deprecate the legacy ``intersphinx_mapping`` format
* #11165: Warn when the ``_t`` suffix is used for template files. The formal
deprecation process will begin no earlier than 31 December 2024.
Templates should change to use the ``.jinja`` filename suffix instead.
For more information, see :ref:`theming-static-templates`.
Patch by James Addison and Adam Turner
Features added Features added
-------------- --------------
@ -65,10 +60,6 @@ Features added
``= 'xelatex'``. Patch by Dimitar Dimitrov ``= 'xelatex'``. Patch by Dimitar Dimitrov
* #11109, #9643: Add :confval:`python_display_short_literal_types` option for * #11109, #9643: Add :confval:`python_display_short_literal_types` option for
condensed rendering of ``Literal`` types. condensed rendering of ``Literal`` types.
* #11165: Support the `officially recommended`_ ``.jinja`` suffix for template
files. Patch by James Addison
.. _officially recommended: https://jinja.palletsprojects.com/en/latest/templates/#template-file-extension
Bugs fixed Bugs fixed
---------- ----------

View File

@ -156,51 +156,13 @@ template static files as well as HTML files. Therefore, Sphinx supports
so-called "static templates", like this: so-called "static templates", like this:
If the name of a file in the ``static/`` directory of a theme (or in the user's If the name of a file in the ``static/`` directory of a theme (or in the user's
static path, for that matter) ends with ``.jinja``, it will be processed by the static path, for that matter) ends with ``_t``, it will be processed by the
template engine. The ``.jinja`` will be removed from the final file name. For template engine. The ``_t`` will be left from the final file name. For
example, the *classic* theme has a file ``static/classic.css.jinja`` which uses example, the *classic* theme has a file ``static/classic.css_t`` which uses
templating to put the colour options into the stylesheet. When a documentation templating to put the color options into the stylesheet. When a documentation
project is built with the classic theme, the output directory will contain a project is built with the classic theme, the output directory will contain a
``_static/classic.css`` file where all template tags have been processed. ``_static/classic.css`` file where all template tags have been processed.
.. versionchanged:: 6.2
The preferred suffix for static templates is now ``.jinja``, in line with
the Jinja project's `recommended file extension`_.
The ``_t`` file suffix for static templates is now considered 'legacy', and
support will eventually be removed. The standard deprecation process will
begin no earlier than 31 December 2024, at which point using ``_t`` suffixes
will emit ``RemovedInSphinx__Warning`` warnings.
If a static template with a ``_t`` suffix is detected, it will be processed
by the template engine, with the ``_t`` suffix removed from the final file
name.
To silence the warning for ``_t`` suffixes, the new
``sphinx.deprecation.OldJinjaSuffixWarning`` class has been added for use
with Python's standard `warning control`_ mechanisms. This class will be
removed no earlier than 31 December 2024, so guard any imports with a
try/except block.
For example, in a ``setup()`` function:
.. code:: python
import warnings
def setup(app):
try:
from sphinx.deprecation import OldJinjaSuffixWarning
except ImportError:
pass # Only silence the warning if it exists!
else:
warnings.filterwarnings('ignore', category=OldJinjaSuffixWarning)
...
.. _recommended file extension: https://jinja.palletsprojects.com/en/latest/templates/#template-file-extension
.. _warning control: https://docs.python.org/3/library/warnings.html#the-warnings-filter
Use custom page metadata in HTML templates Use custom page metadata in HTML templates
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1813,12 +1813,12 @@ Miscellany
.. hint:: .. hint::
As an experimental feature, Sphinx can use user-defined template file for As an experimental feature, Sphinx can use user-defined template file for
LaTeX source if you have a file named ``_templates/latex.tex.jinja`` in your LaTeX source if you have a file named ``_templates/latex.tex_t`` in your
project. project.
Additional files ``longtable.tex.jinja``, ``tabulary.tex.jinja`` and Additional files ``longtable.tex_t``, ``tabulary.tex_t`` and
``tabular.tex.jinja`` can be added to ``_templates/`` to configure some ``tabular.tex_t`` can be added to ``_templates/`` to configure some aspects
aspects of table rendering (such as the caption position). of table rendering (such as the caption position).
.. versionadded:: 1.6 .. versionadded:: 1.6
currently all template variables are unstable and undocumented. currently all template variables are unstable and undocumented.

View File

@ -603,8 +603,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
html.escape(self.refnodes[0]['refuri']))) html.escape(self.refnodes[0]['refuri'])))
# write the project file # write the project file
content_t = path.join(self.template_dir, 'content.opf.jinja') copy_asset_file(path.join(self.template_dir, 'content.opf_t'), self.outdir, metadata)
copy_asset_file(content_t, self.outdir, metadata)
def new_navpoint(self, node: dict[str, Any], level: int, incr: bool = True) -> NavPoint: def new_navpoint(self, node: dict[str, Any], level: int, incr: bool = True) -> NavPoint:
"""Create a new entry in the toc from the node at given level.""" """Create a new entry in the toc from the node at given level."""
@ -687,7 +686,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
navpoints = self.build_navpoints(refnodes) navpoints = self.build_navpoints(refnodes)
level = max(item['level'] for item in self.refnodes) level = max(item['level'] for item in self.refnodes)
level = min(level, self.config.epub_tocdepth) level = min(level, self.config.epub_tocdepth)
copy_asset_file(path.join(self.template_dir, 'toc.ncx.jinja'), self.outdir, copy_asset_file(path.join(self.template_dir, 'toc.ncx_t'), self.outdir,
self.toc_metadata(level, navpoints)) self.toc_metadata(level, navpoints))
def build_epub(self) -> None: def build_epub(self) -> None:

View File

@ -133,10 +133,10 @@ class ChangesBuilder(Builder):
f.write(self.templates.render('changes/rstsource.html', ctx)) f.write(self.templates.render('changes/rstsource.html', ctx))
themectx = {'theme_' + key: val for (key, val) in themectx = {'theme_' + key: val for (key, val) in
self.theme.get_options({}).items()} self.theme.get_options({}).items()}
default_t = path.join(package_dir, 'themes', 'default', 'static', 'default.css.jinja') copy_asset_file(path.join(package_dir, 'themes', 'default', 'static', 'default.css_t'),
copy_asset_file(default_t, self.outdir, context=themectx, renderer=self.templates) self.outdir, context=themectx, renderer=self.templates)
basic = path.join(package_dir, 'themes', 'basic', 'static', 'basic.css') copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'),
copy_asset_file(basic, self.outdir) self.outdir)
def hl(self, text: str, version: str) -> str: def hl(self, text: str, version: str) -> str:
text = html.escape(text) text = html.escape(text)

View File

@ -184,7 +184,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
# 'includehidden' # 'includehidden'
refnodes = self.refnodes refnodes = self.refnodes
navlist = self.build_navlist(refnodes) navlist = self.build_navlist(refnodes)
copy_asset_file(path.join(self.template_dir, 'nav.xhtml.jinja'), self.outdir, copy_asset_file(path.join(self.template_dir, 'nav.xhtml_t'), self.outdir,
self.navigation_doc_metadata(navlist)) self.navigation_doc_metadata(navlist))
# Add nav.xhtml to epub file # Add nav.xhtml to epub file

View File

@ -283,7 +283,7 @@ class MessageCatalogBuilder(I18nBuilder):
ensuredir(path.join(self.outdir, path.dirname(textdomain))) ensuredir(path.join(self.outdir, path.dirname(textdomain)))
context['messages'] = list(catalog) context['messages'] = list(catalog)
content = GettextRenderer(outdir=self.outdir).render('message.pot.jinja', context) content = GettextRenderer(outdir=self.outdir).render('message.pot_t', context)
pofn = path.join(self.outdir, textdomain + '.pot') pofn = path.join(self.outdir, textdomain + '.pot')
if should_write(pofn, content): if should_write(pofn, content):

View File

@ -402,7 +402,7 @@ class LaTeXBuilder(Builder):
# use pre-1.6.x Makefile for make latexpdf on Windows # use pre-1.6.x Makefile for make latexpdf on Windows
if os.name == 'nt': if os.name == 'nt':
staticdirname = path.join(package_dir, 'texinputs_win') staticdirname = path.join(package_dir, 'texinputs_win')
copy_asset_file(path.join(staticdirname, 'Makefile.jinja'), copy_asset_file(path.join(staticdirname, 'Makefile_t'),
self.outdir, context=context) self.outdir, context=context)
@progress_message(__('copying additional files')) @progress_message(__('copying additional files'))
@ -441,7 +441,7 @@ class LaTeXBuilder(Builder):
if self.context['babel'] or self.context['polyglossia']: if self.context['babel'] or self.context['polyglossia']:
context['addtocaptions'] = r'\addto\captions%s' % self.babel.get_language() context['addtocaptions'] = r'\addto\captions%s' % self.babel.get_language()
filename = path.join(package_dir, 'templates', 'latex', 'sphinxmessages.sty.jinja') filename = path.join(package_dir, 'templates', 'latex', 'sphinxmessages.sty_t')
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer()) copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())

View File

@ -370,29 +370,29 @@ def generate(
if 'quiet' not in d: if 'quiet' not in d:
print(__('File %s already exists, skipping.') % fpath) print(__('File %s already exists, skipping.') % fpath)
conf_path = os.path.join(templatedir, 'conf.py.jinja') if templatedir else None conf_path = os.path.join(templatedir, 'conf.py_t') if templatedir else None
if not conf_path or not path.isfile(conf_path): if not conf_path or not path.isfile(conf_path):
conf_path = os.path.join(package_dir, 'templates', 'quickstart', 'conf.py.jinja') conf_path = os.path.join(package_dir, 'templates', 'quickstart', 'conf.py_t')
with open(conf_path, encoding="utf-8") as f: with open(conf_path, encoding="utf-8") as f:
conf_text = f.read() conf_text = f.read()
write_file(path.join(srcdir, 'conf.py'), template.render_string(conf_text, d)) write_file(path.join(srcdir, 'conf.py'), template.render_string(conf_text, d))
masterfile = path.join(srcdir, d['master'] + d['suffix']) masterfile = path.join(srcdir, d['master'] + d['suffix'])
if template._has_custom_template('quickstart/master_doc.rst.jinja'): if template._has_custom_template('quickstart/master_doc.rst_t'):
msg = ('A custom template `master_doc.rst_t` found. It has been renamed to ' msg = ('A custom template `master_doc.rst_t` found. It has been renamed to '
'`root_doc.rst_t`. Please rename it on your project too.') '`root_doc.rst_t`. Please rename it on your project too.')
print(colorize('red', msg)) print(colorize('red', msg))
write_file(masterfile, template.render('quickstart/master_doc.rst.jinja', d)) write_file(masterfile, template.render('quickstart/master_doc.rst_t', d))
else: else:
write_file(masterfile, template.render('quickstart/root_doc.rst.jinja', d)) write_file(masterfile, template.render('quickstart/root_doc.rst_t', d))
if d.get('make_mode') is True: if d.get('make_mode') is True:
makefile_template = 'quickstart/Makefile.new.jinja' makefile_template = 'quickstart/Makefile.new_t'
batchfile_template = 'quickstart/make.bat.new.jinja' batchfile_template = 'quickstart/make.bat.new_t'
else: else:
makefile_template = 'quickstart/Makefile.jinja' makefile_template = 'quickstart/Makefile_t'
batchfile_template = 'quickstart/make.bat.jinja' batchfile_template = 'quickstart/make.bat_t'
if d['makefile'] is True: if d['makefile'] is True:
d['rsrcdir'] = 'source' if d['sep'] else '.' d['rsrcdir'] = 'source' if d['sep'] else '.'

View File

@ -62,31 +62,3 @@ def _deprecation_warning(
warnings.warn(message + " Check CHANGES for Sphinx API modifications.", warnings.warn(message + " Check CHANGES for Sphinx API modifications.",
warning_class, stacklevel=3) warning_class, stacklevel=3)
class OldJinjaSuffixWarning(PendingDeprecationWarning):
"""Warning class for ``_old_jinja_template_suffix_warning``.
This class exists only so that extensions and themes can silence the legacy
filename warning via Python's `warning control`_ mechanisms. See
:ref:`theming-static-templates` for an example.
This warning class will be removed, and the warning class changed to the
appropriate RemovedInSphinx_0Warning no earlier than 31 December 2024, at
which point the standard deprecation process for ``_t`` template suffixes
will start.
.. _warning control: https://docs.python.org/3/library/warnings.html#the-warnings-filter
"""
def _old_jinja_template_suffix_warning(filename: str) -> None:
if filename.endswith('_t'):
warnings.warn(
f"{filename!r}: the '_t' suffix for Jinja templates is deprecated. "
"If the file is a template, use the suffix '.jinja' instead. "
'For more information, see '
'https://www.sphinx-doc.org/en/master/development/theming.html#static-templates',
OldJinjaSuffixWarning,
stacklevel=3,
)

View File

@ -102,7 +102,7 @@ def create_module_file(package: str, basename: str, opts: Any,
'qualname': qualname, 'qualname': qualname,
'automodule_options': options, 'automodule_options': options,
} }
text = ReSTRenderer([user_template_dir, template_dir]).render('module.rst.jinja', context) text = ReSTRenderer([user_template_dir, template_dir]).render('module.rst_t', context)
write_file(qualname, text, opts) write_file(qualname, text, opts)
@ -138,8 +138,7 @@ def create_package_file(root: str, master_package: str, subroot: str, py_files:
'show_headings': not opts.noheadings, 'show_headings': not opts.noheadings,
'maxdepth': opts.maxdepth, 'maxdepth': opts.maxdepth,
} }
engine = ReSTRenderer([user_template_dir, template_dir]) text = ReSTRenderer([user_template_dir, template_dir]).render('package.rst_t', context)
text = engine.render('package.rst.jinja', context)
write_file(pkgname, text, opts) write_file(pkgname, text, opts)
if submodules and opts.separatemodules: if submodules and opts.separatemodules:
@ -164,7 +163,7 @@ def create_modules_toc_file(modules: list[str], opts: Any, name: str = 'modules'
'maxdepth': opts.maxdepth, 'maxdepth': opts.maxdepth,
'docnames': modules, 'docnames': modules,
} }
text = ReSTRenderer([user_template_dir, template_dir]).render('toc.rst.jinja', context) text = ReSTRenderer([user_template_dir, template_dir]).render('toc.rst_t', context)
write_file(name, text, opts) write_file(name, text, opts)

View File

@ -19,7 +19,6 @@ from sphinx import package_dir
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.builders import Builder from sphinx.builders import Builder
from sphinx.config import Config from sphinx.config import Config
from sphinx.deprecation import _old_jinja_template_suffix_warning
from sphinx.errors import SphinxError from sphinx.errors import SphinxError
from sphinx.locale import _, __ from sphinx.locale import _, __
from sphinx.util import logging, sha1 from sphinx.util import logging, sha1
@ -96,20 +95,16 @@ def generate_latex_macro(image_format: str,
} }
if config.imgmath_use_preview: if config.imgmath_use_preview:
template_name = 'preview.tex' template_name = 'preview.tex_t'
else: else:
template_name = 'template.tex' template_name = 'template.tex_t'
for template_dir in config.templates_path: for template_dir in config.templates_path:
# TODO: deprecate '_t' template suffix support after 2024-12-31 template = path.join(confdir, template_dir, template_name)
for template_suffix in ('_t', '.jinja'): if path.exists(template):
template = path.join(confdir, template_dir, template_name + template_suffix) return LaTeXRenderer().render(template, variables)
if path.exists(template):
_old_jinja_template_suffix_warning(template)
return LaTeXRenderer().render(template, variables)
# Default: fallback to a pathless in-library jinja template return LaTeXRenderer(templates_path).render(template_name, variables)
return LaTeXRenderer(templates_path).render(f"{template_name}.jinja", variables)
def ensure_tempdir(builder: Builder) -> str: def ensure_tempdir(builder: Builder) -> str:

View File

@ -8,7 +8,6 @@ from typing import TYPE_CHECKING, Callable
from docutils.utils import relative_path from docutils.utils import relative_path
from sphinx.deprecation import _old_jinja_template_suffix_warning
from sphinx.util.osutil import copyfile, ensuredir from sphinx.util.osutil import copyfile, ensuredir
from sphinx.util.typing import PathMatcher from sphinx.util.typing import PathMatcher
@ -16,19 +15,6 @@ if TYPE_CHECKING:
from sphinx.util.template import BaseRenderer from sphinx.util.template import BaseRenderer
def _template_basename(filename: str) -> str | None:
"""Given an input filename:
If the input looks like a template, then return the filename output should
be written to. Otherwise, return no result (None)."""
# TODO: deprecate '_t' template suffix support after 2024-12-31
if filename.lower().endswith('_t'):
_old_jinja_template_suffix_warning(filename)
return filename[:-2]
elif filename.lower().endswith(".jinja"):
return filename[:-6]
return None
def copy_asset_file(source: str, destination: str, def copy_asset_file(source: str, destination: str,
context: dict | None = None, context: dict | None = None,
renderer: BaseRenderer | None = None) -> None: renderer: BaseRenderer | None = None) -> None:
@ -49,13 +35,14 @@ def copy_asset_file(source: str, destination: str,
# Use source filename if destination points a directory # Use source filename if destination points a directory
destination = os.path.join(destination, os.path.basename(source)) destination = os.path.join(destination, os.path.basename(source))
if _template_basename(source) and context is not None: if source.lower().endswith('_t') and context is not None:
if renderer is None: if renderer is None:
from sphinx.util.template import SphinxRenderer from sphinx.util.template import SphinxRenderer
renderer = SphinxRenderer() renderer = SphinxRenderer()
with open(source, encoding='utf-8') as fsrc: with open(source, encoding='utf-8') as fsrc:
destination = _template_basename(destination) or destination if destination.lower().endswith('_t'):
destination = destination[:-2]
with open(destination, 'w', encoding='utf-8') as fdst: with open(destination, 'w', encoding='utf-8') as fdst:
fdst.write(renderer.render_string(fsrc.read(), context)) fdst.write(renderer.render_string(fsrc.read(), context))
else: else:

View File

@ -16,7 +16,7 @@ from docutils import nodes, writers
from docutils.nodes import Element, Node, Text from docutils.nodes import Element, Node, Text
from sphinx import addnodes, highlighting from sphinx import addnodes, highlighting
from sphinx.deprecation import RemovedInSphinx70Warning, _old_jinja_template_suffix_warning from sphinx.deprecation import RemovedInSphinx70Warning
from sphinx.domains import IndexEntry from sphinx.domains import IndexEntry
from sphinx.domains.std import StandardDomain from sphinx.domains.std import StandardDomain
from sphinx.errors import SphinxError from sphinx.errors import SphinxError
@ -435,8 +435,7 @@ class LaTeXTranslator(SphinxTranslator):
'body': ''.join(self.body), 'body': ''.join(self.body),
'indices': self.generate_indices(), 'indices': self.generate_indices(),
}) })
template = self._find_template('latex.tex') return self.render('latex.tex_t', self.elements)
return self.render(template, self.elements)
def hypertarget(self, id: str, withdoc: bool = True, anchor: bool = True) -> str: def hypertarget(self, id: str, withdoc: bool = True, anchor: bool = True) -> str:
if withdoc: if withdoc:
@ -513,21 +512,14 @@ class LaTeXTranslator(SphinxTranslator):
return ''.join(ret) return ''.join(ret)
def _find_template(self, template_name: str) -> str:
for template_dir in self.config.templates_path:
# TODO: deprecate '_t' template suffix support after 2024-12-31
for template_suffix in ('_t', '.jinja'):
template = path.join(self.builder.confdir, template_dir,
template_name + template_suffix)
if path.exists(template):
_old_jinja_template_suffix_warning(template)
return template
# Default: fallback to a pathless in-library jinja template
return f"{template_name}.jinja"
def render(self, template_name: str, variables: dict[str, Any]) -> str: def render(self, template_name: str, variables: dict[str, Any]) -> str:
renderer = LaTeXRenderer(latex_engine=self.config.latex_engine) renderer = LaTeXRenderer(latex_engine=self.config.latex_engine)
for template_dir in self.config.templates_path:
template = path.join(self.builder.confdir, template_dir,
template_name)
if path.exists(template):
return renderer.render(template, variables)
return renderer.render(template_name, variables) return renderer.render(template_name, variables)
@property @property
@ -910,8 +902,8 @@ class LaTeXTranslator(SphinxTranslator):
def depart_table(self, node: Element) -> None: def depart_table(self, node: Element) -> None:
labels = self.hypertarget_to(node) labels = self.hypertarget_to(node)
table_type = self.table.get_table_type() table_type = self.table.get_table_type()
template = self._find_template(f"{table_type}.tex") table = self.render(table_type + '.tex_t',
table = self.render(template, {'table': self.table, 'labels': labels}) {'table': self.table, 'labels': labels})
self.body.append(BLANKLINE) self.body.append(BLANKLINE)
self.body.append(table) self.body.append(table)
self.body.append(CR) self.body.append(CR)

View File

@ -1,2 +0,0 @@
<# TODO: deprecate '_t' template suffix support after 2024-12-31 #>
AU REVOIR, KANIGGETS

View File

@ -1153,7 +1153,7 @@ def test_html_assets(app):
# html_extra_path # html_extra_path
assert (app.outdir / '.htaccess').exists() assert (app.outdir / '.htaccess').exists()
assert not (app.outdir / '.htpasswd').exists() assert not (app.outdir / '.htpasswd').exists()
assert (app.outdir / 'API.html.jinja').exists() assert (app.outdir / 'API.html_t').exists()
assert (app.outdir / 'css/style.css').exists() assert (app.outdir / 'css/style.css').exists()
assert (app.outdir / 'rimg.png').exists() assert (app.outdir / 'rimg.png').exists()
assert not (app.outdir / '_build' / 'index.html').exists() assert not (app.outdir / '_build' / 'index.html').exists()

View File

@ -1382,10 +1382,6 @@ def test_latex_table_custom_template_caseA(app, status, warning):
result = (app.outdir / 'python.tex').read_text(encoding='utf8') result = (app.outdir / 'python.tex').read_text(encoding='utf8')
assert 'SALUT LES COPAINS' in result assert 'SALUT LES COPAINS' in result
# # TODO: deprecate '_t' template suffix support after 2024-12-31
assert 'TODO' not in result
assert 'AU REVOIR, KANIGGETS' in result
@pytest.mark.sphinx('latex', testroot='latex-table', @pytest.mark.sphinx('latex', testroot='latex-table',
confoverrides={'templates_path': ['_mytemplates']}) confoverrides={'templates_path': ['_mytemplates']})

View File

@ -1,114 +0,0 @@
import warnings
from pathlib import Path
import pytest
from sphinx import deprecation
def test_old_jinja_suffix_warning_is_warning():
assert isinstance(deprecation.OldJinjaSuffixWarning, type)
assert issubclass(deprecation.OldJinjaSuffixWarning, Warning)
assert issubclass(deprecation.OldJinjaSuffixWarning, PendingDeprecationWarning)
with pytest.warns(deprecation.OldJinjaSuffixWarning):
warnings.warn('test_1', category=deprecation.OldJinjaSuffixWarning)
with pytest.warns(PendingDeprecationWarning):
warnings.warn('test_2', category=deprecation.OldJinjaSuffixWarning)
with pytest.warns(Warning):
warnings.warn('test_3', category=deprecation.OldJinjaSuffixWarning)
def test_old_jinja_suffix_warning_simplefilter_always(recwarn):
assert len(recwarn) == 0
warnings.resetwarnings()
warnings.simplefilter('always', category=deprecation.OldJinjaSuffixWarning)
warnings.warn('test_simplefilter_always', category=deprecation.OldJinjaSuffixWarning)
assert len(recwarn) == 1
caught_warning = recwarn[0]
assert caught_warning.category is deprecation.OldJinjaSuffixWarning
assert str(caught_warning.message) == 'test_simplefilter_always'
def test_old_jinja_suffix_warning_filterwarnings_always(recwarn):
assert len(recwarn) == 0
warnings.resetwarnings()
warnings.filterwarnings('always', category=deprecation.OldJinjaSuffixWarning)
warnings.warn('test_filterwarnings_always', category=deprecation.OldJinjaSuffixWarning)
assert len(recwarn) == 1
caught_warning = recwarn[0]
assert caught_warning.category is deprecation.OldJinjaSuffixWarning
assert str(caught_warning.message) == 'test_filterwarnings_always'
def test_old_jinja_suffix_warning_simplefilter_ignore(recwarn):
assert len(recwarn) == 0
warnings.resetwarnings()
warnings.simplefilter('ignore', deprecation.OldJinjaSuffixWarning)
warnings.warn('test_simplefilter_ignore', category=deprecation.OldJinjaSuffixWarning)
assert len(recwarn) == 0
def test_old_jinja_suffix_warning_filterwarnings_ignore(recwarn):
assert len(recwarn) == 0
warnings.resetwarnings()
warnings.filterwarnings('ignore', category=deprecation.OldJinjaSuffixWarning)
warnings.warn('test_filterwarnings_ignore', category=deprecation.OldJinjaSuffixWarning)
assert len(recwarn) == 0
def test__old_jinja_template_suffix_no_warning_css(recwarn):
assert len(recwarn) == 0
warnings.resetwarnings()
warnings.simplefilter('always', category=deprecation.OldJinjaSuffixWarning)
deprecation._old_jinja_template_suffix_warning('template.css')
assert len(recwarn) == 0
def test__old_jinja_template_suffix_no_warning_jinja(recwarn):
assert len(recwarn) == 0
warnings.resetwarnings()
warnings.simplefilter('always', category=deprecation.OldJinjaSuffixWarning)
deprecation._old_jinja_template_suffix_warning('template.css.jinja')
assert len(recwarn) == 0
def test__old_jinja_template_suffix_warning__t():
with pytest.warns(deprecation.OldJinjaSuffixWarning,
match=r"the '_t' suffix for Jinja templates is deprecated"):
deprecation._old_jinja_template_suffix_warning('template.css_t')
def test__old_jinja_template_suffix_warning_stacklevel():
# _old_jinja_template_suffix_warning is only called within functions that
# use template files.
def do_something_with_templates(filename):
deprecation._old_jinja_template_suffix_warning(filename)
# TOJTSWS line number marker
with pytest.warns(deprecation.OldJinjaSuffixWarning) as caught:
do_something_with_templates('template.css_t')
lines = [b''] + Path(__file__).read_bytes().splitlines()
line_number = lines.index(b' # TOJTSWS line number marker') + 2
assert len(caught) == 1
caught_warning = caught[0]
assert caught_warning.category is deprecation.OldJinjaSuffixWarning
assert "the '_t' suffix for Jinja templates is deprecated" in str(caught_warning.message)
assert caught_warning.filename == __file__
assert caught_warning.lineno == line_number

View File

@ -3,7 +3,7 @@
from unittest import mock from unittest import mock
from sphinx.jinja2glue import BuiltinTemplateLoader from sphinx.jinja2glue import BuiltinTemplateLoader
from sphinx.util.fileutil import _template_basename, copy_asset, copy_asset_file from sphinx.util.fileutil import copy_asset, copy_asset_file
class DummyTemplateLoader(BuiltinTemplateLoader): class DummyTemplateLoader(BuiltinTemplateLoader):
@ -28,9 +28,9 @@ def test_copy_asset_file(tempdir):
assert src.read_text(encoding='utf8') == dest.read_text(encoding='utf8') assert src.read_text(encoding='utf8') == dest.read_text(encoding='utf8')
# copy template file # copy template file
src = (tempdir / 'asset.txt.jinja') src = (tempdir / 'asset.txt_t')
src.write_text('# {{var1}} data') src.write_text('# {{var1}} data')
dest = (tempdir / 'output.txt.jinja') dest = (tempdir / 'output.txt_t')
copy_asset_file(src, dest, {'var1': 'template'}, renderer) copy_asset_file(src, dest, {'var1': 'template'}, renderer)
assert not dest.exists() assert not dest.exists()
@ -38,7 +38,7 @@ def test_copy_asset_file(tempdir):
assert (tempdir / 'output.txt').read_text(encoding='utf8') == '# template data' assert (tempdir / 'output.txt').read_text(encoding='utf8') == '# template data'
# copy template file to subdir # copy template file to subdir
src = (tempdir / 'asset.txt.jinja') src = (tempdir / 'asset.txt_t')
src.write_text('# {{var1}} data') src.write_text('# {{var1}} data')
subdir1 = (tempdir / 'subdir') subdir1 = (tempdir / 'subdir')
subdir1.makedirs() subdir1.makedirs()
@ -48,14 +48,14 @@ def test_copy_asset_file(tempdir):
assert (subdir1 / 'asset.txt').read_text(encoding='utf8') == '# template data' assert (subdir1 / 'asset.txt').read_text(encoding='utf8') == '# template data'
# copy template file without context # copy template file without context
src = (tempdir / 'asset.txt.jinja') src = (tempdir / 'asset.txt_t')
subdir2 = (tempdir / 'subdir2') subdir2 = (tempdir / 'subdir2')
subdir2.makedirs() subdir2.makedirs()
copy_asset_file(src, subdir2) copy_asset_file(src, subdir2)
assert not (subdir2 / 'asset.txt').exists() assert not (subdir2 / 'asset.txt').exists()
assert (subdir2 / 'asset.txt.jinja').exists() assert (subdir2 / 'asset.txt_t').exists()
assert (subdir2 / 'asset.txt.jinja').read_text(encoding='utf8') == '# {{var1}} data' assert (subdir2 / 'asset.txt_t').read_text(encoding='utf8') == '# {{var1}} data'
def test_copy_asset(tempdir): def test_copy_asset(tempdir):
@ -65,12 +65,12 @@ def test_copy_asset(tempdir):
source = (tempdir / 'source') source = (tempdir / 'source')
source.makedirs() source.makedirs()
(source / 'index.rst').write_text('index.rst', encoding='utf8') (source / 'index.rst').write_text('index.rst', encoding='utf8')
(source / 'foo.rst.jinja').write_text('{{var1}}.rst', encoding='utf8') (source / 'foo.rst_t').write_text('{{var1}}.rst', encoding='utf8')
(source / '_static').makedirs() (source / '_static').makedirs()
(source / '_static' / 'basic.css').write_text('basic.css', encoding='utf8') (source / '_static' / 'basic.css').write_text('basic.css', encoding='utf8')
(source / '_templates').makedirs() (source / '_templates').makedirs()
(source / '_templates' / 'layout.html').write_text('layout.html', encoding='utf8') (source / '_templates' / 'layout.html').write_text('layout.html', encoding='utf8')
(source / '_templates' / 'sidebar.html.jinja').write_text('sidebar: {{var2}}', encoding='utf8') (source / '_templates' / 'sidebar.html_t').write_text('sidebar: {{var2}}', encoding='utf8')
# copy a single file # copy a single file
assert not (tempdir / 'test1').exists() assert not (tempdir / 'test1').exists()
@ -101,14 +101,3 @@ def test_copy_asset(tempdir):
assert not (destdir / '_static' / 'basic.css').exists() assert not (destdir / '_static' / 'basic.css').exists()
assert (destdir / '_templates' / 'layout.html').exists() assert (destdir / '_templates' / 'layout.html').exists()
assert not (destdir / '_templates' / 'sidebar.html').exists() assert not (destdir / '_templates' / 'sidebar.html').exists()
def test_template_basename():
assert not _template_basename("asset.txt")
assert _template_basename("asset.txt.jinja") == "asset.txt"
assert _template_basename("sidebar.html.jinja") == "sidebar.html"
def test_legacy_template_basename():
# TODO: deprecate '_t' template suffix support after 2024-12-31
assert _template_basename("asset.txt_t") == "asset.txt"

View File

@ -42,9 +42,7 @@ METHOD_MAP = [
# Extraction from Python source files # Extraction from Python source files
('**.py', extract_python), ('**.py', extract_python),
# Extraction from Jinja2 template files # Extraction from Jinja2 template files
('**/templates/latex/**.tex.jinja', extract_jinja2),
('**/templates/latex/**.tex_t', extract_jinja2), ('**/templates/latex/**.tex_t', extract_jinja2),
('**/templates/latex/**.sty.jinja', extract_jinja2),
('**/templates/latex/**.sty_t', extract_jinja2), ('**/templates/latex/**.sty_t', extract_jinja2),
# Extraction from Jinja2 HTML templates # Extraction from Jinja2 HTML templates
('**/themes/**.html', extract_jinja2), ('**/themes/**.html', extract_jinja2),
@ -52,7 +50,6 @@ METHOD_MAP = [
('**/themes/**.xml', extract_jinja2), ('**/themes/**.xml', extract_jinja2),
# Extraction from JavaScript files # Extraction from JavaScript files
('**.js', extract_javascript), ('**.js', extract_javascript),
('**.js.jinja', extract_javascript),
('**.js_t', extract_javascript), ('**.js_t', extract_javascript),
] ]
OPTIONS_MAP = { OPTIONS_MAP = {
@ -61,9 +58,7 @@ OPTIONS_MAP = {
'encoding': 'utf-8', 'encoding': 'utf-8',
}, },
# Extraction from Jinja2 template files # Extraction from Jinja2 template files
'**/templates/latex/**.tex.jinja': TEX_DELIMITERS.copy(),
'**/templates/latex/**.tex_t': TEX_DELIMITERS.copy(), '**/templates/latex/**.tex_t': TEX_DELIMITERS.copy(),
'**/templates/latex/**.sty.jinja': TEX_DELIMITERS.copy(),
'**/templates/latex/**.sty_t': TEX_DELIMITERS.copy(), '**/templates/latex/**.sty_t': TEX_DELIMITERS.copy(),
# Extraction from Jinja2 HTML templates # Extraction from Jinja2 HTML templates
'**/themes/**.html': { '**/themes/**.html': {