From e368ac21ef81c1113a61397c0962f678f9c56769 Mon Sep 17 00:00:00 2001 From: Michael Tesch Date: Fri, 20 Apr 2018 13:13:00 +0200 Subject: [PATCH 01/20] proposed enhancement #4830 --- sphinx/texinputs/sphinx.sty | 1 + sphinx/writers/latex.py | 5 ++++- tests/test_markup.py | 12 ++++++++++-- 3 files changed, 15 insertions(+), 3 deletions(-) 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/writers/latex.py b/sphinx/writers/latex.py index f05959aca..b65821529 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -2409,9 +2409,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('}') 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 From 5a63c2970f99d39a0202174454bd7452f7f79643 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 21 Apr 2018 11:02:46 +0900 Subject: [PATCH 02/20] doc: Add a note for dotfiles on html_static_path (refs: #4859) --- doc/config.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/config.rst b/doc/config.rst index 1c8ae48e0..a0cdbe709 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. From 6d6864abf0f1eaf75a31afeac0aa54a4d00252d0 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 22 Apr 2018 18:00:59 +0900 Subject: [PATCH 03/20] doc: Remove meaningless spaces --- sphinx/transforms/post_transforms/images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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: From a4dbb6e657bf86e5940e352a2935d1b3264d74e2 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 8 Apr 2018 16:19:40 +0900 Subject: [PATCH 04/20] Improve warning messages during including (refs: #4818) --- CHANGES | 1 + sphinx/directives/other.py | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 7a595320c..a1c77c790 100644 --- a/CHANGES +++ b/CHANGES @@ -71,6 +71,7 @@ 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) Bugs fixed ---------- 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): From f4f693eff7b081785cc5704a6ff22cf0371355f3 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 10 Feb 2018 14:25:52 +0900 Subject: [PATCH 05/20] #4459: duplicated labels detector does not work well in parallel build --- CHANGES | 1 + sphinx/domains/c.py | 9 ++++++++- sphinx/domains/javascript.py | 20 +++++++++++++++++++- sphinx/domains/python.py | 25 +++++++++++++++++++++---- sphinx/domains/rst.py | 8 +++++++- sphinx/domains/std.py | 10 +++++++++- sphinx/ext/mathbase.py | 4 ++++ 7 files changed, 69 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index ad3fa708e..a3dca85e9 100644 --- a/CHANGES +++ b/CHANGES @@ -32,6 +32,7 @@ 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 +* #4459: duplicated labels detector does not work well in parallel build Testing -------- diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index f0c81db7b..df07c7731 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -19,6 +19,7 @@ from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType from sphinx.locale import l_, _ from sphinx.roles import XRefRole +from sphinx.util import logging from sphinx.util.docfields import Field, TypedField from sphinx.util.nodes import make_refnode @@ -29,6 +30,8 @@ if False: from sphinx.builders import Builder # NOQA from sphinx.environment import BuildEnvironment # NOQA +logger = logging.getLogger(__name__) + # RE to split at word boundaries wsplit_re = re.compile(r'(\W+)') @@ -287,9 +290,13 @@ class CDomain(Domain): def merge_domaindata(self, docnames, otherdata): # type: (List[unicode], Dict) -> None - # XXX check duplicates for fullname, (fn, objtype) in otherdata['objects'].items(): if fn in docnames: + if fullname in self.data['objects']: + other, _ = self.data['objects'][fullname] + logger.warning('duplicate C object description of %s, ' + 'other instance in %s' % + (fullname, self.env.doc2path(other))) self.data['objects'][fullname] = (fn, objtype) def resolve_xref(self, env, fromdocname, builder, diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index 734969fc1..e64177cdc 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -18,6 +18,7 @@ from sphinx.domains import Domain, ObjType from sphinx.domains.python import _pseudo_parse_arglist from sphinx.locale import l_, _ from sphinx.roles import XRefRole +from sphinx.util import logging from sphinx.util.docfields import Field, GroupedField, TypedField from sphinx.util.nodes import make_refnode @@ -29,6 +30,8 @@ if False: from sphinx.builders import Builder # NOQA from sphinx.environment import BuildEnvironment # NOQA +logger = logging.getLogger(__name__) + class JSObject(ObjectDescription): """ @@ -255,6 +258,12 @@ class JSModule(Directive): noindex = 'noindex' in self.options ret = [] if not noindex: + modules = env.domaindata['js']['modules'] + if mod_name in modules: + self.state_machine.reporter.warning( + 'duplicate module description of %s, ' % mod_name + + 'other instance in ' + self.env.doc2path(modules[mod_name]), + line=self.lineno) env.domaindata['js']['modules'][mod_name] = env.docname # Make a duplicate entry in 'objects' to facilitate searching for # the module in JavaScriptDomain.find_obj() @@ -335,12 +344,21 @@ class JavaScriptDomain(Domain): def merge_domaindata(self, docnames, otherdata): # type: (List[unicode], Dict) -> None - # XXX check duplicates for fullname, (fn, objtype) in otherdata['objects'].items(): if fn in docnames: + if fullname in self.data['objects']: + otherdoc, _ = self.data['objects'][fullname] + logger.warning('duplicate object description of %s, ' + 'other instance in %s' % + (fullname, self.env.doc2path(otherdoc))) self.data['objects'][fullname] = (fn, objtype) for mod_name, pkg_docname in otherdata['modules'].items(): if pkg_docname in docnames: + if mod_name in self.data['modules']: + otherdoc = self.data['modules'][mod_name] + logger.warning('duplicate module description of %s, ' + 'other instance in %s' % + (mod_name, self.env.doc2path(otherdoc))) self.data['modules'][mod_name] = pkg_docname def find_obj(self, env, mod_name, prefix, name, typ, searchorder=0): diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index b0900b385..47ab5cd12 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -560,9 +560,17 @@ 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) + modules = env.domaindata['py']['modules'] + if modname in modules: + self.state_machine.reporter.warning( + 'duplicate module description of %s, ' + 'other instance in %s, use :noindex: for one of them' % + (modname, self.env.doc2path(modules[modname])), + line=self.lineno) + 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') @@ -757,12 +765,21 @@ class PythonDomain(Domain): def merge_domaindata(self, docnames, otherdata): # type: (List[unicode], Dict) -> None - # XXX check duplicates? for fullname, (fn, objtype) in otherdata['objects'].items(): if fn in docnames: + if fullname in self.data['objects']: + otherdoc, _ = self.data['objects'][fullname] + logger.warning('duplicate object description of %s, ' + 'other instance in %s, use :noindex: for one of them' % + (fullname, self.env.doc2path(otherdoc))) self.data['objects'][fullname] = (fn, objtype) for modname, data in otherdata['modules'].items(): if data[0] in docnames: + if modname in self.data['modules']: + otherdoc, _, _, _ = self.data['modules'][modname] + logger.warning('duplicate module description of %s, ' + 'other instance in %s, use :noindex: for one of them' % + (modname, self.env.doc2path(otherdoc))) self.data['modules'][modname] = data def find_obj(self, env, modname, classname, name, type, searchmode=0): diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py index c14eb180f..609fa501f 100644 --- a/sphinx/domains/rst.py +++ b/sphinx/domains/rst.py @@ -18,6 +18,7 @@ from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType from sphinx.locale import l_, _ from sphinx.roles import XRefRole +from sphinx.util import logging from sphinx.util.nodes import make_refnode if False: @@ -29,6 +30,7 @@ if False: from sphinx.environment import BuildEnvironment # NOQA +logger = logging.getLogger(__name__) dir_sig_re = re.compile(r'\.\. (.+?)::(.*)$') @@ -139,9 +141,13 @@ class ReSTDomain(Domain): def merge_domaindata(self, docnames, otherdata): # type: (List[unicode], Dict) -> None - # XXX check duplicates for (typ, name), doc in otherdata['objects'].items(): if doc in docnames: + if (typ, name) in self.data['objects']: + otherdoc = self.data['objects'][typ, name] + logger.warning('duplicate description of %s %s, ' + 'other instance in %s' % + (typ, name, self.env.doc2path(otherdoc))) self.data['objects'][typ, name] = doc def resolve_xref(self, env, fromdocname, builder, typ, target, node, diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 937760c45..2b726d3e7 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -547,7 +547,6 @@ class StandardDomain(Domain): def merge_domaindata(self, docnames, otherdata): # type: (List[unicode], Dict) -> None - # XXX duplicates? for key, data in otherdata['progoptions'].items(): if data[0] in docnames: self.data['progoptions'][key] = data @@ -556,6 +555,11 @@ class StandardDomain(Domain): self.data['objects'][key] = data for key, data in otherdata['citations'].items(): if data[0] in docnames: + if key in self.data['citations']: + otherdoc, _, _ = self.data['catations'] + logger.warning('duplicate citation %s, other instance in %s' % + (key, self.env.doc2path(otherdoc)), + type='ref', subtype='citation') self.data['citations'][key] = data for key, data in otherdata['citation_refs'].items(): citation_refs = self.data['citation_refs'].setdefault(key, []) @@ -564,6 +568,10 @@ class StandardDomain(Domain): citation_refs.append(docname) for key, data in otherdata['labels'].items(): if data[0] in docnames: + if key in self.data['labels']: + otherdoc, _, _ = self.data['labels'] + logger.warning('duplicate label %s, other instance in %s' % + (key, self.env.doc2path(otherdoc))) self.data['labels'][key] = data for key, data in otherdata['anonlabels'].items(): if data[0] in docnames: diff --git a/sphinx/ext/mathbase.py b/sphinx/ext/mathbase.py index 3cc734537..b217d5d56 100644 --- a/sphinx/ext/mathbase.py +++ b/sphinx/ext/mathbase.py @@ -72,6 +72,10 @@ class MathDomain(Domain): # type: (Iterable[unicode], Dict) -> None for labelid, (doc, eqno) in otherdata['objects'].items(): if doc in docnames: + if labelid in self.data['objects']: + otherdoc, _ = self.data['objects'] + logger.warning('duplicate label of equation %s, other instance in %s' % + (labelid, self.env.doc2path(otherdoc))) self.data['objects'][labelid] = (doc, eqno) def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): From a31c0ddfca721600d630f77a6ef363417f76362c Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 22 Apr 2018 19:25:02 +0900 Subject: [PATCH 06/20] Fix #4878: Crashed with extension which returns invalid metadata --- CHANGES | 1 + sphinx/registry.py | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index ad3fa708e..1f4026ddb 100644 --- a/CHANGES +++ b/CHANGES @@ -32,6 +32,7 @@ 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 +* #4878: Crashed with extension which returns invalid metadata Testing -------- diff --git a/sphinx/registry.py b/sphinx/registry.py index cc012b3f7..cdae77224 100644 --- a/sphinx/registry.py +++ b/sphinx/registry.py @@ -340,6 +340,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() From d97dc05b374b611e779cefe3556863d256492e4c Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 22 Apr 2018 20:00:46 +0900 Subject: [PATCH 07/20] Fix #4873: Adjust word-break of deprecated-APIs table --- doc/_themes/sphinx13/static/sphinx13.css | 4 ++++ doc/extdev/index.rst | 2 ++ 2 files changed, 6 insertions(+) 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/extdev/index.rst b/doc/extdev/index.rst index ace43fd71..b6c737643 100644 --- a/doc/extdev/index.rst +++ b/doc/extdev/index.rst @@ -99,6 +99,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 From d5a108428dcb25b71980a02904b6b2ae0376f296 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 23 Apr 2018 01:23:45 +0900 Subject: [PATCH 08/20] Bump to 1.7.3 final --- CHANGES | 19 ++----------------- sphinx/__init__.py | 4 ++-- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 48d95d852..c5666219a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,17 +1,5 @@ -Release 1.7.3 (in development) -============================== - -Dependencies ------------- - -Incompatible changes --------------------- - -Deprecated ----------- - -Features added --------------- +Release 1.7.3 (released Apr 23, 2018) +===================================== Bugs fixed ---------- @@ -35,9 +23,6 @@ Bugs fixed * #4459: duplicated labels detector does not work well in parallel build * #4878: Crashed with extension which returns invalid metadata -Testing --------- - Release 1.7.2 (released Mar 21, 2018) ===================================== diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 67278f4c0..b1fb31b26 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -31,13 +31,13 @@ if 'PYTHONWARNINGS' not in os.environ: warnings.filterwarnings('ignore', "'U' mode is deprecated", DeprecationWarning, module='docutils.io') -__version__ = '1.7.3+' +__version__ = '1.7.3' __released__ = '1.7.3' # used when Sphinx builds its own docs # version info for better programmatic use # possible values for 3rd element: 'alpha', 'beta', 'rc', 'final' # 'final' has 0 as the last element -version_info = (1, 7, 3, 'beta', 0) +version_info = (1, 7, 3, 'final', 0) package_dir = path.abspath(path.dirname(__file__)) From b4a6841c466e38e8df636d2d967d1f90221acdb1 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 23 Apr 2018 01:30:45 +0900 Subject: [PATCH 09/20] Bump version --- CHANGES | 21 +++++++++++++++++++++ sphinx/__init__.py | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index c5666219a..dd715b8ba 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,24 @@ +Release 1.7.4 (in development) +============================== + +Dependencies +------------ + +Incompatible changes +-------------------- + +Deprecated +---------- + +Features added +-------------- + +Bugs fixed +---------- + +Testing +-------- + Release 1.7.3 (released Apr 23, 2018) ===================================== diff --git a/sphinx/__init__.py b/sphinx/__init__.py index b1fb31b26..28da450cb 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -31,13 +31,13 @@ if 'PYTHONWARNINGS' not in os.environ: warnings.filterwarnings('ignore', "'U' mode is deprecated", DeprecationWarning, module='docutils.io') -__version__ = '1.7.3' -__released__ = '1.7.3' # used when Sphinx builds its own docs +__version__ = '1.7.4+' +__released__ = '1.7.4' # used when Sphinx builds its own docs # version info for better programmatic use # possible values for 3rd element: 'alpha', 'beta', 'rc', 'final' # 'final' has 0 as the last element -version_info = (1, 7, 3, 'final', 0) +version_info = (1, 7, 4, 'beta', 0) package_dir = path.abspath(path.dirname(__file__)) From 3735ba39db51ee429344f88b8201cc3ac37496f4 Mon Sep 17 00:00:00 2001 From: Shingo Kitagawa Date: Mon, 23 Apr 2018 17:21:02 +0900 Subject: [PATCH 10/20] fix issue #4885 https://github.com/sphinx-doc/sphinx/issues/4885 --- sphinx/domains/python.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 72e794944..89ed2f676 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -584,7 +584,7 @@ class PyModule(Directive): self.state_machine.reporter.warning( 'duplicate module description of %s, ' 'other instance in %s, use :noindex: for one of them' % - (modname, self.env.doc2path(modules[modname])), + (modname, env.doc2path(modules[modname][0])), line=self.lineno) modules[modname] = (env.docname, self.options.get('synopsis', ''), From 3b36ac8f53322036c5fe91ffda730718998f1650 Mon Sep 17 00:00:00 2001 From: Sumana Harihareswara Date: Mon, 23 Apr 2018 09:27:17 -0400 Subject: [PATCH 11/20] Fix PyPI link in theming docs --- doc/theming.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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/ From 51f7d351a141a623efd06f2682d90ce8aad412e4 Mon Sep 17 00:00:00 2001 From: Shingo Kitagawa Date: Mon, 23 Apr 2018 17:21:02 +0900 Subject: [PATCH 12/20] fix issue #4885 https://github.com/sphinx-doc/sphinx/issues/4885 --- sphinx/domains/python.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 47ab5cd12..25c83244c 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -565,7 +565,7 @@ class PyModule(Directive): self.state_machine.reporter.warning( 'duplicate module description of %s, ' 'other instance in %s, use :noindex: for one of them' % - (modname, self.env.doc2path(modules[modname])), + (modname, env.doc2path(modules[modname][0])), line=self.lineno) modules[modname] = (env.docname, self.options.get('synopsis', ''), From 7a13a5996b1315d5edbd8897d501018f0b22b317 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 24 Apr 2018 00:44:27 +0900 Subject: [PATCH 13/20] Update CHANGES for PR #4887 --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index dd715b8ba..856d23e8b 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,8 @@ Features added Bugs fixed ---------- +* #4885, #4887: py domain: Crashed with duplicated objects + Testing -------- From 1a59aca8a107e053b865bd1b5193f930d0fb8c24 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 24 Apr 2018 01:02:39 +0900 Subject: [PATCH 14/20] Fix #4889: latex: sphinx.writers.latex causes recusrive import --- CHANGES | 1 + sphinx/writers/latex.py | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 856d23e8b..6812d23fe 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,7 @@ Bugs fixed ---------- * #4885, #4887: py domain: Crashed with duplicated objects +* #4889: latex: sphinx.writers.latex causes recusrive import Testing -------- diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index f5209eb38..17eabc462 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 @@ -2561,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 From d2ed2d4c4c44fa2009bfdf536a85eeda0c6b72f2 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 24 Apr 2018 01:09:34 +0900 Subject: [PATCH 15/20] Fix #4885: jsdomain also crashed with duplicated objects --- CHANGES | 2 +- sphinx/domains/javascript.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 856d23e8b..5456397ca 100644 --- a/CHANGES +++ b/CHANGES @@ -16,7 +16,7 @@ Features added Bugs fixed ---------- -* #4885, #4887: py domain: Crashed with duplicated objects +* #4885, #4887: domains: Crashed with duplicated objects Testing -------- diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index e64177cdc..eca7edda0 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -262,7 +262,7 @@ class JSModule(Directive): if mod_name in modules: self.state_machine.reporter.warning( 'duplicate module description of %s, ' % mod_name + - 'other instance in ' + self.env.doc2path(modules[mod_name]), + 'other instance in ' + env.doc2path(modules[mod_name]), line=self.lineno) env.domaindata['js']['modules'][mod_name] = env.docname # Make a duplicate entry in 'objects' to facilitate searching for From 0a0803fd450ec618f24a03cf9ef4309b9db1d36b Mon Sep 17 00:00:00 2001 From: jfbu Date: Tue, 24 Apr 2018 14:09:53 +0200 Subject: [PATCH 16/20] Update CHANGES for PR #4868 --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 069a89ec8..aa7d8cc65 100644 --- a/CHANGES +++ b/CHANGES @@ -72,6 +72,8 @@ Features added * #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) Bugs fixed ---------- From acb7edcae85318e373725fd003e3609fdef71d79 Mon Sep 17 00:00:00 2001 From: jfbu Date: Wed, 25 Apr 2018 10:26:12 +0200 Subject: [PATCH 17/20] Fix typos in a docstring (refs: #4901) --- sphinx/util/logging.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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! From 10d127d017727835085639c941e11817b0096b30 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Wed, 25 Apr 2018 22:44:03 +0900 Subject: [PATCH 18/20] Revert f4f693eff7b081785cc5704a6ff22cf0371355f3 --- sphinx/domains/c.py | 9 +-------- sphinx/domains/javascript.py | 20 +------------------- sphinx/domains/python.py | 26 +++++--------------------- sphinx/domains/rst.py | 8 +------- sphinx/domains/std.py | 10 +--------- sphinx/ext/mathbase.py | 4 ---- 6 files changed, 9 insertions(+), 68 deletions(-) diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index df07c7731..f0c81db7b 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -19,7 +19,6 @@ from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType from sphinx.locale import l_, _ from sphinx.roles import XRefRole -from sphinx.util import logging from sphinx.util.docfields import Field, TypedField from sphinx.util.nodes import make_refnode @@ -30,8 +29,6 @@ if False: from sphinx.builders import Builder # NOQA from sphinx.environment import BuildEnvironment # NOQA -logger = logging.getLogger(__name__) - # RE to split at word boundaries wsplit_re = re.compile(r'(\W+)') @@ -290,13 +287,9 @@ class CDomain(Domain): def merge_domaindata(self, docnames, otherdata): # type: (List[unicode], Dict) -> None + # XXX check duplicates for fullname, (fn, objtype) in otherdata['objects'].items(): if fn in docnames: - if fullname in self.data['objects']: - other, _ = self.data['objects'][fullname] - logger.warning('duplicate C object description of %s, ' - 'other instance in %s' % - (fullname, self.env.doc2path(other))) self.data['objects'][fullname] = (fn, objtype) def resolve_xref(self, env, fromdocname, builder, diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index eca7edda0..734969fc1 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -18,7 +18,6 @@ from sphinx.domains import Domain, ObjType from sphinx.domains.python import _pseudo_parse_arglist from sphinx.locale import l_, _ from sphinx.roles import XRefRole -from sphinx.util import logging from sphinx.util.docfields import Field, GroupedField, TypedField from sphinx.util.nodes import make_refnode @@ -30,8 +29,6 @@ if False: from sphinx.builders import Builder # NOQA from sphinx.environment import BuildEnvironment # NOQA -logger = logging.getLogger(__name__) - class JSObject(ObjectDescription): """ @@ -258,12 +255,6 @@ class JSModule(Directive): noindex = 'noindex' in self.options ret = [] if not noindex: - modules = env.domaindata['js']['modules'] - if mod_name in modules: - self.state_machine.reporter.warning( - 'duplicate module description of %s, ' % mod_name + - 'other instance in ' + env.doc2path(modules[mod_name]), - line=self.lineno) env.domaindata['js']['modules'][mod_name] = env.docname # Make a duplicate entry in 'objects' to facilitate searching for # the module in JavaScriptDomain.find_obj() @@ -344,21 +335,12 @@ class JavaScriptDomain(Domain): def merge_domaindata(self, docnames, otherdata): # type: (List[unicode], Dict) -> None + # XXX check duplicates for fullname, (fn, objtype) in otherdata['objects'].items(): if fn in docnames: - if fullname in self.data['objects']: - otherdoc, _ = self.data['objects'][fullname] - logger.warning('duplicate object description of %s, ' - 'other instance in %s' % - (fullname, self.env.doc2path(otherdoc))) self.data['objects'][fullname] = (fn, objtype) for mod_name, pkg_docname in otherdata['modules'].items(): if pkg_docname in docnames: - if mod_name in self.data['modules']: - otherdoc = self.data['modules'][mod_name] - logger.warning('duplicate module description of %s, ' - 'other instance in %s' % - (mod_name, self.env.doc2path(otherdoc))) self.data['modules'][mod_name] = pkg_docname def find_obj(self, env, mod_name, prefix, name, typ, searchorder=0): diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 25c83244c..2b46596af 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -560,17 +560,10 @@ class PyModule(Directive): env.ref_context['py:module'] = modname ret = [] if not noindex: - modules = env.domaindata['py']['modules'] - if modname in modules: - self.state_machine.reporter.warning( - 'duplicate module description of %s, ' - 'other instance in %s, use :noindex: for one of them' % - (modname, env.doc2path(modules[modname][0])), - line=self.lineno) - 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') @@ -765,21 +758,12 @@ class PythonDomain(Domain): def merge_domaindata(self, docnames, otherdata): # type: (List[unicode], Dict) -> None + # XXX check duplicates? for fullname, (fn, objtype) in otherdata['objects'].items(): if fn in docnames: - if fullname in self.data['objects']: - otherdoc, _ = self.data['objects'][fullname] - logger.warning('duplicate object description of %s, ' - 'other instance in %s, use :noindex: for one of them' % - (fullname, self.env.doc2path(otherdoc))) self.data['objects'][fullname] = (fn, objtype) for modname, data in otherdata['modules'].items(): if data[0] in docnames: - if modname in self.data['modules']: - otherdoc, _, _, _ = self.data['modules'][modname] - logger.warning('duplicate module description of %s, ' - 'other instance in %s, use :noindex: for one of them' % - (modname, self.env.doc2path(otherdoc))) self.data['modules'][modname] = data def find_obj(self, env, modname, classname, name, type, searchmode=0): diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py index 609fa501f..c14eb180f 100644 --- a/sphinx/domains/rst.py +++ b/sphinx/domains/rst.py @@ -18,7 +18,6 @@ from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType from sphinx.locale import l_, _ from sphinx.roles import XRefRole -from sphinx.util import logging from sphinx.util.nodes import make_refnode if False: @@ -30,7 +29,6 @@ if False: from sphinx.environment import BuildEnvironment # NOQA -logger = logging.getLogger(__name__) dir_sig_re = re.compile(r'\.\. (.+?)::(.*)$') @@ -141,13 +139,9 @@ class ReSTDomain(Domain): def merge_domaindata(self, docnames, otherdata): # type: (List[unicode], Dict) -> None + # XXX check duplicates for (typ, name), doc in otherdata['objects'].items(): if doc in docnames: - if (typ, name) in self.data['objects']: - otherdoc = self.data['objects'][typ, name] - logger.warning('duplicate description of %s %s, ' - 'other instance in %s' % - (typ, name, self.env.doc2path(otherdoc))) self.data['objects'][typ, name] = doc def resolve_xref(self, env, fromdocname, builder, typ, target, node, diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 2b726d3e7..937760c45 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -547,6 +547,7 @@ class StandardDomain(Domain): def merge_domaindata(self, docnames, otherdata): # type: (List[unicode], Dict) -> None + # XXX duplicates? for key, data in otherdata['progoptions'].items(): if data[0] in docnames: self.data['progoptions'][key] = data @@ -555,11 +556,6 @@ class StandardDomain(Domain): self.data['objects'][key] = data for key, data in otherdata['citations'].items(): if data[0] in docnames: - if key in self.data['citations']: - otherdoc, _, _ = self.data['catations'] - logger.warning('duplicate citation %s, other instance in %s' % - (key, self.env.doc2path(otherdoc)), - type='ref', subtype='citation') self.data['citations'][key] = data for key, data in otherdata['citation_refs'].items(): citation_refs = self.data['citation_refs'].setdefault(key, []) @@ -568,10 +564,6 @@ class StandardDomain(Domain): citation_refs.append(docname) for key, data in otherdata['labels'].items(): if data[0] in docnames: - if key in self.data['labels']: - otherdoc, _, _ = self.data['labels'] - logger.warning('duplicate label %s, other instance in %s' % - (key, self.env.doc2path(otherdoc))) self.data['labels'][key] = data for key, data in otherdata['anonlabels'].items(): if data[0] in docnames: diff --git a/sphinx/ext/mathbase.py b/sphinx/ext/mathbase.py index b217d5d56..3cc734537 100644 --- a/sphinx/ext/mathbase.py +++ b/sphinx/ext/mathbase.py @@ -72,10 +72,6 @@ class MathDomain(Domain): # type: (Iterable[unicode], Dict) -> None for labelid, (doc, eqno) in otherdata['objects'].items(): if doc in docnames: - if labelid in self.data['objects']: - otherdoc, _ = self.data['objects'] - logger.warning('duplicate label of equation %s, other instance in %s' % - (labelid, self.env.doc2path(otherdoc))) self.data['objects'][labelid] = (doc, eqno) def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): From f7b3292d87e9a2b7eae0b4ef72e87779beefc699 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 26 Apr 2018 00:54:38 +0900 Subject: [PATCH 19/20] Bump to 1.7.4 final --- CHANGES | 19 ++----------------- sphinx/__init__.py | 4 ++-- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 6af237189..ef4fe78b4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,17 +1,5 @@ -Release 1.7.4 (in development) -============================== - -Dependencies ------------- - -Incompatible changes --------------------- - -Deprecated ----------- - -Features added --------------- +Release 1.7.4 (released Apr 25, 2018) +===================================== Bugs fixed ---------- @@ -19,9 +7,6 @@ Bugs fixed * #4885, #4887: domains: Crashed with duplicated objects * #4889: latex: sphinx.writers.latex causes recusrive import -Testing --------- - Release 1.7.3 (released Apr 23, 2018) ===================================== diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 28da450cb..1c276d66a 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -31,13 +31,13 @@ if 'PYTHONWARNINGS' not in os.environ: warnings.filterwarnings('ignore', "'U' mode is deprecated", DeprecationWarning, module='docutils.io') -__version__ = '1.7.4+' +__version__ = '1.7.4' __released__ = '1.7.4' # used when Sphinx builds its own docs # version info for better programmatic use # possible values for 3rd element: 'alpha', 'beta', 'rc', 'final' # 'final' has 0 as the last element -version_info = (1, 7, 4, 'beta', 0) +version_info = (1, 7, 4, 'final', 0) package_dir = path.abspath(path.dirname(__file__)) From 6ad0ad6f1721bcf5f04765db9b1fdb315d9042b6 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 26 Apr 2018 01:02:14 +0900 Subject: [PATCH 20/20] Bump version --- CHANGES | 21 +++++++++++++++++++++ sphinx/__init__.py | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index ef4fe78b4..43c14e5b4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,24 @@ +Release 1.7.5 (in development) +============================== + +Dependencies +------------ + +Incompatible changes +-------------------- + +Deprecated +---------- + +Features added +-------------- + +Bugs fixed +---------- + +Testing +-------- + Release 1.7.4 (released Apr 25, 2018) ===================================== diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 1c276d66a..7b3ddfea8 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -31,13 +31,13 @@ if 'PYTHONWARNINGS' not in os.environ: warnings.filterwarnings('ignore', "'U' mode is deprecated", DeprecationWarning, module='docutils.io') -__version__ = '1.7.4' -__released__ = '1.7.4' # used when Sphinx builds its own docs +__version__ = '1.7.5+' +__released__ = '1.7.5' # used when Sphinx builds its own docs # version info for better programmatic use # possible values for 3rd element: 'alpha', 'beta', 'rc', 'final' # 'final' has 0 as the last element -version_info = (1, 7, 4, 'final', 0) +version_info = (1, 7, 5, 'beta', 0) package_dir = path.abspath(path.dirname(__file__))