[Python-modules-commits] [sphinx] 01/01: New upstream version 1.6.7

Dmitry Shachnev mitya57 at moszumanska.debian.org
Mon Feb 5 12:31:55 UTC 2018


This is an automated email from the git hooks/post-receive script.

mitya57 pushed a commit to branch upstream
in repository sphinx.

commit 163ed32da6f52f5e1c5d913ae60ccb44e2289340
Author: Dmitry Shachnev <mitya57 at gmail.com>
Date:   Mon Feb 5 15:09:33 2018 +0300

    New upstream version 1.6.7
---
 CHANGES                                            |  30 +-
 PKG-INFO                                           |   2 +-
 Sphinx.egg-info/PKG-INFO                           |   2 +-
 Sphinx.egg-info/SOURCES.txt                        |  11 +-
 sphinx/__init__.py                                 |   6 +-
 sphinx/apidoc.py                                   |  13 +-
 sphinx/builders/html.py                            | 107 ++-
 sphinx/domains/std.py                              |   5 +-
 sphinx/ext/autodoc.py                              |   8 +-
 sphinx/ext/autosectionlabel.py                     |  13 +
 sphinx/ext/autosummary/__init__.py                 |  19 +-
 sphinx/ext/graphviz.py                             |  70 +-
 sphinx/ext/intersphinx.py                          |  32 +-
 sphinx/ext/mathbase.py                             |  14 +-
 sphinx/search/fr.py                                |   2 +-
 sphinx/themes/basic/static/basic.css_t             |   5 +
 .../static/{jquery-3.1.0.js => jquery-3.2.1.js}    | 769 +++++++++++++--------
 sphinx/themes/basic/static/jquery.js               |   8 +-
 sphinx/transforms/__init__.py                      |   5 +
 sphinx/util/nodes.py                               |   2 +
 sphinx/writers/latex.py                            |   2 -
 tests/roots/test-apidoc-pep420/a/b/e/__init__.py   |   0
 tests/roots/test-apidoc-pep420/a/b/e/f.py          |   1 +
 tests/roots/test-ext-autodoc/autodoc_dummy_bar.py  |   5 +
 tests/roots/test-ext-autodoc/bug2437/__init__.py   |   0
 .../test-ext-autodoc/bug2437/autodoc_dummy_foo.py  |   3 +
 tests/roots/test-ext-autodoc/conf.py               |   2 +
 tests/roots/test-ext-autodoc/contents.rst          |   6 +
 ...le_having_threeparagraphs_cell_in_first_col.tex |  20 +
 tests/roots/test-latex-table/tabular.rst           |  14 +
 tests/roots/test-root/markup.txt                   |   2 +
 tests/roots/test-smartquotes/conf.py               |   7 +
 tests/roots/test-smartquotes/index.rst             |   4 +
 tests/test_apidoc.py                               |  60 ++
 tests/test_autodoc.py                              |  12 +-
 tests/test_build_html.py                           |   2 +
 tests/test_build_html5.py                          |   2 +
 tests/test_build_latex.py                          |  19 +-
 tests/test_ext_autodoc.py                          |  10 +
 tests/test_ext_autosummary.py                      |   1 +
 tests/test_ext_graphviz.py                         |  62 ++
 tests/test_ext_intersphinx.py                      |  32 +
 tests/test_ext_math.py                             |   6 +-
 tests/test_smartquotes.py                          |  92 +++
 tests/test_theming.py                              |   2 +-
 45 files changed, 1089 insertions(+), 400 deletions(-)

diff --git a/CHANGES b/CHANGES
index 05c1abd..2cddc27 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,14 +1,27 @@
-Release 1.6.6 (released Jan 08, 2018)
+Release 1.6.7 (released Feb 04, 2018)
 =====================================
 
-Dependencies
-------------
+Bugs fixed
+----------
 
-Incompatible changes
---------------------
+* #1922: html search: Upper characters problem in French
+* #4412: Updated jQuery version from 3.1.0 to 3.2.1
+* #4438: math: math with labels with whitespace cause html error
+* #2437: make full reference for classes, aliased with "alias of"
+* #4434: pure numbers as link targets produce warning
+* #4477: Build fails after building specific files
+* #4449: apidoc: include "empty" packages that contain modules
+* #3917: citation labels are tranformed to ellipsis
+* #4501: graphviz: epub3 validation error caused if graph is not clickable
+* #4514: graphviz: workaround for wrong map ID which graphviz generates
+* #4525: autosectionlabel does not support parallel build
+* #3953: Do not raise warning when there is a working intersphinx inventory
+* #4487: math: ValueError is raised on parallel build. Thanks to jschueller.
+* #2372: autosummary: invalid signatures are shown for type annotated functions
+* #3942: html: table is not aligned to center even if ``:align: center``
 
-Deprecated
-----------
+Release 1.6.6 (released Jan 08, 2018)
+=====================================
 
 Features added
 --------------
