diff --git a/CHANGES b/CHANGES index 4a94fc3e6..bcac10b6a 100644 --- a/CHANGES +++ b/CHANGES @@ -76,6 +76,9 @@ Features added * #4834: Ensure set object descriptions are reproducible. * #4828: Allow to override :confval:`numfig_format` partially. Full definition is not needed. +* Improve warning messages during including (refs: #4818) +* LaTeX: separate customizability of :rst:role:`guilabel` and + :rst:role:`menuselection` (refs: #4830) * Add ``Config.read()`` classmethod to create a new config object from configuration file @@ -92,7 +95,7 @@ Features removed * ``sphinx.ext.pngmath`` extension -Release 1.7.3 (in development) +Release 1.7.5 (in development) ============================== Dependencies @@ -110,6 +113,24 @@ Features added Bugs fixed ---------- +Testing +-------- + +Release 1.7.4 (released Apr 25, 2018) +===================================== + +Bugs fixed +---------- + +* #4885, #4887: domains: Crashed with duplicated objects +* #4889: latex: sphinx.writers.latex causes recusrive import + +Release 1.7.3 (released Apr 23, 2018) +===================================== + +Bugs fixed +---------- + * #4769: autodoc loses the first staticmethod parameter * #4790: autosummary: too wide two column tables in PDF builds * #4795: Latex customization via ``_templates/longtable.tex_t`` is broken @@ -126,9 +147,8 @@ Bugs fixed * toctree directive tries to glob for URL having query_string * #4871: html search: Upper characters problem in German * #4717: latex: Compilation for German docs failed with LuaLaTeX and XeLaTeX - -Testing --------- +* #4459: duplicated labels detector does not work well in parallel build +* #4878: Crashed with extension which returns invalid metadata Release 1.7.2 (released Mar 21, 2018) ===================================== diff --git a/doc/_themes/sphinx13/static/sphinx13.css b/doc/_themes/sphinx13/static/sphinx13.css index 24a33fba7..eff18df3c 100644 --- a/doc/_themes/sphinx13/static/sphinx13.css +++ b/doc/_themes/sphinx13/static/sphinx13.css @@ -302,6 +302,10 @@ cite, code, tt { letter-spacing: -0.02em; } +table.deprecated code.literal { + word-break: break-all; +} + tt { background-color: #f2f2f2; border: 1px solid #ddd; diff --git a/doc/config.rst b/doc/config.rst index 2279cffe4..be0be745f 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -877,6 +877,18 @@ that use Sphinx's HTMLWriter class. named :file:`default.css` will overwrite the theme's :file:`default.css`. + .. note:: + + For security reason, dotfiles under ``html_static_path`` will + not be copied. If you'd like to copy them intentionally, please + add them each filepath to this setting:: + + html_static_path = ['_static', '_static/.htaccess'] + + Another way to do that, you can also use + :confval:`html_extra_path`. It allows to copy dotfiles under + the directories. + .. versionchanged:: 0.4 The paths in :confval:`html_static_path` can now contain subdirectories. diff --git a/doc/extdev/index.rst b/doc/extdev/index.rst index e096bf993..5b15533a3 100644 --- a/doc/extdev/index.rst +++ b/doc/extdev/index.rst @@ -108,6 +108,8 @@ The following is a list of deprecated interface. .. list-table:: deprecated APIs :header-rows: 1 + :class: deprecated + :widths: 40, 10, 10, 40 * - Target - Deprecated diff --git a/doc/theming.rst b/doc/theming.rst index bbc52cbbe..e20ab49ef 100644 --- a/doc/theming.rst +++ b/doc/theming.rst @@ -427,6 +427,6 @@ Third Party Themes Besides this, there are a lot of third party themes. You can find them on PyPI__, GitHub__, sphinx-themes.org__ and so on. -.. __: https://pypi.python.org/pypi?:action=browse&c=599 +.. __: https://pypi.org/search/?q=&o=&c=Framework+%3A%3A+Sphinx+%3A%3A+Theme .. __: https://github.com/search?utf8=%E2%9C%93&q=sphinx+theme&type= .. __: https://sphinx-themes.org/ diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index 7adbe3f10..41b21f917 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -8,6 +8,7 @@ """ import re +from contextlib import contextmanager from docutils import nodes from docutils.parsers.rst import directives @@ -436,6 +437,7 @@ class Include(BaseInclude, SphinxDirective): def run(self): # type: () -> List[nodes.Node] + current_filename = self.env.doc2path(self.env.docname) if self.arguments[0].startswith('<') and \ self.arguments[0].endswith('>'): # docutils "standard" includes, do not do path processing @@ -443,7 +445,27 @@ class Include(BaseInclude, SphinxDirective): rel_filename, filename = self.env.relfn2path(self.arguments[0]) self.arguments[0] = filename self.env.note_included(filename) - return BaseInclude.run(self) + with patched_warnings(self, current_filename): + return BaseInclude.run(self) + + +@contextmanager +def patched_warnings(directive, parent_filename): + # type: (BaseInclude, unicode) -> Generator[None, None, None] + """Add includee filename to the warnings during inclusion.""" + try: + original = directive.state_machine.insert_input + + def insert_input(input_lines, source): + # type: (Any, unicode) -> None + source += ' ' % parent_filename + original(input_lines, source) + + # patch insert_input() temporarily + directive.state_machine.insert_input = insert_input + yield + finally: + directive.state_machine.insert_input = original def setup(app): diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 312b509a0..1daac3227 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -579,9 +579,10 @@ class PyModule(Directive): env.ref_context['py:module'] = modname ret = [] if not noindex: - env.domaindata['py']['modules'][modname] = \ - (env.docname, self.options.get('synopsis', ''), - self.options.get('platform', ''), 'deprecated' in self.options) + env.domaindata['py']['modules'][modname] = (env.docname, + self.options.get('synopsis', ''), + self.options.get('platform', ''), + 'deprecated' in self.options) # make a duplicate entry in 'objects' to facilitate searching for # the module in PythonDomain.find_obj() env.domaindata['py']['objects'][modname] = (env.docname, 'module') diff --git a/sphinx/registry.py b/sphinx/registry.py index dc42219ae..e11f0654d 100644 --- a/sphinx/registry.py +++ b/sphinx/registry.py @@ -471,6 +471,7 @@ class SphinxComponentRegistry(object): logger.warning(__('extension %r returned an unsupported object from ' 'its setup() function; it should return None or a ' 'metadata dictionary'), extname) + metadata = {} app.extensions[extname] = Extension(extname, mod, **metadata) app._setting_up_extension.pop() diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 17aa6644d..8ff218504 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -1578,6 +1578,7 @@ \protected\def\sphinxtablecontinued#1{\textsf{#1}} \protected\def\sphinxtitleref#1{\emph{#1}} \protected\def\sphinxmenuselection#1{\emph{#1}} +\protected\def\sphinxguilabel#1{\emph{#1}} \protected\def\sphinxaccelerator#1{\underline{#1}} \protected\def\sphinxcrossref#1{\emph{#1}} \protected\def\sphinxtermref#1{\emph{#1}} diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py index 7d52d5b8e..a6b82f262 100644 --- a/sphinx/transforms/post_transforms/images.py +++ b/sphinx/transforms/post_transforms/images.py @@ -175,7 +175,7 @@ class ImageConverter(BaseImageConverter): PNG and JPEG as image formats. However it does not support SVG images. For such case, to use image converters allows to embed these unsupported images into the document. One of image converters; - :ref:`sphinx.ext. imgconverter ` can convert + :ref:`sphinx.ext.imgconverter ` can convert a SVG image to PNG format using Imagemagick internally. There are three steps to make your custom image converter: diff --git a/sphinx/util/logging.py b/sphinx/util/logging.py index 1ac4fb327..5034c007d 100644 --- a/sphinx/util/logging.py +++ b/sphinx/util/logging.py @@ -62,13 +62,13 @@ def getLogger(name): # type: (str) -> SphinxLoggerAdapter """Get logger wrapped by :class:`sphinx.util.logging.SphinxLoggerAdapter`. - Sphinx logger always uses ``sphinx.*`` namesapce to be independent from - settings of root logger. It ensure logging is consistent even if a + Sphinx logger always uses ``sphinx.*`` namespace to be independent from + settings of root logger. It ensures logging is consistent even if a third-party extension or imported application resets logger settings. Example usage:: - >>> from sphinx.utils import logging + >>> from sphinx.util import logging >>> logger = logging.getLogger(__name__) >>> logger.info('Hello, this is an extension!') Hello, this is an extension! diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 7aa266ca9..aa5d2badb 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -23,7 +23,6 @@ from six import itervalues, text_type from sphinx import addnodes from sphinx import highlighting -from sphinx.builders.latex.transforms import URI_SCHEMES, ShowUrlsTransform # NOQA # for compatibility from sphinx.errors import SphinxError from sphinx.locale import admonitionlabels, _, __ from sphinx.util import split_into, logging @@ -2427,9 +2426,12 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_inline(self, node): # type: (nodes.Node) -> None classes = node.get('classes', []) - if classes in [['menuselection'], ['guilabel']]: + if classes in [['menuselection']]: self.body.append(r'\sphinxmenuselection{') self.context.append('}') + elif classes in [['guilabel']]: + self.body.append(r'\sphinxguilabel{') + self.context.append('}') elif classes in [['accelerator']]: self.body.append(r'\sphinxaccelerator{') self.context.append('}') @@ -2558,3 +2560,10 @@ class LaTeXTranslator(nodes.NodeVisitor): def unknown_visit(self, node): # type: (nodes.Node) -> None raise NotImplementedError('Unknown node: ' + node.__class__.__name__) + + +# Import old modules here for compatibility +# They should be imported after `LaTeXTranslator` to avoid recursive import. +# +# refs: https://github.com/sphinx-doc/sphinx/issues/4889 +from sphinx.builders.latex.transforms import URI_SCHEMES, ShowUrlsTransform # NOQA diff --git a/tests/test_markup.py b/tests/test_markup.py index 37a1a721b..802202639 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -162,12 +162,20 @@ def get_verifier(verify, verify_re): '\\sphinxmenuselection{a \\(\\rightarrow\\) b}', ), ( - # interpolation of ampersands in guilabel/menuselection + # interpolation of ampersands in menuselection + 'verify', + ':menuselection:`&Foo -&&- &Bar`', + (u'

Foo ' + '-&- Bar

'), + r'\sphinxmenuselection{\sphinxaccelerator{F}oo -\&- \sphinxaccelerator{B}ar}', + ), + ( + # interpolation of ampersands in guilabel 'verify', ':guilabel:`&Foo -&&- &Bar`', (u'

Foo ' '-&- Bar

'), - r'\sphinxmenuselection{\sphinxaccelerator{F}oo -\&- \sphinxaccelerator{B}ar}', + r'\sphinxguilabel{\sphinxaccelerator{F}oo -\&- \sphinxaccelerator{B}ar}', ), ( # non-interpolation of dashes in option role