@@ -46,9 +59,6 @@ Bugs fixed
 * Fix links to external option docs with intersphinx (refs: #3769)
 * #4091: Private members not documented without :undoc-members:
 
-Testing
---------
-
 Release 1.6.5 (released Oct 23, 2017)
 =====================================
 
diff --git a/PKG-INFO b/PKG-INFO
index 0a07f98..00e7159 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: Sphinx
-Version: 1.6.6
+Version: 1.6.7
 Summary: Python documentation generator
 Home-page: http://sphinx-doc.org/
 Author: Georg Brandl
diff --git a/Sphinx.egg-info/PKG-INFO b/Sphinx.egg-info/PKG-INFO
index 0a07f98..00e7159 100644
--- a/Sphinx.egg-info/PKG-INFO
+++ b/Sphinx.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: Sphinx
-Version: 1.6.6
+Version: 1.6.7
 Summary: Python documentation generator
 Home-page: http://sphinx-doc.org/
 Author: Georg Brandl
diff --git a/Sphinx.egg-info/SOURCES.txt b/Sphinx.egg-info/SOURCES.txt
index d2eff6b..8f7ad85 100644
--- a/Sphinx.egg-info/SOURCES.txt
+++ b/Sphinx.egg-info/SOURCES.txt
@@ -481,7 +481,7 @@ sphinx/themes/basic/static/doctools.js_t
 sphinx/themes/basic/static/down-pressed.png
 sphinx/themes/basic/static/down.png
 sphinx/themes/basic/static/file.png
-sphinx/themes/basic/static/jquery-3.1.0.js
+sphinx/themes/basic/static/jquery-3.2.1.js
 sphinx/themes/basic/static/jquery.js
 sphinx/themes/basic/static/minus.png
 sphinx/themes/basic/static/plus.png
@@ -664,6 +664,7 @@ tests/test_pycode.py
 tests/test_quickstart.py
 tests/test_search.py
 tests/test_setup_command.py
+tests/test_smartquotes.py
 tests/test_templating.py
 tests/test_theming.py
 tests/test_toctree.py
@@ -699,6 +700,8 @@ tests/roots/test-api-set-translator/translator.py
 tests/roots/test-api-set-translator/nonext/conf.py
 tests/roots/test-apidoc-pep420/a/b/c/__init__.py
 tests/roots/test-apidoc-pep420/a/b/c/d.py
+tests/roots/test-apidoc-pep420/a/b/e/__init__.py
+tests/roots/test-apidoc-pep420/a/b/e/f.py
 tests/roots/test-apidoc-pep420/a/b/x/y.py
 tests/roots/test-apidoc-toc/mypackage/__init__.py
 tests/roots/test-apidoc-toc/mypackage/main.py
@@ -779,9 +782,12 @@ tests/roots/test-double-inheriting-theme/conf.py
 tests/roots/test-double-inheriting-theme/index.rst
 tests/roots/test-double-inheriting-theme/base_themes_dir/base_theme1/theme.conf
 tests/roots/test-double-inheriting-theme/base_themes_dir/base_theme2/theme.conf
+tests/roots/test-ext-autodoc/autodoc_dummy_bar.py
 tests/roots/test-ext-autodoc/autodoc_dummy_module.py
 tests/roots/test-ext-autodoc/conf.py
 tests/roots/test-ext-autodoc/contents.rst
+tests/roots/test-ext-autodoc/bug2437/__init__.py
+tests/roots/test-ext-autodoc/bug2437/autodoc_dummy_foo.py
 tests/roots/test-ext-autosectionlabel/conf.py
 tests/roots/test-ext-autosectionlabel/index.rst
 tests/roots/test-ext-autosectionlabel-prefix-document/conf.py
@@ -955,6 +961,7 @@ tests/roots/test-latex-table/expects/simple_table.tex
 tests/roots/test-latex-table/expects/table_having_caption.tex
 tests/roots/test-latex-table/expects/table_having_problematic_cell.tex
 tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex
+tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex
 tests/roots/test-latex-table/expects/table_having_verbatim.tex
 tests/roots/test-latex-table/expects/table_having_widths.tex
 tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex
@@ -1035,6 +1042,8 @@ tests/roots/test-setup/setup.cfg
 tests/roots/test-setup/setup.py
 tests/roots/test-setup/doc/conf.py
 tests/roots/test-setup/doc/contents.txt
+tests/roots/test-smartquotes/conf.py
+tests/roots/test-smartquotes/index.rst
 tests/roots/test-stylesheets/conf.py
 tests/roots/test-stylesheets/index.rst
 tests/roots/test-stylesheets/_templates/layout.html
diff --git a/sphinx/__init__.py b/sphinx/__init__.py
index 332bfe9..85a4f42 100644
--- a/sphinx/__init__.py
+++ b/sphinx/__init__.py
@@ -34,13 +34,13 @@ if 'PYTHONWARNINGS' not in os.environ:
 warnings.filterwarnings('ignore', "'U' mode is deprecated",
                         DeprecationWarning, module='docutils.io')
 
-__version__ = '1.6.6'
-__released__ = '1.6.6'  # used when Sphinx builds its own docs
+__version__ = '1.6.7'
+__released__ = '1.6.7'  # 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, 6, 6, 'final', 0)
+version_info = (1, 6, 7, 'final', 0)
 
 package_dir = path.abspath(path.dirname(__file__))
 
diff --git a/sphinx/apidoc.py b/sphinx/apidoc.py
index 3b51469..06cbfa0 100644
--- a/sphinx/apidoc.py
+++ b/sphinx/apidoc.py
@@ -16,6 +16,7 @@
 """
 from __future__ import print_function
 
+import glob
 import os
 import sys
 import optparse
@@ -194,7 +195,17 @@ def shall_skip(module, opts):
 
     # skip it if there is nothing (or just \n or \r\n) in the file
     if path.exists(module) and path.getsize(module) <= 2:
-        return True
+        skip = True
+        if os.path.basename(module) == '__init__.py':
+            pattern = path.join(path.dirname(module), '*.py')
+            # We only want to skip packages if they do not contain any
+            # .py files other than __init__.py.
+            other_modules = list(glob.glob(pattern))
+            other_modules.remove(module)
+            skip = not other_modules
+
+        if skip:
+            return True
 
     # skip if it has a "private" name and this is selected
     filename = path.basename(module)
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index 68f3832..7be90e4 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -54,9 +54,11 @@ from sphinx.environment.adapters.indexentries import IndexEntries
 
 if False:
     # For type annotation
-    from typing import Any, Dict, Iterable, Iterator, List, Type, Tuple, Union  # NOQA
-    from sphinx.domains import Domain, Index  # NOQA
+    from typing import Any, Dict, IO, Iterable, Iterator, List, Type, Tuple, Union  # NOQA
     from sphinx.application import Sphinx  # NOQA
+    from sphinx.config import Config  # NOQA
+    from sphinx.domains import Domain, Index  # NOQA
+    from sphinx.util.tags import Tags  # NOQA
 
 # Experimental HTML5 Writer
 if is_html5_writer_available():
@@ -147,6 +149,60 @@ class Stylesheet(text_type):
         return self
 
 
+class BuildInfo(object):
+    """buildinfo file manipulator.
+
+    HTMLBuilder and its family are storing their own envdata to ``.buildinfo``.
+    This class is a manipulator for the file.
+    """
+
+    @classmethod
+    def load(cls, f):
+        # type: (IO) -> BuildInfo
+        try:
+            lines = f.readlines()
+            assert lines[0].rstrip() == '# Sphinx build info version 1'
+            assert lines[2].startswith('config: ')
+            assert lines[3].startswith('tags: ')
+
+            build_info = BuildInfo()
+            build_info.config_hash = lines[2].split()[1].strip()
+            build_info.tags_hash = lines[3].split()[1].strip()
+            return build_info
+        except Exception as exc:
+            raise ValueError('build info file is broken: %r' % exc)
+
+    def __init__(self, config=None, tags=None):
+        # type: (Config, Tags) -> None
+        self.config_hash = u''
+        self.tags_hash = u''
+
+        if config:
+            values = dict((c.name, c.value) for c in config.filter('html'))
+            self.config_hash = get_stable_hash(values)
+
+        if tags:
+            self.tags_hash = get_stable_hash(sorted(tags))
+
+    def __eq__(self, other):  # type: ignore
+        # type: (BuildInfo) -> bool
+        return (self.config_hash == other.config_hash and
+                self.tags_hash == other.tags_hash)
+
+    def __ne__(self, other):  # type: ignore
+        # type: (BuildInfo) -> bool
+        return not (self == other)  # for py27
+
+    def dump(self, f):
+        # type: (IO) -> None
+        f.write('# Sphinx build info version 1\n'
+                '# This file hashes the configuration used when building these files.'
+                ' When it is not found, a full rebuild will be done.\n'
+                'config: %s\n'
+                'tags: %s\n' %
+                (self.config_hash, self.tags_hash))
+
+
 class StandaloneHTMLBuilder(Builder):
     """
     Builds standalone HTML docs.
@@ -189,9 +245,7 @@ class StandaloneHTMLBuilder(Builder):
 
     def init(self):
         # type: () -> None
-        # a hash of all config values that, if changed, cause a full rebuild
-        self.config_hash = ''  # type: unicode
-        self.tags_hash = ''  # type: unicode
+        self.build_info = BuildInfo(self.config, self.tags)
         # basename of images directory
         self.imagedir = '_images'
         # section numbers for headings in the currently visited document
@@ -272,32 +326,19 @@ class StandaloneHTMLBuilder(Builder):
 
     def get_outdated_docs(self):
         # type: () -> Iterator[unicode]
-        cfgdict = dict((confval.name, confval.value) for confval in self.config.filter('html'))
-        self.config_hash = get_stable_hash(cfgdict)
-        self.tags_hash = get_stable_hash(sorted(self.tags))
-        old_config_hash = old_tags_hash = ''
         try:
             with open(path.join(self.outdir, '.buildinfo')) as fp:
-                version = fp.readline()
-                if version.rstrip() != '# Sphinx build info version 1':
-                    raise ValueError
-                fp.readline()  # skip commentary
-                cfg, old_config_hash = fp.readline().strip().split(': ')
-                if cfg != 'config':
-                    raise ValueError
-                tag, old_tags_hash = fp.readline().strip().split(': ')
-                if tag != 'tags':
-                    raise ValueError
-        except ValueError:
-            logger.warning('unsupported build info format in %r, building all',
-                           path.join(self.outdir, '.buildinfo'))
-        except Exception:
+                buildinfo = BuildInfo.load(fp)
+
+            if self.build_info != buildinfo:
+                for docname in self.env.found_docs:
+                    yield docname
+                return
+        except ValueError as exc:
+            logger.warning('Failed to read build info file: %r', exc)
+        except IOError:
+            # ignore errors on reading
             pass
-        if old_config_hash != self.config_hash or \
-           old_tags_hash != self.tags_hash:
-            for docname in self.env.found_docs:
-                yield docname
-            return
 
         if self.templates:
             template_mtime = self.templates.newest_template_mtime()
@@ -775,14 +816,9 @@ class StandaloneHTMLBuilder(Builder):
 
     def write_buildinfo(self):
         # type: () -> None
-        # write build info file
         try:
             with open(path.join(self.outdir, '.buildinfo'), 'w') as fp:
-                fp.write('# Sphinx build info version 1\n'
-                         '# This file hashes the configuration used when building'
-                         ' these files. When it is not found, a full rebuild will'
-                         ' be done.\nconfig: %s\ntags: %s\n' %
-                         (self.config_hash, self.tags_hash))
+                self.build_info.dump(fp)
         except IOError as exc:
             logger.warning('Failed to write build info file: %r', exc)
 
@@ -1235,8 +1271,7 @@ class SerializingHTMLBuilder(StandaloneHTMLBuilder):
 
     def init(self):
         # type: () -> None
-        self.config_hash = ''
-        self.tags_hash = ''
+        self.build_info = BuildInfo(self.config, self.tags)
         self.imagedir = '_images'
         self.current_docname = None
         self.theme = None       # no theme necessary
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index 68baa04..a261090 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -607,8 +607,9 @@ class StandardDomain(Domain):
             if node.tagname == 'target' and 'refid' in node:  # indirect hyperlink targets
                 node = document.ids.get(node['refid'])
                 labelid = node['names'][0]
-            if name.isdigit() or 'refuri' in node or \
-               node.tagname.startswith('desc_'):
+            if (node.tagname == 'footnote' or
+                    'refuri' in node or
+                    node.tagname.startswith('desc_')):
                 # ignore footnote labels, labels automatically generated from a
                 # link and object descriptions
                 continue
diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py
index bd68664..1ccd746 100644
--- a/sphinx/ext/autodoc.py
+++ b/sphinx/ext/autodoc.py
@@ -1513,8 +1513,14 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter):  # type:
     def add_content(self, more_content, no_docstring=False):
         # type: (Any, bool) -> None
         if self.doc_as_attr:
-            classname = safe_getattr(self.object, '__name__', None)
+            classname = safe_getattr(self.object, '__qualname__', None)
+            if not classname:
+                classname = safe_getattr(self.object, '__name__', None)
             if classname:
+                module = safe_getattr(self.object, '__module__', None)
+                parentmodule = safe_getattr(self.parent, '__module__', None)
+                if module and module != parentmodule:
+                    classname = str(module) + u'.' + str(classname)
                 content = ViewList(
                     [_('alias of :class:`%s`') % classname], source='')
                 ModuleLevelDocumenter.add_content(self, content,
diff --git a/sphinx/ext/autosectionlabel.py b/sphinx/ext/autosectionlabel.py
index fbb7d03..33c92ef 100644
--- a/sphinx/ext/autosectionlabel.py
+++ b/sphinx/ext/autosectionlabel.py
@@ -15,8 +15,14 @@ from sphinx.util.nodes import clean_astext
 
 logger = logging.getLogger(__name__)
 
+if False:
+    # For type annotation
+    from typing import Any, Dict  # NOQA
+    from sphinx.application import Sphinx  # NOQA
+
 
 def register_sections_as_label(app, document):
+    # type: (Sphinx, nodes.Node) -> None
     labels = app.env.domaindata['std']['labels']
     anonlabels = app.env.domaindata['std']['anonlabels']
     for node in document.traverse(nodes.section):
@@ -38,5 +44,12 @@ def register_sections_as_label(app, document):
 
 
 def setup(app):
+    # type: (Sphinx) -> Dict[unicode, Any]
     app.add_config_value('autosectionlabel_prefix_document', False, 'env')
     app.connect('doctree-read', register_sections_as_label)
+
+    return {
+        'version': 'builtin',
+        'parallel_read_safe': True,
+        'parallel_write_safe': True,
+    }
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index 08776ba..769ae4a 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -397,10 +397,20 @@ class Autosummary(Directive):
         return [table_spec, table]
 
 
+def strip_arg_typehint(s):
+    # type: (unicode) -> unicode
+    """Strip a type hint from argument definition."""
+    return s.split(':')[0].strip()
+
+
 def mangle_signature(sig, max_chars=30):
     # type: (unicode, int) -> unicode
     """Reformat a function signature to a more compact form."""
-    s = re.sub(r"^\((.*)\)$", r"\1", sig).strip()
+    # Strip return type annotation
+    s = re.sub(r"\)\s*->\s.*$", ")", sig)
+
+    # Remove parenthesis
+    s = re.sub(r"^\((.*)\)$", r"\1", s).strip()
 
     # Strip strings (which can contain things that confuse the code below)
     s = re.sub(r"\\\\", "", s)
@@ -422,6 +432,13 @@ def mangle_signature(sig, max_chars=30):
         opts.insert(0, m.group(2))
         s = m.group(1)[:-2]
 
+    # Strip typehints
+    for i, arg in enumerate(args):
+        args[i] = strip_arg_typehint(arg)
+
+    for i, opt in enumerate(opts):
+        opts[i] = strip_arg_typehint(opt)
+
     # Produce a more compact signature
     sig = limited_join(", ", args, max_chars=max_chars - 2)
     if opts:
diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py
index 5465948..715b7dd 100644
--- a/sphinx/ext/graphviz.py
+++ b/sphinx/ext/graphviz.py
@@ -38,13 +38,54 @@ if False:
 logger = logging.getLogger(__name__)
 
 
-mapname_re = re.compile(r'<map id="(.*?)"')
-
-
 class GraphvizError(SphinxError):
     category = 'Graphviz error'
 
 
+class ClickableMapDefinition(object):
+    """A manipulator for clickable map file of graphviz."""
+    maptag_re = re.compile('<map id="(.*?)"')
+    href_re = re.compile('href=".*?"')
+
+    def __init__(self, filename, content, dot=''):
+        # type: (unicode, unicode, unicode) -> None
+        self.id = None  # type: unicode
+        self.filename = filename
+        self.content = content.splitlines()
+        self.clickable = []  # type: List[unicode]
+
+        self.parse(dot=dot)
+
+    def parse(self, dot=None):
+        # type: (unicode) -> None
+        matched = self.maptag_re.match(self.content[0])   # type: ignore
+        if not matched:
+            raise GraphvizError('Invalid clickable map file found: %s' % self.filename)
+
+        self.id = matched.group(1)
+        if self.id == '%3':
+            # graphviz generates wrong ID if graph name not specified
+            # https://gitlab.com/graphviz/graphviz/issues/1327
+            hashed = sha1(dot.encode('utf-8')).hexdigest()
+            self.id = 'grapviz%s' % hashed[-10:]
+            self.content[0] = self.content[0].replace('%3', self.id)
+
+        for line in self.content:
+            if self.href_re.search(line):  # type: ignore
+                self.clickable.append(line)
+
+    def generate_clickable_map(self):
+        # type: () -> unicode
+        """Generate clickable map tags if clickable item exists.
+
+        If not exists, this only returns empty string.
+        """
+        if self.clickable:
+            return '\n'.join([self.content[0]] + self.clickable + [self.content[-1]])
+        else:
+            return ''
+
+
 class graphviz(nodes.General, nodes.Inline, nodes.Element):
     pass
 
@@ -254,18 +295,17 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
             <p class="warning">%s</p></object>\n''' % (fname, alt)
             self.body.append(svgtag)
         else:
-            with open(outfn + '.map', 'rb') as mapfile:
-                imgmap = mapfile.readlines()
-            if len(imgmap) == 2:
-                # nothing in image map (the lines are <map> and </map>)
-                self.body.append('<img src="%s" alt="%s" %s/>\n' %
-                                 (fname, alt, imgcss))
-            else:
-                # has a map: get the name of the map and connect the parts
-                mapname = mapname_re.match(imgmap[0].decode('utf-8')).group(1)  # type: ignore
-                self.body.append('<img src="%s" alt="%s" usemap="#%s" %s/>\n' %
-                                 (fname, alt, mapname, imgcss))
-                self.body.extend([item.decode('utf-8') for item in imgmap])
+            with codecs.open(outfn + '.map', 'r', encoding='utf-8') as mapfile:  # type: ignore
+                imgmap = ClickableMapDefinition(outfn + '.map', mapfile.read(), dot=code)
+                if imgmap.clickable:
+                    # has a map
+                    self.body.append('<img src="%s" alt="%s" usemap="#%s" %s/>\n' %
+                                     (fname, alt, imgmap.id, imgcss))
+                    self.body.append(imgmap.generate_clickable_map())
+                else:
+                    # nothing in image map
+                    self.body.append('<img src="%s" alt="%s" %s/>\n' %
+                                     (fname, alt, imgcss))
         if 'align' in node:
             self.body.append('</div>\n')
 
diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py
index 9336c4b..8432b2b 100644
--- a/sphinx/ext/intersphinx.py
+++ b/sphinx/ext/intersphinx.py
@@ -179,9 +179,9 @@ def fetch_inventory(app, uri, inv):
         else:
             f = open(path.join(app.srcdir, inv), 'rb')
     except Exception as err:
-        logger.warning('intersphinx inventory %r not fetchable due to %s: %s',
-                       inv, err.__class__, err)
-        return
+        err.args = ('intersphinx inventory %r not fetchable due to %s: %s',
+                    inv, err.__class__, err)
+        raise
     try:
         if hasattr(f, 'url'):
             newinv = f.url  # type: ignore
@@ -197,8 +197,9 @@ def fetch_inventory(app, uri, inv):
             except ValueError as exc:
                 raise ValueError('unknown or unsupported inventory version: %r' % exc)
     except Exception as err:
-        logger.warning('intersphinx inventory %r not readable due to %s: %s',
-                       inv, err.__class__.__name__, err)
+        err.args = ('intersphinx inventory %r not readable due to %s: %s',
+                    inv, err.__class__.__name__, err)
+        raise
     else:
         return invdata
 
@@ -232,6 +233,7 @@ def load_mappings(app):
         else:
             invs = inv  # type: ignore
 
+        failures = []
         for inv in invs:
             if not inv:
                 inv = posixpath.join(uri, INVENTORY_FILENAME)
@@ -241,12 +243,30 @@ def load_mappings(app):
                     or inventories.cache[uri][1] < cache_time:
                 safe_inv_url = _get_safe_url(inv)  # type: ignore
                 logger.info('loading intersphinx inventory from %s...', safe_inv_url)
-                invdata = fetch_inventory(app, uri, inv)
+                try:
+                    invdata = fetch_inventory(app, uri, inv)
+                except Exception as err:
+                    failures.append(err.args)
+                    continue
+
                 if invdata:
                     inventories.cache[uri] = (name, now, invdata)
                     update = True
                     break
 
+        if failures == []:
+            pass
+        elif len(failures) < len(invs):
+            logger.info("encountered some issues with some of the inventories,"
+                        " but they had working alternatives:")
+            for fail in failures:
+                logger.info(*fail)
+        else:
+            logger.warning("failed to reach any of the inventories "
+                           "with the following issues:")
+            for fail in failures:
+                logger.warning(*fail)
+
     if update:
         inventories.clear()
 
diff --git a/sphinx/ext/mathbase.py b/sphinx/ext/mathbase.py
index 549ca30..514fcda 100644
--- a/sphinx/ext/mathbase.py
+++ b/sphinx/ext/mathbase.py
@@ -10,6 +10,7 @@
 """
 
 from docutils import nodes, utils
+from docutils.nodes import make_id
 from docutils.parsers.rst import Directive, directives
 
 from sphinx.roles import XRefRole
@@ -59,15 +60,15 @@ class MathDomain(Domain):
 
     def clear_doc(self, docname):
         # type: (unicode) -> None
-        for labelid, (doc, eqno) in list(self.data['objects'].items()):
+        for equation_id, (doc, eqno) in list(self.data['objects'].items()):
             if doc == docname:
-                del self.data['objects'][labelid]
+                del self.data['objects'][equation_id]
 
     def merge_domaindata(self, docnames, otherdata):
         # type: (Iterable[unicode], Dict) -> None
         for labelid, (doc, eqno) in otherdata['objects'].items():
             if doc in docnames:
-                self.data['objects'][labelid] = doc
+                self.data['objects'][labelid] = (doc, eqno)
 
     def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
         # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node  # NOQA
@@ -81,8 +82,8 @@ class MathDomain(Domain):
                 return newnode
             else:
                 title = nodes.Text("(%d)" % number)
-                return make_refnode(builder, fromdocname, docname,
-                                    "equation-" + target, title)
+                node_id = make_id('equation-%s' % target)
+                return make_refnode(builder, fromdocname, docname, node_id, title)
         else:
             return None
 
@@ -226,7 +227,8 @@ class MathDirective(Directive):
             node['number'] = eqno
 
             # add target node
-            target = nodes.target('', '', ids=['equation-' + node['label']])
+            node_id = make_id('equation-%s' % node['label'])
+            target = nodes.target('', '', ids=[node_id])
             self.state.document.note_explicit_target(target)
             ret.insert(0, target)
         except UserWarning as exc:
diff --git a/sphinx/search/fr.py b/sphinx/search/fr.py
index 2cf7035..615a473 100644
--- a/sphinx/search/fr.py
+++ b/sphinx/search/fr.py
@@ -207,4 +207,4 @@ class SearchFrench(SearchLanguage):
         self.stemmer = snowballstemmer.stemmer('french')
 
     def stem(self, word):
-        return self.stemmer.stemWord(word)
+        return self.stemmer.stemWord(word.lower())
diff --git a/sphinx/themes/basic/static/basic.css_t b/sphinx/themes/basic/static/basic.css_t
index 745864e..407ef95 100644
--- a/sphinx/themes/basic/static/basic.css_t
+++ b/sphinx/themes/basic/static/basic.css_t
@@ -332,6 +332,11 @@ table.docutils {
     border-collapse: collapse;
 }
 
+table.align-center {
+    margin-left: auto;
+    margin-right: auto;
+}
+
 table caption span.caption-number {
     font-style: italic;
 }
diff --git a/sphinx/themes/basic/static/jquery-3.1.0.js b/sphinx/themes/basic/static/jquery-3.2.1.js
similarity index 94%
rename from sphinx/themes/basic/static/jquery-3.1.0.js
rename to sphinx/themes/basic/static/jquery-3.2.1.js
index f2fc274..d2d8ca4 100644
--- a/sphinx/themes/basic/static/jquery-3.1.0.js
+++ b/sphinx/themes/basic/static/jquery-3.2.1.js
@@ -1,16 +1,15 @@
-/*eslint-disable no-unused-vars*/
 /*!
- * jQuery JavaScript Library v3.1.0
+ * jQuery JavaScript Library v3.2.1
  * https://jquery.com/
  *
  * Includes Sizzle.js
  * https://sizzlejs.com/
  *
- * Copyright jQuery Foundation and other contributors
+ * Copyright JS Foundation and other contributors
  * Released under the MIT license
  * https://jquery.org/license
  *
- * Date: 2016-07-07T21:44Z
+ * Date: 2017-03-20T18:59Z
  */
 ( function( global, factory ) {
 
@@ -83,13 +82,13 @@ var support = {};
 		doc.head.appendChild( script ).parentNode.removeChild( script );
 	}
 /* global Symbol */
-// Defining this global in .eslintrc would create a danger of using the global
+// Defining this global in .eslintrc.json would create a danger of using the global
 // unguarded in another place, it seems safer to define global only for this module
 
 
 
 var
-	version = "3.1.0",
+	version = "3.2.1",
 
 	// Define a local copy of jQuery
 	jQuery = function( selector, context ) {
@@ -129,13 +128,14 @@ jQuery.fn = jQuery.prototype = {
 	// Get the Nth element in the matched element set OR
 	// Get the whole matched element set as a clean array
 	get: function( num ) {
-		return num != null ?
 
-			// Return just the one element from the set
-			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
+		// Return all the elements in a clean array
+		if ( num == null ) {
+			return slice.call( this );
+		}
 
-			// Return all the elements in a clean array
-			slice.call( this );
+		// Return just the one element from the set
+		return num < 0 ? this[ num + this.length ] : this[ num ];
 	},
 
 	// Take an array of elements and push it onto the stack
@@ -236,11 +236,11 @@ jQuery.extend = jQuery.fn.extend = function() {
 
 				// Recurse if we're merging plain objects or arrays
 				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
-					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
+					( copyIsArray = Array.isArray( copy ) ) ) ) {
 
 					if ( copyIsArray ) {
 						copyIsArray = false;
-						clone = src && jQuery.isArray( src ) ? src : [];
+						clone = src && Array.isArray( src ) ? src : [];
 
 					} else {
 						clone = src && jQuery.isPlainObject( src ) ? src : {};
@@ -279,8 +279,6 @@ jQuery.extend( {
 		return jQuery.type( obj ) === "function";
 	},
 
-	isArray: Array.isArray,
-
 	isWindow: function( obj ) {
 		return obj != null && obj === obj.window;
 	},
@@ -355,10 +353,6 @@ jQuery.extend( {
 		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
 	},
 
-	nodeName: function( elem, name ) {
-		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
-	},
-
 	each: function( obj, callback ) {
 		var length, i = 0;
 
@@ -543,14 +537,14 @@ function isArrayLike( obj ) {
 }
 var Sizzle =
 /*!
- * Sizzle CSS Selector Engine v2.3.0
+ * Sizzle CSS Selector Engine v2.3.3
  * https://sizzlejs.com/
  *
  * Copyright jQuery Foundation and other contributors
  * Released under the MIT license
  * http://jquery.org/license
  *
- * Date: 2016-01-04
+ * Date: 2016-08-08
  */
 (function( window ) {
 
@@ -696,7 +690,7 @@ var i,
 
 	// CSS string/identifier serialization
 	// https://drafts.csswg.org/cssom/#common-serializing-idioms
-	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,
+	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
 	fcssescape = function( ch, asCodePoint ) {
 		if ( asCodePoint ) {
 
@@ -723,7 +717,7 @@ var i,
 
 	disabledAncestor = addCombinator(
 		function( elem ) {
-			return elem.disabled === true;
+			return elem.disabled === true && ("form" in elem || "label" in elem);
 		},
 		{ dir: "parentNode", next: "legend" }
 	);
@@ -1009,26 +1003,54 @@ function createButtonPseudo( type ) {
  * @param {Boolean} disabled true for :disabled; false for :enabled
  */
 function createDisabledPseudo( disabled ) {
-	// Known :disabled false positives:
-	// IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset)
-	// not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+
+	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
 	return function( elem ) {
 
-		// Check form elements and option elements for explicit disabling
-		return "label" in elem && elem.disabled === disabled ||
-			"form" in elem && elem.disabled === disabled ||
+		// Only certain elements can match :enabled or :disabled
+		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+		if ( "form" in elem ) {
+
+			// Check for inherited disabledness on relevant non-disabled elements:
+			// * listed form-associated elements in a disabled fieldset
+			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
+			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+			// * option elements in a disabled optgroup
+			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+			// All such elements have a "form" property.
+			if ( elem.parentNode && elem.disabled === false ) {
+
+				// Option elements defer to a parent optgroup if present
+				if ( "label" in elem ) {
+					if ( "label" in elem.parentNode ) {
+						return elem.parentNode.disabled === disabled;
+					} else {
+						return elem.disabled === disabled;
+					}
+				}
 
-			// Check non-disabled form elements for fieldset[disabled] ancestors
-			"form" in elem && elem.disabled === false && (
-				// Support: IE6-11+
-				// Ancestry is covered for us
-				elem.isDisabled === disabled ||
+				// Support: IE 6 - 11
+				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
+				return elem.isDisabled === disabled ||
 
-				// Otherwise, assume any non-<option> under fieldset[disabled] is disabled
-				/* jshint -W018 */
-				elem.isDisabled !== !disabled &&
-					("label" in elem || !disabledAncestor( elem )) !== disabled
-			);
+					// Where there is no isDisabled, check manually
+					/* jshint -W018 */
+					elem.isDisabled !== !disabled &&
+						disabledAncestor( elem ) === disabled;
+			}
+
+			return elem.disabled === disabled;
+
+		// Try to winnow out elements that can't be disabled before trusting the disabled property.
+		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+		// even exist on them, let alone have a boolean value.
+		} else if ( "label" in elem ) {
+			return elem.disabled === disabled;
+		}
+
+		// Remaining elements are neither :enabled nor :disabled
+		return false;
 	};
 }
 
@@ -1144,25 +1166,21 @@ setDocument = Sizzle.setDocument = function( node ) {
 		return !document.getElementsByName || !document.getElementsByName( expando ).length;
 	});
 
-	// ID find and filter
+	// ID filter and find
 	if ( support.getById ) {
-		Expr.find["ID"] = function( id, context ) {
-			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
-				var m = context.getElementById( id );
-				return m ? [ m ] : [];
-			}
-		};
 		Expr.filter["ID"] = function( id ) {
 			var attrId = id.replace( runescape, funescape );
 			return function( elem ) {
 				return elem.getAttribute("id") === attrId;
 			};
 		};
+		Expr.find["ID"] = function( id, context ) {
+			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+				var elem = context.getElementById( id );
+				return elem ? [ elem ] : [];
+			}
+		};
 	} else {
-		// Support: IE6/7
-		// getElementById is not reliable as a find shortcut
-		delete Expr.find["ID"];
-
 		Expr.filter["ID"] =  function( id ) {
 			var attrId = id.replace( runescape, funescape );
 			return function( elem ) {
@@ -1171,6 +1189,36 @@ setDocument = Sizzle.setDocument = function( node ) {
 				return node && node.value === attrId;
 			};
 		};
+
+		// Support: IE 6 - 7 only
+		// getElementById is not reliable as a find shortcut
+		Expr.find["ID"] = function( id, context ) {
+			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+				var node, i, elems,
+					elem = context.getElementById( id );
+
+				if ( elem ) {
+
+					// Verify the id attribute
+					node = elem.getAttributeNode("id");
+					if ( node && node.value === id ) {
+						return [ elem ];
+					}
+
... 2038 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/sphinx.git



More information about the Python-modules-commits mailing list