From 2e3e22ee03f7093f62c53cab8efe0d21e79d2c14 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 11:06:59 +0200 Subject: [PATCH 001/124] apply the type preprocessor only after the check for prefer_type --- sphinx/ext/napoleon/docstring.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 95fb1e538..a41e9fdd4 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -1067,6 +1067,10 @@ class NumpyDocstring(GoogleDocstring): _name, _type = line, '' _name, _type = _name.strip(), _type.strip() _name = self._escape_args_and_kwargs(_name) + + if prefer_type and not _type: + _type, _name = _name, _type + if self._config.napoleon_use_param: _type = _convert_numpy_type_spec( _type, @@ -1074,8 +1078,6 @@ class NumpyDocstring(GoogleDocstring): translations=self._config.napoleon_type_aliases or {}, ) - if prefer_type and not _type: - _type, _name = _name, _type indent = self._get_indent(line) + 1 _desc = self._dedent(self._consume_indented_block(indent)) _desc = self.__class__(_desc, self._config).lines() From 697fc8b16c211dc8515afd3f6df8d7c3baca469d Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 11:25:57 +0200 Subject: [PATCH 002/124] add test for the raises, yields and returns sections --- tests/test_ext_napoleon_docstring.py | 53 +++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 56812d193..017737387 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1607,6 +1607,20 @@ Example Function (""" Example Function +Raises +------ +CustomError + If the dimensions couldn't be parsed. + +""", """ +Example Function + +:raises package.CustomError: If the dimensions couldn't be parsed. +"""), + ################################ + (""" +Example Function + Raises ------ :class:`exc.InvalidDimensionsError` @@ -1619,7 +1633,7 @@ Example Function :raises exc.InvalidArgumentsError: """)] for docstring, expected in docstrings: - config = Config() + config = Config(napoleon_type_aliases={"CustomError": "package.CustomError"}) app = mock.Mock() actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) @@ -1646,6 +1660,43 @@ Example Function actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) + docstring = """ +Example Function + +Returns +------- +ndarray + A :math:`n \\times 2` array containing + a bunch of math items +""" + config = Config(napoleon_type_aliases={"ndarray": ":class:`numpy.ndarray`"}) + actual = str(NumpyDocstring(docstring, config, app, "method")) + self.assertEqual(expected, actual) + + def test_yield_types(self): + docstring = dedent(""" + Example Function + + Yields + ------ + scalar or array-like + The result of the computation + """) + expected = dedent(""" + Example Function + + :Yields: :term:`scalar` or :class:`array-like ` -- The result of the computation + """) + config = Config( + napoleon_type_aliases={ + "scalar": ":term:`scalar`", + "array-like": ":class:`array-like `", + } + ) + app = mock.Mock() + actual = str(NumpyDocstring(docstring, config, app, "method")) + self.assertEqual(expected, actual) + def test_section_header_underline_length(self): docstrings = [(""" Summary line From fa760c326a1a96e9fe9f373b9b94757dd636e12f Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 11:30:14 +0200 Subject: [PATCH 003/124] move the translations to a named variable --- tests/test_ext_napoleon_docstring.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 017737387..991e5a232 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1687,12 +1687,11 @@ ndarray :Yields: :term:`scalar` or :class:`array-like ` -- The result of the computation """) - config = Config( - napoleon_type_aliases={ - "scalar": ":term:`scalar`", - "array-like": ":class:`array-like `", - } - ) + translations = { + "scalar": ":term:`scalar`", + "array-like": ":class:`array-like `", + } + config = Config(napoleon_type_aliases=translations) app = mock.Mock() actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) From 278a057104a26e33b6a986f3a1184482b90cdbbd Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 11:35:39 +0200 Subject: [PATCH 004/124] move the return types and yield types tests to above the raises test --- tests/test_ext_napoleon_docstring.py | 81 +++++++++++++++------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 991e5a232..35e2f36bd 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1443,6 +1443,51 @@ arg_ : type self.assertEqual(expected, actual) + def test_return_types(self): + docstring = dedent(""" + Returns + ------- + DataFrame + a dataframe + """) + expected = dedent(""" + :returns: a dataframe + :rtype: :class:`~pandas.DataFrame` + """) + translations = { + "DataFrame": "~pandas.DataFrame", + } + config = Config( + napoleon_use_param=True, + napoleon_use_rtype=True, + napoleon_type_aliases=translations, + ) + actual = str(NumpyDocstring(docstring, config)) + self.assertEqual(expected, actual) + + def test_yield_types(self): + docstring = dedent(""" + Example Function + + Yields + ------ + scalar or array-like + The result of the computation + """) + expected = dedent(""" + Example Function + + :Yields: :term:`scalar` or :class:`array-like ` -- The result of the computation + """) + translations = { + "scalar": ":term:`scalar`", + "array-like": ":class:`array-like `", + } + config = Config(napoleon_type_aliases=translations) + app = mock.Mock() + actual = str(NumpyDocstring(docstring, config, app, "method")) + self.assertEqual(expected, actual) + def test_raises_types(self): docstrings = [(""" Example Function @@ -1660,42 +1705,6 @@ Example Function actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) - docstring = """ -Example Function - -Returns -------- -ndarray - A :math:`n \\times 2` array containing - a bunch of math items -""" - config = Config(napoleon_type_aliases={"ndarray": ":class:`numpy.ndarray`"}) - actual = str(NumpyDocstring(docstring, config, app, "method")) - self.assertEqual(expected, actual) - - def test_yield_types(self): - docstring = dedent(""" - Example Function - - Yields - ------ - scalar or array-like - The result of the computation - """) - expected = dedent(""" - Example Function - - :Yields: :term:`scalar` or :class:`array-like ` -- The result of the computation - """) - translations = { - "scalar": ":term:`scalar`", - "array-like": ":class:`array-like `", - } - config = Config(napoleon_type_aliases=translations) - app = mock.Mock() - actual = str(NumpyDocstring(docstring, config, app, "method")) - self.assertEqual(expected, actual) - def test_section_header_underline_length(self): docstrings = [(""" Summary line From 2c75aaaa5452ab093e71138b6f864859cfb08554 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 11:36:15 +0200 Subject: [PATCH 005/124] move the GoogleDocstring test to the appropriate test class --- tests/test_ext_napoleon_docstring.py | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 35e2f36bd..14929bc0d 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1078,6 +1078,22 @@ Methods: options={'noindex': True})) self.assertEqual(expected, actual) + def test_keywords_with_types(self): + docstring = """\ +Do as you please + +Keyword Args: + gotham_is_yours (None): shall interfere. +""" + actual = str(GoogleDocstring(docstring)) + expected = """\ +Do as you please + +:keyword gotham_is_yours: shall interfere. +:kwtype gotham_is_yours: None +""" + self.assertEqual(expected, actual) + class NumpyDocstringTest(BaseDocstringTest): docstrings = [( @@ -2191,22 +2207,6 @@ definition_after_normal_text : int actual = str(NumpyDocstring(docstring, config)) self.assertEqual(expected, actual) - def test_keywords_with_types(self): - docstring = """\ -Do as you please - -Keyword Args: - gotham_is_yours (None): shall interfere. -""" - actual = str(GoogleDocstring(docstring)) - expected = """\ -Do as you please - -:keyword gotham_is_yours: shall interfere. -:kwtype gotham_is_yours: None -""" - self.assertEqual(expected, actual) - @contextmanager def warns(warning, match): match_re = re.compile(match) From d9fb3bc25cecdcca78172e39b6b62723ba7f4dc5 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 14:35:33 +0200 Subject: [PATCH 006/124] search the role for See Also items in the intersphinx inventory --- sphinx/ext/napoleon/docstring.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 95fb1e538..b1e5ca374 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -1131,6 +1131,7 @@ class NumpyDocstring(GoogleDocstring): func_name1, func_name2, :meth:`func_name`, func_name3 """ + inventory = getattr(self._app.builder.env, "intersphinx_inventory", {}) items = [] def parse_item_name(text: str) -> Tuple[str, str]: @@ -1151,6 +1152,25 @@ class NumpyDocstring(GoogleDocstring): items.append((name, list(rest), role)) del rest[:] + def search_inventory(inventory, name, hint=None): + roles = list(inventory.keys()) + if hint is not None: + preferred = [ + role + for role in roles + if role.split(":", 1)[-1].startswith(hint) + ] + roles = preferred + [role for role in roles if role not in preferred] + + for role in roles: + objects = inventory[role] + found = objects.get(name, None) + if found is not None: + domain, role = role.split(":", 1) + return role + + return None + current_func = None rest = [] # type: List[str] @@ -1206,6 +1226,10 @@ class NumpyDocstring(GoogleDocstring): lines = [] # type: List[str] last_had_desc = True for func, desc, role in items: + if not role: + raw_role = search_inventory(inventory, func, hint=func_role) + role = roles.get(raw_role, raw_role) + if role: link = ':%s:`%s`' % (role, func) elif func_role: From c812370427f2e60174f74938e3ee26c1c0849a66 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 14:59:54 +0200 Subject: [PATCH 007/124] expect the normal raises and yields to be preprocessed, too --- tests/test_ext_napoleon_docstring.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 14929bc0d..5900f37d1 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1175,7 +1175,7 @@ class NumpyDocstringTest(BaseDocstringTest): """ Single line summary - :returns: *str* -- Extended + :returns: :class:`str` -- Extended description of return value """ ), ( @@ -1191,7 +1191,7 @@ class NumpyDocstringTest(BaseDocstringTest): """ Single line summary - :returns: *str* -- Extended + :returns: :class:`str` -- Extended description of return value """ ), ( @@ -1227,7 +1227,7 @@ class NumpyDocstringTest(BaseDocstringTest): """ Single line summary - :Yields: *str* -- Extended + :Yields: :class:`str` -- Extended description of yielded value """ ), ( @@ -1243,7 +1243,7 @@ class NumpyDocstringTest(BaseDocstringTest): """ Single line summary - :Yields: *str* -- Extended + :Yields: :class:`str` -- Extended description of yielded value """ )] From e69724245135f152699d3f4a8b3c20992d9448ed Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 20:48:59 +0200 Subject: [PATCH 008/124] fix the tests by falling back to a empty dict on AttributeError --- sphinx/ext/napoleon/docstring.py | 6 +++++- tests/test_ext_napoleon_docstring.py | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index b1e5ca374..ada2a790e 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -1131,7 +1131,11 @@ class NumpyDocstring(GoogleDocstring): func_name1, func_name2, :meth:`func_name`, func_name3 """ - inventory = getattr(self._app.builder.env, "intersphinx_inventory", {}) + try: + inventory = self._app.builder.env.intersphinx_inventory + except AttributeError: + inventory = {} + items = [] def parse_item_name(text: str) -> Tuple[str, str]: diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 56812d193..0894a9bff 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1365,6 +1365,7 @@ otherfunc : relationship config = Config() app = mock.Mock() + app.builder.env = None actual = str(NumpyDocstring(docstring, config, app, "method")) expected = """\ @@ -1379,6 +1380,27 @@ numpy.multivariate_normal(mean, cov, shape=None, spam=None) """ self.assertEqual(expected, actual) + config = Config() + app = mock.Mock() + app.builder.env.intersphinx_inventory = { + "py:func": {"funcs": (), "otherfunc": ()}, + "py:meth": {"some": (), "other": ()}, + } + actual = str(NumpyDocstring(docstring, config, app, "method")) + + expected = """\ +numpy.multivariate_normal(mean, cov, shape=None, spam=None) + +.. seealso:: + + :meth:`some`, :meth:`other`, :func:`funcs` + \n\ + :func:`otherfunc` + relationship +""" + self.assertEqual(expected, actual) + + def test_colon_in_return_type(self): docstring = """ Summary From ca0bd28681afd72c826603eeef5a3ec8fac4e8dd Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 6 Aug 2020 13:17:40 +0200 Subject: [PATCH 009/124] ignore the mypy error on possibly failing attribute lookup --- sphinx/ext/napoleon/docstring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index ada2a790e..13a32cff8 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -1132,7 +1132,7 @@ class NumpyDocstring(GoogleDocstring): """ try: - inventory = self._app.builder.env.intersphinx_inventory + inventory = self._app.builder.env.intersphinx_inventory # type: ignore except AttributeError: inventory = {} From 4428393403ad98e49459e36085c7f0a85a627bab Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 6 Aug 2020 14:08:34 +0200 Subject: [PATCH 010/124] translate the functions before attempting to find a matching role --- sphinx/ext/napoleon/docstring.py | 22 +++++++++++++++++++ tests/test_ext_napoleon_docstring.py | 32 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 13a32cff8..d60deff6c 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -1175,6 +1175,22 @@ class NumpyDocstring(GoogleDocstring): return None + def translate(func, description, role): + translations = self._config.napoleon_type_aliases + if role is not None or not translations: + return func, description, role + + translated = translations.get(func, func) + match = self._name_rgx.match(translated) + if not match: + return translated, description, role + + groups = match.groupdict() + role = groups["role"] + new_func = groups["name"] or groups["name2"] + + return new_func, description, role + current_func = None rest = [] # type: List[str] @@ -1205,6 +1221,12 @@ class NumpyDocstring(GoogleDocstring): if not items: return [] + # apply type aliases + items = [ + translate(func, description, role) + for func, description, role in items + ] + roles = { 'method': 'meth', 'meth': 'meth', diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 0894a9bff..57bdf1342 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1400,6 +1400,38 @@ numpy.multivariate_normal(mean, cov, shape=None, spam=None) """ self.assertEqual(expected, actual) + docstring = """\ +numpy.multivariate_normal(mean, cov, shape=None, spam=None) + +See Also +-------- +some, other, :func:`funcs` +otherfunc : relationship + +""" + translations = { + "other": "MyClass.other", + "otherfunc": ":func:`~my_package.otherfunc`", + } + config = Config(napoleon_type_aliases=translations) + app = mock.Mock() + app.builder.env.intersphinx_inventory = { + "py:func": {"funcs": (), "otherfunc": ()}, + "py:meth": {"some": (), "MyClass.other": ()}, + } + actual = str(NumpyDocstring(docstring, config, app, "method")) + + expected = """\ +numpy.multivariate_normal(mean, cov, shape=None, spam=None) + +.. seealso:: + + :meth:`some`, :meth:`MyClass.other`, :func:`funcs` + \n\ + :func:`~my_package.otherfunc` + relationship +""" + self.assertEqual(expected, actual) def test_colon_in_return_type(self): docstring = """ From 75602f290ad14c263d4b8243ab5788a4c33e5d15 Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 6 Aug 2020 16:38:49 +0200 Subject: [PATCH 011/124] make sure the roles are stripped from invalid names, too --- sphinx/ext/napoleon/docstring.py | 3 +++ tests/test_ext_napoleon_docstring.py | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 1612a2d90..8e9e4d3d6 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -693,6 +693,9 @@ class GoogleDocstring: m = self._name_rgx.match(_type) if m and m.group('name'): _type = m.group('name') + elif _xref_regex.match(_type): + pos = _type.find('`') + _type = _type[pos + 1:-1] _type = ' ' + _type if _type else '' _desc = self._strip_empty(_desc) _descs = ' ' + '\n '.join(_desc) if any(_desc) else '' diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 74e54eded..d8ad64b96 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1682,6 +1682,20 @@ Example Function (""" Example Function +Raises +------ +AnotherError + If the dimensions couldn't be parsed. + +""", """ +Example Function + +:raises ~package.AnotherError: If the dimensions couldn't be parsed. +"""), + ################################ + (""" +Example Function + Raises ------ :class:`exc.InvalidDimensionsError` @@ -1694,7 +1708,11 @@ Example Function :raises exc.InvalidArgumentsError: """)] for docstring, expected in docstrings: - config = Config(napoleon_type_aliases={"CustomError": "package.CustomError"}) + translations = { + "CustomError": "package.CustomError", + "AnotherError": ":py:exc:`~package.AnotherError`", + } + config = Config(napoleon_type_aliases=translations) app = mock.Mock() actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) From 95c861facb752daeacca09a118f48f323ffcea32 Mon Sep 17 00:00:00 2001 From: Keewis Date: Fri, 7 Aug 2020 12:43:56 +0200 Subject: [PATCH 012/124] always use :obj: instead of searching the inventory --- sphinx/ext/napoleon/docstring.py | 36 ++-------------------------- tests/test_ext_napoleon_docstring.py | 31 +++--------------------- 2 files changed, 5 insertions(+), 62 deletions(-) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index d60deff6c..a7c799697 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -1131,11 +1131,6 @@ class NumpyDocstring(GoogleDocstring): func_name1, func_name2, :meth:`func_name`, func_name3 """ - try: - inventory = self._app.builder.env.intersphinx_inventory # type: ignore - except AttributeError: - inventory = {} - items = [] def parse_item_name(text: str) -> Tuple[str, str]: @@ -1227,41 +1222,14 @@ class NumpyDocstring(GoogleDocstring): for func, description, role in items ] - roles = { - 'method': 'meth', - 'meth': 'meth', - 'function': 'func', - 'func': 'func', - 'class': 'class', - 'exception': 'exc', - 'exc': 'exc', - 'object': 'obj', - 'obj': 'obj', - 'module': 'mod', - 'mod': 'mod', - 'data': 'data', - 'constant': 'const', - 'const': 'const', - 'attribute': 'attr', - 'attr': 'attr' - } - if self._what is None: - func_role = 'obj' - else: - func_role = roles.get(self._what, '') + func_role = 'obj' lines = [] # type: List[str] last_had_desc = True for func, desc, role in items: - if not role: - raw_role = search_inventory(inventory, func, hint=func_role) - role = roles.get(raw_role, raw_role) - if role: link = ':%s:`%s`' % (role, func) - elif func_role: - link = ':%s:`%s`' % (func_role, func) else: - link = "`%s`_" % func + link = ':%s:`%s`' % (func_role, func) if desc or last_had_desc: lines += [''] lines += [link] diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 57bdf1342..18a7cc88b 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1365,7 +1365,6 @@ otherfunc : relationship config = Config() app = mock.Mock() - app.builder.env = None actual = str(NumpyDocstring(docstring, config, app, "method")) expected = """\ @@ -1373,29 +1372,9 @@ numpy.multivariate_normal(mean, cov, shape=None, spam=None) .. seealso:: - :meth:`some`, :meth:`other`, :meth:`funcs` + :obj:`some`, :obj:`other`, :obj:`funcs` \n\ - :meth:`otherfunc` - relationship -""" - self.assertEqual(expected, actual) - - config = Config() - app = mock.Mock() - app.builder.env.intersphinx_inventory = { - "py:func": {"funcs": (), "otherfunc": ()}, - "py:meth": {"some": (), "other": ()}, - } - actual = str(NumpyDocstring(docstring, config, app, "method")) - - expected = """\ -numpy.multivariate_normal(mean, cov, shape=None, spam=None) - -.. seealso:: - - :meth:`some`, :meth:`other`, :func:`funcs` - \n\ - :func:`otherfunc` + :obj:`otherfunc` relationship """ self.assertEqual(expected, actual) @@ -1415,10 +1394,6 @@ otherfunc : relationship } config = Config(napoleon_type_aliases=translations) app = mock.Mock() - app.builder.env.intersphinx_inventory = { - "py:func": {"funcs": (), "otherfunc": ()}, - "py:meth": {"some": (), "MyClass.other": ()}, - } actual = str(NumpyDocstring(docstring, config, app, "method")) expected = """\ @@ -1426,7 +1401,7 @@ numpy.multivariate_normal(mean, cov, shape=None, spam=None) .. seealso:: - :meth:`some`, :meth:`MyClass.other`, :func:`funcs` + :obj:`some`, :obj:`MyClass.other`, :func:`funcs` \n\ :func:`~my_package.otherfunc` relationship From 1bf7fe424e16625f2ab4ad5824ca4aab6cf0ae65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Thu, 6 Aug 2020 09:18:36 +0200 Subject: [PATCH 013/124] i18n: Add support for having single text domain The gettext_compact can now be a string which is then a single domain for all documents. Fixes #784 --- doc/usage/configuration.rst | 6 ++++++ sphinx/builders/gettext.py | 2 +- sphinx/util/i18n.py | 6 ++++-- tests/test_build_gettext.py | 18 ++++++++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index add78326b..3fc3a5306 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -756,9 +756,15 @@ documentation on :ref:`intl` for details. If true, a document's text domain is its docname if it is a top-level project file and its very base directory otherwise. + If set to string, all document's text domain is this string, making all + documents use single text domain. + By default, the document ``markup/code.rst`` ends up in the ``markup`` text domain. With this option set to ``False``, it is ``markup/code``. + .. versionchanged:: 3.3 + The string value is now accepted. + .. confval:: gettext_uuid If true, Sphinx generates uuid information for version tracking in message diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index 8e30762e9..f8a19c57a 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -316,7 +316,7 @@ class MessageCatalogBuilder(I18nBuilder): def setup(app: Sphinx) -> Dict[str, Any]: app.add_builder(MessageCatalogBuilder) - app.add_config_value('gettext_compact', True, 'gettext') + app.add_config_value('gettext_compact', True, 'gettext', Any) app.add_config_value('gettext_location', True, 'gettext') app.add_config_value('gettext_uuid', False, 'gettext') app.add_config_value('gettext_auto_build', True, 'env') diff --git a/sphinx/util/i18n.py b/sphinx/util/i18n.py index 2177fc7b7..41407f4e1 100644 --- a/sphinx/util/i18n.py +++ b/sphinx/util/i18n.py @@ -14,7 +14,7 @@ import warnings from collections import namedtuple from datetime import datetime, timezone from os import path -from typing import Callable, Generator, List, Set, Tuple +from typing import Callable, Generator, List, Set, Tuple, Union import babel.dates from babel.messages.mofile import write_mo @@ -128,8 +128,10 @@ def find_catalog(docname: str, compaction: bool) -> str: return ret -def docname_to_domain(docname: str, compation: bool) -> str: +def docname_to_domain(docname: str, compation: Union[bool, str]) -> str: """Convert docname to domain for catalogs.""" + if isinstance(compation, str): + return compation if compation: return docname.split(SEP, 1)[0] else: diff --git a/tests/test_build_gettext.py b/tests/test_build_gettext.py index 1c86b8daa..074602ea9 100644 --- a/tests/test_build_gettext.py +++ b/tests/test_build_gettext.py @@ -174,3 +174,21 @@ def test_gettext_template_msgid_order_in_sphinxpot(app): 'msgid "This is Template 2\\.".*'), result, flags=re.S) + + +@pytest.mark.sphinx( + 'gettext', srcdir='root-gettext', + confoverrides={'gettext_compact': 'documentation'}) +def test_build_single_pot(app): + app.builder.build_all() + + assert (app.outdir / 'documentation.pot').isfile() + + result = (app.outdir / 'documentation.pot').read_text() + assert re.search( + ('msgid "Todo".*' + 'msgid "Like footnotes.".*' + 'msgid "The minute.".*' + 'msgid "Generated section".*'), + result, + flags=re.S) From a4487f1762e722b1d7639ec13c531a7c2f8ce889 Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Sun, 9 Aug 2020 11:44:41 +0200 Subject: [PATCH 014/124] Check if LaTeX package already added --- sphinx/registry.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sphinx/registry.py b/sphinx/registry.py index 0aec0a9fd..4d1e9eb72 100644 --- a/sphinx/registry.py +++ b/sphinx/registry.py @@ -367,7 +367,14 @@ class SphinxComponentRegistry: logger.debug('[app] adding js_file: %r, %r', filename, attributes) self.js_files.append((filename, attributes)) + def has_latex_package(self, name: str) -> bool: + packages = self.latex_packages + self.latex_packages_after_hyperref + return bool([x for x in packages if x[0] == name]) + def add_latex_package(self, name: str, options: str, after_hyperref: bool = False) -> None: + if self.has_latex_package(name): + logger.warn("latex package '%s' already included" % name) + logger.debug('[app] adding latex package: %r', name) if after_hyperref: self.latex_packages_after_hyperref.append((name, options)) From 5f82825e273dfc5df3c4ef499876def8b024fa81 Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Sun, 9 Aug 2020 13:33:42 +0200 Subject: [PATCH 015/124] Customize jinja comment-tag --- sphinx/util/template.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sphinx/util/template.py b/sphinx/util/template.py index 18047d687..bb078a2a2 100644 --- a/sphinx/util/template.py +++ b/sphinx/util/template.py @@ -84,6 +84,8 @@ class LaTeXRenderer(SphinxRenderer): self.env.variable_end_string = '%>' self.env.block_start_string = '<%' self.env.block_end_string = '%>' + self.env.comment_start_string = '<#' + self.env.comment_end_string = '<#' class ReSTRenderer(SphinxRenderer): From 6cf1301c9e479bc886a237ece76d0b8ae8675a41 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 10 Aug 2020 13:18:45 +0900 Subject: [PATCH 016/124] Remove pylint task At present, pylint has no longer been used in this project. This removes the tasks and files for pylint from repository. --- Makefile | 4 - tox.ini | 10 -- utils/pylintrc | 301 ------------------------------------------------- 3 files changed, 315 deletions(-) delete mode 100644 utils/pylintrc diff --git a/Makefile b/Makefile index d37d8546e..9cff012d4 100644 --- a/Makefile +++ b/Makefile @@ -64,10 +64,6 @@ type-check: doclinter: python utils/doclinter.py CHANGES *.rst doc/ -.PHONY: pylint -pylint: - @pylint --rcfile utils/pylintrc sphinx - .PHONY: test test: @$(PYTHON) -m pytest -v $(TEST) diff --git a/tox.ini b/tox.ini index bddd822a6..547fe7c40 100644 --- a/tox.ini +++ b/tox.ini @@ -40,16 +40,6 @@ extras = commands = flake8 {posargs} -[testenv:pylint] -basepython = python3 -description = - Run source code analyzer. -deps = - pylint - {[testenv]deps} -commands = - pylint --rcfile utils/pylintrc sphinx - [testenv:coverage] basepython = python3 description = diff --git a/utils/pylintrc b/utils/pylintrc deleted file mode 100644 index c2b338b79..000000000 --- a/utils/pylintrc +++ /dev/null @@ -1,301 +0,0 @@ -# lint Python modules using external checkers. -# -# This is the main checker controlling the other ones and the reports -# generation. It is itself both a raw checker and an astng checker in order -# to: -# * handle message activation / deactivation at the module level -# * handle some basic but necessary stats'data (number of classes, methods...) -# -[MASTER] - -# Specify a configuration file. -#rcfile= - -# Profiled execution. -profile=no - -# Add to the black list. It should be a base name, not a -# path. You may set this option multiple times. -ignore=.svn - -# Pickle collected data for later comparisons. -persistent=yes - -# Set the cache size for astng objects. -cache-size=500 - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - - -[MESSAGES CONTROL] - -# Enable only checker(s) with the given id(s). This option conflict with the -# disable-checker option -#enable-checker= - -# Enable all checker(s) except those with the given id(s). This option conflict -# with the disable-checker option -#disable-checker= - -# Enable all messages in the listed categories. -#enable-msg-cat= - -# Disable all messages in the listed categories. -#disable-msg-cat= - -# Enable the message(s) with the given id(s). -#enable-msg= - -# Disable the message(s) with the given id(s). -disable-msg=C0323,W0142,C0301,C0103,C0111,E0213,C0302,C0203,W0703,R0201,W0613,W0612,W0622 - - -[REPORTS] - -# set the output format. Available formats are text, parseable, colorized and -# html -output-format=colorized - -# Include message's id in output -include-ids=yes - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". -files-output=no - -# Tells wether to display a full report or only the messages -reports=yes - -# Python expression which should return a note less than 10 (10 is the highest -# note).You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (R0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Add a comment according to your evaluation note. This is used by the global -# evaluation report (R0004). -comment=no - -# Enable the report(s) with the given id(s). -#enable-report= - -# Disable the report(s) with the given id(s). -#disable-report= - - -# checks for -# * unused variables / imports -# * undefined variables -# * redefinition of variable from builtins or from an outer scope -# * use of variable before assigment -# -[VARIABLES] - -# Tells wether we should check for unused import in __init__ files. -init-import=no - -# A regular expression matching names used for dummy variables (i.e. not used). -dummy-variables-rgx=_|dummy - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - - -# try to find bugs in the code using type inference -# -[TYPECHECK] - -# Tells wether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# When zope mode is activated, consider the acquired-members option to ignore -# access to some undefined attributes. -zope=no - -# List of members which are usually get through zope's acquisition mecanism and -# so shouldn't trigger E0201 when accessed (need zope=yes to be considered). -acquired-members=REQUEST,acl_users,aq_parent - - -# checks for : -# * doc strings -# * modules / classes / functions / methods / arguments / variables name -# * number of arguments, local variables, branchs, returns and statements in -# functions, methods -# * required module attributes -# * dangerous default values as arguments -# * redefinition of function / method / class -# * uses of the global statement -# -[BASIC] - -# Required attributes for module, separated by a comma -required-attributes= - -# Regular expression which should only match functions or classes name which do -# not require a docstring -no-docstring-rgx=__.*__ - -# Regular expression which should only match correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression which should only match correct module level names -const-rgx=(([A-Z_][A-Z1-9_]*)|(__.*__))$ - -# Regular expression which should only match correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression which should only match correct function names -function-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct method names -method-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct instance attribute names -attr-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct argument names -argument-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct variable names -variable-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct list comprehension / -# generator expression variable names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# List of builtins function names that should not be used, separated by a comma -bad-functions=apply,input - - -# checks for sign of poor/misdesign: -# * number of methods, attributes, local variables... -# * size, complexity of functions, methods -# -[DESIGN] - -# Maximum number of arguments for function / method -max-args=12 - -# Maximum number of locals for function / method body -max-locals=30 - -# Maximum number of return / yield for function / method body -max-returns=12 - -# Maximum number of branch for function / method body -max-branchs=30 - -# Maximum number of statements in function / method body -max-statements=60 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=20 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=0 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - - -# checks for -# * external modules dependencies -# * relative / wildcard imports -# * cyclic imports -# * uses of deprecated modules -# -[IMPORTS] - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,string,TERMIOS,Bastion,rexec - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report R0402 must not be disabled) -import-graph= - -# Create a graph of external dependencies in the given file (report R0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of internal dependencies in the given file (report R0402 must -# not be disabled) -int-import-graph= - - -# checks for : -# * methods without self as first argument -# * overridden methods signature -# * access only to existant members via self -# * attributes not defined in the __init__ method -# * supported interfaces implementation -# * unreachable code -# -[CLASSES] - -# List of interface methods to ignore, separated by a comma. This is used for -# instance to not check methods defines in Zope's Interface base class. -ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - - -# checks for similarities and duplicated code. This computation may be -# memory / CPU intensive, so you should disable it if you experiments some -# problems. -# -[SIMILARITIES] - -# Minimum lines number of a similarity. -min-similarity-lines=10 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - - -# checks for: -# * warning notes in the code -# * PEP 263: source code with non ascii character but no encoding declaration -# -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,XXX,TODO - - -# checks for : -# * unauthorized constructions -# * strict indentation -# * line length -# * use of <> instead of != -# -[FORMAT] - -# Maximum number of characters on a single line. -max-line-length=90 - -# Maximum number of lines in a module -max-module-lines=1000 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' From 53a82a56303ae2e0be1e5613db0da3611b1aabb1 Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Wed, 12 Aug 2020 16:29:26 +0200 Subject: [PATCH 017/124] Use node as location --- sphinx/writers/html.py | 2 +- sphinx/writers/html5.py | 2 +- sphinx/writers/latex.py | 6 +++--- sphinx/writers/texinfo.py | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 4375bf326..8813c2d12 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -450,7 +450,7 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator): highlighted = self.highlighter.highlight_block( node.rawsource, lang, opts=opts, linenos=linenos, - location=(self.builder.current_docname, node.line), **highlight_args + location=node, **highlight_args ) starttag = self.starttag(node, 'div', suffix='', CLASS='highlight-%s notranslate' % lang) diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index c1252f4d0..4ceeaafdf 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -402,7 +402,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): highlighted = self.highlighter.highlight_block( node.rawsource, lang, opts=opts, linenos=linenos, - location=(self.builder.current_docname, node.line), **highlight_args + location=node, **highlight_args ) starttag = self.starttag(node, 'div', suffix='', CLASS='highlight-%s notranslate' % lang) diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 73a22a76b..b77202951 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -651,7 +651,7 @@ class LaTeXTranslator(SphinxTranslator): if len(node.children) != 1 and not isinstance(node.children[0], nodes.Text): logger.warning(__('document title is not a single Text node'), - location=(self.curfilestack[-1], node.line)) + location=node) if not self.elements['title']: # text needs to be escaped since it is inserted into # the output literally @@ -684,7 +684,7 @@ class LaTeXTranslator(SphinxTranslator): else: logger.warning(__('encountered title node not in section, topic, table, ' 'admonition or sidebar'), - location=(self.curfilestack[-1], node.line or '')) + location=node) self.body.append('\\sphinxstyleothertitle{') self.context.append('}\n') self.in_title = 1 @@ -1762,7 +1762,7 @@ class LaTeXTranslator(SphinxTranslator): hlcode = self.highlighter.highlight_block( node.rawsource, lang, opts=opts, linenos=linenos, - location=(self.curfilestack[-1], node.line), **highlight_args + location=node, **highlight_args ) if self.in_footnote: self.body.append('\n\\sphinxSetupCodeBlockInFootnote') diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 8c52a0868..5ad2831dd 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -628,7 +628,7 @@ class TexinfoTranslator(SphinxTranslator): elif not isinstance(parent, nodes.section): logger.warning(__('encountered title node not in section, topic, table, ' 'admonition or sidebar'), - location=(self.curfilestack[-1], node.line)) + location=node) self.visit_rubric(node) else: try: @@ -1186,7 +1186,7 @@ class TexinfoTranslator(SphinxTranslator): self.body.append('\n@caption{') else: logger.warning(__('caption not inside a figure.'), - location=(self.curfilestack[-1], node.line)) + location=node) def depart_caption(self, node: Element) -> None: if (isinstance(node.parent, nodes.figure) or @@ -1262,11 +1262,11 @@ class TexinfoTranslator(SphinxTranslator): def unimplemented_visit(self, node: Element) -> None: logger.warning(__("unimplemented node type: %r"), node, - location=(self.curfilestack[-1], node.line)) + location=node) def unknown_visit(self, node: Node) -> None: logger.warning(__("unknown node type: %r"), node, - location=(self.curfilestack[-1], node.line)) + location=node) def unknown_departure(self, node: Node) -> None: pass From 4baa7ce99b6a4a79c203140555743eaa50aed28c Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 13 Aug 2020 01:53:30 +0900 Subject: [PATCH 018/124] Update CHANGES for PR #8102 --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index d0e4e6316..b0b8de1ea 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,9 @@ Features added Bugs fixed ---------- +* #8093: The highlight warning has wrong location in some builders (LaTeX, + singlehtml and so on) + Testing -------- From 088b04917033f142b9e9830a2dca86f8d3bc95f1 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 13 Aug 2020 23:16:59 +0900 Subject: [PATCH 019/124] Fix #8103: autodoc: cached_property is not considered as a property sphinx.util.inspect:isproperty() does not considers that cached_property decorator that has been added since Python 3.8 is a kind of properties. This fixes it. --- CHANGES | 1 + sphinx/util/inspect.py | 5 +++++ .../target/cached_property.py | 7 +++++++ tests/test_ext_autodoc.py | 20 +++++++++++++++++++ 4 files changed, 33 insertions(+) create mode 100644 tests/roots/test-ext-autodoc/target/cached_property.py diff --git a/CHANGES b/CHANGES index b0b8de1ea..e78905ee6 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Features added Bugs fixed ---------- +* #8103: autodoc: functools.cached_property is not considered as a property * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index a5c64f882..37997e6b2 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -304,6 +304,11 @@ def iscoroutinefunction(obj: Any) -> bool: def isproperty(obj: Any) -> bool: """Check if the object is property.""" + if sys.version_info > (3, 8): + from functools import cached_property # cached_property is available since py3.8 + if isinstance(obj, cached_property): + return True + return isinstance(obj, property) diff --git a/tests/roots/test-ext-autodoc/target/cached_property.py b/tests/roots/test-ext-autodoc/target/cached_property.py new file mode 100644 index 000000000..63ec09f8e --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/cached_property.py @@ -0,0 +1,7 @@ +from functools import cached_property + + +class Foo: + @cached_property + def prop(self) -> int: + return 1 diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index 15e1f3539..b7d3bc54e 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -881,6 +881,26 @@ def test_autodoc_descriptor(app): ] +@pytest.mark.skipif(sys.version_info < (3, 8), + reason='cached_property is available since python3.8.') +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_autodoc_cached_property(app): + options = {"members": None, + "undoc-members": True} + actual = do_autodoc(app, 'class', 'target.cached_property.Foo', options) + assert list(actual) == [ + '', + '.. py:class:: Foo()', + ' :module: target.cached_property', + '', + '', + ' .. py:method:: Foo.prop', + ' :module: target.cached_property', + ' :property:', + '', + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_member_order(app): # case member-order='bysource' From 1bca9f9587cfdfc82293c4c83679c6e3a03b5c3f Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 14 Aug 2020 00:07:01 +0900 Subject: [PATCH 020/124] Close #8100: html: Show a better error message for html_static_files The HTML Builder crashes if error raised on copying html_static_files. This handles the exception and show a better error message to let users the reason of errors (ex. failed on extracting Jinja templates). --- CHANGES | 3 +++ sphinx/builders/html/__init__.py | 13 +++++++++++-- sphinx/util/fileutil.py | 18 +++++++++++++----- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index b0b8de1ea..119235eac 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,9 @@ Deprecated Features added -------------- +* #8100: html: Show a better error message for failures on copying + html_static_files + Bugs fixed ---------- diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py index 923212a99..c30aa9cfd 100644 --- a/sphinx/builders/html/__init__.py +++ b/sphinx/builders/html/__init__.py @@ -751,18 +751,27 @@ class StandaloneHTMLBuilder(Builder): copyfile(jsfile, path.join(self.outdir, '_static', '_stemmer.js')) def copy_theme_static_files(self, context: Dict) -> None: + def onerror(filename: str, error: Exception) -> None: + logger.warning(__('Failed to copy a file in html_static_file: %s: %r'), + filename, error) + if self.theme: for entry in self.theme.get_theme_dirs()[::-1]: copy_asset(path.join(entry, 'static'), path.join(self.outdir, '_static'), - excluded=DOTFILES, context=context, renderer=self.templates) + excluded=DOTFILES, context=context, + renderer=self.templates, onerror=onerror) def copy_html_static_files(self, context: Dict) -> None: + def onerror(filename: str, error: Exception) -> None: + logger.warning(__('Failed to copy a file in html_static_file: %s: %r'), + filename, error) + excluded = Matcher(self.config.exclude_patterns + ["**/.*"]) for entry in self.config.html_static_path: copy_asset(path.join(self.confdir, entry), path.join(self.outdir, '_static'), - excluded, context=context, renderer=self.templates) + excluded, context=context, renderer=self.templates, onerror=onerror) def copy_html_logo(self) -> None: if self.config.html_logo: diff --git a/sphinx/util/fileutil.py b/sphinx/util/fileutil.py index d8e896d48..eec1ae463 100644 --- a/sphinx/util/fileutil.py +++ b/sphinx/util/fileutil.py @@ -10,7 +10,7 @@ import os import posixpath -from typing import Dict +from typing import Callable, Dict from docutils.utils import relative_path @@ -56,7 +56,8 @@ def copy_asset_file(source: str, destination: str, def copy_asset(source: str, destination: str, excluded: PathMatcher = lambda path: False, - context: Dict = None, renderer: "BaseRenderer" = None) -> None: + context: Dict = None, renderer: "BaseRenderer" = None, + onerror: Callable[[str, Exception], None] = None) -> None: """Copy asset files to destination recursively. On copying, it expands the template variables if context argument is given and @@ -67,6 +68,7 @@ def copy_asset(source: str, destination: str, excluded: PathMatcher = lambda pat :param excluded: The matcher to determine the given path should be copied or not :param context: The template variables. If not given, template files are simply copied :param renderer: The template engine. If not given, SphinxRenderer is used by default + :param onerror: The error handler. """ if not os.path.exists(source): return @@ -90,6 +92,12 @@ def copy_asset(source: str, destination: str, excluded: PathMatcher = lambda pat for filename in files: if not excluded(posixpath.join(reldir, filename)): - copy_asset_file(posixpath.join(root, filename), - posixpath.join(destination, reldir), - context, renderer) + try: + copy_asset_file(posixpath.join(root, filename), + posixpath.join(destination, reldir), + context, renderer) + except Exception as exc: + if onerror: + onerror(posixpath.join(root, filename), exc) + else: + raise From 2f971a61f3fda7ead81f1434913ed0d2f52d82cf Mon Sep 17 00:00:00 2001 From: harupy <17039389+harupy@users.noreply.github.com> Date: Fri, 14 Aug 2020 00:41:17 +0900 Subject: [PATCH 021/124] Color pytest output log --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index bddd822a6..e2bad0293 100644 --- a/tox.ini +++ b/tox.ini @@ -55,7 +55,7 @@ basepython = python3 description = Run code coverage checks. setenv = - PYTEST_ADDOPTS = --cov sphinx --cov-config {toxinidir}/setup.cfg + PYTEST_ADDOPTS = --cov sphinx --cov-config {toxinidir}/setup.cfg --color yes commands = {[testenv]commands} coverage report From 2a632598c3c93222bcfcf2654593c08ee2c9271c Mon Sep 17 00:00:00 2001 From: harupy <17039389+harupy@users.noreply.github.com> Date: Fri, 14 Aug 2020 00:48:41 +0900 Subject: [PATCH 022/124] fix --- tox.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index e2bad0293..119944d6e 100644 --- a/tox.ini +++ b/tox.ini @@ -26,6 +26,7 @@ extras = test setenv = PYTHONWARNINGS = all,ignore::ImportWarning:importlib._bootstrap_external,ignore::DeprecationWarning:site,ignore::DeprecationWarning:distutils + PYTEST_ADDOPTS = --color yes commands= pytest --durations 25 {posargs} @@ -55,7 +56,7 @@ basepython = python3 description = Run code coverage checks. setenv = - PYTEST_ADDOPTS = --cov sphinx --cov-config {toxinidir}/setup.cfg --color yes + PYTEST_ADDOPTS = --cov sphinx --cov-config {toxinidir}/setup.cfg commands = {[testenv]commands} coverage report From ec7e8aa5ebc4f1ace46c7ba45360314335910e7a Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 14 Aug 2020 14:23:03 +0900 Subject: [PATCH 023/124] Update CHANGES for PR #8058 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index b0b8de1ea..e808cdfde 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Features added Bugs fixed ---------- +* #8085: i18n: Add support for having single text domain * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) From 19f6c39c48ed043f986e5d17b42aadc55c200a4a Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Fri, 7 Aug 2020 14:19:12 +0200 Subject: [PATCH 024/124] Invite users to ask their questions on Stackoverflow --- .github/ISSUE_TEMPLATE/config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index c9009b90e..226532b79 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,5 +2,8 @@ blank_issues_enabled: false # default: true contact_links: - name: Question + url: https://stackoverflow.com/questions/tagged/python-sphinx + about: For Q&A purpose, please use Stackoverflow with the tag python-sphinx +- name: Discussion url: https://groups.google.com/forum/#!forum/sphinx-users - about: For Q&A purpose, please use sphinx-users mailing list. + about: For general discussion, please use sphinx-users mailing list. From e45f55d32fc6d64f868f37b3588e20957f09b705 Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Sat, 15 Aug 2020 13:22:22 +0200 Subject: [PATCH 025/124] Add rubric in Getting help --- doc/internals/contributing.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/internals/contributing.rst b/doc/internals/contributing.rst index 0e464478a..1f4a31013 100644 --- a/doc/internals/contributing.rst +++ b/doc/internals/contributing.rst @@ -12,6 +12,9 @@ Getting help The Sphinx community maintains a number of mailing lists and IRC channels. +Stack Overflow with tag `python-sphinx`_ + Questions and answers about use and development. + sphinx-users Mailing list for user support. @@ -21,6 +24,7 @@ sphinx-dev #sphinx-doc on irc.freenode.net IRC channel for development questions and user support. +.. _python-sphinx: https://stackoverflow.com/questions/tagged/python-sphinx Bug Reports and Feature Requests -------------------------------- From 439f75afd256ae259a72e39d1cf0e31711b94a85 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 18 Aug 2020 16:01:52 +0200 Subject: [PATCH 026/124] enable preprocessing in the tests --- tests/test_ext_napoleon_docstring.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 538227514..da456e4a2 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1543,6 +1543,7 @@ arg_ : type config = Config( napoleon_use_param=True, napoleon_use_rtype=True, + napoleon_preprocess_types=True, napoleon_type_aliases=translations, ) actual = str(NumpyDocstring(docstring, config)) @@ -1566,7 +1567,7 @@ arg_ : type "scalar": ":term:`scalar`", "array-like": ":class:`array-like `", } - config = Config(napoleon_type_aliases=translations) + config = Config(napoleon_type_aliases=translations, napoleon_preprocess_types=True) app = mock.Mock() actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) @@ -1779,7 +1780,7 @@ Example Function "CustomError": "package.CustomError", "AnotherError": ":py:exc:`~package.AnotherError`", } - config = Config(napoleon_type_aliases=translations) + config = Config(napoleon_type_aliases=translations, napoleon_preprocess_types=True) app = mock.Mock() actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) From 5c744d834259d4144e779a79eaf0c9e312e75ed6 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Thu, 20 Aug 2020 22:37:37 +0100 Subject: [PATCH 027/124] =?UTF-8?q?=F0=9F=93=9A=20DOCS:=20Improve=20build?= =?UTF-8?q?=20process=20overview?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/extdev/appapi.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/extdev/appapi.rst b/doc/extdev/appapi.rst index 036b57ec1..9a29aa77f 100644 --- a/doc/extdev/appapi.rst +++ b/doc/extdev/appapi.rst @@ -179,8 +179,10 @@ type for that event:: 11. event.env-get-updated(app, env) 11. event.env-check-consistency(app, env) + # The updated-docs list can be builder dependent, but generally includes all new/changed documents, + # plus any output from `env-get-updated`, and then all "parent" documents in the ToC tree # For builders that output a single page, they are first joined into a single doctree before post-transforms/doctree-resolved - for docname in docnames: + for docname in updated-docs: 12. apply post-transforms (by priority): docutils.document -> docutils.document 13. event.doctree-resolved(app, doctree, docname) - (for any reference node that fails to resolve) event.missing-reference(env, node, contnode) From 46177f6af324ec2110b0c73467ee2659e75485e3 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Fri, 21 Aug 2020 01:58:28 +0100 Subject: [PATCH 028/124] Correct numbers --- doc/extdev/appapi.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/extdev/appapi.rst b/doc/extdev/appapi.rst index 9a29aa77f..df3eb3d67 100644 --- a/doc/extdev/appapi.rst +++ b/doc/extdev/appapi.rst @@ -177,19 +177,18 @@ type for that event:: 9. (if running in parallel mode, for each process) event.env-merged-info(app, env, docnames, other) 10. event.env-updated(app, env) 11. event.env-get-updated(app, env) - 11. event.env-check-consistency(app, env) + 12. event.env-check-consistency(app, env) # The updated-docs list can be builder dependent, but generally includes all new/changed documents, # plus any output from `env-get-updated`, and then all "parent" documents in the ToC tree # For builders that output a single page, they are first joined into a single doctree before post-transforms/doctree-resolved for docname in updated-docs: - 12. apply post-transforms (by priority): docutils.document -> docutils.document - 13. event.doctree-resolved(app, doctree, docname) + 13. apply post-transforms (by priority): docutils.document -> docutils.document + 14. event.doctree-resolved(app, doctree, docname) - (for any reference node that fails to resolve) event.missing-reference(env, node, contnode) - 14. Generate output files - - 15. event.build-finished(app, exception) + 15. Generate output files + 16. event.build-finished(app, exception) Here is a more detailed list of these events. From e0b2162a77a8a6021f9e17129d6fa23eeceac48c Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 22 Aug 2020 00:44:07 +0900 Subject: [PATCH 029/124] Fix #8143: AttributeError if autodoc_default_options contains False autodoc crahses when autodoc_default_options contains False value unexpectedly. After this change, it also accepts False. --- CHANGES | 2 ++ sphinx/ext/autodoc/__init__.py | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index d6870c750..fde891098 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,8 @@ Bugs fixed ---------- * #8085: i18n: Add support for having single text domain +* #8143: autodoc: AttributeError is raised when False value is passed to + autodoc_default_options * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index b61a96c84..ed02c2c90 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -94,7 +94,10 @@ def members_option(arg: Any) -> Union[object, List[str]]: """Used to convert the :members: option to auto directives.""" if arg is None or arg is True: return ALL - return [x.strip() for x in arg.split(',') if x.strip()] + elif arg is False: + return None + else: + return [x.strip() for x in arg.split(',') if x.strip()] def members_set_option(arg: Any) -> Union[object, Set[str]]: @@ -172,7 +175,7 @@ def merge_members_option(options: Dict) -> None: members = options.setdefault('members', []) for key in {'private-members', 'special-members'}: - if key in options and options[key] is not ALL: + if key in options and options[key] not in (ALL, None): for member in options[key]: if member not in members: members.append(member) From 642686159fb18fb3eec00563aa4773b941dad5bb Mon Sep 17 00:00:00 2001 From: Juan Carrano Date: Fri, 21 Aug 2020 13:53:36 +0200 Subject: [PATCH 030/124] autodoc: Test the signature of typing.Generic subclasses. This test is currently failing because typing.Generic.__new__ clobbers the real signature. --- .../test-ext-autodoc/target/generic_class.py | 12 ++++++++++++ tests/test_ext_autodoc.py | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/roots/test-ext-autodoc/target/generic_class.py diff --git a/tests/roots/test-ext-autodoc/target/generic_class.py b/tests/roots/test-ext-autodoc/target/generic_class.py new file mode 100644 index 000000000..cf4c5ed37 --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/generic_class.py @@ -0,0 +1,12 @@ +from typing import TypeVar, Generic + + +T = TypeVar('T') + + +# Test that typing.Generic's __new__ method does not mask our class' +# __init__ signature. +class A(Generic[T]): + """docstring for A""" + def __init__(self, a, b=None): + pass diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index 90a2ec95a..e90125ba9 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -290,6 +290,22 @@ def test_format_signature(app): '(b, c=42, *d, **e)' +@pytest.mark.skipif(sys.version_info < (3, 5), reason='typing is available since python3.5.') +@pytest.mark.xfail +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_autodoc_process_signature_typing_generic(app): + actual = do_autodoc(app, 'class', 'target.generic_class.A', {}) + + assert list(actual) == [ + '', + '.. py:class:: A(a, b=None)', + ' :module: target.generic_class', + '', + ' docstring for A', + '', + ] + + def test_autodoc_process_signature_typehints(app): captured = [] From 740be7f2a5c03c0bbfd96420843074c1c5cb6c10 Mon Sep 17 00:00:00 2001 From: Juan Carrano Date: Fri, 21 Aug 2020 14:00:48 +0200 Subject: [PATCH 031/124] autodoc: blacklist typing.Generic.__new__ When documenting classes derived from typing.Generic (essentially all classes in the typing module) the constructor signature would show an unhelpful (*args, **kwds). typing.Generic has a __new__ method which was picked up by sphinx. With this patch it is skipped and constructor signatures for generic classes are shown as they should. --- sphinx/ext/autodoc/__init__.py | 11 +++++++++++ tests/test_ext_autodoc.py | 1 - 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index b61a96c84..05681ea5e 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -1317,6 +1317,12 @@ _METACLASS_CALL_BLACKLIST = [ ] +# Types whose __new__ signature is a pass-thru. +_CLASS_NEW_BLACKLIST = [ + 'typing.Generic.__new__', +] + + class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: ignore """ Specialized Documenter subclass for classes. @@ -1385,6 +1391,11 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: # Now we check if the 'obj' class has a '__new__' method new = get_user_defined_function_or_method(self.object, '__new__') + + if new is not None: + if "{0.__module__}.{0.__qualname__}".format(new) in _CLASS_NEW_BLACKLIST: + new = None + if new is not None: self.env.app.emit('autodoc-before-process-signature', new, True) try: diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index e90125ba9..904107efe 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -291,7 +291,6 @@ def test_format_signature(app): @pytest.mark.skipif(sys.version_info < (3, 5), reason='typing is available since python3.5.') -@pytest.mark.xfail @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_process_signature_typing_generic(app): actual = do_autodoc(app, 'class', 'target.generic_class.A', {}) From 4313060c8a7fe0aa60bdf1d370453fbd350de9fd Mon Sep 17 00:00:00 2001 From: Gaurav Lalchandani Date: Sat, 22 Aug 2020 20:00:41 +0530 Subject: [PATCH 032/124] Fixes #8146: When identifying bases, only use classes from builtins In inheritance_diagram extension, while iterating over bases, we verify if the base class is one of the Python built-in class or not. As of now, we simply check for its presence in all `builtins` objects. Please note, `builtins` not only has built-in classes, but also functions (like `open`) and other built-in objects. To avoid any sort of future problem, it seems better to only use classes (and of course exception classes). --- sphinx/ext/inheritance_diagram.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py index 7b2383fca..71a123b15 100644 --- a/sphinx/ext/inheritance_diagram.py +++ b/sphinx/ext/inheritance_diagram.py @@ -66,6 +66,10 @@ module_sig_re = re.compile(r'''^(?:([\w.]*)\.)? # module names ''', re.VERBOSE) +py_builtins = [obj for obj in vars(builtins).values() + if inspect.isclass(obj)] + + def try_import(objname: str) -> Any: """Import a object or module using *name* and *currentmodule*. *name* should be a relative name from *currentmodule* or @@ -178,7 +182,6 @@ class InheritanceGraph: traverse to. Multiple names can be specified separated by comma. """ all_classes = {} - py_builtins = vars(builtins).values() def recurse(cls: Any) -> None: if not show_builtins and cls in py_builtins: From 6b87b8030c16e195ccd8b2246fe8d5f6d24e893b Mon Sep 17 00:00:00 2001 From: Kai Welke Date: Sun, 23 Aug 2020 09:29:56 +0200 Subject: [PATCH 033/124] Fix comment end string in LaTeXRenderer Fix bug introduced by commit 5f82825e27 in `self.env.comment_end_string` --- sphinx/util/template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/util/template.py b/sphinx/util/template.py index bb078a2a2..8785928a9 100644 --- a/sphinx/util/template.py +++ b/sphinx/util/template.py @@ -85,7 +85,7 @@ class LaTeXRenderer(SphinxRenderer): self.env.block_start_string = '<%' self.env.block_end_string = '%>' self.env.comment_start_string = '<#' - self.env.comment_end_string = '<#' + self.env.comment_end_string = '#>' class ReSTRenderer(SphinxRenderer): From 05ad7e80208aee3956e630be10f1685b0bbea5b1 Mon Sep 17 00:00:00 2001 From: Dominic Davis-Foster Date: Tue, 25 Aug 2020 13:48:17 +0100 Subject: [PATCH 034/124] Fix typo in warning emitted from Sphinx.add_lexer() --- sphinx/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/application.py b/sphinx/application.py index d84a2c975..385b74d8a 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -1004,7 +1004,7 @@ class Sphinx: logger.debug('[app] adding lexer: %r', (alias, lexer)) if isinstance(lexer, Lexer): warnings.warn('app.add_lexer() API changed; ' - 'Please give lexer class instead instance', + 'Please give lexer class instead of instance', RemovedInSphinx40Warning, stacklevel=2) lexers[alias] = lexer else: From 2b646082d7551a859da7cfe77051b2e036fb18f3 Mon Sep 17 00:00:00 2001 From: Dominic Davis-Foster Date: Tue, 25 Aug 2020 13:49:12 +0100 Subject: [PATCH 035/124] Fix typo'd comment in SphinxComponentRegistry.add_html_math_renderer() --- sphinx/registry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/registry.py b/sphinx/registry.py index 4d1e9eb72..8c468796a 100644 --- a/sphinx/registry.py +++ b/sphinx/registry.py @@ -401,7 +401,7 @@ class SphinxComponentRegistry: def load_extension(self, app: "Sphinx", extname: str) -> None: """Load a Sphinx extension.""" - if extname in app.extensions: # alread loaded + if extname in app.extensions: # already loaded return if extname in EXTENSION_BLACKLIST: logger.warning(__('the extension %r was already merged with Sphinx since ' From 849ef212bc3ab604a9f9c8bf85232eddc7d71017 Mon Sep 17 00:00:00 2001 From: Falko Axmann Date: Sun, 30 Aug 2020 14:39:20 +0200 Subject: [PATCH 036/124] Fixes minor typo in quickstart.rst --- doc/usage/quickstart.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/usage/quickstart.rst b/doc/usage/quickstart.rst index 8d2de021e..1d7e540a6 100644 --- a/doc/usage/quickstart.rst +++ b/doc/usage/quickstart.rst @@ -15,7 +15,7 @@ Much of Sphinx's power comes from the richness of its default plain-text markup format, :doc:`reStructuredText `, along with it's :doc:`significant extensibility capabilities `. -The goal of this document is to give you a quick taste of what Sphinx it is and +The goal of this document is to give you a quick taste of what Sphinx is and how you might use it. When you're done here, you can check out the :doc:`installation guide ` followed by the intro to the default markup format used by Sphinx, :doc:`reStucturedText From 7a3170b77a7414e1cc21d478528057e88d7fbb9f Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Thu, 3 Sep 2020 15:22:50 +0200 Subject: [PATCH 037/124] Fix some broken links --- doc/develop.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/develop.rst b/doc/develop.rst index 080251ba6..1287a6539 100644 --- a/doc/develop.rst +++ b/doc/develop.rst @@ -140,14 +140,14 @@ started with writing your own extensions. .. _slideshare: https://www.slideshare.net/ .. _TikZ/PGF LaTeX package: https://sourceforge.net/projects/pgf/ .. _MATLAB: https://www.mathworks.com/products/matlab.html -.. _swf: https://bitbucket.org/klorenz/sphinxcontrib-swf -.. _findanything: https://bitbucket.org/klorenz/sphinxcontrib-findanything -.. _cmakedomain: https://bitbucket.org/klorenz/sphinxcontrib-cmakedomain +.. _swf: https://github.com/sphinx-contrib/swf +.. _findanything: https://github.com/sphinx-contrib/findanything +.. _cmakedomain: https://github.com/sphinx-contrib/cmakedomain .. _GNU Make: https://www.gnu.org/software/make/ -.. _makedomain: https://bitbucket.org/klorenz/sphinxcontrib-makedomain +.. _makedomain: https://github.com/sphinx-contrib/makedomain .. _inlinesyntaxhighlight: https://sphinxcontrib-inlinesyntaxhighlight.readthedocs.io/ .. _CMake: https://cmake.org -.. _domaintools: https://bitbucket.org/klorenz/sphinxcontrib-domaintools +.. _domaintools: https://github.com/sphinx-contrib/domaintools .. _restbuilder: https://pypi.org/project/sphinxcontrib-restbuilder/ .. _Lasso: http://www.lassosoft.com/ .. _beamer: https://pypi.org/project/sphinxcontrib-beamer/ From d78306c7f9c97d24648de2650a7bb99288da02f4 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 5 Sep 2020 18:52:59 +0900 Subject: [PATCH 038/124] Fix #8163: Update warning message for :dedent: option --- sphinx/directives/code.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index f1f4a341a..4ca849cf0 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -72,7 +72,7 @@ def dedent_lines(lines: List[str], dedent: int, location: Tuple[str, int] = None return lines if any(s[:dedent].strip() for s in lines): - logger.warning(__('Over dedent has detected'), location=location) + logger.warning(__('non-whitespace stripped by dedent'), location=location) new_lines = [] for line in lines: From 1e5231d5232f278ef812737fbfa35b3ad8279257 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 6 Sep 2020 01:30:34 +0000 Subject: [PATCH 039/124] Bump http-proxy from 1.17.0 to 1.18.1 Bumps [http-proxy](https://github.com/http-party/node-http-proxy) from 1.17.0 to 1.18.1. - [Release notes](https://github.com/http-party/node-http-proxy/releases) - [Changelog](https://github.com/http-party/node-http-proxy/blob/master/CHANGELOG.md) - [Commits](https://github.com/http-party/node-http-proxy/compare/1.17.0...1.18.1) Signed-off-by: dependabot[bot] --- package-lock.json | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3fb91e21..087afcf3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -385,12 +385,6 @@ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "dev": true - }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -535,14 +529,22 @@ } }, "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "requires": { - "eventemitter3": "^3.0.0", + "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", "requires-port": "^1.0.0" + }, + "dependencies": { + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + } } }, "iconv-lite": { From 8d882e473769448e4685988db74cc8e1480564ac Mon Sep 17 00:00:00 2001 From: Fabio Utzig Date: Fri, 28 Aug 2020 15:40:15 -0300 Subject: [PATCH 040/124] domains: c: cpp: fix typos Signed-off-by: Fabio Utzig --- sphinx/domains/c.py | 2 +- sphinx/domains/cpp.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index d8ccc2e3d..7e153472e 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -1792,7 +1792,7 @@ class Symbol: if not declaration: if Symbol.debug_lookup: - Symbol.debug_print("no delcaration") + Symbol.debug_print("no declaration") Symbol.debug_indent -= 2 # good, just a scope creation # TODO: what if we have more than one symbol? diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 92d578427..7b10f8166 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -4292,7 +4292,7 @@ class Symbol: if not declaration: if Symbol.debug_lookup: - Symbol.debug_print("no delcaration") + Symbol.debug_print("no declaration") Symbol.debug_indent -= 2 # good, just a scope creation # TODO: what if we have more than one symbol? From 8c4193027b6ed62c7eaf8c127f3b1b6fa8ca28a2 Mon Sep 17 00:00:00 2001 From: Fabio Utzig Date: Fri, 28 Aug 2020 15:39:06 -0300 Subject: [PATCH 041/124] domains: c: add missing intersphinx object types For intersphinx to be able to resolve references to C-Domain objects, it needs to have them declared in the obj_types dict. This is currently missing enum, enumerator, struct and union so those can't be referenced by an external project. This commit fixes the issue by adding them. Signed-off-by: Fabio Utzig --- sphinx/domains/c.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index d8ccc2e3d..a7bebdcda 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -3607,6 +3607,10 @@ class CDomain(Domain): 'macro': ObjType(_('macro'), 'macro'), 'type': ObjType(_('type'), 'type'), 'var': ObjType(_('variable'), 'data'), + 'enum': ObjType(_('enum'), 'enum'), + 'enumerator': ObjType(_('enumerator'), 'enumerator'), + 'struct': ObjType(_('struct'), 'struct'), + 'union': ObjType(_('union'), 'union'), } directives = { From 42bfed2cb3d9ca6622e45e440aaaebaae3c5e0ee Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 10 Sep 2020 22:34:36 +0900 Subject: [PATCH 042/124] Fix #8192: napoleon: description is disappeared by inline literals The napoloen wrongly parses a parameter definition because regexp matches literal string by longest match unexpectedly. --- CHANGES | 1 + sphinx/ext/napoleon/docstring.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index fde891098..89c4bdfb5 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,7 @@ Bugs fixed * #8085: i18n: Add support for having single text domain * #8143: autodoc: AttributeError is raised when False value is passed to autodoc_default_options +* #8192: napoleon: description is disappeared when it contains inline literals * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 4397d0e41..97eaa0fd6 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -36,7 +36,7 @@ _numpy_section_regex = re.compile(r'^[=\-`:\'"~^_*+#<>]{2,}\s*$') _single_colon_regex = re.compile(r'(? Date: Sat, 12 Sep 2020 16:04:41 +0900 Subject: [PATCH 043/124] Fix #8190: autodoc: parse error for docstring w/o ending blank lines autodoc raises a parsing error if some extension generates a docstring not having blank lines at the tail. This appends a blank line if generated one does not contain it. --- CHANGES | 2 ++ sphinx/ext/autodoc/__init__.py | 5 +++++ tests/test_ext_autodoc_events.py | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index fde891098..c8de2d7e6 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,8 @@ Bugs fixed * #8085: i18n: Add support for having single text domain * #8143: autodoc: AttributeError is raised when False value is passed to autodoc_default_options +* #8190: autodoc: parsing error is raised if some extension replaces docstring + by string not ending with blank lines * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index ed02c2c90..23fb43a4d 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -535,6 +535,11 @@ class Documenter: self.env.app.emit('autodoc-process-docstring', self.objtype, self.fullname, self.object, self.options, docstringlines) + + if docstringlines and docstringlines[-1] != '': + # append a blank line to the end of the docstring + docstringlines.append('') + yield from docstringlines def get_sourcename(self) -> str: diff --git a/tests/test_ext_autodoc_events.py b/tests/test_ext_autodoc_events.py index 4e8348abc..7ddc952ab 100644 --- a/tests/test_ext_autodoc_events.py +++ b/tests/test_ext_autodoc_events.py @@ -28,7 +28,8 @@ def test_process_docstring(app): '.. py:function:: func()', ' :module: target.process_docstring', '', - ' my docstring' + ' my docstring', + '', ] From 59766c23513fe6a82deb04ba0cca10075d023fec Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Sat, 12 Sep 2020 14:33:57 +0200 Subject: [PATCH 044/124] Update CHANGES after PR --- CHANGES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 5176d8372..ae9505742 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,10 @@ Features added Bugs fixed ---------- +* #8188: C, add missing items to internal object types dictionary, + e.g., preventing intersphinx from resolving them. + + Testing -------- From 85b24a2e88ea71edc728aff3b078d34c2f374f06 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 13 Sep 2020 09:16:32 +0900 Subject: [PATCH 045/124] Fix our test failed with pygments-2.7.0 Since pygments-2.7.0, it has changed the style of output HTML. That makes our test broken. This fixes it to pass with new pygments. --- tests/test_build_html.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test_build_html.py b/tests/test_build_html.py index e949f1157..1efc6c14a 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -10,8 +10,10 @@ import os import re +from distutils.version import LooseVersion from itertools import cycle, chain +import pygments import pytest from html5lib import HTMLParser @@ -1591,4 +1593,8 @@ def test_html_codeblock_linenos_style_inline(app): app.build() content = (app.outdir / 'index.html').read_text() - assert '1 ' in content + pygments_version = tuple(LooseVersion(pygments.__version__).version) + if pygments_version > (2, 7): + assert '1' in content + else: + assert '1 ' in content From 564a577a4a27e24efe02e9ff1cb9013dc472ed80 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 13 Sep 2020 11:10:33 +0900 Subject: [PATCH 046/124] Fix #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex --- CHANGES | 1 + sphinx/builders/latex/__init__.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 89980530f..abf169928 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ Bugs fixed * #8143: autodoc: AttributeError is raised when False value is passed to autodoc_default_options * #8192: napoleon: description is disappeared when it contains inline literals +* #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index 88c471675..ffb17d2eb 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -505,7 +505,7 @@ def validate_latex_theme_options(app: Sphinx, config: Config) -> None: def install_pakcages_for_ja(app: Sphinx) -> None: """Install packages for Japanese.""" - if app.config.language == 'ja': + if app.config.language == 'ja' and app.config.latex_engine in ('platex', 'uplatex'): app.add_latex_package('pxjahyper', after_hyperref=True) From 500f45fd4c34559cdbf9f28eae3e159fc5b7f2d8 Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Sun, 13 Sep 2020 16:25:09 +0200 Subject: [PATCH 047/124] C, recursive alias declarations Fixes sphinx-doc/sphinx#8141 --- CHANGES | 2 + doc/usage/restructuredtext/domains.rst | 12 +++++ sphinx/domains/c.py | 70 +++++++++++++++++++------- 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index dca1b4a2e..8a5da7a19 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,8 @@ Features added * #8100: html: Show a better error message for failures on copying html_static_files +* #8141: C: added a ``maxdepth`` option to :rst:dir:`c:alias` to insert + nested declarations. Bugs fixed ---------- diff --git a/doc/usage/restructuredtext/domains.rst b/doc/usage/restructuredtext/domains.rst index 311b03d66..f3754ab7c 100644 --- a/doc/usage/restructuredtext/domains.rst +++ b/doc/usage/restructuredtext/domains.rst @@ -744,6 +744,18 @@ The following directive can be used for this purpose. .. versionadded:: 3.2 + + .. rubric:: Options + + .. rst:directive:option:: maxdepth: int + + Insert nested declarations as well, up to the total depth given. + Use 0 for infinite depth and 1 for just the mentioned declaration. + Defaults to 1. + + .. versionadded:: 3.3 + + .. c:namespace-pop:: diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index c759dacbd..304c871ea 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -136,8 +136,8 @@ class ASTIdentifier(ASTBaseBase): reftype='identifier', reftarget=targetText, modname=None, classname=None) - # key = symbol.get_lookup_key() - # pnode['c:parent_key'] = key + key = symbol.get_lookup_key() + pnode['c:parent_key'] = key if self.is_anon(): pnode += nodes.strong(text="[anonymous]") else: @@ -1562,6 +1562,11 @@ class Symbol: for s in sChild.get_all_symbols(): yield s + @property + def children(self) -> Iterator["Symbol"]: + for c in self._children: + yield c + @property def children_recurse_anon(self) -> Iterator["Symbol"]: for c in self._children: @@ -3408,10 +3413,13 @@ class CNamespacePopObject(SphinxDirective): class AliasNode(nodes.Element): - def __init__(self, sig: str, env: "BuildEnvironment" = None, + def __init__(self, sig: str, maxdepth: int, document: Any, env: "BuildEnvironment" = None, parentKey: LookupKey = None) -> None: super().__init__() self.sig = sig + self.maxdepth = maxdepth + assert maxdepth >= 0 + self.document = document if env is not None: if 'c:parent_symbol' not in env.temp_data: root = env.domaindata['c']['root_symbol'] @@ -3428,6 +3436,37 @@ class AliasNode(nodes.Element): class AliasTransform(SphinxTransform): default_priority = ReferencesResolver.default_priority - 1 + def _render_symbol(self, s: Symbol, maxdepth: int, document: Any) -> List[Node]: + nodes = [] # type: List[Node] + options = dict() # type: ignore + signode = addnodes.desc_signature('', '') + nodes.append(signode) + s.declaration.describe_signature(signode, 'markName', self.env, options) + if maxdepth == 0: + recurse = True + elif maxdepth == 1: + recurse = False + else: + maxdepth -= 1 + recurse = True + if recurse: + content = addnodes.desc_content() + desc = addnodes.desc() + content.append(desc) + desc.document = document + desc['domain'] = 'c' + # 'desctype' is a backwards compatible attribute + desc['objtype'] = desc['desctype'] = 'alias' + desc['noindex'] = True + + for sChild in s.children: + childNodes = self._render_symbol(sChild, maxdepth, document) + desc.extend(childNodes) + + if len(desc.children) != 0: + nodes.append(content) + return nodes + def apply(self, **kwargs: Any) -> None: for node in self.document.traverse(AliasNode): sig = node.sig @@ -3468,17 +3507,16 @@ class AliasTransform(SphinxTransform): logger.warning("Could not find C declaration for alias '%s'." % name, location=node) node.replace_self(signode) - else: - nodes = [] - options = dict() # type: ignore - signode = addnodes.desc_signature(sig, '') - nodes.append(signode) - s.declaration.describe_signature(signode, 'markName', self.env, options) - node.replace_self(nodes) + continue + + nodes = self._render_symbol(s, maxdepth=node.maxdepth, document=node.document) + node.replace_self(nodes) class CAliasObject(ObjectDescription): - option_spec = {} # type: Dict + option_spec = { + 'maxdepth': directives.nonnegative_int + } # type: Dict def run(self) -> List[Node]: if ':' in self.name: @@ -3494,16 +3532,10 @@ class CAliasObject(ObjectDescription): node['noindex'] = True self.names = [] # type: List[str] + maxdepth = self.options.get('maxdepth', 1) signatures = self.get_signatures() for i, sig in enumerate(signatures): - node.append(AliasNode(sig, env=self.env)) - - contentnode = addnodes.desc_content() - node.append(contentnode) - self.before_content() - self.state.nested_parse(self.content, self.content_offset, contentnode) - self.env.temp_data['object'] = None - self.after_content() + node.append(AliasNode(sig, maxdepth, self.state.document, env=self.env)) return [node] From 49e7400123a10ad833af8997df58e98634091e4e Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Mon, 14 Sep 2020 21:01:41 +0200 Subject: [PATCH 048/124] C, fix names in get_objects() Fixes sphinx-doc/sphinx#8160 --- CHANGES | 1 + sphinx/domains/c.py | 26 ++++++++++++-------------- tests/test_domain_c.py | 18 +++++++++++------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index ae9505742..564eb799a 100644 --- a/CHANGES +++ b/CHANGES @@ -18,6 +18,7 @@ Bugs fixed * #8188: C, add missing items to internal object types dictionary, e.g., preventing intersphinx from resolving them. +* C, fix anon objects in intersphinx. Testing diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index c759dacbd..4d88bd8e8 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -12,7 +12,6 @@ import re from typing import ( Any, Callable, Dict, Generator, Iterator, List, Type, TypeVar, Tuple, Union ) -from typing import cast from docutils import nodes from docutils.nodes import Element, Node, TextElement, system_message @@ -3153,10 +3152,6 @@ class CObject(ObjectDescription): self.state.document.note_explicit_target(signode) - domain = cast(CDomain, self.env.get_domain('c')) - if name not in domain.objects: - domain.objects[name] = (domain.env.docname, newestId, self.objtype) - if 'noindexentry' not in self.options: indexText = self.get_index_text(name) self.indexnode['entries'].append(('single', indexText, newestId, '', None)) @@ -3649,10 +3644,6 @@ class CDomain(Domain): 'objects': {}, # fullname -> docname, node_id, objtype } # type: Dict[str, Union[Symbol, Dict[str, Tuple[str, str, str]]]] - @property - def objects(self) -> Dict[str, Tuple[str, str, str]]: - return self.data.setdefault('objects', {}) # fullname -> docname, node_id, objtype - def clear_doc(self, docname: str) -> None: if Symbol.debug_show_tree: print("clear_doc:", docname) @@ -3668,9 +3659,6 @@ class CDomain(Domain): print(self.data['root_symbol'].dump(1)) print("\tafter end") print("clear_doc end:", docname) - for fullname, (fn, _id, _l) in list(self.objects.items()): - if fn == docname: - del self.objects[fullname] def process_doc(self, env: BuildEnvironment, docname: str, document: nodes.document) -> None: @@ -3756,8 +3744,18 @@ class CDomain(Domain): return [] def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]: - for refname, (docname, node_id, objtype) in list(self.objects.items()): - yield (refname, refname, objtype, docname, node_id, 1) + rootSymbol = self.data['root_symbol'] + for symbol in rootSymbol.get_all_symbols(): + if symbol.declaration is None: + continue + assert symbol.docname + fullNestedName = symbol.get_full_nested_name() + name = str(fullNestedName).lstrip('.') + dispname = fullNestedName.get_display_string().lstrip('.') + objectType = symbol.declaration.objectType + docname = symbol.docname + newestId = symbol.declaration.get_newest_id() + yield (name, dispname, objectType, docname, newestId, 1) def setup(app: Sphinx) -> Dict[str, Any]: diff --git a/tests/test_domain_c.py b/tests/test_domain_c.py index b6f72287e..7509b1aa9 100644 --- a/tests/test_domain_c.py +++ b/tests/test_domain_c.py @@ -562,6 +562,13 @@ def test_build_domain_c_semicolon(app, status, warning): assert len(ws) == 0 +def _get_obj(app, queryName): + domain = app.env.get_domain('c') + for name, dispname, objectType, docname, anchor, prio in domain.get_objects(): + if name == queryName: + return (docname, anchor, objectType) + return (queryName, "not", "found") + def test_cfunction(app): text = (".. c:function:: PyObject* " "PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)") @@ -569,8 +576,7 @@ def test_cfunction(app): assert_node(doctree[1], addnodes.desc, desctype="function", domain="c", objtype="function", noindex=False) - domain = app.env.get_domain('c') - entry = domain.objects.get('PyType_GenericAlloc') + entry = _get_obj(app, 'PyType_GenericAlloc') assert entry == ('index', 'c.PyType_GenericAlloc', 'function') @@ -580,8 +586,7 @@ def test_cmember(app): assert_node(doctree[1], addnodes.desc, desctype="member", domain="c", objtype="member", noindex=False) - domain = app.env.get_domain('c') - entry = domain.objects.get('PyTypeObject.tp_bases') + entry = _get_obj(app, 'PyTypeObject.tp_bases') assert entry == ('index', 'c.PyTypeObject.tp_bases', 'member') @@ -591,9 +596,8 @@ def test_cvar(app): assert_node(doctree[1], addnodes.desc, desctype="var", domain="c", objtype="var", noindex=False) - domain = app.env.get_domain('c') - entry = domain.objects.get('PyClass_Type') - assert entry == ('index', 'c.PyClass_Type', 'var') + entry = _get_obj(app, 'PyClass_Type') + assert entry == ('index', 'c.PyClass_Type', 'member') def test_noindexentry(app): From add70354f1a49a5a6d4f8c1d0dd1fdf21fcd24cc Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 16 Sep 2020 14:29:27 +0100 Subject: [PATCH 049/124] Fix 'oneside' latex output Sphinx.sty had an FIXME bug where documents with the 'oneside' option would output lots of the following warnings when building the document: Package Fancyhdr Warning: \fancyfoot's `E' option without twoside option is useless on input line 309. Fix the problem by using \if@twoside around the offending tex code that tries to set format for the even pages. 'Even' pages don't exist on oneside builds, which causes the warning to be emitted. Fixes: #8215 --- CHANGES | 1 + sphinx/texinputs/sphinx.sty | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 37719297f..583975c8e 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,7 @@ Bugs fixed * #8192: napoleon: description is disappeared when it contains inline literals * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) +* #8215: Eliminate Fancyhdr build warnings for oneside documents Testing -------- diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index a3e91ad34..e52ed5975 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -588,12 +588,14 @@ {% classes with \chapter command \fancypagestyle{normal}{ \fancyhf{} - % FIXME: this presupposes "twoside". - % If "oneside" class option, there are warnings in LaTeX log. - \fancyfoot[LE,RO]{{\py@HeaderFamily\thepage}} + \fancyfoot[RO]{{\py@HeaderFamily\thepage}} \fancyfoot[LO]{{\py@HeaderFamily\nouppercase{\rightmark}}} - \fancyfoot[RE]{{\py@HeaderFamily\nouppercase{\leftmark}}} - \fancyhead[LE,RO]{{\py@HeaderFamily \@title\sphinxheadercomma\py@release}} + \fancyhead[RO]{{\py@HeaderFamily \@title\sphinxheadercomma\py@release}} + \if@twoside + \fancyfoot[LE]{{\py@HeaderFamily\thepage}} + \fancyfoot[RE]{{\py@HeaderFamily\nouppercase{\leftmark}}} + \fancyhead[LE]{{\py@HeaderFamily \@title\sphinxheadercomma\py@release}} + \fi \renewcommand{\headrulewidth}{0.4pt} \renewcommand{\footrulewidth}{0.4pt} % define chaptermark with \@chappos when \@chappos is available for Japanese @@ -605,7 +607,8 @@ % page of a chapter `clean.' \fancypagestyle{plain}{ \fancyhf{} - \fancyfoot[LE,RO]{{\py@HeaderFamily\thepage}} + \fancyfoot[RO]{{\py@HeaderFamily\thepage}} + \if@twoside\fancyfoot[LE]{{\py@HeaderFamily\thepage}}\fi \renewcommand{\headrulewidth}{0pt} \renewcommand{\footrulewidth}{0.4pt} } From f00e75278c5999f40b214d8934357fbf0e705417 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 20 Sep 2020 17:34:49 +0900 Subject: [PATCH 050/124] Fix #8172: napoleon: Potential of regex denial of service in google style docs --- CHANGES | 1 + sphinx/ext/napoleon/docstring.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 89980530f..a0dcc3998 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ Bugs fixed * #8143: autodoc: AttributeError is raised when False value is passed to autodoc_default_options * #8192: napoleon: description is disappeared when it contains inline literals +* #8172: napoleon: Potential of regex denial of service in google style docs * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 97eaa0fd6..d36fdd17a 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -31,7 +31,7 @@ logger = logging.getLogger(__name__) _directive_regex = re.compile(r'\.\. \S+::') _google_section_regex = re.compile(r'^(\s|\w)+:\s*$') -_google_typed_arg_regex = re.compile(r'\s*(.+?)\s*\(\s*(.*[^\s]+)\s*\)') +_google_typed_arg_regex = re.compile(r'(.+?)\(\s*(.*[^\s]+)\s*\)') _numpy_section_regex = re.compile(r'^[=\-`:\'"~^_*+#<>]{2,}\s*$') _single_colon_regex = re.compile(r'(? Date: Mon, 21 Sep 2020 00:45:18 +0900 Subject: [PATCH 051/124] latex: Fix a typo (refs: #8206) Fix a typo in the name of function: install_pakcages_for_ja() --- sphinx/builders/latex/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index ffb17d2eb..1caa9ecb4 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -503,7 +503,7 @@ def validate_latex_theme_options(app: Sphinx, config: Config) -> None: config.latex_theme_options.pop(key) -def install_pakcages_for_ja(app: Sphinx) -> None: +def install_packages_for_ja(app: Sphinx) -> None: """Install packages for Japanese.""" if app.config.language == 'ja' and app.config.latex_engine in ('platex', 'uplatex'): app.add_latex_package('pxjahyper', after_hyperref=True) @@ -556,7 +556,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_builder(LaTeXBuilder) app.connect('config-inited', validate_config_values, priority=800) app.connect('config-inited', validate_latex_theme_options, priority=800) - app.connect('builder-inited', install_pakcages_for_ja) + app.connect('builder-inited', install_packages_for_ja) app.add_config_value('latex_engine', default_latex_engine, None, ENUM('pdflatex', 'xelatex', 'lualatex', 'platex', 'uplatex')) From 5ef4825b57c8fd84488e38f7f5cf78ccf3d72698 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 10 Aug 2020 02:23:52 +0900 Subject: [PATCH 052/124] Close #8081: latex: Allow to add LaTeX package until writing tex file This postpones the evaluation of LaTeX packages via ``app.add_latex_package()`` to just before writing .tex file. That allows extensions to add LaTeX packages during reading and resolving phase. --- CHANGES | 5 +++++ doc/extdev/deprecated.rst | 10 ++++++++++ sphinx/builders/latex/__init__.py | 28 +++++++++++++++++++++------- sphinx/testing/util.py | 2 -- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index 738baf341..b459af41e 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,9 @@ Incompatible changes Deprecated ---------- +* ``sphinx.builders.latex.LaTeXBuilder.usepackages`` +* ``sphinx.builders.latex.LaTeXBuilder.usepackages_afger_hyperref`` + Features added -------------- @@ -17,6 +20,8 @@ Features added html_static_files * #8141: C: added a ``maxdepth`` option to :rst:dir:`c:alias` to insert nested declarations. +* #8081: LaTeX: Allow to add LaTeX package via ``app.add_latex_package()`` until + just before writing .tex file Bugs fixed ---------- diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst index 829bfc32b..d7ad21fff 100644 --- a/doc/extdev/deprecated.rst +++ b/doc/extdev/deprecated.rst @@ -26,6 +26,16 @@ The following is a list of deprecated interfaces. - (will be) Removed - Alternatives + * - ``sphinx.builders.latex.LaTeXBuilder.usepackages`` + - 3.3 + - 5.0 + - N/A + + * - ``sphinx.builders.latex.LaTeXBuilder.usepackages_afger_hyperref`` + - 3.3 + - 5.0 + - N/A + * - ``sphinx.ext.autodoc.members_set_option()`` - 3.2 - 5.0 diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index ffb17d2eb..b58a44adf 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -24,7 +24,7 @@ from sphinx.builders.latex.constants import ADDITIONAL_SETTINGS, DEFAULT_SETTING from sphinx.builders.latex.theming import Theme, ThemeFactory from sphinx.builders.latex.util import ExtBabel from sphinx.config import Config, ENUM -from sphinx.deprecation import RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning from sphinx.environment.adapters.asset import ImageAdapter from sphinx.errors import NoUri, SphinxError from sphinx.locale import _, __ @@ -128,8 +128,6 @@ class LaTeXBuilder(Builder): self.docnames = [] # type: Iterable[str] self.document_data = [] # type: List[Tuple[str, str, str, str, str, bool]] self.themes = ThemeFactory(self.app) - self.usepackages = self.app.registry.latex_packages - self.usepackages_after_hyperref = self.app.registry.latex_packages_after_hyperref texescape.init() self.init_context() @@ -179,10 +177,6 @@ class LaTeXBuilder(Builder): key = (self.config.latex_engine, self.config.language[:2]) self.context.update(ADDITIONAL_SETTINGS.get(key, {})) - # Apply extension settings to context - self.context['packages'] = self.usepackages - self.context['packages_after_hyperref'] = self.usepackages_after_hyperref - # Apply user settings to context self.context.update(self.config.latex_elements) self.context['release'] = self.config.release @@ -203,6 +197,13 @@ class LaTeXBuilder(Builder): # Show the release label only if release value exists self.context.setdefault('releasename', _('Release')) + def update_context(self) -> None: + """Update template variables for .tex file just before writing.""" + # Apply extension settings to context + registry = self.app.registry + self.context['packages'] = registry.latex_packages + self.context['packages_after_hyperref'] = registry.latex_packages_after_hyperref + def init_babel(self) -> None: self.babel = ExtBabel(self.config.language, not self.context['babel']) if self.config.language and not self.babel.is_supported_language(): @@ -290,6 +291,7 @@ class LaTeXBuilder(Builder): doctree['tocdepth'] = tocdepth self.post_process_images(doctree) self.update_doc_context(title, author, theme) + self.update_context() with progress_message(__("writing")): docsettings._author = author @@ -448,6 +450,18 @@ class LaTeXBuilder(Builder): filename = path.join(package_dir, 'templates', 'latex', 'sphinxmessages.sty_t') copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer()) + @property + def usepackages(self) -> List[Tuple[str, str]]: + warnings.warn('LaTeXBuilder.usepackages is deprecated.', + RemovedInSphinx50Warning, stacklevel=2) + return self.app.registry.latex_packages + + @property + def usepackages_after_hyperref(self) -> List[Tuple[str, str]]: + warnings.warn('LaTeXBuilder.usepackages_after_hyperref is deprecated.', + RemovedInSphinx50Warning, stacklevel=2) + return self.app.registry.latex_packages_after_hyperref + def patch_settings(settings: Any) -> Any: """Make settings object to show deprecation messages.""" diff --git a/sphinx/testing/util.py b/sphinx/testing/util.py index 5ac334068..80ca84cb3 100644 --- a/sphinx/testing/util.py +++ b/sphinx/testing/util.py @@ -21,7 +21,6 @@ from docutils.nodes import Node from docutils.parsers.rst import directives, roles from sphinx import application, locale -from sphinx.builders.latex import LaTeXBuilder from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.pycode import ModuleAnalyzer from sphinx.testing.path import path @@ -141,7 +140,6 @@ class SphinxTestApp(application.Sphinx): def cleanup(self, doctrees: bool = False) -> None: ModuleAnalyzer.cache.clear() - LaTeXBuilder.usepackages = [] locale.translators.clear() sys.path[:] = self._saved_path sys.modules.pop('autodoc_fodder', None) From a0116eaa582810e56a4661a22a574baf6bff33f1 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Sun, 20 Sep 2020 17:36:01 -0500 Subject: [PATCH 053/124] Fix typo: anchestor -> ancestor. --- doc/usage/extensions/autodoc.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/usage/extensions/autodoc.rst b/doc/usage/extensions/autodoc.rst index 71f49c240..802be3bd0 100644 --- a/doc/usage/extensions/autodoc.rst +++ b/doc/usage/extensions/autodoc.rst @@ -229,7 +229,7 @@ inserting them into the page source under a suitable :rst:dir:`py:module`, .. versionchanged:: 3.0 - It takes an anchestor class name as an argument. + It takes an ancestor class name as an argument. * It's possible to override the signature for explicitly documented callable objects (functions, methods, classes) with the regular syntax that will From d0ba4f8d449858440c4407033a28bddf9b5611b3 Mon Sep 17 00:00:00 2001 From: Guillaume Melquiond Date: Wed, 23 Sep 2020 18:43:38 +0200 Subject: [PATCH 054/124] Strip the token name from productionlist. When the user tries to align production rules, Sphinx gets confused by spaces around leading tokens. In the following, references to mygroup:bad1 and mygroup:bad2 are missing, while the one to mygroup:correct is present. .. productionlist:: mygroup correct: `correct` | `bad1` | `bad2` bad1 : `correct` | `bad1` | `bad2` bad2: `correct` | `bad1` | `bad2` Since it is useful to be able to align colons in a production list, this commit systematically strips leading and trailing whitespaces from the production name. --- sphinx/domains/std.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 7eaaa531d..39f67b54e 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -500,7 +500,8 @@ class ProductionList(SphinxDirective): except ValueError: break subnode = addnodes.production(rule) - subnode['tokenname'] = name.strip() + name = name.strip() + subnode['tokenname'] = name if subnode['tokenname']: prefix = 'grammar-token-%s' % productionGroup node_id = make_id(self.env, self.state.document, prefix, name) From 189406f65b19330b31f124e77a6d501a8611ed3f Mon Sep 17 00:00:00 2001 From: Nathan Shammah Date: Wed, 23 Sep 2020 19:53:47 +0200 Subject: [PATCH 055/124] add mitiq to examples --- EXAMPLES | 1 + 1 file changed, 1 insertion(+) diff --git a/EXAMPLES b/EXAMPLES index b87d8e73e..19f23172f 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -330,6 +330,7 @@ Documentation using a custom theme or integrated in a website * `Lasso `__ * `Mako `__ * `MirrorBrain `__ +* `Mitiq `__ * `MongoDB `__ * `Music21 `__ * `MyHDL `__ From f7b872e673f9b359a61fd287a7338a28077840d2 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 20 Sep 2020 17:48:00 +0900 Subject: [PATCH 056/124] Fix #8175: intersphinx: Potential of regex denial of service by inventory --- CHANGES | 1 + sphinx/util/inventory.py | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 3e155f33a..aa7b92d73 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,7 @@ Bugs fixed * #8192: napoleon: description is disappeared when it contains inline literals * #8172: napoleon: Potential of regex denial of service in google style docs * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex +* #8175: intersphinx: Potential of regex denial of service by broken inventory * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) diff --git a/sphinx/util/inventory.py b/sphinx/util/inventory.py index 9b647ccac..1e3572323 100644 --- a/sphinx/util/inventory.py +++ b/sphinx/util/inventory.py @@ -122,11 +122,16 @@ class InventoryFile: for line in stream.read_compressed_lines(): # be careful to handle names with embedded spaces correctly - m = re.match(r'(?x)(.+?)\s+(\S*:\S*)\s+(-?\d+)\s+?(\S*)\s+(.*)', + m = re.match(r'(?x)(.+?)\s+(\S+)\s+(-?\d+)\s+?(\S*)\s+(.*)', line.rstrip()) if not m: continue name, type, prio, location, dispname = m.groups() + if ':' not in type: + # wrong type value. type should be in the form of "{domain}:{objtype}" + # + # Note: To avoid the regex DoS, this is implemented in python (refs: #8175) + continue if type == 'py:module' and type in invdata and name in invdata[type]: # due to a bug in 1.1 and below, # two inventory entries are created From 3f584155a5faab333cf8da1b3573c79c0d1e27dc Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 28 Sep 2020 01:41:49 +0900 Subject: [PATCH 057/124] Update CHANGES for PR #8239 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 3e155f33a..575838f4a 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,7 @@ Bugs fixed * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) +* #8239: Failed to refer a token in productionlist if it is indented Testing -------- From 786972e47f6d25d438b4bb7cf6ae0c43358d41f2 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Sun, 27 Sep 2020 20:54:50 +0200 Subject: [PATCH 058/124] linkcheck: take source directory into account for local files --- sphinx/builders/linkcheck.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index 9b54afc7c..4ea98f1d3 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -210,7 +210,7 @@ class CheckExternalLinksBuilder(Builder): else: return 'redirected', new_url, 0 - def check() -> Tuple[str, str, int]: + def check(srcdir: str) -> Tuple[str, str, int]: # check for various conditions without bothering the network if len(uri) == 0 or uri.startswith(('#', 'mailto:')): return 'unchecked', '', 0 @@ -219,7 +219,7 @@ class CheckExternalLinksBuilder(Builder): # non supported URI schemes (ex. ftp) return 'unchecked', '', 0 else: - if path.exists(path.join(self.srcdir, uri)): + if path.exists(path.join(srcdir, uri)): return 'working', '', 0 else: for rex in self.to_ignore: @@ -256,7 +256,8 @@ class CheckExternalLinksBuilder(Builder): uri, docname, lineno = self.wqueue.get() if uri is None: break - status, info, code = check() + srcdir = path.dirname(self.env.doc2path(docname)) + status, info, code = check(srcdir) self.rqueue.put((uri, docname, lineno, status, info, code)) def process_result(self, result: Tuple[str, str, int, str, str, int]) -> None: From c08214fe92c8ab61219ce46af0ff634a57b8431c Mon Sep 17 00:00:00 2001 From: Robert Cohn Date: Wed, 30 Sep 2020 20:47:56 -0400 Subject: [PATCH 059/124] add parallel to SphinxTestApp --- sphinx/testing/util.py | 4 ++-- tests/test_build_html.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/sphinx/testing/util.py b/sphinx/testing/util.py index 80ca84cb3..c0dd1feac 100644 --- a/sphinx/testing/util.py +++ b/sphinx/testing/util.py @@ -108,7 +108,7 @@ class SphinxTestApp(application.Sphinx): def __init__(self, buildername: str = 'html', srcdir: path = None, freshenv: bool = False, confoverrides: Dict = None, status: IO = None, warning: IO = None, - tags: List[str] = None, docutilsconf: str = None) -> None: + tags: List[str] = None, docutilsconf: str = None, parallel: int = 0) -> None: if docutilsconf is not None: (srcdir / 'docutils.conf').write_text(docutilsconf) @@ -133,7 +133,7 @@ class SphinxTestApp(application.Sphinx): try: super().__init__(srcdir, confdir, outdir, doctreedir, buildername, confoverrides, status, warning, - freshenv, warningiserror, tags) + freshenv, warningiserror, tags, parallel=parallel) except Exception: self.cleanup() raise diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 1efc6c14a..acb3ca764 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -421,6 +421,12 @@ def test_html5_output(app, cached_etree_parse, fname, expect): check_xpath(cached_etree_parse(app.outdir / fname), fname, *expect) +@pytest.mark.skipif(docutils.__version_info__ < (0, 13), + reason='docutils-0.13 or above is required') +@pytest.mark.sphinx('html', parallel=2) +def test_html_parallel(app): + app.build() + @pytest.mark.skipif(docutils.__version_info__ < (0, 13), reason='docutils-0.13 or above is required') @pytest.mark.sphinx('html') From 3d81abef9cc8c765d3cf5bc419b21917243cf56d Mon Sep 17 00:00:00 2001 From: Robert Cohn Date: Thu, 1 Oct 2020 11:12:39 -0400 Subject: [PATCH 060/124] respond to review comments --- tests/test_build_html.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_build_html.py b/tests/test_build_html.py index acb3ca764..8cd541481 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -421,12 +421,11 @@ def test_html5_output(app, cached_etree_parse, fname, expect): check_xpath(cached_etree_parse(app.outdir / fname), fname, *expect) -@pytest.mark.skipif(docutils.__version_info__ < (0, 13), - reason='docutils-0.13 or above is required') @pytest.mark.sphinx('html', parallel=2) def test_html_parallel(app): app.build() + @pytest.mark.skipif(docutils.__version_info__ < (0, 13), reason='docutils-0.13 or above is required') @pytest.mark.sphinx('html') From bbf0754db1d0a8961a467621fa2964df5afb8ffd Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 2 Oct 2020 01:17:43 +0900 Subject: [PATCH 061/124] Update CHANGES for PR #8257 --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 4ff6d130f..49c303196 100644 --- a/CHANGES +++ b/CHANGES @@ -43,6 +43,8 @@ Bugs fixed Testing -------- +* #8257: Support parallel build in sphinx.testing + Release 3.2.2 (in development) ============================== From 1ff1f3cf5b2f3402074d84395a0374fee8ac2a9e Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 3 Oct 2020 01:25:38 +0900 Subject: [PATCH 062/124] Update CHANGES for PR #8142 --- CHANGES | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 49c303196..22876d43b 100644 --- a/CHANGES +++ b/CHANGES @@ -32,8 +32,10 @@ Bugs fixed * #8103: autodoc: functools.cached_property is not considered as a property * #8190: autodoc: parsing error is raised if some extension replaces docstring by string not ending with blank lines +* #8142: autodoc: Wrong constructor signature for the class derived from + typing.Generic * #8192: napoleon: description is disappeared when it contains inline literals -* #8172: napoleon: Potential of regex denial of service in google style docs +* #8142: napoleon: Potential of regex denial of service in google style docs * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex * #8175: intersphinx: Potential of regex denial of service by broken inventory * #8093: The highlight warning has wrong location in some builders (LaTeX, From 785f4d695cfca0eeb537c92166808bc9f187d8c0 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 3 Oct 2020 12:00:33 +0900 Subject: [PATCH 063/124] Fix #7964: autodoc: Tuple in default value is wrongly rendered This implements tuple literal support to sphinx.pycode.ast.unparse(). --- CHANGES | 1 + sphinx/pycode/ast.py | 18 ++++++++++++++++-- tests/test_pycode_ast.py | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 22876d43b..bfe8910d1 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,7 @@ Bugs fixed by string not ending with blank lines * #8142: autodoc: Wrong constructor signature for the class derived from typing.Generic +* #7964: autodoc: Tuple in default value is wrongly rendered * #8192: napoleon: description is disappeared when it contains inline literals * #8142: napoleon: Potential of regex denial of service in google style docs * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex diff --git a/sphinx/pycode/ast.py b/sphinx/pycode/ast.py index 9bafff11c..2583448d5 100644 --- a/sphinx/pycode/ast.py +++ b/sphinx/pycode/ast.py @@ -166,14 +166,28 @@ class _UnparseVisitor(ast.NodeVisitor): return "{" + ", ".join(self.visit(e) for e in node.elts) + "}" def visit_Subscript(self, node: ast.Subscript) -> str: - return "%s[%s]" % (self.visit(node.value), self.visit(node.slice)) + def is_simple_tuple(value: ast.AST) -> bool: + return ( + isinstance(value, ast.Tuple) and + bool(value.elts) and + not any(isinstance(elt, ast.Starred) for elt in value.elts) + ) + + if is_simple_tuple(node.slice): + elts = ", ".join(self.visit(e) for e in node.slice.elts) # type: ignore + return "%s[%s]" % (self.visit(node.value), elts) + elif isinstance(node.slice, ast.Index) and is_simple_tuple(node.slice.value): + elts = ", ".join(self.visit(e) for e in node.slice.value.elts) # type: ignore + return "%s[%s]" % (self.visit(node.value), elts) + else: + return "%s[%s]" % (self.visit(node.value), self.visit(node.slice)) def visit_UnaryOp(self, node: ast.UnaryOp) -> str: return "%s %s" % (self.visit(node.op), self.visit(node.operand)) def visit_Tuple(self, node: ast.Tuple) -> str: if node.elts: - return ", ".join(self.visit(e) for e in node.elts) + return "(" + ", ".join(self.visit(e) for e in node.elts) + ")" else: return "()" diff --git a/tests/test_pycode_ast.py b/tests/test_pycode_ast.py index 9b12d24d5..32a784b74 100644 --- a/tests/test_pycode_ast.py +++ b/tests/test_pycode_ast.py @@ -53,7 +53,7 @@ from sphinx.pycode import ast ("+ a", "+ a"), # UAdd ("- 1", "- 1"), # UnaryOp ("- a", "- a"), # USub - ("(1, 2, 3)", "1, 2, 3"), # Tuple + ("(1, 2, 3)", "(1, 2, 3)"), # Tuple ("()", "()"), # Tuple (empty) ]) def test_unparse(source, expected): From f2c0dfe7c454589d9a2681369e51a0d073bfd4ba Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 26 Jul 2020 16:05:14 +0900 Subject: [PATCH 064/124] Close #6518: autodoc: Add autodoc_type_aliases autodoc_type_aliases allows to keep user defined type alises not evaluated in the generated document. --- doc/usage/extensions/autodoc.rst | 38 +++++++++++++++ sphinx/ext/autodoc/__init__.py | 37 +++++++++----- sphinx/util/inspect.py | 6 +-- sphinx/util/typing.py | 6 ++- .../test-ext-autodoc/target/annotations.py | 25 ++++++++++ tests/test_ext_autodoc_configs.py | 48 +++++++++++++++++++ 6 files changed, 144 insertions(+), 16 deletions(-) create mode 100644 tests/roots/test-ext-autodoc/target/annotations.py diff --git a/doc/usage/extensions/autodoc.rst b/doc/usage/extensions/autodoc.rst index 802be3bd0..2d8a216c0 100644 --- a/doc/usage/extensions/autodoc.rst +++ b/doc/usage/extensions/autodoc.rst @@ -515,6 +515,44 @@ There are also config values that you can set: New option ``'description'`` is added. +.. confval:: autodoc_type_aliases + + A dictionary for users defined `type aliases`__ that maps a type name to the + full-qualified object name. It is used to keep type aliases not evaluated in + the document. Defaults to empty (``{}``). + + The type aliases are only available if your program enables `Postponed + Evaluation of Annotations (PEP 563)`__ feature via ``from __future__ import + annotations``. + + For example, there is code using a type alias:: + + from __future__ import annotations + + AliasType = Union[List[Dict[Tuple[int, str], Set[int]]], Tuple[str, List[str]]] + + def f() -> AliasType: + ... + + If ``autodoc_type_aliases`` is not set, autodoc will generate internal mark-up + from this code as following:: + + .. py:function:: f() -> Union[List[Dict[Tuple[int, str], Set[int]]], Tuple[str, List[str]]] + + ... + + If you set ``autodoc_type_aliases`` as + ``{'AliasType': 'your.module.TypeAlias'}``, it generates a following document + internally:: + + .. py:function:: f() -> your.module.AliasType: + + ... + + .. __: https://www.python.org/dev/peps/pep-0563/ + .. __: https://mypy.readthedocs.io/en/latest/kinds_of_types.html#type-aliases + .. versionadded:: 3.3 + .. confval:: autodoc_warningiserror This value controls the behavior of :option:`sphinx-build -W` during diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 35bb1c90d..d7c5d2242 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -1213,7 +1213,8 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ try: self.env.app.emit('autodoc-before-process-signature', self.object, False) - sig = inspect.signature(self.object, follow_wrapped=True) + sig = inspect.signature(self.object, follow_wrapped=True, + type_aliases=self.env.config.autodoc_type_aliases) args = stringify_signature(sig, **kwargs) except TypeError as exc: logger.warning(__("Failed to get a function signature for %s: %s"), @@ -1262,7 +1263,9 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ if overloaded: __globals__ = safe_getattr(self.object, '__globals__', {}) for overload in self.analyzer.overloads.get('.'.join(self.objpath)): - overload = evaluate_signature(overload, __globals__) + overload = evaluate_signature(overload, __globals__, + self.env.config.autodoc_type_aliases) + sig = stringify_signature(overload, **kwargs) sigs.append(sig) @@ -1271,7 +1274,7 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ def annotate_to_first_argument(self, func: Callable, typ: Type) -> None: """Annotate type hint to the first argument of function if needed.""" try: - sig = inspect.signature(func) + sig = inspect.signature(func, type_aliases=self.env.config.autodoc_type_aliases) except TypeError as exc: logger.warning(__("Failed to get a function signature for %s: %s"), self.fullname, exc) @@ -1392,7 +1395,8 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: if call is not None: self.env.app.emit('autodoc-before-process-signature', call, True) try: - sig = inspect.signature(call, bound_method=True) + sig = inspect.signature(call, bound_method=True, + type_aliases=self.env.config.autodoc_type_aliases) return type(self.object), '__call__', sig except ValueError: pass @@ -1407,7 +1411,8 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: if new is not None: self.env.app.emit('autodoc-before-process-signature', new, True) try: - sig = inspect.signature(new, bound_method=True) + sig = inspect.signature(new, bound_method=True, + type_aliases=self.env.config.autodoc_type_aliases) return self.object, '__new__', sig except ValueError: pass @@ -1417,7 +1422,8 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: if init is not None: self.env.app.emit('autodoc-before-process-signature', init, True) try: - sig = inspect.signature(init, bound_method=True) + sig = inspect.signature(init, bound_method=True, + type_aliases=self.env.config.autodoc_type_aliases) return self.object, '__init__', sig except ValueError: pass @@ -1428,7 +1434,8 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: # the signature from, so just pass the object itself to our hook. self.env.app.emit('autodoc-before-process-signature', self.object, False) try: - sig = inspect.signature(self.object, bound_method=False) + sig = inspect.signature(self.object, bound_method=False, + type_aliases=self.env.config.autodoc_type_aliases) return None, None, sig except ValueError: pass @@ -1475,7 +1482,8 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: method = safe_getattr(self._signature_class, self._signature_method_name, None) __globals__ = safe_getattr(method, '__globals__', {}) for overload in self.analyzer.overloads.get(qualname): - overload = evaluate_signature(overload, __globals__) + overload = evaluate_signature(overload, __globals__, + self.env.config.autodoc_type_aliases) parameters = list(overload.parameters.values()) overload = overload.replace(parameters=parameters[1:], @@ -1820,11 +1828,13 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: else: if inspect.isstaticmethod(self.object, cls=self.parent, name=self.object_name): self.env.app.emit('autodoc-before-process-signature', self.object, False) - sig = inspect.signature(self.object, bound_method=False) + sig = inspect.signature(self.object, bound_method=False, + type_aliases=self.env.config.autodoc_type_aliases) else: self.env.app.emit('autodoc-before-process-signature', self.object, True) sig = inspect.signature(self.object, bound_method=True, - follow_wrapped=True) + follow_wrapped=True, + type_aliases=self.env.config.autodoc_type_aliases) args = stringify_signature(sig, **kwargs) except TypeError as exc: logger.warning(__("Failed to get a method signature for %s: %s"), @@ -1884,7 +1894,9 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: if overloaded: __globals__ = safe_getattr(self.object, '__globals__', {}) for overload in self.analyzer.overloads.get('.'.join(self.objpath)): - overload = evaluate_signature(overload, __globals__) + overload = evaluate_signature(overload, __globals__, + self.env.config.autodoc_type_aliases) + if not inspect.isstaticmethod(self.object, cls=self.parent, name=self.object_name): parameters = list(overload.parameters.values()) @@ -1897,7 +1909,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: def annotate_to_first_argument(self, func: Callable, typ: Type) -> None: """Annotate type hint to the first argument of function if needed.""" try: - sig = inspect.signature(func) + sig = inspect.signature(func, type_aliases=self.env.config.autodoc_type_aliases) except TypeError as exc: logger.warning(__("Failed to get a method signature for %s: %s"), self.fullname, exc) @@ -2237,6 +2249,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value('autodoc_mock_imports', [], True) app.add_config_value('autodoc_typehints', "signature", True, ENUM("signature", "description", "none")) + app.add_config_value('autodoc_type_aliases', {}, True) app.add_config_value('autodoc_warningiserror', True, True) app.add_config_value('autodoc_inherit_docstrings', True, True) app.add_event('autodoc-before-process-signature') diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 37997e6b2..378174993 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -439,8 +439,8 @@ def _should_unwrap(subject: Callable) -> bool: return False -def signature(subject: Callable, bound_method: bool = False, follow_wrapped: bool = False - ) -> inspect.Signature: +def signature(subject: Callable, bound_method: bool = False, follow_wrapped: bool = False, + type_aliases: Dict = {}) -> inspect.Signature: """Return a Signature object for the given *subject*. :param bound_method: Specify *subject* is a bound method or not @@ -470,7 +470,7 @@ def signature(subject: Callable, bound_method: bool = False, follow_wrapped: boo try: # Update unresolved annotations using ``get_type_hints()``. - annotations = typing.get_type_hints(subject) + annotations = typing.get_type_hints(subject, None, type_aliases) for i, param in enumerate(parameters): if isinstance(param.annotation, str) and param.name in annotations: parameters[i] = param.replace(annotation=annotations[param.name]) diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py index d71ca1b2d..4dac3b695 100644 --- a/sphinx/util/typing.py +++ b/sphinx/util/typing.py @@ -63,7 +63,11 @@ def is_system_TypeVar(typ: Any) -> bool: def stringify(annotation: Any) -> str: """Stringify type annotation object.""" if isinstance(annotation, str): - return annotation + if annotation.startswith("'") and annotation.endswith("'"): + # might be a double Forward-ref'ed type. Go unquoting. + return annotation[1:-2] + else: + return annotation elif isinstance(annotation, TypeVar): # type: ignore return annotation.__name__ elif not annotation: diff --git a/tests/roots/test-ext-autodoc/target/annotations.py b/tests/roots/test-ext-autodoc/target/annotations.py new file mode 100644 index 000000000..667149b26 --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/annotations.py @@ -0,0 +1,25 @@ +from __future__ import annotations +from typing import overload + + +myint = int + + +def sum(x: myint, y: myint) -> myint: + """docstring""" + return x + y + + +@overload +def mult(x: myint, y: myint) -> myint: + ... + + +@overload +def mult(x: float, y: float) -> float: + ... + + +def mult(x, y): + """docstring""" + return x, y diff --git a/tests/test_ext_autodoc_configs.py b/tests/test_ext_autodoc_configs.py index 3d0bfd395..7d51b7f0e 100644 --- a/tests/test_ext_autodoc_configs.py +++ b/tests/test_ext_autodoc_configs.py @@ -642,6 +642,54 @@ def test_autodoc_typehints_description_for_invalid_node(app): restructuredtext.parse(app, text) # raises no error +@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.') +@pytest.mark.sphinx('text', testroot='ext-autodoc') +def test_autodoc_type_aliases(app): + # default + options = {"members": None} + actual = do_autodoc(app, 'module', 'target.annotations', options) + assert list(actual) == [ + '', + '.. py:module:: target.annotations', + '', + '', + '.. py:function:: mult(x: int, y: int) -> int', + ' mult(x: float, y: float) -> float', + ' :module: target.annotations', + '', + ' docstring', + '', + '', + '.. py:function:: sum(x: int, y: int) -> int', + ' :module: target.annotations', + '', + ' docstring', + '', + ] + + # define aliases + app.config.autodoc_type_aliases = {'myint': 'myint'} + actual = do_autodoc(app, 'module', 'target.annotations', options) + assert list(actual) == [ + '', + '.. py:module:: target.annotations', + '', + '', + '.. py:function:: mult(x: myint, y: myint) -> myint', + ' mult(x: float, y: float) -> float', + ' :module: target.annotations', + '', + ' docstring', + '', + '', + '.. py:function:: sum(x: myint, y: myint) -> myint', + ' :module: target.annotations', + '', + ' docstring', + '', + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_default_options(app): # no settings From 5166dd194c27b63d2211e70272d9a39ffda36744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Sat, 3 Oct 2020 13:47:01 +0200 Subject: [PATCH 065/124] Strip trailing whitespaces and normalize line endings Trailing whitespace do not have impact on the result, they are just unused bytes. Most text editors are configured to strip trailing whitespaces. Remove them all in one go. Update a handful of files to use the UNIX line ending. --- CHANGES | 4 +- doc/_themes/sphinx13/static/sphinx13.css | 2 +- doc/usage/extensions/coverage.rst | 2 +- doc/usage/installation.rst | 2 +- doc/usage/restructuredtext/directives.rst | 4 +- sphinx/locale/ar/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/bg/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/bn/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/ca/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/cak/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/cs/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/cy/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/da/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/de/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/el/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/eo/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/es/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/et/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/eu/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/fa/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/fi/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/fr/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/he/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/hi/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/hr/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/hu/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/id/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/it/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/ja/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/ko/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/lt/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/lv/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/mk/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/ne/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/nl/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/pl/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/pt/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/ro/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/ru/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/si/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/sk/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/sl/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/sq/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/sr/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/sv/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/ta/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/te/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/tr/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/ur/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/vi/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po | 2 +- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po | 2 +- .../search/non-minified-js/danish-stemmer.js | 4 +- .../search/non-minified-js/dutch-stemmer.js | 4 +- .../search/non-minified-js/finnish-stemmer.js | 4 +- .../search/non-minified-js/french-stemmer.js | 4 +- .../search/non-minified-js/german-stemmer.js | 4 +- .../non-minified-js/hungarian-stemmer.js | 4 +- .../search/non-minified-js/italian-stemmer.js | 4 +- .../non-minified-js/norwegian-stemmer.js | 4 +- .../search/non-minified-js/porter-stemmer.js | 4 +- .../non-minified-js/portuguese-stemmer.js | 4 +- .../non-minified-js/romanian-stemmer.js | 4 +- .../search/non-minified-js/russian-stemmer.js | 4 +- .../search/non-minified-js/spanish-stemmer.js | 4 +- .../search/non-minified-js/swedish-stemmer.js | 4 +- .../search/non-minified-js/turkish-stemmer.js | 4 +- sphinx/texinputs/sphinx.sty | 4 +- sphinx/texinputs/sphinxcyrillic.sty | 2 +- sphinx/texinputs/sphinxhowto.cls | 2 +- sphinx/themes/nature/static/nature.css_t | 66 +++++++++---------- sphinx/themes/pyramid/static/pyramid.css_t | 64 +++++++++--------- .../themes/sphinxdoc/static/sphinxdoc.css_t | 2 +- tests/roots/test-circular/conf.py | 2 +- .../roots/test-intl/xx/LC_MESSAGES/toctree.po | 2 +- tests/roots/test-numbered-circular/conf.py | 2 +- tests/roots/test-theming/MANIFEST.in | 4 +- tests/roots/test-theming/conf.py | 6 +- tests/roots/test-theming/index.rst | 10 +-- tests/roots/test-theming/setup.py | 22 +++---- .../roots/test-theming/test_theme/__init__.py | 10 +-- tests/test_pycode.py | 2 +- 89 files changed, 191 insertions(+), 191 deletions(-) diff --git a/CHANGES b/CHANGES index 22876d43b..318338208 100644 --- a/CHANGES +++ b/CHANGES @@ -171,7 +171,7 @@ Bugs fixed contains a hyperlink target * #7469: autosummary: "Module attributes" header is not translatable * #7940: apidoc: An extra newline is generated at the end of the rst file if a - module has submodules + module has submodules * #4258: napoleon: decorated special methods are not shown * #7799: napoleon: parameters are not escaped for combined params in numpydoc * #7780: napoleon: multiple paramaters declaration in numpydoc was wrongly @@ -338,7 +338,7 @@ Features added * #7543: html theme: Add top and bottom margins to tables * #7695: html theme: Add viewport meta tag for basic theme * #7721: html theme: classic: default codetextcolor/codebgcolor doesn't override - Pygments + Pygments * C and C++: allow semicolon in the end of declarations. * C++, parse parameterized noexcept specifiers. * #7294: C++, parse expressions with user-defined literals. diff --git a/doc/_themes/sphinx13/static/sphinx13.css b/doc/_themes/sphinx13/static/sphinx13.css index 7c1d46e83..c8fb2e5c9 100644 --- a/doc/_themes/sphinx13/static/sphinx13.css +++ b/doc/_themes/sphinx13/static/sphinx13.css @@ -239,7 +239,7 @@ div.footer a { /* -- body styles ----------------------------------------------------------- */ -p { +p { margin: 0.8em 0 0.5em 0; } diff --git a/doc/usage/extensions/coverage.rst b/doc/usage/extensions/coverage.rst index db989f38d..5e6b04feb 100644 --- a/doc/usage/extensions/coverage.rst +++ b/doc/usage/extensions/coverage.rst @@ -51,7 +51,7 @@ should check: .. versionadded:: 1.1 -.. confval:: coverage_show_missing_items +.. confval:: coverage_show_missing_items Print objects that are missing to standard output also. ``False`` by default. diff --git a/doc/usage/installation.rst b/doc/usage/installation.rst index c9bef974d..46ef6a51e 100644 --- a/doc/usage/installation.rst +++ b/doc/usage/installation.rst @@ -171,7 +171,7 @@ Docker images for Sphinx are published on the `Docker Hub `_ - `sphinxdoc/sphinx-latexpdf `_ -Former one is used for standard usage of Sphinx, and latter one is mainly used for PDF builds using LaTeX. +Former one is used for standard usage of Sphinx, and latter one is mainly used for PDF builds using LaTeX. Please choose one for your purpose. .. note:: diff --git a/doc/usage/restructuredtext/directives.rst b/doc/usage/restructuredtext/directives.rst index e94106148..92bf78489 100644 --- a/doc/usage/restructuredtext/directives.rst +++ b/doc/usage/restructuredtext/directives.rst @@ -665,7 +665,7 @@ __ http://pygments.org/docs/lexers .. note:: If you want to select only ``[second-section]`` of ini file like the - following, you can use ``:start-at: [second-section]`` and + following, you can use ``:start-at: [second-section]`` and ``:end-before: [third-section]``: .. code-block:: ini @@ -692,7 +692,7 @@ __ http://pygments.org/docs/lexers # [initialize] app.start(":8000") # [initialize] - + When lines have been selected in any of the ways described above, the line numbers in ``emphasize-lines`` refer to those selected lines, counted diff --git a/sphinx/locale/ar/LC_MESSAGES/sphinx.po b/sphinx/locale/ar/LC_MESSAGES/sphinx.po index bd69d2aeb..371395b7b 100644 --- a/sphinx/locale/ar/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ar/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Mohammed Shannaq , 2018 msgid "" diff --git a/sphinx/locale/bg/LC_MESSAGES/sphinx.po b/sphinx/locale/bg/LC_MESSAGES/sphinx.po index 79329a57a..6d36b05f3 100644 --- a/sphinx/locale/bg/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/bg/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/bn/LC_MESSAGES/sphinx.po b/sphinx/locale/bn/LC_MESSAGES/sphinx.po index 63aae6877..98ecbe5d0 100644 --- a/sphinx/locale/bn/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/bn/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # FIRST AUTHOR , 2009 msgid "" diff --git a/sphinx/locale/ca/LC_MESSAGES/sphinx.po b/sphinx/locale/ca/LC_MESSAGES/sphinx.po index 6a8e317b1..9cbebc74a 100644 --- a/sphinx/locale/ca/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ca/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # FIRST AUTHOR , 2009 msgid "" diff --git a/sphinx/locale/cak/LC_MESSAGES/sphinx.po b/sphinx/locale/cak/LC_MESSAGES/sphinx.po index b729d5f1f..2ea8716e3 100644 --- a/sphinx/locale/cak/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/cak/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Julien Malard , 2019 msgid "" diff --git a/sphinx/locale/cs/LC_MESSAGES/sphinx.po b/sphinx/locale/cs/LC_MESSAGES/sphinx.po index 8952713e1..1e7890782 100644 --- a/sphinx/locale/cs/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/cs/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # FIRST AUTHOR , 2008 # Vilibald W. , 2014-2015 diff --git a/sphinx/locale/cy/LC_MESSAGES/sphinx.po b/sphinx/locale/cy/LC_MESSAGES/sphinx.po index 12f2aecd2..19a4c83d3 100644 --- a/sphinx/locale/cy/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/cy/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # FIRST AUTHOR , 2016 # Geraint Palmer , 2016 diff --git a/sphinx/locale/da/LC_MESSAGES/sphinx.po b/sphinx/locale/da/LC_MESSAGES/sphinx.po index 317b832d2..47fcbfd6f 100644 --- a/sphinx/locale/da/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/da/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # askhl , 2010-2011 # Jakob Lykke Andersen , 2014,2016 diff --git a/sphinx/locale/de/LC_MESSAGES/sphinx.po b/sphinx/locale/de/LC_MESSAGES/sphinx.po index 8d5cd4e43..2eaab8597 100644 --- a/sphinx/locale/de/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/de/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Georg Brandl , 2013-2015 # Jean-François B. , 2018 diff --git a/sphinx/locale/el/LC_MESSAGES/sphinx.po b/sphinx/locale/el/LC_MESSAGES/sphinx.po index 54eb341ec..03f5d01fe 100644 --- a/sphinx/locale/el/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/el/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Stelios Vitalis , 2015 # tzoumakers tzoumakers , 2019 diff --git a/sphinx/locale/eo/LC_MESSAGES/sphinx.po b/sphinx/locale/eo/LC_MESSAGES/sphinx.po index 6c94360c6..1af0769f3 100644 --- a/sphinx/locale/eo/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/eo/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Dinu Gherman , 2014 msgid "" diff --git a/sphinx/locale/es/LC_MESSAGES/sphinx.po b/sphinx/locale/es/LC_MESSAGES/sphinx.po index be149e88a..a01ae6c80 100644 --- a/sphinx/locale/es/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/es/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Edward Villegas-Pulgarin , 2018 # Edward Villegas-Pulgarin , 2019 diff --git a/sphinx/locale/et/LC_MESSAGES/sphinx.po b/sphinx/locale/et/LC_MESSAGES/sphinx.po index a87de4d11..1f40f10c0 100644 --- a/sphinx/locale/et/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/et/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Aivar Annamaa , 2011 # Ivar Smolin , 2012 diff --git a/sphinx/locale/eu/LC_MESSAGES/sphinx.po b/sphinx/locale/eu/LC_MESSAGES/sphinx.po index 80dbae5a3..c6f25f8b0 100644 --- a/sphinx/locale/eu/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/eu/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Ales Zabala Alava , 2011 # Asier Iturralde Sarasola , 2018 diff --git a/sphinx/locale/fa/LC_MESSAGES/sphinx.po b/sphinx/locale/fa/LC_MESSAGES/sphinx.po index ddca8112c..066cfc4bb 100644 --- a/sphinx/locale/fa/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/fa/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/fi/LC_MESSAGES/sphinx.po b/sphinx/locale/fi/LC_MESSAGES/sphinx.po index 19233894d..6e18d601a 100644 --- a/sphinx/locale/fi/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/fi/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # FIRST AUTHOR , 2009 msgid "" diff --git a/sphinx/locale/fr/LC_MESSAGES/sphinx.po b/sphinx/locale/fr/LC_MESSAGES/sphinx.po index b01d956c0..740e9ba70 100644 --- a/sphinx/locale/fr/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/fr/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Christophe CHAUVET , 2017 # Christophe CHAUVET , 2013,2015 diff --git a/sphinx/locale/he/LC_MESSAGES/sphinx.po b/sphinx/locale/he/LC_MESSAGES/sphinx.po index 7332af27f..1f8d45480 100644 --- a/sphinx/locale/he/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/he/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # FIRST AUTHOR , 2011 msgid "" diff --git a/sphinx/locale/hi/LC_MESSAGES/sphinx.po b/sphinx/locale/hi/LC_MESSAGES/sphinx.po index 7fd40316b..5effb078c 100644 --- a/sphinx/locale/hi/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/hi/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Ajay Singh , 2019 # Purnank H. Ghumalia , 2015-2016 diff --git a/sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po b/sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po index 78f66e29e..b1047a51f 100644 --- a/sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/hr/LC_MESSAGES/sphinx.po b/sphinx/locale/hr/LC_MESSAGES/sphinx.po index c1f1d4be0..20e336487 100644 --- a/sphinx/locale/hr/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/hr/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Mario Šarić, 2015-2020 msgid "" diff --git a/sphinx/locale/hu/LC_MESSAGES/sphinx.po b/sphinx/locale/hu/LC_MESSAGES/sphinx.po index fe58d1895..ecf147f1f 100644 --- a/sphinx/locale/hu/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/hu/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # FIRST AUTHOR , 2011 # Molnár Dénes , 2017 diff --git a/sphinx/locale/id/LC_MESSAGES/sphinx.po b/sphinx/locale/id/LC_MESSAGES/sphinx.po index d11a59d35..d1ff01f34 100644 --- a/sphinx/locale/id/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/id/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Arif Budiman , 2016-2017 # FIRST AUTHOR , 2009 diff --git a/sphinx/locale/it/LC_MESSAGES/sphinx.po b/sphinx/locale/it/LC_MESSAGES/sphinx.po index 9c871d0d2..c0aeb2e06 100644 --- a/sphinx/locale/it/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/it/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Denis Cappellin , 2018 # Paolo Cavallini , 2013-2017 diff --git a/sphinx/locale/ja/LC_MESSAGES/sphinx.po b/sphinx/locale/ja/LC_MESSAGES/sphinx.po index d9299e58c..1477b3d8a 100644 --- a/sphinx/locale/ja/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ja/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # shirou - しろう , 2013 # Akitoshi Ohta , 2011 diff --git a/sphinx/locale/ko/LC_MESSAGES/sphinx.po b/sphinx/locale/ko/LC_MESSAGES/sphinx.po index bf3bbe78e..56fff17d1 100644 --- a/sphinx/locale/ko/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ko/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Minho Ryang , 2019 # YT H , 2019 diff --git a/sphinx/locale/lt/LC_MESSAGES/sphinx.po b/sphinx/locale/lt/LC_MESSAGES/sphinx.po index fbf5b0a1d..4df91eb54 100644 --- a/sphinx/locale/lt/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/lt/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # DALIUS DOBRAVOLSKAS , 2010 msgid "" diff --git a/sphinx/locale/lv/LC_MESSAGES/sphinx.po b/sphinx/locale/lv/LC_MESSAGES/sphinx.po index a3968756d..ca8ef8240 100644 --- a/sphinx/locale/lv/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/lv/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/mk/LC_MESSAGES/sphinx.po b/sphinx/locale/mk/LC_MESSAGES/sphinx.po index 5543d45fd..397828d91 100644 --- a/sphinx/locale/mk/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/mk/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Vasil Vangelovski , 2013 msgid "" diff --git a/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po b/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po index b061b0361..05fe2c92c 100644 --- a/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/ne/LC_MESSAGES/sphinx.po b/sphinx/locale/ne/LC_MESSAGES/sphinx.po index 46590097d..22e4ef626 100644 --- a/sphinx/locale/ne/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ne/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # FIRST AUTHOR , 2011 # Takeshi KOMIYA , 2016 diff --git a/sphinx/locale/nl/LC_MESSAGES/sphinx.po b/sphinx/locale/nl/LC_MESSAGES/sphinx.po index d5eb16c6f..4bdf9f43b 100644 --- a/sphinx/locale/nl/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/nl/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Bram Geron, 2017 # brechtm, 2016 diff --git a/sphinx/locale/pl/LC_MESSAGES/sphinx.po b/sphinx/locale/pl/LC_MESSAGES/sphinx.po index ac8488a45..73b7a6478 100644 --- a/sphinx/locale/pl/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/pl/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # m_aciek , 2017-2020 # Michael Gielda , 2014 diff --git a/sphinx/locale/pt/LC_MESSAGES/sphinx.po b/sphinx/locale/pt/LC_MESSAGES/sphinx.po index 4b0c30cb7..e08ce7a5d 100644 --- a/sphinx/locale/pt/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/pt/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po index dba58f93e..3e9e2965f 100644 --- a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Claudio Rogerio Carvalho Filho , 2016 # FIRST AUTHOR , 2008 diff --git a/sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po b/sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po index 7d219561a..6c78b0813 100644 --- a/sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Pedro Algarvio , 2013 # Takeshi KOMIYA , 2016 diff --git a/sphinx/locale/ro/LC_MESSAGES/sphinx.po b/sphinx/locale/ro/LC_MESSAGES/sphinx.po index 6a4591643..721f8dcd2 100644 --- a/sphinx/locale/ro/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ro/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Razvan Stefanescu , 2015-2017 # Takeshi KOMIYA , 2016 diff --git a/sphinx/locale/ru/LC_MESSAGES/sphinx.po b/sphinx/locale/ru/LC_MESSAGES/sphinx.po index e69207f4e..d8572db5f 100644 --- a/sphinx/locale/ru/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ru/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Alex Salikov , 2019 # Dmitry Shachnev , 2013 diff --git a/sphinx/locale/si/LC_MESSAGES/sphinx.po b/sphinx/locale/si/LC_MESSAGES/sphinx.po index a257711c5..d03be451e 100644 --- a/sphinx/locale/si/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/si/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # callkalpa , 2013 msgid "" diff --git a/sphinx/locale/sk/LC_MESSAGES/sphinx.po b/sphinx/locale/sk/LC_MESSAGES/sphinx.po index 7d4bb2118..07d654695 100644 --- a/sphinx/locale/sk/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/sk/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # FIRST AUTHOR , 2008 # Slavko , 2013-2019 diff --git a/sphinx/locale/sl/LC_MESSAGES/sphinx.po b/sphinx/locale/sl/LC_MESSAGES/sphinx.po index 80dde8bd0..6ceca74a0 100644 --- a/sphinx/locale/sl/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/sl/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/sq/LC_MESSAGES/sphinx.po b/sphinx/locale/sq/LC_MESSAGES/sphinx.po index bf21f378d..fb1b0e26c 100644 --- a/sphinx/locale/sq/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/sq/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/sr/LC_MESSAGES/sphinx.po b/sphinx/locale/sr/LC_MESSAGES/sphinx.po index 1df55881c..2bcfcf51c 100644 --- a/sphinx/locale/sr/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/sr/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Risto Pejasinovic , 2019 msgid "" diff --git a/sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po b/sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po index a7b82e633..574d218de 100644 --- a/sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po b/sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po index dad4f3542..3e7ac5ba4 100644 --- a/sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/sv/LC_MESSAGES/sphinx.po b/sphinx/locale/sv/LC_MESSAGES/sphinx.po index bbf5e5ff1..af26ab2f1 100644 --- a/sphinx/locale/sv/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/sv/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/ta/LC_MESSAGES/sphinx.po b/sphinx/locale/ta/LC_MESSAGES/sphinx.po index bb1c77f28..cc19b6dfa 100644 --- a/sphinx/locale/ta/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ta/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Julien Malard , 2019 msgid "" diff --git a/sphinx/locale/te/LC_MESSAGES/sphinx.po b/sphinx/locale/te/LC_MESSAGES/sphinx.po index c6c3c45f1..32c1fc59e 100644 --- a/sphinx/locale/te/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/te/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/tr/LC_MESSAGES/sphinx.po b/sphinx/locale/tr/LC_MESSAGES/sphinx.po index 996d6e67c..b37c18d50 100644 --- a/sphinx/locale/tr/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/tr/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # BouRock, 2020 # Fırat Özgül , 2013-2016 diff --git a/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po b/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po index 2b43faa32..791426dd7 100644 --- a/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Petro Sasnyk , 2009 msgid "" diff --git a/sphinx/locale/ur/LC_MESSAGES/sphinx.po b/sphinx/locale/ur/LC_MESSAGES/sphinx.po index c674b9283..c37314be1 100644 --- a/sphinx/locale/ur/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ur/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: msgid "" msgstr "" diff --git a/sphinx/locale/vi/LC_MESSAGES/sphinx.po b/sphinx/locale/vi/LC_MESSAGES/sphinx.po index 83b579ea4..20c77edeb 100644 --- a/sphinx/locale/vi/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/vi/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Hoat Le Van , 2014 msgid "" diff --git a/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po b/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po index 47cb76210..5b9491c53 100644 --- a/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Yinian Chin , 2015,2017-2018 # Hsiaoming Yang , 2018 diff --git a/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po b/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po index 67b4d2b81..435fe0453 100644 --- a/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po @@ -1,7 +1,7 @@ # Translations template for Sphinx. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# +# # Translators: # Adrian Liaw , 2018 # Fred Lin , 2008 diff --git a/sphinx/search/non-minified-js/danish-stemmer.js b/sphinx/search/non-minified-js/danish-stemmer.js index f6309327f..36943d22a 100644 --- a/sphinx/search/non-minified-js/danish-stemmer.js +++ b/sphinx/search/non-minified-js/danish-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/dutch-stemmer.js b/sphinx/search/non-minified-js/dutch-stemmer.js index 15c053a8d..997f1467b 100644 --- a/sphinx/search/non-minified-js/dutch-stemmer.js +++ b/sphinx/search/non-minified-js/dutch-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/finnish-stemmer.js b/sphinx/search/non-minified-js/finnish-stemmer.js index 210c3e13d..5b520c00f 100644 --- a/sphinx/search/non-minified-js/finnish-stemmer.js +++ b/sphinx/search/non-minified-js/finnish-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/french-stemmer.js b/sphinx/search/non-minified-js/french-stemmer.js index 3b3c0607f..75255a03d 100644 --- a/sphinx/search/non-minified-js/french-stemmer.js +++ b/sphinx/search/non-minified-js/french-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/german-stemmer.js b/sphinx/search/non-minified-js/german-stemmer.js index 4f1dc1cf3..a5beb8f3a 100644 --- a/sphinx/search/non-minified-js/german-stemmer.js +++ b/sphinx/search/non-minified-js/german-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/hungarian-stemmer.js b/sphinx/search/non-minified-js/hungarian-stemmer.js index c9a6347c6..67fd1cdf0 100644 --- a/sphinx/search/non-minified-js/hungarian-stemmer.js +++ b/sphinx/search/non-minified-js/hungarian-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/italian-stemmer.js b/sphinx/search/non-minified-js/italian-stemmer.js index ca16ff24c..52daef58f 100644 --- a/sphinx/search/non-minified-js/italian-stemmer.js +++ b/sphinx/search/non-minified-js/italian-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/norwegian-stemmer.js b/sphinx/search/non-minified-js/norwegian-stemmer.js index 38b64c5a8..5c6eba182 100644 --- a/sphinx/search/non-minified-js/norwegian-stemmer.js +++ b/sphinx/search/non-minified-js/norwegian-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/porter-stemmer.js b/sphinx/search/non-minified-js/porter-stemmer.js index 7a0f4558a..d07e7a426 100644 --- a/sphinx/search/non-minified-js/porter-stemmer.js +++ b/sphinx/search/non-minified-js/porter-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/portuguese-stemmer.js b/sphinx/search/non-minified-js/portuguese-stemmer.js index 35f21aa8f..4042c0aef 100644 --- a/sphinx/search/non-minified-js/portuguese-stemmer.js +++ b/sphinx/search/non-minified-js/portuguese-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/romanian-stemmer.js b/sphinx/search/non-minified-js/romanian-stemmer.js index f71f44a68..545d3ee2e 100644 --- a/sphinx/search/non-minified-js/romanian-stemmer.js +++ b/sphinx/search/non-minified-js/romanian-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/russian-stemmer.js b/sphinx/search/non-minified-js/russian-stemmer.js index 74d630968..87f4844e0 100644 --- a/sphinx/search/non-minified-js/russian-stemmer.js +++ b/sphinx/search/non-minified-js/russian-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/spanish-stemmer.js b/sphinx/search/non-minified-js/spanish-stemmer.js index 21b648fa8..6c5d2da91 100644 --- a/sphinx/search/non-minified-js/spanish-stemmer.js +++ b/sphinx/search/non-minified-js/spanish-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/swedish-stemmer.js b/sphinx/search/non-minified-js/swedish-stemmer.js index fd2a58f0a..1d8aba8f4 100644 --- a/sphinx/search/non-minified-js/swedish-stemmer.js +++ b/sphinx/search/non-minified-js/swedish-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/search/non-minified-js/turkish-stemmer.js b/sphinx/search/non-minified-js/turkish-stemmer.js index f8f088576..22bd7538d 100644 --- a/sphinx/search/non-minified-js/turkish-stemmer.js +++ b/sphinx/search/non-minified-js/turkish-stemmer.js @@ -143,7 +143,7 @@ JSX.resetProfileResults = function () { return $__jsx_profiler.resetResults(); }; JSX.DEBUG = false; -var GeneratorFunction$0 = +var GeneratorFunction$0 = (function () { try { return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); @@ -151,7 +151,7 @@ var GeneratorFunction$0 = return function GeneratorFunction () {}; } })(); -var __jsx_generator_object$0 = +var __jsx_generator_object$0 = (function () { function __jsx_generator_object() { this.__next = 0; diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index a3e91ad34..2b83ab85b 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -1823,7 +1823,7 @@ % fix a space-gobbling issue due to LaTeX's original \do@noligs % TODO: using \@noligs as patched by upquote.sty is now unneeded because % either ` and ' are escaped (non-unicode engines) or they don't build -% ligatures (unicode engines). Thus remove this and unify handling of `, <, >, +% ligatures (unicode engines). Thus remove this and unify handling of `, <, >, % ' and - with the characters . , ; ? ! / as handled via % \sphinxbreaksviaactive. % Hence \sphinx@do@noligs will be removed, or rather replaced with code @@ -1905,7 +1905,7 @@ % Special characters % % This definition prevents en-dash and em-dash TeX ligatures. -% +% % It inserts a potential breakpoint after the hyphen. This is to keep in sync % with behavior in code-blocks, parsed and inline literals. For a breakpoint % before the hyphen use \leavevmode\kern\z@- (within \makeatletter/\makeatother) diff --git a/sphinx/texinputs/sphinxcyrillic.sty b/sphinx/texinputs/sphinxcyrillic.sty index 482b4e3f7..6747b5ec6 100644 --- a/sphinx/texinputs/sphinxcyrillic.sty +++ b/sphinx/texinputs/sphinxcyrillic.sty @@ -15,7 +15,7 @@ % https://tex.stackexchange.com/a/460325/ % 159 Cyrillic glyphs as available in X2 TeX 8bit font encoding % This assumes inputenc loaded with utf8 option, or LaTeX release -% as recent as 2018/04/01 which does it automatically. +% as recent as 2018/04/01 which does it automatically. \@tfor\next:=% {Ё}{Ђ}{Є}{Ѕ}{І}{Ј}{Љ}{Њ}{Ћ}{Ў}{Џ}{А}{Б}{В}{Г}{Д}{Е}{Ж}{З}{И}{Й}% {К}{Л}{М}{Н}{О}{П}{Р}{С}{Т}{У}{Ф}{Х}{Ц}{Ч}{Ш}{Щ}{Ъ}{Ы}{Ь}{Э}{Ю}% diff --git a/sphinx/texinputs/sphinxhowto.cls b/sphinx/texinputs/sphinxhowto.cls index 57d73cebf..0848a79fd 100644 --- a/sphinx/texinputs/sphinxhowto.cls +++ b/sphinx/texinputs/sphinxhowto.cls @@ -76,7 +76,7 @@ \endgroup \noindent\rule{\textwidth}{1pt}\par \vspace{12pt}% -} +} \newcommand\sphinxtableofcontentshook{} \pagenumbering{arabic} diff --git a/sphinx/themes/nature/static/nature.css_t b/sphinx/themes/nature/static/nature.css_t index 34893b86a..7df474a91 100644 --- a/sphinx/themes/nature/static/nature.css_t +++ b/sphinx/themes/nature/static/nature.css_t @@ -8,11 +8,11 @@ * :license: BSD, see LICENSE for details. * */ - + @import url("basic.css"); - + /* -- page layout ----------------------------------------------------------- */ - + body { font-family: Arial, sans-serif; font-size: 100%; @@ -34,18 +34,18 @@ div.bodywrapper { hr { border: 1px solid #B1B4B6; } - + div.document { background-color: #eee; } - + div.body { background-color: #ffffff; color: #3E4349; padding: 0 30px 30px 30px; font-size: 0.9em; } - + div.footer { color: #555; width: 100%; @@ -53,12 +53,12 @@ div.footer { text-align: center; font-size: 75%; } - + div.footer a { color: #444; text-decoration: underline; } - + div.related { background-color: #6BA81E; line-height: 32px; @@ -66,11 +66,11 @@ div.related { text-shadow: 0px 1px 0 #444; font-size: 0.9em; } - + div.related a { color: #E2F3CC; } - + div.sphinxsidebar { font-size: 0.75em; line-height: 1.5em; @@ -79,7 +79,7 @@ div.sphinxsidebar { div.sphinxsidebarwrapper{ padding: 20px 0; } - + div.sphinxsidebar h3, div.sphinxsidebar h4 { font-family: Arial, sans-serif; @@ -95,30 +95,30 @@ div.sphinxsidebar h4 { div.sphinxsidebar h4{ font-size: 1.1em; } - + div.sphinxsidebar h3 a { color: #444; } - - + + div.sphinxsidebar p { color: #888; padding: 5px 20px; } - + div.sphinxsidebar p.topless { } - + div.sphinxsidebar ul { margin: 10px 20px; padding: 0; color: #000; } - + div.sphinxsidebar a { color: #444; } - + div.sphinxsidebar input { border: 1px solid #ccc; font-family: sans-serif; @@ -131,17 +131,17 @@ div.sphinxsidebar .searchformwrapper { } /* -- body styles ----------------------------------------------------------- */ - + a { color: #005B81; text-decoration: none; } - + a:hover { color: #E32E00; text-decoration: underline; } - + div.body h1, div.body h2, div.body h3, @@ -156,30 +156,30 @@ div.body h6 { padding: 5px 0 5px 10px; text-shadow: 0px 1px 0 white } - + div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; } div.body h2 { font-size: 150%; background-color: #C8D5E3; } div.body h3 { font-size: 120%; background-color: #D8DEE3; } div.body h4 { font-size: 110%; background-color: #D8DEE3; } div.body h5 { font-size: 100%; background-color: #D8DEE3; } div.body h6 { font-size: 100%; background-color: #D8DEE3; } - + a.headerlink { color: #c60f0f; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } - + a.headerlink:hover { background-color: #c60f0f; color: white; } - + div.body p, div.body dd, div.body li { line-height: 1.5em; } - + div.admonition p.admonition-title + p { display: inline; } @@ -188,29 +188,29 @@ div.note { background-color: #eee; border: 1px solid #ccc; } - + div.seealso { background-color: #ffc; border: 1px solid #ff6; } - + div.topic { background-color: #eee; } - + div.warning { background-color: #ffe4e4; border: 1px solid #f66; } - + p.admonition-title { display: inline; } - + p.admonition-title:after { content: ":"; } - + pre { padding: 10px; line-height: 1.2em; @@ -220,7 +220,7 @@ pre { -webkit-box-shadow: 1px 1px 1px #d8d8d8; -moz-box-shadow: 1px 1px 1px #d8d8d8; } - + code { background-color: #ecf0f3; color: #222; diff --git a/sphinx/themes/pyramid/static/pyramid.css_t b/sphinx/themes/pyramid/static/pyramid.css_t index dafd898d5..0bab3d1a2 100644 --- a/sphinx/themes/pyramid/static/pyramid.css_t +++ b/sphinx/themes/pyramid/static/pyramid.css_t @@ -8,11 +8,11 @@ * :license: BSD, see LICENSE for details. * */ - + @import url("basic.css"); - + /* -- page layout ----------------------------------------------------------- */ - + body { font-family: "Nobile", sans-serif; font-size: 100%; @@ -34,7 +34,7 @@ div.bodywrapper { hr { border: 1px solid #B1B4B6; } - + div.document { background-color: #eee; } @@ -59,7 +59,7 @@ div.body { border-right-style: none; overflow: auto; } - + div.footer { color: #ffffff; width: 100%; @@ -69,7 +69,7 @@ div.footer { background: transparent; clear:both; } - + div.footer a { color: #ffffff; text-decoration: none; @@ -79,14 +79,14 @@ div.footer a:hover { color: #e88f00; text-decoration: underline; } - + div.related { line-height: 30px; color: #373839; font-size: 0.8em; background-color: #eee; } - + div.related a { color: #1b61d6; } @@ -94,7 +94,7 @@ div.related a { div.related ul { padding-left: calc({{ theme_sidebarwidth|todim }} + 10px); } - + div.sphinxsidebar { font-size: 0.75em; line-height: 1.5em; @@ -103,7 +103,7 @@ div.sphinxsidebar { div.sphinxsidebarwrapper{ padding: 10px 0; } - + div.sphinxsidebar h3, div.sphinxsidebar h4 { font-family: "Neuton", sans-serif; @@ -118,30 +118,30 @@ div.sphinxsidebar h4 { div.sphinxsidebar h4{ font-size: 1.3em; } - + div.sphinxsidebar h3 a { color: #000000; } - - + + div.sphinxsidebar p { color: #888; padding: 5px 20px; } - + div.sphinxsidebar p.topless { } - + div.sphinxsidebar ul { margin: 10px 20px; padding: 0; color: #373839; } - + div.sphinxsidebar a { color: #444; } - + div.sphinxsidebar input { border: 1px solid #ccc; font-family: sans-serif; @@ -171,16 +171,16 @@ p.sidebar-title { } /* -- body styles ----------------------------------------------------------- */ - + a, a .pre { color: #1b61d6; text-decoration: none; } - + a:hover, a:hover .pre { text-decoration: underline; } - + div.body h1, div.body h2, div.body h3, @@ -194,29 +194,29 @@ div.body h6 { margin: 30px 0px 10px 0px; padding: 5px 0; } - + div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; } div.body h2 { font-size: 150%; background-color: #ffffff; } div.body h3 { font-size: 120%; background-color: #ffffff; } div.body h4 { font-size: 110%; background-color: #ffffff; } div.body h5 { font-size: 100%; background-color: #ffffff; } div.body h6 { font-size: 100%; background-color: #ffffff; } - + a.headerlink { color: #1b61d6; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } - + a.headerlink:hover { text-decoration: underline; } - + div.body p, div.body dd, div.body li { line-height: 1.5em; } - + div.admonition p.admonition-title + p { display: inline; } @@ -236,7 +236,7 @@ div.note { padding: 10px 20px 10px 60px; background: #e1ecfe url(dialog-note.png) no-repeat 10px 8px; } - + div.seealso { background: #fff6bf url(dialog-seealso.png) no-repeat 10px 8px; border: 2px solid #ffd324; @@ -244,7 +244,7 @@ div.seealso { border-right-style: none; padding: 10px 20px 10px 60px; } - + div.topic { background: #eeeeee; border: 2px solid #C6C9CB; @@ -252,7 +252,7 @@ div.topic { border-right-style: none; border-left-style: none; } - + div.warning { background: #fbe3e4 url(dialog-warning.png) no-repeat 10px 8px; border: 2px solid #fbc2c4; @@ -268,18 +268,18 @@ div.admonition-todo { border-left-style: none; padding: 10px 20px 10px 60px; } - + div.note p.admonition-title, div.warning p.admonition-title, div.seealso p.admonition-title, div.admonition-todo p.admonition-title { display: none; } - + p.admonition-title:after { content: ":"; } - + pre { padding: 10px; line-height: 1.2em; @@ -289,7 +289,7 @@ pre { border-right-style: none; border-left-style: none; } - + code { background-color: transparent; color: #222; diff --git a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t index f9961ae36..8eca63278 100644 --- a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +++ b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t @@ -138,7 +138,7 @@ div.footer a { /* -- body styles ----------------------------------------------------------- */ -p { +p { margin: 0.8em 0 0.5em 0; } diff --git a/tests/roots/test-circular/conf.py b/tests/roots/test-circular/conf.py index 027d21cda..a45d22e28 100644 --- a/tests/roots/test-circular/conf.py +++ b/tests/roots/test-circular/conf.py @@ -1 +1 @@ -exclude_patterns = ['_build'] +exclude_patterns = ['_build'] diff --git a/tests/roots/test-intl/xx/LC_MESSAGES/toctree.po b/tests/roots/test-intl/xx/LC_MESSAGES/toctree.po index 8ca1dc52c..62cccdfc1 100644 --- a/tests/roots/test-intl/xx/LC_MESSAGES/toctree.po +++ b/tests/roots/test-intl/xx/LC_MESSAGES/toctree.po @@ -1,5 +1,5 @@ # SOME DESCRIPTIVE TITLE. -# Copyright (C) +# Copyright (C) # This file is distributed under the same license as the Sphinx intl package. # FIRST AUTHOR , YEAR. # diff --git a/tests/roots/test-numbered-circular/conf.py b/tests/roots/test-numbered-circular/conf.py index 027d21cda..a45d22e28 100644 --- a/tests/roots/test-numbered-circular/conf.py +++ b/tests/roots/test-numbered-circular/conf.py @@ -1 +1 @@ -exclude_patterns = ['_build'] +exclude_patterns = ['_build'] diff --git a/tests/roots/test-theming/MANIFEST.in b/tests/roots/test-theming/MANIFEST.in index 0e977e756..0ace41cb7 100644 --- a/tests/roots/test-theming/MANIFEST.in +++ b/tests/roots/test-theming/MANIFEST.in @@ -1,2 +1,2 @@ -recursive-include test_theme *.conf - +recursive-include test_theme *.conf + diff --git a/tests/roots/test-theming/conf.py b/tests/roots/test-theming/conf.py index 062b9cf83..0db7cf035 100644 --- a/tests/roots/test-theming/conf.py +++ b/tests/roots/test-theming/conf.py @@ -1,3 +1,3 @@ -html_theme = 'test-theme' -html_theme_path = ['.', 'test_theme'] -exclude_patterns = ['_build'] +html_theme = 'test-theme' +html_theme_path = ['.', 'test_theme'] +exclude_patterns = ['_build'] diff --git a/tests/roots/test-theming/index.rst b/tests/roots/test-theming/index.rst index 18a9a4e2f..214dcd7eb 100644 --- a/tests/roots/test-theming/index.rst +++ b/tests/roots/test-theming/index.rst @@ -1,5 +1,5 @@ -======= -Theming -======= - - +======= +Theming +======= + + diff --git a/tests/roots/test-theming/setup.py b/tests/roots/test-theming/setup.py index e62007f36..02ee259c0 100644 --- a/tests/roots/test-theming/setup.py +++ b/tests/roots/test-theming/setup.py @@ -1,11 +1,11 @@ -from setuptools import setup, find_packages - -setup( - name='test-theme', - packages=find_packages(), - include_package_data=True, - entry_points=""" - [sphinx_themes] - path = test_theme:get_path - """, -) +from setuptools import setup, find_packages + +setup( + name='test-theme', + packages=find_packages(), + include_package_data=True, + entry_points=""" + [sphinx_themes] + path = test_theme:get_path + """, +) diff --git a/tests/roots/test-theming/test_theme/__init__.py b/tests/roots/test-theming/test_theme/__init__.py index 398408c5d..13bdc4b2c 100644 --- a/tests/roots/test-theming/test_theme/__init__.py +++ b/tests/roots/test-theming/test_theme/__init__.py @@ -1,5 +1,5 @@ -import os - - -def get_path(): - return os.path.dirname(os.path.abspath(__file__)) +import os + + +def get_path(): + return os.path.dirname(os.path.abspath(__file__)) diff --git a/tests/test_pycode.py b/tests/test_pycode.py index 458e813f6..20f01f17d 100644 --- a/tests/test_pycode.py +++ b/tests/test_pycode.py @@ -26,7 +26,7 @@ def test_ModuleAnalyzer_get_module_source(): ModuleAnalyzer.get_module_source('builtins') with pytest.raises(PycodeError): ModuleAnalyzer.get_module_source('itertools') - + def test_ModuleAnalyzer_for_string(): analyzer = ModuleAnalyzer.for_string('print("Hello world")', 'module_name') From 5ea8ee133dfac71e58d1d6fb8f6b38a7ba249a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Sat, 3 Oct 2020 12:59:47 +0200 Subject: [PATCH 066/124] Fix #8268: make linkcheck report HTTP errors --- CHANGES | 1 + sphinx/builders/linkcheck.py | 1 + .../roots/test-linkcheck-localserver/conf.py | 2 ++ .../test-linkcheck-localserver/index.rst | 1 + tests/test_build_linkcheck.py | 36 +++++++++++++++++++ 5 files changed, 41 insertions(+) create mode 100644 tests/roots/test-linkcheck-localserver/conf.py create mode 100644 tests/roots/test-linkcheck-localserver/index.rst diff --git a/CHANGES b/CHANGES index 22876d43b..7013a6d01 100644 --- a/CHANGES +++ b/CHANGES @@ -41,6 +41,7 @@ Bugs fixed * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) * #8239: Failed to refer a token in productionlist if it is indented +* #8268: linkcheck: Report HTTP errors when ``linkcheck_anchors`` is ``True`` Testing -------- diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index 9b54afc7c..1083e82ec 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -166,6 +166,7 @@ class CheckExternalLinksBuilder(Builder): # Read the whole document and see if #anchor exists response = requests.get(req_url, stream=True, config=self.app.config, auth=auth_info, **kwargs) + response.raise_for_status() found = check_anchor(response, unquote(anchor)) if not found: diff --git a/tests/roots/test-linkcheck-localserver/conf.py b/tests/roots/test-linkcheck-localserver/conf.py new file mode 100644 index 000000000..2ba1f85e8 --- /dev/null +++ b/tests/roots/test-linkcheck-localserver/conf.py @@ -0,0 +1,2 @@ +exclude_patterns = ['_build'] +linkcheck_anchors = True diff --git a/tests/roots/test-linkcheck-localserver/index.rst b/tests/roots/test-linkcheck-localserver/index.rst new file mode 100644 index 000000000..807fe964b --- /dev/null +++ b/tests/roots/test-linkcheck-localserver/index.rst @@ -0,0 +1 @@ +`local server `_ diff --git a/tests/test_build_linkcheck.py b/tests/test_build_linkcheck.py index 7d85f10c5..a78587668 100644 --- a/tests/test_build_linkcheck.py +++ b/tests/test_build_linkcheck.py @@ -8,8 +8,10 @@ :license: BSD, see LICENSE for details. """ +import http.server import json import re +import threading from unittest import mock import pytest @@ -106,6 +108,21 @@ def test_anchors_ignored(app, status, warning): # expect all ok when excluding #top assert not content +@pytest.mark.sphinx('linkcheck', testroot='linkcheck-localserver', freshenv=True) +def test_raises_for_invalid_status(app, status, warning): + server_thread = HttpServerThread(InternalServerErrorHandler, daemon=True) + server_thread.start() + try: + app.builder.build_all() + finally: + server_thread.terminate() + content = (app.outdir / 'output.txt').read_text() + assert content == ( + "index.rst:1: [broken] http://localhost:7777/#anchor: " + "500 Server Error: Internal Server Error " + "for url: http://localhost:7777/\n" + ) + @pytest.mark.sphinx( 'linkcheck', testroot='linkcheck', freshenv=True, @@ -160,3 +177,22 @@ def test_linkcheck_request_headers(app, status, warning): assert headers["X-Secret"] == "open sesami" else: assert headers["Accept"] == "text/html,application/xhtml+xml;q=0.9,*/*;q=0.8" + + +class HttpServerThread(threading.Thread): + def __init__(self, handler, *args, **kwargs): + super().__init__(*args, **kwargs) + self.server = http.server.HTTPServer(("localhost", 7777), handler) + + def run(self): + self.server.serve_forever(poll_interval=0.01) + + def terminate(self): + self.server.shutdown() + self.server.server_close() + self.join() + + +class InternalServerErrorHandler(http.server.BaseHTTPRequestHandler): + def do_GET(self): + self.send_error(500, "Internal Server Error") From 6f5d45ffff68c2c1892f1a29af0ea1bd5e4e4796 Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Sat, 3 Oct 2020 15:20:41 +0200 Subject: [PATCH 067/124] C++, improve warning and debug messages --- sphinx/domains/cpp.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 7b10f8166..e5a6201e5 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -4107,7 +4107,7 @@ class Symbol: Symbol.debug_print("self:") print(self.to_string(Symbol.debug_indent + 1), end="") Symbol.debug_print("nestedName: ", nestedName) - Symbol.debug_print("templateDecls: ", templateDecls) + Symbol.debug_print("templateDecls: ", ",".join(str(t) for t in templateDecls)) Symbol.debug_print("strictTemplateParamArgLists:", strictTemplateParamArgLists) Symbol.debug_print("ancestorLookupType:", ancestorLookupType) Symbol.debug_print("templateShorthand: ", templateShorthand) @@ -4231,7 +4231,7 @@ class Symbol: Symbol.debug_indent += 1 Symbol.debug_print("_add_symbols:") Symbol.debug_indent += 1 - Symbol.debug_print("tdecls:", templateDecls) + Symbol.debug_print("tdecls:", ",".join(str(t) for t in templateDecls)) Symbol.debug_print("nn: ", nestedName) Symbol.debug_print("decl: ", declaration) Symbol.debug_print("doc: ", docname) @@ -4370,7 +4370,11 @@ class Symbol: # if there is an empty symbol, fill that one if len(noDecl) == 0: if Symbol.debug_lookup: - Symbol.debug_print("no match, no empty, candSybmol is not None?:", candSymbol is not None) # NOQA + Symbol.debug_print("no match, no empty") + if candSymbol is not None: + Symbol.debug_print("result is already created candSymbol") + else: + Symbol.debug_print("result is makeCandSymbol()") Symbol.debug_indent -= 2 if candSymbol is not None: return candSymbol @@ -6814,10 +6818,12 @@ class CPPObject(ObjectDescription): parentSymbol = env.temp_data['cpp:parent_symbol'] parentDecl = parentSymbol.declaration if parentDecl is not None and parentDecl.objectType == 'function': - logger.warning("C++ declarations inside functions are not supported." + - " Parent function is " + - str(parentSymbol.get_full_nested_name()), - location=self.get_source_info()) + msg = "C++ declarations inside functions are not supported." \ + " Parent function: {}\nDirective name: {}\nDirective arg: {}" + logger.warning(msg.format( + str(parentSymbol.get_full_nested_name()), + self.name, self.arguments[0] + ), location=self.get_source_info()) name = _make_phony_error_name() symbol = parentSymbol.add_name(name) env.temp_data['cpp:last_symbol'] = symbol From 178c05b0597e144fdc2117c7b46ac15723a290e8 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 3 Oct 2020 22:26:32 +0900 Subject: [PATCH 068/124] Close #7996: manpage: Add man_make_section_directory Add a new config variable; man_make_section_directory to make a section directory on build man page. During 3.x, it defaults to False and will be changed to True on 4.0 release. --- CHANGES | 2 ++ doc/usage/configuration.rst | 6 ++++++ sphinx/builders/manpage.py | 10 ++++++++-- tests/test_build_manpage.py | 7 +++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index df70ab46e..c5791a368 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,8 @@ Features added nested declarations. * #8081: LaTeX: Allow to add LaTeX package via ``app.add_latex_package()`` until just before writing .tex file +* #7996: manpage: Add :confval:`man_make_section_directory` to make a section + directory on build man page Bugs fixed ---------- diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 3fc3a5306..270fcbf33 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -2245,6 +2245,12 @@ These options influence manual page output. .. versionadded:: 1.1 +.. confval:: man_make_section_directory + + If true, make a section directory on build man page. Default is False. + + .. versionadded:: 3.3 + .. _texinfo-options: diff --git a/sphinx/builders/manpage.py b/sphinx/builders/manpage.py index 4166dece9..2a10ba62f 100644 --- a/sphinx/builders/manpage.py +++ b/sphinx/builders/manpage.py @@ -24,7 +24,7 @@ from sphinx.util import logging from sphinx.util import progress_message from sphinx.util.console import darkgreen # type: ignore from sphinx.util.nodes import inline_all_toctrees -from sphinx.util.osutil import make_filename_from_project +from sphinx.util.osutil import ensuredir, make_filename_from_project from sphinx.writers.manpage import ManualPageWriter, ManualPageTranslator @@ -80,7 +80,12 @@ class ManualPageBuilder(Builder): docsettings.authors = authors docsettings.section = section - targetname = '%s.%s' % (name, section) + if self.config.man_make_section_directory: + ensuredir(path.join(self.outdir, str(section))) + targetname = '%s/%s.%s' % (section, name, section) + else: + targetname = '%s.%s' % (name, section) + logger.info(darkgreen(targetname) + ' { ', nonl=True) destination = FileOutput( destination_path=path.join(self.outdir, targetname), @@ -115,6 +120,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value('man_pages', default_man_pages, None) app.add_config_value('man_show_urls', False, None) + app.add_config_value('man_make_section_directory', False, None) return { 'version': 'builtin', diff --git a/tests/test_build_manpage.py b/tests/test_build_manpage.py index c3c41a2ae..d4b1a320e 100644 --- a/tests/test_build_manpage.py +++ b/tests/test_build_manpage.py @@ -30,6 +30,13 @@ def test_all(app, status, warning): assert 'Footnotes' not in content +@pytest.mark.sphinx('man', testroot='basic', + confoverrides={'man_make_section_directory': True}) +def test_man_make_section_directory(app, status, warning): + app.build() + assert (app.outdir / '1' / 'python.1').exists() + + @pytest.mark.sphinx('man', testroot='directive-code') def test_captioned_code_block(app, status, warning): app.builder.build_all() From a555e3db8a2e38dc7f79c3dd8ac6cd406f70c9e1 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 12 Sep 2020 21:15:20 +0900 Subject: [PATCH 069/124] Fix #8200: autodoc: type aliases break type formatting The annotation option is shared between auto directives unexpectedly. It causes supression of type annotations for objects after GenericAlias definition. --- CHANGES | 1 + sphinx/ext/autodoc/__init__.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index df70ab46e..5637f66d6 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,7 @@ Bugs fixed by string not ending with blank lines * #8142: autodoc: Wrong constructor signature for the class derived from typing.Generic +* #8200: autodoc: type aliases break type formatting of autoattribute * #8192: napoleon: description is disappeared when it contains inline literals * #8142: napoleon: Potential of regex denial of service in google style docs * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index d7c5d2242..83c44c8df 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -1731,7 +1731,8 @@ class GenericAliasDocumenter(DataDocumenter): return inspect.isgenericalias(member) def add_directive_header(self, sig: str) -> None: - self.options.annotation = SUPPRESS # type: ignore + self.options = Options(self.options) + self.options['annotation'] = SUPPRESS super().add_directive_header(sig) def add_content(self, more_content: Any, no_docstring: bool = False) -> None: @@ -1755,7 +1756,8 @@ class TypeVarDocumenter(DataDocumenter): return isinstance(member, TypeVar) and isattr # type: ignore def add_directive_header(self, sig: str) -> None: - self.options.annotation = SUPPRESS # type: ignore + self.options = Options(self.options) + self.options['annotation'] = SUPPRESS super().add_directive_header(sig) def get_doc(self, encoding: str = None, ignore: int = None) -> List[List[str]]: From 777bcb43fa26aeaf34329c56cb1e316da0a1d9e6 Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Sat, 3 Oct 2020 16:00:28 +0200 Subject: [PATCH 070/124] C++, properly reject functions as duplicates Fixes sphinx-doc/sphinx#8270 --- CHANGES | 2 ++ sphinx/domains/cpp.py | 5 +++++ tests/test_domain_cpp.py | 15 +++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/CHANGES b/CHANGES index 564eb799a..93cc5fb8c 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,8 @@ Bugs fixed * #8188: C, add missing items to internal object types dictionary, e.g., preventing intersphinx from resolving them. * C, fix anon objects in intersphinx. +* #8270, C++, properly reject functions as duplicate declarations if a + non-function declaration of the same name already exists. Testing diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index e5a6201e5..c43c55d5b 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -4360,6 +4360,11 @@ class Symbol: if Symbol.debug_lookup: Symbol.debug_print("candId:", candId) for symbol in withDecl: + # but all existing must be functions as well, + # otherwise we declare it to be a duplicate + if symbol.declaration.objectType != 'function': + handleDuplicateDeclaration(symbol, candSymbol) + # (not reachable) oldId = symbol.declaration.get_newest_id() if Symbol.debug_lookup: Symbol.debug_print("oldId: ", oldId) diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py index 558d69911..ec7a2b262 100644 --- a/tests/test_domain_cpp.py +++ b/tests/test_domain_cpp.py @@ -1236,3 +1236,18 @@ def test_noindexentry(app): assert_node(doctree, (addnodes.index, desc, addnodes.index, desc)) assert_node(doctree[0], addnodes.index, entries=[('single', 'f (C++ function)', '_CPPv41fv', '', None)]) assert_node(doctree[2], addnodes.index, entries=[]) + + +def test_mix_decl_duplicate(app, warning): + # Issue 8270 + text = (".. cpp:struct:: A\n" + ".. cpp:function:: void A()\n" + ".. cpp:struct:: A\n") + restructuredtext.parse(app, text) + ws = warning.getvalue().split("\n") + assert len(ws) == 5 + assert "index.rst:2: WARNING: Duplicate C++ declaration, also defined in 'index'." in ws[0] + assert "Declaration is 'void A()'." in ws[1] + assert "index.rst:3: WARNING: Duplicate C++ declaration, also defined in 'index'." in ws[2] + assert "Declaration is 'A'." in ws[3] + assert ws[4] == "" \ No newline at end of file From f0f90a5ce2bcd171f93720333eefa3e3c2bd9332 Mon Sep 17 00:00:00 2001 From: shimizukawa Date: Sun, 4 Oct 2020 06:24:04 +0900 Subject: [PATCH 071/124] Fix: missing and redundant spacing (and etc) for console output on building. Before this fixing: ``` generating indices... genindexdone writing additional pages... searchdone copying static files... ... done ``` After this fixing: ``` generating indices... genindex done writing additional pages... search done copying static files... done ``` This tiny trouble has been introduced at #6538 (sphinx-2.0.0 Mar 29, 2019) --- sphinx/builders/html/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py index c30aa9cfd..beb650991 100644 --- a/sphinx/builders/html/__init__.py +++ b/sphinx/builders/html/__init__.py @@ -641,17 +641,17 @@ class StandaloneHTMLBuilder(Builder): def gen_additional_pages(self) -> None: # additional pages from conf.py for pagename, template in self.config.html_additional_pages.items(): - logger.info(' ' + pagename, nonl=True) + logger.info(pagename + ' ', nonl=True) self.handle_page(pagename, {}, template) # the search page if self.search: - logger.info(' search', nonl=True) + logger.info('search ', nonl=True) self.handle_page('search', {}, 'search.html') # the opensearch xml file if self.config.html_use_opensearch and self.search: - logger.info(' opensearch', nonl=True) + logger.info('opensearch ', nonl=True) fn = path.join(self.outdir, '_static', 'opensearch.xml') self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn) @@ -669,7 +669,7 @@ class StandaloneHTMLBuilder(Builder): 'genindexcounts': indexcounts, 'split_index': self.config.html_split_index, } - logger.info(' genindex', nonl=True) + logger.info('genindex ', nonl=True) if self.config.html_split_index: self.handle_page('genindex', genindexcontext, @@ -691,7 +691,7 @@ class StandaloneHTMLBuilder(Builder): 'content': content, 'collapse_index': collapse, } - logger.info(' ' + indexname, nonl=True) + logger.info(indexname + ' ', nonl=True) self.handle_page(indexname, indexcontext, 'domainindex.html') def copy_image_files(self) -> None: @@ -785,7 +785,7 @@ class StandaloneHTMLBuilder(Builder): def copy_static_files(self) -> None: try: - with progress_message(__('copying static files... ')): + with progress_message(__('copying static files')): ensuredir(path.join(self.outdir, '_static')) # prepare context for templates From d1f8dddeff742ca09dca6ab829410248b919a5c5 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 4 Oct 2020 10:15:38 +0900 Subject: [PATCH 072/124] Update CHANGES for PR #8277 --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index df70ab46e..b82c2e948 100644 --- a/CHANGES +++ b/CHANGES @@ -38,6 +38,8 @@ Bugs fixed * #8142: napoleon: Potential of regex denial of service in google style docs * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex * #8175: intersphinx: Potential of regex denial of service by broken inventory +* #8277: sphinx-build: missing and redundant spacing (and etc) for console + output on building * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) * #8239: Failed to refer a token in productionlist if it is indented From 9a0a0f9ae15d717a5503fc3883159ae6c4210254 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 3 Oct 2020 02:01:12 +0900 Subject: [PATCH 073/124] Fix #8157: autodoc: TypeError is raised when annotation has invalid __args__ Typically, the __args__ attribute of type annotations is a tuple containing arguments for the types (ex. The __args__ of `List[int]` is `(int,)`). But some kind of types has non tuple __args__ attribute. For example, `nptyping.NDArray` is one of them. This fixes the TypeError when the invalid __args__ attribute found. --- CHANGES | 1 + sphinx/util/typing.py | 5 ++++- tests/test_util_typing.py | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index b82c2e948..e30d42e43 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,7 @@ Bugs fixed by string not ending with blank lines * #8142: autodoc: Wrong constructor signature for the class derived from typing.Generic +* #8157: autodoc: TypeError is raised when annotation has invalid __args__ * #8192: napoleon: description is disappeared when it contains inline literals * #8142: napoleon: Potential of regex denial of service in google style docs * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py index 4dac3b695..8eca67220 100644 --- a/sphinx/util/typing.py +++ b/sphinx/util/typing.py @@ -109,7 +109,10 @@ def _stringify_py37(annotation: Any) -> str: return repr(annotation) if getattr(annotation, '__args__', None): - if qualname == 'Union': + if not isinstance(annotation.__args__, (list, tuple)): + # broken __args__ found + pass + elif qualname == 'Union': if len(annotation.__args__) > 1 and annotation.__args__[-1] is NoneType: if len(annotation.__args__) > 2: args = ', '.join(stringify(a) for a in annotation.__args__[:-1]) diff --git a/tests/test_util_typing.py b/tests/test_util_typing.py index 932fdbfc0..3f8ddbb37 100644 --- a/tests/test_util_typing.py +++ b/tests/test_util_typing.py @@ -32,6 +32,10 @@ class MyList(List[T]): pass +class BrokenType: + __args__ = int + + def test_stringify(): assert stringify(int) == "int" assert stringify(str) == "str" @@ -113,3 +117,7 @@ def test_stringify_type_hints_alias(): MyTuple = Tuple[str, str] assert stringify(MyStr) == "str" assert stringify(MyTuple) == "Tuple[str, str]" # type: ignore + + +def test_stringify_broken_type_hints(): + assert stringify(BrokenType) == 'test_util_typing.BrokenType' From 37235c71e04aff3b93ae98f12456a34666635a9d Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 14 Aug 2020 16:11:23 +0900 Subject: [PATCH 074/124] Fix #6640: i18n: Failed to override system message translation Our document describes that users can override system messages via their own message catalog named `sphinx.mo` under the locale_dirs. But it has not been used since its beginning of i18n mechanism because the priority of users' message catalog is lower than system's. This makes the priority of users' message catalog higher than system's. --- CHANGES | 1 + sphinx/application.py | 7 +++++-- sphinx/locale/__init__.py | 2 +- tests/test_intl.py | 29 +++++++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index e30d42e43..481ade0b8 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,7 @@ Bugs fixed ---------- * #8085: i18n: Add support for having single text domain +* #6640: i18n: Failed to override system message translation * #8143: autodoc: AttributeError is raised when False value is passed to autodoc_default_options * #8103: autodoc: functools.cached_property is not considered as a property diff --git a/sphinx/application.py b/sphinx/application.py index 385b74d8a..f91027bf7 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -18,7 +18,7 @@ import warnings from collections import deque from io import StringIO from os import path -from typing import Any, Callable, Dict, IO, List, Tuple, Union +from typing import Any, Callable, Dict, IO, List, Optional, Tuple, Union from docutils import nodes from docutils.nodes import Element, TextElement @@ -293,7 +293,10 @@ class Sphinx: if catalog.domain == 'sphinx' and catalog.is_outdated(): catalog.write_mo(self.config.language) - locale_dirs = [None, path.join(package_dir, 'locale')] + list(repo.locale_dirs) + locale_dirs = [None] # type: List[Optional[str]] + locale_dirs += list(repo.locale_dirs) + locale_dirs += [path.join(package_dir, 'locale')] + self.translator, has_translation = locale.init(locale_dirs, self.config.language) if has_translation or self.config.language == 'en': # "en" never needs to be translated diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py index 385ca3566..5210dc725 100644 --- a/sphinx/locale/__init__.py +++ b/sphinx/locale/__init__.py @@ -106,7 +106,7 @@ class _TranslationProxy(UserString): translators = defaultdict(NullTranslations) # type: Dict[Tuple[str, str], NullTranslations] -def init(locale_dirs: List[str], language: str, +def init(locale_dirs: List[Optional[str]], language: str, catalog: str = 'sphinx', namespace: str = 'general') -> Tuple[NullTranslations, bool]: """Look for message catalogs in `locale_dirs` and *ensure* that there is at least a NullTranslations catalog set in `translators`. If called multiple diff --git a/tests/test_intl.py b/tests/test_intl.py index 1d1282baa..c0b87d5ce 100644 --- a/tests/test_intl.py +++ b/tests/test_intl.py @@ -14,8 +14,10 @@ import re import pytest from babel.messages import pofile, mofile +from babel.messages.catalog import Catalog from docutils import nodes +from sphinx import locale from sphinx.testing.util import ( path, etree_parse, strip_escseq, assert_re_search, assert_not_re_search, assert_startswith, assert_node @@ -1289,3 +1291,30 @@ def test_image_glob_intl_using_figure_language_filename(app): def getwarning(warnings): return strip_escseq(warnings.getvalue().replace(os.sep, '/')) + + +@pytest.mark.sphinx('html', testroot='basic', confoverrides={'language': 'de'}) +def test_customize_system_message(make_app, app_params, sphinx_test_tempdir): + try: + # clear translators cache + locale.translators.clear() + + # prepare message catalog (.po) + locale_dir = sphinx_test_tempdir / 'basic' / 'locales' / 'de' / 'LC_MESSAGES' + locale_dir.makedirs() + with (locale_dir / 'sphinx.po').open('wb') as f: + catalog = Catalog() + catalog.add('Quick search', 'QUICK SEARCH') + pofile.write_po(f, catalog) + + # construct application and convert po file to .mo + args, kwargs = app_params + app = make_app(*args, **kwargs) + assert (locale_dir / 'sphinx.mo').exists() + assert app.translator.gettext('Quick search') == 'QUICK SEARCH' + + app.build() + content = (app.outdir / 'index.html').read_text() + assert 'QUICK SEARCH' in content + finally: + locale.translators.clear() From 2d37ba44193aac1f7082382ceb34e85078e64a32 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 3 Oct 2020 13:33:37 +0900 Subject: [PATCH 075/124] autodoc: deprecate SingledispatchFunctionDocumenter In #7487, SingledispatchFunctionDocumenter is merged into FunctionDocumenter. SingledispatchMethodDocumenter is also. As a result, They are no longer needed. So this deprecates them. --- CHANGES | 2 ++ doc/extdev/deprecated.rst | 10 ++++++++++ sphinx/ext/autodoc/__init__.py | 10 ++++++++++ 3 files changed, 22 insertions(+) diff --git a/CHANGES b/CHANGES index 4252376b0..a7f27ac4d 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,8 @@ Deprecated * ``sphinx.builders.latex.LaTeXBuilder.usepackages`` * ``sphinx.builders.latex.LaTeXBuilder.usepackages_afger_hyperref`` +* ``sphinx.ext.autodoc.SingledispatchFunctionDocumenter`` +* ``sphinx.ext.autodoc.SingledispatchMethodDocumenter`` Features added -------------- diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst index d7ad21fff..2bb8aebfd 100644 --- a/doc/extdev/deprecated.rst +++ b/doc/extdev/deprecated.rst @@ -36,6 +36,16 @@ The following is a list of deprecated interfaces. - 5.0 - N/A + * - ``sphinx.ext.autodoc.SingledispatchFunctionDocumenter`` + - 3.3 + - 5.0 + - ``sphinx.ext.autodoc.FunctionDocumenter`` + + * - ``sphinx.ext.autodoc.SingledispatchMethodDocumenter`` + - 3.3 + - 5.0 + - ``sphinx.ext.autodoc.MethodDocumenter`` + * - ``sphinx.ext.autodoc.members_set_option()`` - 3.2 - 5.0 diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index d7c5d2242..6eff27102 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -1302,6 +1302,11 @@ class SingledispatchFunctionDocumenter(FunctionDocumenter): Retained for backwards compatibility, now does the same as the FunctionDocumenter """ + def __init__(self, *args: Any, **kwargs: Any) -> None: + warnings.warn("%s is deprecated." % self.__class__.__name__, + RemovedInSphinx50Warning, stacklevel=2) + super().__init__(*args, **kwargs) + class DecoratorDocumenter(FunctionDocumenter): """ @@ -1936,6 +1941,11 @@ class SingledispatchMethodDocumenter(MethodDocumenter): Retained for backwards compatibility, now does the same as the MethodDocumenter """ + def __init__(self, *args: Any, **kwargs: Any) -> None: + warnings.warn("%s is deprecated." % self.__class__.__name__, + RemovedInSphinx50Warning, stacklevel=2) + super().__init__(*args, **kwargs) + class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): # type: ignore """ From 7f7a207626cfa62871fb315c70e88ea690f85250 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 4 Oct 2020 14:13:03 +0900 Subject: [PATCH 076/124] docs: Add documentation for "override" flag of app API --- sphinx/application.py | 51 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/sphinx/application.py b/sphinx/application.py index f91027bf7..daab09058 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -471,8 +471,10 @@ class Sphinx: def add_builder(self, builder: "Type[Builder]", override: bool = False) -> None: """Register a new builder. - *builder* must be a class that inherits from - :class:`~sphinx.builders.Builder`. + *builder* must be a class that inherits from :class:`~sphinx.builders.Builder`. + + If *override* is True, the given *builder* is forcedly installed even if + a builder having the same name is already installed. .. versionchanged:: 1.8 Add *override* keyword. @@ -529,6 +531,9 @@ class Sphinx: builtin translator. This allows extensions to use custom translator and define custom nodes for the translator (see :meth:`add_node`). + If *override* is True, the given *translator_class* is forcedly installed even if + a translator for *name* is already installed. + .. versionadded:: 1.3 .. versionchanged:: 1.8 Add *override* keyword. @@ -563,6 +568,9 @@ class Sphinx: Obviously, translators for which you don't specify visitor methods will choke on the node when encountered in a document to translate. + If *override* is True, the given *node* is forcedly installed even if + a node having the same name is already installed. + .. versionchanged:: 0.5 Added the support for keyword arguments giving visit functions. """ @@ -598,6 +606,9 @@ class Sphinx: Other keyword arguments are used for node visitor functions. See the :meth:`.Sphinx.add_node` for details. + If *override* is True, the given *node* is forcedly installed even if + a node having the same name is already installed. + .. versionadded:: 1.4 """ self.registry.add_enumerable_node(node, figtype, title_getter, override=override) @@ -633,6 +644,9 @@ class Sphinx: add_directive('literalinclude', LiteralIncludeDirective) + If *override* is True, the given *cls* is forcedly installed even if + a directive named as *name* is already installed. + .. versionchanged:: 0.6 Docutils 0.5-style directive classes are now supported. .. deprecated:: 1.8 @@ -655,6 +669,9 @@ class Sphinx: `_ for more information. + If *override* is True, the given *role* is forcedly installed even if + a role named as *name* is already installed. + .. versionchanged:: 1.8 Add *override* keyword. """ @@ -670,6 +687,9 @@ class Sphinx: Register a Docutils role that does nothing but wrap its contents in the node given by *nodeclass*. + If *override* is True, the given *nodeclass* is forcedly installed even if + a role named as *name* is already installed. + .. versionadded:: 0.6 .. versionchanged:: 1.8 Add *override* keyword. @@ -689,6 +709,9 @@ class Sphinx: Make the given *domain* (which must be a class; more precisely, a subclass of :class:`~sphinx.domains.Domain`) known to Sphinx. + If *override* is True, the given *domain* is forcedly installed even if + a domain having the same name is already installed. + .. versionadded:: 1.0 .. versionchanged:: 1.8 Add *override* keyword. @@ -702,6 +725,9 @@ class Sphinx: Like :meth:`add_directive`, but the directive is added to the domain named *domain*. + If *override* is True, the given *directive* is forcedly installed even if + a directive named as *name* is already installed. + .. versionadded:: 1.0 .. versionchanged:: 1.8 Add *override* keyword. @@ -715,6 +741,9 @@ class Sphinx: Like :meth:`add_role`, but the role is added to the domain named *domain*. + If *override* is True, the given *role* is forcedly installed even if + a role named as *name* is already installed. + .. versionadded:: 1.0 .. versionchanged:: 1.8 Add *override* keyword. @@ -728,6 +757,9 @@ class Sphinx: Add a custom *index* class to the domain named *domain*. *index* must be a subclass of :class:`~sphinx.domains.Index`. + If *override* is True, the given *index* is forcedly installed even if + an index having the same name is already installed. + .. versionadded:: 1.0 .. versionchanged:: 1.8 Add *override* keyword. @@ -791,6 +823,9 @@ class Sphinx: For the role content, you have the same syntactical possibilities as for standard Sphinx roles (see :ref:`xref-syntax`). + If *override* is True, the given object_type is forcedly installed even if + an object_type having the same name is already installed. + .. versionchanged:: 1.8 Add *override* keyword. """ @@ -827,6 +862,9 @@ class Sphinx: (Of course, the element following the ``topic`` directive needn't be a section.) + If *override* is True, the given crossref_type is forcedly installed even if + a crossref_type having the same name is already installed. + .. versionchanged:: 1.8 Add *override* keyword. """ @@ -1022,6 +1060,9 @@ class Sphinx: new types of objects. See the source of the autodoc module for examples on how to subclass :class:`Documenter`. + If *override* is True, the given *cls* is forcedly installed even if + a documenter having the same name is already installed. + .. todo:: Add real docs for Documenter and subclassing .. versionadded:: 0.6 @@ -1070,6 +1111,9 @@ class Sphinx: Same as :confval:`source_suffix`. The users can override this using the setting. + If *override* is True, the given *suffix* is forcedly installed even if + a same suffix is already installed. + .. versionadded:: 1.8 """ self.registry.add_source_suffix(suffix, filetype, override=override) @@ -1077,6 +1121,9 @@ class Sphinx: def add_source_parser(self, *args: Any, **kwargs: Any) -> None: """Register a parser class. + If *override* is True, the given *parser* is forcedly installed even if + a parser for the same suffix is already installed. + .. versionadded:: 1.4 .. versionchanged:: 1.8 *suffix* argument is deprecated. It only accepts *parser* argument. From 129e09c6e3c591e1376c164672220ced3f3cee12 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 4 Oct 2020 14:15:41 +0900 Subject: [PATCH 077/124] refactor: Change signature of app.add_source_parser() To make compatible with old versions, app.add_source_parser() have taken two types of arguments. But the compatibility was no longer needed since 3.0. So it would be better to use clearer signature. --- sphinx/application.py | 5 +++-- sphinx/registry.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sphinx/application.py b/sphinx/application.py index f91027bf7..1c433107e 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -22,6 +22,7 @@ from typing import Any, Callable, Dict, IO, List, Optional, Tuple, Union from docutils import nodes from docutils.nodes import Element, TextElement +from docutils.parsers import Parser from docutils.parsers.rst import Directive, roles from docutils.transforms import Transform from pygments.lexer import Lexer @@ -1074,7 +1075,7 @@ class Sphinx: """ self.registry.add_source_suffix(suffix, filetype, override=override) - def add_source_parser(self, *args: Any, **kwargs: Any) -> None: + def add_source_parser(self, parser: "Type[Parser]", override: bool = False) -> None: """Register a parser class. .. versionadded:: 1.4 @@ -1084,7 +1085,7 @@ class Sphinx: .. versionchanged:: 1.8 Add *override* keyword. """ - self.registry.add_source_parser(*args, **kwargs) + self.registry.add_source_parser(parser, override=override) def add_env_collector(self, collector: "Type[EnvironmentCollector]") -> None: """Register an environment collector class. diff --git a/sphinx/registry.py b/sphinx/registry.py index 8c468796a..d0c00b85f 100644 --- a/sphinx/registry.py +++ b/sphinx/registry.py @@ -259,12 +259,12 @@ class SphinxComponentRegistry: else: self.source_suffix[suffix] = filetype - def add_source_parser(self, parser: "Type[Parser]", **kwargs: Any) -> None: + def add_source_parser(self, parser: "Type[Parser]", override: bool = False) -> None: logger.debug('[app] adding search source_parser: %r', parser) # create a map from filetype to parser for filetype in parser.supported: - if filetype in self.source_parsers and not kwargs.get('override'): + if filetype in self.source_parsers and not override: raise ExtensionError(__('source_parser for %r is already registered') % filetype) else: From 7b395f6b25ce1fa78480508a1de4be2510fd2189 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 4 Oct 2020 14:22:02 +0900 Subject: [PATCH 078/124] docs: Fix an example for add_directive() --- sphinx/application.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sphinx/application.py b/sphinx/application.py index f91027bf7..d06986764 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -611,14 +611,14 @@ class Sphinx: details, see `the Docutils docs `_ . - For example, the (already existing) :rst:dir:`literalinclude` directive - would be added like this: + For example, a custom directive named ``my-directive`` would be added + like this: .. code-block:: python from docutils.parsers.rst import Directive, directives - class LiteralIncludeDirective(Directive): + class MyDirective(Directive): has_content = True required_arguments = 1 optional_arguments = 0 @@ -631,7 +631,8 @@ class Sphinx: def run(self): ... - add_directive('literalinclude', LiteralIncludeDirective) + def setup(app): + add_directive('my-directive', MyDirective) .. versionchanged:: 0.6 Docutils 0.5-style directive classes are now supported. From 66dda1fc50249e9da62e79380251d8795b8e36df Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 8 Aug 2020 21:20:55 +0900 Subject: [PATCH 079/124] Fix #6914: figure numbers are unexpectedly assigned to uncaptioned items The figure numbers should be assigned to items only having captions or titles. This uses `get_numfig_title()` to ensures it on assign numbers. --- CHANGES | 1 + sphinx/environment/collectors/toctree.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index 4252376b0..11b758399 100644 --- a/CHANGES +++ b/CHANGES @@ -47,6 +47,7 @@ Bugs fixed singlehtml and so on) * #8239: Failed to refer a token in productionlist if it is indented * #8268: linkcheck: Report HTTP errors when ``linkcheck_anchors`` is ``True`` +* #6914: figure numbers are unexpectedly assigned to uncaptioned items Testing -------- diff --git a/sphinx/environment/collectors/toctree.py b/sphinx/environment/collectors/toctree.py index e168bd9c4..d6cdc8354 100644 --- a/sphinx/environment/collectors/toctree.py +++ b/sphinx/environment/collectors/toctree.py @@ -224,6 +224,10 @@ class TocTreeCollector(EnvironmentCollector): def get_figtype(node: Node) -> str: for domain in env.domains.values(): figtype = domain.get_enumerable_node_type(node) + if domain.name == 'std' and not domain.get_numfig_title(node): # type: ignore + # Skip if uncaptioned node + continue + if figtype: return figtype From 6b3d4458796d3ed2f536c09b60c2573a276db417 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Sun, 4 Oct 2020 10:02:57 +0200 Subject: [PATCH 080/124] Pass docname instead of srcdir --- sphinx/builders/linkcheck.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index 4ea98f1d3..c632220db 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -210,7 +210,7 @@ class CheckExternalLinksBuilder(Builder): else: return 'redirected', new_url, 0 - def check(srcdir: str) -> Tuple[str, str, int]: + def check(docname: str) -> Tuple[str, str, int]: # check for various conditions without bothering the network if len(uri) == 0 or uri.startswith(('#', 'mailto:')): return 'unchecked', '', 0 @@ -219,6 +219,7 @@ class CheckExternalLinksBuilder(Builder): # non supported URI schemes (ex. ftp) return 'unchecked', '', 0 else: + srcdir = path.dirname(self.env.doc2path(docname)) if path.exists(path.join(srcdir, uri)): return 'working', '', 0 else: @@ -256,8 +257,7 @@ class CheckExternalLinksBuilder(Builder): uri, docname, lineno = self.wqueue.get() if uri is None: break - srcdir = path.dirname(self.env.doc2path(docname)) - status, info, code = check(srcdir) + status, info, code = check(docname) self.rqueue.put((uri, docname, lineno, status, info, code)) def process_result(self, result: Tuple[str, str, int, str, str, int]) -> None: From 45717977ac9e492f3090cbfa665bae883a8272e2 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 19 Jul 2020 00:50:36 +0900 Subject: [PATCH 081/124] Fix #7973: imgconverter: Check availability of imagemagick only once To prevent checking the availability of image converters times and times again, this stores the result to the class variable. It is not a good design to have a state globally. So this should be refactored in the future. --- CHANGES | 1 + sphinx/transforms/post_transforms/images.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index aea356897..c3b66b4d8 100644 --- a/CHANGES +++ b/CHANGES @@ -45,6 +45,7 @@ Bugs fixed * #8175: intersphinx: Potential of regex denial of service by broken inventory * #8277: sphinx-build: missing and redundant spacing (and etc) for console output on building +* #7973: imgconverter: Check availability of imagemagick many times * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) * #8239: Failed to refer a token in productionlist if it is indented diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py index f2cacac3c..949c09dde 100644 --- a/sphinx/transforms/post_transforms/images.py +++ b/sphinx/transforms/post_transforms/images.py @@ -11,7 +11,7 @@ import os import re from math import ceil -from typing import Any, Dict, List, Tuple +from typing import Any, Dict, List, Optional, Tuple from docutils import nodes @@ -175,6 +175,13 @@ class ImageConverter(BaseImageConverter): """ default_priority = 200 + #: The converter is available or not. Will be filled at the first call of + #: the build. The result is shared in the same process. + #: + #: .. todo:: This should be refactored not to store the state without class + #: variable. + available = None # type: Optional[bool] + #: A conversion rules the image converter supports. #: It is represented as a list of pair of source image format (mimetype) and #: destination one:: @@ -187,16 +194,14 @@ class ImageConverter(BaseImageConverter): conversion_rules = [] # type: List[Tuple[str, str]] def __init__(self, *args: Any, **kwargs: Any) -> None: - self.available = None # type: bool - # the converter is available or not. - # Will be checked at first conversion super().__init__(*args, **kwargs) def match(self, node: nodes.image) -> bool: if not self.app.builder.supported_image_types: return False elif self.available is None: - self.available = self.is_available() + # store the value to the class variable to share it during the build + self.__class__.available = self.is_available() if not self.available: return False From 941c9ba23d9498be80f0abe1930e2ceb9f4c7a16 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 4 Oct 2020 17:18:38 +0900 Subject: [PATCH 082/124] Update CHANGES for PR #8245 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index aea356897..eb6e05270 100644 --- a/CHANGES +++ b/CHANGES @@ -49,6 +49,7 @@ Bugs fixed singlehtml and so on) * #8239: Failed to refer a token in productionlist if it is indented * #8268: linkcheck: Report HTTP errors when ``linkcheck_anchors`` is ``True`` +* #8245: linkcheck: take source directory into account for local files * #6914: figure numbers are unexpectedly assigned to uncaptioned items Testing From 0b32e72635f6e117824b5cba3b8b38254a6a2644 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 4 Oct 2020 01:45:47 +0900 Subject: [PATCH 083/124] pycode: ast.unparse() construct number literals using source code Developers can write number literals in several ways. For example, decimal (1234), hexadecimal (0x1234), octal decimal (0o1234) and so on. But, AST module don't mind how the numbers written in the code. As a result, ast.unparse() could not reproduce the original form of number literals. This allows to construct number literals as possible using original source code. Note: This is only available in Python 3.8+. --- sphinx/pycode/ast.py | 11 +++++++++-- tests/test_pycode_ast.py | 14 +++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/sphinx/pycode/ast.py b/sphinx/pycode/ast.py index 2583448d5..17d78f4eb 100644 --- a/sphinx/pycode/ast.py +++ b/sphinx/pycode/ast.py @@ -58,17 +58,19 @@ def parse(code: str, mode: str = 'exec') -> "ast.AST": return ast.parse(code, mode=mode) -def unparse(node: Optional[ast.AST]) -> Optional[str]: +def unparse(node: Optional[ast.AST], code: str = '') -> Optional[str]: """Unparse an AST to string.""" if node is None: return None elif isinstance(node, str): return node - return _UnparseVisitor().visit(node) + return _UnparseVisitor(code).visit(node) # a greatly cut-down version of `ast._Unparser` class _UnparseVisitor(ast.NodeVisitor): + def __init__(self, code: str = '') -> None: + self.code = code def _visit_op(self, node: ast.AST) -> str: return OPERATORS[node.__class__] @@ -195,6 +197,11 @@ class _UnparseVisitor(ast.NodeVisitor): def visit_Constant(self, node: ast.Constant) -> str: if node.value is Ellipsis: return "..." + elif isinstance(node.value, (int, float, complex)): + if self.code and sys.version_info > (3, 8): + return ast.get_source_segment(self.code, node) + else: + return repr(node.value) else: return repr(node.value) diff --git a/tests/test_pycode_ast.py b/tests/test_pycode_ast.py index 32a784b74..bbff64dd0 100644 --- a/tests/test_pycode_ast.py +++ b/tests/test_pycode_ast.py @@ -58,7 +58,7 @@ from sphinx.pycode import ast ]) def test_unparse(source, expected): module = ast.parse(source) - assert ast.unparse(module.body[0].value) == expected + assert ast.unparse(module.body[0].value, source) == expected def test_unparse_None(): @@ -66,8 +66,12 @@ def test_unparse_None(): @pytest.mark.skipif(sys.version_info < (3, 8), reason='python 3.8+ is required.') -def test_unparse_py38(): - source = "lambda x=0, /, y=1, *args, z, **kwargs: x + y + z" - expected = "lambda x=0, /, y=1, *args, z, **kwargs: ..." +@pytest.mark.parametrize('source,expected', [ + ("lambda x=0, /, y=1, *args, z, **kwargs: x + y + z", + "lambda x=0, /, y=1, *args, z, **kwargs: ..."), # posonlyargs + ("0x1234", "0x1234"), # Constant + ("1_000_000", "1_000_000"), # Constant +]) +def test_unparse_py38(source, expected): module = ast.parse(source) - assert ast.unparse(module.body[0].value) == expected + assert ast.unparse(module.body[0].value, source) == expected From cc941db40b946534da8897a29631325d96313a6e Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 4 Oct 2020 10:31:02 +0900 Subject: [PATCH 084/124] Fix #8255: py domain: number in defarg is changed to decimal Number literals in default argument value is converted to decimal form unexpectedly by AST module. This fixes the signature parsing code to recosntruct it correctly. Note: This is only available in Python 3.8+. --- CHANGES | 2 ++ sphinx/util/inspect.py | 25 +++++++++++++------------ tests/test_domain_py.py | 13 +++++++++++++ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 600efc466..c907992dc 100644 --- a/CHANGES +++ b/CHANGES @@ -49,6 +49,8 @@ Bugs fixed * #8277: sphinx-build: missing and redundant spacing (and etc) for console output on building * #7973: imgconverter: Check availability of imagemagick many times +* #8255: py domain: number in default argument value is changed from hexadecimal + to decimal * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) * #8239: Failed to refer a token in productionlist if it is indented diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 378174993..f2cd8070b 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -600,13 +600,14 @@ def stringify_signature(sig: inspect.Signature, show_annotation: bool = True, def signature_from_str(signature: str) -> inspect.Signature: """Create a Signature object from string.""" - module = ast.parse('def func' + signature + ': pass') + code = 'def func' + signature + ': pass' + module = ast.parse(code) function = cast(ast.FunctionDef, module.body[0]) # type: ignore - return signature_from_ast(function) + return signature_from_ast(function, code) -def signature_from_ast(node: ast.FunctionDef) -> inspect.Signature: +def signature_from_ast(node: ast.FunctionDef, code: str = '') -> inspect.Signature: """Create a Signature object from AST *node*.""" args = node.args defaults = list(args.defaults) @@ -626,9 +627,9 @@ def signature_from_ast(node: ast.FunctionDef) -> inspect.Signature: if defaults[i] is Parameter.empty: default = Parameter.empty else: - default = ast_unparse(defaults[i]) + default = ast_unparse(defaults[i], code) - annotation = ast_unparse(arg.annotation) or Parameter.empty + annotation = ast_unparse(arg.annotation, code) or Parameter.empty params.append(Parameter(arg.arg, Parameter.POSITIONAL_ONLY, default=default, annotation=annotation)) @@ -636,29 +637,29 @@ def signature_from_ast(node: ast.FunctionDef) -> inspect.Signature: if defaults[i + posonlyargs] is Parameter.empty: default = Parameter.empty else: - default = ast_unparse(defaults[i + posonlyargs]) + default = ast_unparse(defaults[i + posonlyargs], code) - annotation = ast_unparse(arg.annotation) or Parameter.empty + annotation = ast_unparse(arg.annotation, code) or Parameter.empty params.append(Parameter(arg.arg, Parameter.POSITIONAL_OR_KEYWORD, default=default, annotation=annotation)) if args.vararg: - annotation = ast_unparse(args.vararg.annotation) or Parameter.empty + annotation = ast_unparse(args.vararg.annotation, code) or Parameter.empty params.append(Parameter(args.vararg.arg, Parameter.VAR_POSITIONAL, annotation=annotation)) for i, arg in enumerate(args.kwonlyargs): - default = ast_unparse(args.kw_defaults[i]) or Parameter.empty - annotation = ast_unparse(arg.annotation) or Parameter.empty + default = ast_unparse(args.kw_defaults[i], code) or Parameter.empty + annotation = ast_unparse(arg.annotation, code) or Parameter.empty params.append(Parameter(arg.arg, Parameter.KEYWORD_ONLY, default=default, annotation=annotation)) if args.kwarg: - annotation = ast_unparse(args.kwarg.annotation) or Parameter.empty + annotation = ast_unparse(args.kwarg.annotation, code) or Parameter.empty params.append(Parameter(args.kwarg.arg, Parameter.VAR_KEYWORD, annotation=annotation)) - return_annotation = ast_unparse(node.returns) or Parameter.empty + return_annotation = ast_unparse(node.returns, code) or Parameter.empty return inspect.Signature(params, return_annotation=return_annotation) diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index b98f37912..8040af9cc 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -386,6 +386,19 @@ def test_pyfunction_signature_full_py38(app): [desc_parameter, desc_sig_operator, "/"])]) +@pytest.mark.skipif(sys.version_info < (3, 8), reason='python 3.8+ is required.') +def test_pyfunction_with_number_literals(app): + text = ".. py:function:: hello(age=0x10, height=1_6_0)" + doctree = restructuredtext.parse(app, text) + assert_node(doctree[1][0][1], + [desc_parameterlist, ([desc_parameter, ([desc_sig_name, "age"], + [desc_sig_operator, "="], + [nodes.inline, "0x10"])], + [desc_parameter, ([desc_sig_name, "height"], + [desc_sig_operator, "="], + [nodes.inline, "1_6_0"])])]) + + def test_optional_pyfunction_signature(app): text = ".. py:function:: compile(source [, filename [, symbol]]) -> ast object" doctree = restructuredtext.parse(app, text) From bd49c3c2efad25707eb95b7a68b19d886c9e4f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Mon, 5 Oct 2020 08:32:26 +0200 Subject: [PATCH 085/124] Outdated comment in docs config for intersphinx Intersphinx is in use since 6a396c7eb85e4f2e2291652c454352bad1a397f4. --- doc/conf.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index f62e02a34..74e5a8b80 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -110,8 +110,6 @@ texinfo_documents = [ 1), ] -# We're not using intersphinx right now, but if we did, this would be part of -# the mapping: intersphinx_mapping = {'python': ('https://docs.python.org/3/', None)} # Sphinx document translation with sphinx gettext feature uses these settings: From 3eecf133d8a8af2f22f6f122d3245a1e2db940eb Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Mon, 5 Oct 2020 09:29:16 +0100 Subject: [PATCH 086/124] Fix #8289: Allow to suppress "duplicated ToC entry found" warnings from epub builder --- CHANGES | 2 ++ doc/usage/configuration.rst | 6 ++++++ sphinx/builders/_epub_base.py | 7 ++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 600efc466..e9a6220bf 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,8 @@ Features added just before writing .tex file * #7996: manpage: Add :confval:`man_make_section_directory` to make a section directory on build man page +* #8289: Allow to suppress "duplicated ToC entry found" warnings from epub builder + using :confval:`suppress_warnings`. Bugs fixed ---------- diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 270fcbf33..1cda6a055 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -316,6 +316,7 @@ General configuration * ``toc.circular`` * ``toc.secnum`` * ``epub.unknown_project_files`` + * ``epub.duplicated_toc_entry`` * ``autosectionlabel.*`` You can choose from these types. @@ -340,6 +341,11 @@ General configuration Added ``autosectionlabel.*`` + + .. versionchanged:: 3.3.0 + + Added ``epub.duplicated_toc_entry`` + .. confval:: needs_sphinx If set to a ``major.minor`` version string like ``'1.1'``, Sphinx will diff --git a/sphinx/builders/_epub_base.py b/sphinx/builders/_epub_base.py index 95f9ab8ed..b126182e9 100644 --- a/sphinx/builders/_epub_base.py +++ b/sphinx/builders/_epub_base.py @@ -208,7 +208,12 @@ class EpubBuilder(StandaloneHTMLBuilder): appeared = set() # type: Set[str] for node in nodes: if node['refuri'] in appeared: - logger.warning(__('duplicated ToC entry found: %s'), node['refuri']) + logger.warning( + __('duplicated ToC entry found: %s'), + node['refuri'], + type="epub", + subtype="duplicated_toc_entry", + ) else: appeared.add(node['refuri']) From 6dbe28a632c4c9c6c12beaf8e0f6a00d5fa163c6 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 4 Oct 2020 22:23:45 +0900 Subject: [PATCH 087/124] Fix #7786: autodoc: can't detect overloaded methods defined in other file --- CHANGES | 1 + sphinx/ext/autodoc/__init__.py | 30 +++++++++++-------- .../test-ext-autodoc/target/overload2.py | 5 ++++ tests/test_ext_autodoc.py | 16 ++++++++++ 4 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 tests/roots/test-ext-autodoc/target/overload2.py diff --git a/CHANGES b/CHANGES index 600efc466..3ee075353 100644 --- a/CHANGES +++ b/CHANGES @@ -42,6 +42,7 @@ Bugs fixed * #8157: autodoc: TypeError is raised when annotation has invalid __args__ * #7964: autodoc: Tuple in default value is wrongly rendered * #8200: autodoc: type aliases break type formatting of autoattribute +* #7786: autodoc: can't detect overloaded methods defined in other file * #8192: napoleon: description is disappeared when it contains inline literals * #8142: napoleon: Potential of regex denial of service in google style docs * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 434fc40e9..b68fc73c9 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -1471,22 +1471,14 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: return '' sig = super().format_signature() - - overloaded = False - qualname = None - # TODO: recreate analyzer for the module of class (To be clear, owner of the method) - if self._signature_class and self._signature_method_name and self.analyzer: - qualname = '.'.join([self._signature_class.__qualname__, - self._signature_method_name]) - if qualname in self.analyzer.overloads: - overloaded = True - sigs = [] - if overloaded: + + overloads = self.get_overloaded_signatures() + if overloads: # Use signatures for overloaded methods instead of the implementation method. method = safe_getattr(self._signature_class, self._signature_method_name, None) __globals__ = safe_getattr(method, '__globals__', {}) - for overload in self.analyzer.overloads.get(qualname): + for overload in overloads: overload = evaluate_signature(overload, __globals__, self.env.config.autodoc_type_aliases) @@ -1500,6 +1492,20 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: return "\n".join(sigs) + def get_overloaded_signatures(self) -> List[Signature]: + if self._signature_class and self._signature_method_name: + for cls in self._signature_class.__mro__: + try: + analyzer = ModuleAnalyzer.for_module(cls.__module__) + analyzer.parse() + qualname = '.'.join([cls.__qualname__, self._signature_method_name]) + if qualname in analyzer.overloads: + return analyzer.overloads.get(qualname) + except PycodeError: + pass + + return [] + def add_directive_header(self, sig: str) -> None: sourcename = self.get_sourcename() diff --git a/tests/roots/test-ext-autodoc/target/overload2.py b/tests/roots/test-ext-autodoc/target/overload2.py new file mode 100644 index 000000000..e901f791b --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/overload2.py @@ -0,0 +1,5 @@ +from target.overload import Bar + + +class Baz(Bar): + pass diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index 7fff09bb6..9cb54de5b 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -2002,6 +2002,22 @@ def test_overload(app): ] +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_overload2(app): + options = {"members": None} + actual = do_autodoc(app, 'module', 'target.overload2', options) + assert list(actual) == [ + '', + '.. py:module:: target.overload2', + '', + '', + '.. py:class:: Baz(x: int, y: int)', + ' Baz(x: str, y: str)', + ' :module: target.overload2', + '', + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_pymodule_for_ModuleLevelDocumenter(app): app.env.ref_context['py:module'] = 'target.classes' From 4f19f400bfb22f0549c69718f193371c6d9208fa Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 6 Oct 2020 01:53:28 +0900 Subject: [PATCH 088/124] refactor: Remove rst_epilog from test-root/conf.py I found test-root defines rst_epilog in its conf.py. It causes side-effects to many test cases in Sphinx's testing because test-root is widely used. This removes the configuration from test-root not to cause side-effects to our testings. Note: We already have test cases for rst_epilog in test_util_rst. --- tests/roots/test-root/conf.py | 2 -- tests/roots/test-root/markup.txt | 4 +++- tests/test_build_html.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/roots/test-root/conf.py b/tests/roots/test-root/conf.py index b3cc12ae0..c3a890045 100644 --- a/tests/roots/test-root/conf.py +++ b/tests/roots/test-root/conf.py @@ -32,8 +32,6 @@ pygments_style = 'sphinx' show_authors = True numfig = True -rst_epilog = '.. |subst| replace:: global substitution' - html_sidebars = {'**': ['localtoc.html', 'relations.html', 'sourcelink.html', 'customsb.html', 'searchbox.html'], 'index': ['contentssb.html', 'localtoc.html', 'globaltoc.html']} diff --git a/tests/roots/test-root/markup.txt b/tests/roots/test-root/markup.txt index e6adef55e..7cd3e95ea 100644 --- a/tests/roots/test-root/markup.txt +++ b/tests/roots/test-root/markup.txt @@ -22,7 +22,9 @@ Meta markup Generic reST ------------ -A |subst| (the definition is in rst_epilog). +A |subst|! + +.. |subst| replace:: global substitution .. highlight:: none diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 8cd541481..1f9f8eac7 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -258,7 +258,7 @@ def test_html4_output(app, status, warning): (".//pre/strong", 'try_stmt'), (".//pre/a[@href='#grammar-token-try1_stmt']/code/span", 'try1_stmt'), # tests for ``only`` directive - (".//p", 'A global substitution.'), + (".//p", 'A global substitution!'), (".//p", 'In HTML.'), (".//p", 'In both.'), (".//p", 'Always present'), From 3f26564c283d4800b7fea7402622f9cfd5efbf61 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Mon, 5 Oct 2020 22:10:25 +0100 Subject: [PATCH 089/124] Apply suggestions from code review --- CHANGES | 2 +- doc/usage/configuration.rst | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index e9a6220bf..2dd313092 100644 --- a/CHANGES +++ b/CHANGES @@ -26,7 +26,7 @@ Features added just before writing .tex file * #7996: manpage: Add :confval:`man_make_section_directory` to make a section directory on build man page -* #8289: Allow to suppress "duplicated ToC entry found" warnings from epub builder +* #8289: epub: Allow to suppress "duplicated ToC entry found" warnings from epub builder using :confval:`suppress_warnings`. Bugs fixed diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 1cda6a055..4881b8629 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -341,7 +341,6 @@ General configuration Added ``autosectionlabel.*`` - .. versionchanged:: 3.3.0 Added ``epub.duplicated_toc_entry`` From 529d19ff81976a75275082bc34156dd38f97da98 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Mon, 5 Oct 2020 22:12:34 +0100 Subject: [PATCH 090/124] wrap CHANGES at 85 cols --- CHANGES | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 2dd313092..5f3a17520 100644 --- a/CHANGES +++ b/CHANGES @@ -26,8 +26,8 @@ Features added just before writing .tex file * #7996: manpage: Add :confval:`man_make_section_directory` to make a section directory on build man page -* #8289: epub: Allow to suppress "duplicated ToC entry found" warnings from epub builder - using :confval:`suppress_warnings`. +* #8289: epub: Allow to suppress "duplicated ToC entry found" warnings from epub + builder using :confval:`suppress_warnings`. Bugs fixed ---------- From d10802fa6ab7ca6f0e48c67b36da888da291d011 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Wed, 7 Oct 2020 14:23:02 -0400 Subject: [PATCH 091/124] TST: Add test --- tests/test_domain_py.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index 8040af9cc..ceea51508 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -313,7 +313,7 @@ def test_pyfunction_signature(app): def test_pyfunction_signature_full(app): text = (".. py:function:: hello(a: str, b = 1, *args: str, " - "c: bool = True, **kwargs: str) -> str") + "c: bool = True, d: tuple = (1, 2), **kwargs: str) -> str") doctree = restructuredtext.parse(app, text) assert_node(doctree, (addnodes.index, [desc, ([desc_signature, ([desc_name, "hello"], @@ -343,6 +343,14 @@ def test_pyfunction_signature_full(app): [desc_sig_operator, "="], " ", [nodes.inline, "True"])], + [desc_parameter, ([desc_sig_name, "d"], + [desc_sig_punctuation, ":"], + " ", + [desc_sig_name, pending_xref, "tuple"], + " ", + [desc_sig_operator, "="], + " ", + [nodes.inline, "(1, 2)"])], [desc_parameter, ([desc_sig_operator, "**"], [desc_sig_name, "kwargs"], [desc_sig_punctuation, ":"], From 55f79195317e0fc4f9b98062cbb4fa875024a996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Sun, 11 Oct 2020 11:41:42 +0200 Subject: [PATCH 092/124] Linkcheck: Use Thread daemon argument Instead of using a separate call. --- sphinx/builders/linkcheck.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index a9e6b05b0..d6631dd2c 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -106,8 +106,7 @@ class CheckExternalLinksBuilder(Builder): self.rqueue = queue.Queue() # type: queue.Queue self.workers = [] # type: List[threading.Thread] for i in range(self.app.config.linkcheck_workers): - thread = threading.Thread(target=self.check_thread) - thread.setDaemon(True) + thread = threading.Thread(target=self.check_thread, daemon=True) thread.start() self.workers.append(thread) From 15251574a97ffa13b9c62255733296c2a3ab50b4 Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Tue, 13 Oct 2020 12:30:13 +0200 Subject: [PATCH 093/124] C, fix links to function parameters --- CHANGES | 2 + sphinx/domains/c.py | 38 +++++++++++++++---- sphinx/domains/cpp.py | 2 +- .../test-domain-c/function_param_target.rst | 5 +++ tests/test_domain_c.py | 34 +++++++++++++++++ 5 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 tests/roots/test-domain-c/function_param_target.rst diff --git a/CHANGES b/CHANGES index 93cc5fb8c..a8426dff8 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,8 @@ Bugs fixed * C, fix anon objects in intersphinx. * #8270, C++, properly reject functions as duplicate declarations if a non-function declaration of the same name already exists. +* C, fix references to function parameters. + Link to the function instead of a non-existing anchor. Testing diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 4d88bd8e8..16f2c876f 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -10,7 +10,7 @@ import re from typing import ( - Any, Callable, Dict, Generator, Iterator, List, Type, TypeVar, Tuple, Union + Any, Callable, cast, Dict, Generator, Iterator, List, Type, TypeVar, Tuple, Union ) from docutils import nodes @@ -46,6 +46,11 @@ from sphinx.util.nodes import make_refnode logger = logging.getLogger(__name__) T = TypeVar('T') +DeclarationType = Union[ + "ASTStruct", "ASTUnion", "ASTEnum", "ASTEnumerator", + "ASTType", "ASTTypeWithInit", "ASTMacro", +] + # https://en.cppreference.com/w/c/keyword _keywords = [ 'auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', 'double', @@ -635,6 +640,10 @@ class ASTFunctionParameter(ASTBase): self.arg = arg self.ellipsis = ellipsis + def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + # the anchor will be our parent + return symbol.parent.declaration.get_id(version, prefixed=False) + def _stringify(self, transform: StringifyTransform) -> str: if self.ellipsis: return '...' @@ -1148,6 +1157,9 @@ class ASTType(ASTBase): def name(self) -> ASTNestedName: return self.decl.name + def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + return symbol.get_full_nested_name().get_id(version) + @property def function_params(self) -> List[ASTFunctionParameter]: return self.decl.function_params @@ -1190,6 +1202,9 @@ class ASTTypeWithInit(ASTBase): def name(self) -> ASTNestedName: return self.type.name + def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + return self.type.get_id(version, objectType, symbol) + def _stringify(self, transform: StringifyTransform) -> str: res = [] res.append(transform(self.type)) @@ -1241,6 +1256,9 @@ class ASTMacro(ASTBase): def name(self) -> ASTNestedName: return self.ident + def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + return symbol.get_full_nested_name().get_id(version) + def _stringify(self, transform: StringifyTransform) -> str: res = [] res.append(transform(self.ident)) @@ -1341,7 +1359,8 @@ class ASTEnumerator(ASTBase): class ASTDeclaration(ASTBaseBase): - def __init__(self, objectType: str, directiveType: str, declaration: Any, + def __init__(self, objectType: str, directiveType: str, + declaration: Union[DeclarationType, ASTFunctionParameter], semicolon: bool = False) -> None: self.objectType = objectType self.directiveType = directiveType @@ -1358,18 +1377,20 @@ class ASTDeclaration(ASTBaseBase): @property def name(self) -> ASTNestedName: - return self.declaration.name + decl = cast(DeclarationType, self.declaration) + return decl.name @property def function_params(self) -> List[ASTFunctionParameter]: if self.objectType != 'function': return None - return self.declaration.function_params + decl = cast(ASTType, self.declaration) + return decl.function_params def get_id(self, version: int, prefixed: bool = True) -> str: if self.objectType == 'enumerator' and self.enumeratorScopedSymbol: return self.enumeratorScopedSymbol.declaration.get_id(version, prefixed) - id_ = self.symbol.get_full_nested_name().get_id(version) + id_ = self.declaration.get_id(version, self.objectType, self.symbol) if prefixed: return _id_prefix[version] + id_ else: @@ -1412,7 +1433,8 @@ class ASTDeclaration(ASTBaseBase): elif self.objectType == 'enumerator': mainDeclNode += addnodes.desc_annotation('enumerator ', 'enumerator ') elif self.objectType == 'type': - prefix = self.declaration.get_type_declaration_prefix() + decl = cast(ASTType, self.declaration) + prefix = decl.get_type_declaration_prefix() prefix += ' ' mainDeclNode += addnodes.desc_annotation(prefix, prefix) else: @@ -2982,7 +3004,7 @@ class DefinitionParser(BaseParser): def parse_pre_v3_type_definition(self) -> ASTDeclaration: self.skip_ws() - declaration = None # type: Any + declaration = None # type: DeclarationType if self.skip_word('struct'): typ = 'struct' declaration = self._parse_struct() @@ -3005,7 +3027,7 @@ class DefinitionParser(BaseParser): 'macro', 'struct', 'union', 'enum', 'enumerator', 'type'): raise Exception('Internal error, unknown directiveType "%s".' % directiveType) - declaration = None # type: Any + declaration = None # type: DeclarationType if objectType == 'member': declaration = self._parse_type_with_init(named=True, outer='member') elif objectType == 'function': diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index c43c55d5b..0e996532f 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -1836,7 +1836,7 @@ class ASTFunctionParameter(ASTBase): # this is not part of the normal name mangling in C++ if symbol: # the anchor will be our parent - return symbol.parent.declaration.get_id(version, prefixed=None) + return symbol.parent.declaration.get_id(version, prefixed=False) # else, do the usual if self.ellipsis: return 'z' diff --git a/tests/roots/test-domain-c/function_param_target.rst b/tests/roots/test-domain-c/function_param_target.rst new file mode 100644 index 000000000..05de01445 --- /dev/null +++ b/tests/roots/test-domain-c/function_param_target.rst @@ -0,0 +1,5 @@ +.. c:function:: void f(int i) + + - :c:var:`i` + +- :c:var:`f.i` diff --git a/tests/test_domain_c.py b/tests/test_domain_c.py index 7509b1aa9..43d71f74e 100644 --- a/tests/test_domain_c.py +++ b/tests/test_domain_c.py @@ -9,6 +9,8 @@ """ import pytest +from xml.etree import ElementTree + from sphinx import addnodes from sphinx.addnodes import desc from sphinx.domains.c import DefinitionParser, DefinitionError @@ -529,6 +531,25 @@ def filter_warnings(warning, file): return res +def extract_role_links(app, filename): + t = (app.outdir / filename).read_text() + lis = [l for l in t.split('\n') if l.startswith(" Date: Wed, 14 Oct 2020 18:00:29 +0100 Subject: [PATCH 094/124] Prevent arrow key changing page on buttons --- sphinx/themes/basic/static/doctools.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sphinx/themes/basic/static/doctools.js b/sphinx/themes/basic/static/doctools.js index daccd209d..7d88f807d 100644 --- a/sphinx/themes/basic/static/doctools.js +++ b/sphinx/themes/basic/static/doctools.js @@ -285,9 +285,10 @@ var Documentation = { initOnKeyListeners: function() { $(document).keydown(function(event) { var activeElementType = document.activeElement.tagName; - // don't navigate when in search box or textarea + // don't navigate when in search box, textarea, dropdown or button if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' - && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) { + && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey) { switch (event.keyCode) { case 37: // left var prevHref = $('link[rel="prev"]').prop('href'); From 10335feed7939aafc0dfb29d4f2bfaacc03b1c22 Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Sun, 18 Oct 2020 06:36:11 +0800 Subject: [PATCH 095/124] Correct a typo in texinfo.py --- sphinx/writers/texinfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 5ad2831dd..a33d3363f 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -369,7 +369,7 @@ class TexinfoTranslator(SphinxTranslator): """Return an escaped string suitable for use as an argument to a Texinfo command.""" s = self.escape(s) - # commas are the argument delimeters + # commas are the argument delimiters s = s.replace(',', '@comma{}') # normalize white space s = ' '.join(s.split()).strip() From ed1f26ba47dd675c8dfb55f5679c73a95af5f04d Mon Sep 17 00:00:00 2001 From: Tetsuo Koyama Date: Thu, 22 Oct 2020 12:11:07 +0900 Subject: [PATCH 096/124] :new: OpenFAST in EXAMPLES --- EXAMPLES | 1 + 1 file changed, 1 insertion(+) diff --git a/EXAMPLES b/EXAMPLES index 19f23172f..74fa36510 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -230,6 +230,7 @@ Documentation using sphinx_rtd_theme * `MyHDL `__ * `Nextflow `__ * `NICOS `__ (customized) +* `OpenFAST `__ * `Pelican `__ * `picamera `__ * `Pillow `__ From ccc77b8305a6347f61398c35ee743561a893cbf4 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 24 Oct 2020 14:14:11 +0900 Subject: [PATCH 097/124] Fix mypy violations (with mypy-0.790) --- setup.py | 2 +- sphinx/ext/autodoc/__init__.py | 2 +- sphinx/search/__init__.py | 10 +++++----- sphinx/util/typing.py | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/setup.py b/setup.py index a404f1fa5..8505d2679 100644 --- a/setup.py +++ b/setup.py @@ -44,7 +44,7 @@ extras_require = { 'lint': [ 'flake8>=3.5.0', 'flake8-import-order', - 'mypy>=0.780', + 'mypy>=0.790', 'docutils-stubs', ], 'test': [ diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index b61a96c84..23cdc4b28 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -1725,7 +1725,7 @@ class TypeVarDocumenter(DataDocumenter): @classmethod def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any ) -> bool: - return isinstance(member, TypeVar) and isattr # type: ignore + return isinstance(member, TypeVar) and isattr def add_directive_header(self, sig: str) -> None: self.options.annotation = SUPPRESS # type: ignore diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py index 4534dd333..048b333d5 100644 --- a/sphinx/search/__init__.py +++ b/sphinx/search/__init__.py @@ -297,8 +297,8 @@ class IndexBuilder: frozen.get('envversion') != self.env.version: raise ValueError('old format') index2fn = frozen['docnames'] - self._filenames = dict(zip(index2fn, frozen['filenames'])) # type: ignore - self._titles = dict(zip(index2fn, frozen['titles'])) # type: ignore + self._filenames = dict(zip(index2fn, frozen['filenames'])) + self._titles = dict(zip(index2fn, frozen['titles'])) def load_terms(mapping: Dict[str, Any]) -> Dict[str, Set[str]]: rv = {} @@ -359,13 +359,13 @@ class IndexBuilder: def get_terms(self, fn2index: Dict) -> Tuple[Dict[str, List[str]], Dict[str, List[str]]]: rvs = {}, {} # type: Tuple[Dict[str, List[str]], Dict[str, List[str]]] for rv, mapping in zip(rvs, (self._mapping, self._title_mapping)): - for k, v in mapping.items(): # type: ignore + for k, v in mapping.items(): if len(v) == 1: fn, = v if fn in fn2index: - rv[k] = fn2index[fn] # type: ignore + rv[k] = fn2index[fn] else: - rv[k] = sorted([fn2index[fn] for fn in v if fn in fn2index]) # type: ignore # NOQA + rv[k] = sorted([fn2index[fn] for fn in v if fn in fn2index]) return rvs def freeze(self) -> Dict[str, Any]: diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py index d71ca1b2d..23812db96 100644 --- a/sphinx/util/typing.py +++ b/sphinx/util/typing.py @@ -57,14 +57,14 @@ Inventory = Dict[str, Dict[str, Tuple[str, str, str, str]]] def is_system_TypeVar(typ: Any) -> bool: """Check *typ* is system defined TypeVar.""" modname = getattr(typ, '__module__', '') - return modname == 'typing' and isinstance(typ, TypeVar) # type: ignore + return modname == 'typing' and isinstance(typ, TypeVar) def stringify(annotation: Any) -> str: """Stringify type annotation object.""" if isinstance(annotation, str): return annotation - elif isinstance(annotation, TypeVar): # type: ignore + elif isinstance(annotation, TypeVar): return annotation.__name__ elif not annotation: return repr(annotation) From b62f635f425773653932e82b80167b0da32ff660 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 24 Oct 2020 16:00:00 +0900 Subject: [PATCH 098/124] Disable testing with nightly python temporarily --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d73be03ec..47a8e7c7a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,9 +24,6 @@ jobs: env: - TOXENV=du15 - PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg" - - python: 'nightly' - env: - - TOXENV=du16 - language: node_js node_js: '10.7' From 3171a44032f216a1775d86302d939e271e3ab2e9 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 24 Oct 2020 20:11:23 +0900 Subject: [PATCH 099/124] Fix #8321: linkcheck: ``tel:`` schema hyperlinks are detected as errors --- CHANGES | 1 + sphinx/builders/linkcheck.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 0405e1d93..8dbbd5290 100644 --- a/CHANGES +++ b/CHANGES @@ -57,6 +57,7 @@ Bugs fixed * #8239: Failed to refer a token in productionlist if it is indented * #8268: linkcheck: Report HTTP errors when ``linkcheck_anchors`` is ``True`` * #8245: linkcheck: take source directory into account for local files +* #8321: linkcheck: ``tel:`` schema hyperlinks are detected as errors * #6914: figure numbers are unexpectedly assigned to uncaptioned items Testing diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index a9e6b05b0..85d5c5d86 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -213,7 +213,7 @@ class CheckExternalLinksBuilder(Builder): def check(docname: str) -> Tuple[str, str, int]: # check for various conditions without bothering the network - if len(uri) == 0 or uri.startswith(('#', 'mailto:')): + if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'tel:')): return 'unchecked', '', 0 elif not uri.startswith(('http:', 'https:')): if uri_re.match(uri): From cc97a076407d20a495f95c1b2dfa996d629d5452 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 4 Oct 2020 17:47:06 +0900 Subject: [PATCH 100/124] Fix #7785: autodoc_typehints=none does not effect to overloads --- CHANGES | 1 + sphinx/ext/autodoc/__init__.py | 10 +++++-- tests/test_ext_autodoc_configs.py | 48 +++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 4031d2bcc..3c54f1f7c 100644 --- a/CHANGES +++ b/CHANGES @@ -45,6 +45,7 @@ Bugs fixed * #7964: autodoc: Tuple in default value is wrongly rendered * #8200: autodoc: type aliases break type formatting of autoattribute * #7786: autodoc: can't detect overloaded methods defined in other file +* #7785: autodoc: autodoc_typehints='none' does not effect to overloaded functions * #8192: napoleon: description is disappeared when it contains inline literals * #8142: napoleon: Potential of regex denial of service in google style docs * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 978fd5df8..7343d41b6 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -1240,7 +1240,9 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ def format_signature(self, **kwargs: Any) -> str: sigs = [] - if self.analyzer and '.'.join(self.objpath) in self.analyzer.overloads: + if (self.analyzer and + '.'.join(self.objpath) in self.analyzer.overloads and + self.env.config.autodoc_typehints == 'signature'): # Use signatures for overloaded functions instead of the implementation function. overloaded = True else: @@ -1474,7 +1476,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: sigs = [] overloads = self.get_overloaded_signatures() - if overloads: + if overloads and self.env.config.autodoc_typehints == 'signature': # Use signatures for overloaded methods instead of the implementation method. method = safe_getattr(self._signature_class, self._signature_method_name, None) __globals__ = safe_getattr(method, '__globals__', {}) @@ -1882,7 +1884,9 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: def format_signature(self, **kwargs: Any) -> str: sigs = [] - if self.analyzer and '.'.join(self.objpath) in self.analyzer.overloads: + if (self.analyzer and + '.'.join(self.objpath) in self.analyzer.overloads and + self.env.config.autodoc_typehints == 'signature'): # Use signatures for overloaded methods instead of the implementation method. overloaded = True else: diff --git a/tests/test_ext_autodoc_configs.py b/tests/test_ext_autodoc_configs.py index 7d51b7f0e..8ebe12d40 100644 --- a/tests/test_ext_autodoc_configs.py +++ b/tests/test_ext_autodoc_configs.py @@ -610,6 +610,54 @@ def test_autodoc_typehints_none(app): ] +@pytest.mark.sphinx('html', testroot='ext-autodoc', + confoverrides={'autodoc_typehints': 'none'}) +def test_autodoc_typehints_none_for_overload(app): + options = {"members": None} + actual = do_autodoc(app, 'module', 'target.overload', options) + assert list(actual) == [ + '', + '.. py:module:: target.overload', + '', + '', + '.. py:class:: Bar(x, y)', + ' :module: target.overload', + '', + ' docstring', + '', + '', + '.. py:class:: Baz(x, y)', + ' :module: target.overload', + '', + ' docstring', + '', + '', + '.. py:class:: Foo(x, y)', + ' :module: target.overload', + '', + ' docstring', + '', + '', + '.. py:class:: Math()', + ' :module: target.overload', + '', + ' docstring', + '', + '', + ' .. py:method:: Math.sum(x, y)', + ' :module: target.overload', + '', + ' docstring', + '', + '', + '.. py:function:: sum(x, y)', + ' :module: target.overload', + '', + ' docstring', + '', + ] + + @pytest.mark.sphinx('text', testroot='ext-autodoc', confoverrides={'autodoc_typehints': "description"}) def test_autodoc_typehints_description(app): From 5a866d5e7c57883d647d1d5bfa08c80cec923c73 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Mon, 19 Oct 2020 14:31:25 +0200 Subject: [PATCH 101/124] basic CSS: disable "user-select" on span.linenos --- sphinx/themes/basic/static/basic.css_t | 1 + 1 file changed, 1 insertion(+) diff --git a/sphinx/themes/basic/static/basic.css_t b/sphinx/themes/basic/static/basic.css_t index 0a71a7a91..38b9fb553 100644 --- a/sphinx/themes/basic/static/basic.css_t +++ b/sphinx/themes/basic/static/basic.css_t @@ -764,6 +764,7 @@ div.code-block-caption code { } table.highlighttable td.linenos, +span.linenos, div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ user-select: none; } From 38a6838119744e3ce147d244c46ccd7eadec4403 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Sat, 24 Oct 2020 15:12:58 +0200 Subject: [PATCH 102/124] Add CHANGES for #8320 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 4031d2bcc..718579663 100644 --- a/CHANGES +++ b/CHANGES @@ -60,6 +60,7 @@ Bugs fixed * #8268: linkcheck: Report HTTP errors when ``linkcheck_anchors`` is ``True`` * #8245: linkcheck: take source directory into account for local files * #6914: figure numbers are unexpectedly assigned to uncaptioned items +* #8320: make "inline" line numbers un-selectable Testing -------- From 91f5448b2596f30b26e413edbafa4917ece578e3 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Sat, 24 Oct 2020 15:21:31 +0200 Subject: [PATCH 103/124] Override Pygments CSS with theme CSS --- sphinx/themes/basic/layout.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html index 9163a18a2..131d2c533 100644 --- a/sphinx/themes/basic/layout.html +++ b/sphinx/themes/basic/layout.html @@ -95,8 +95,8 @@ {%- endmacro %} {%- macro css() %} - + {%- for css in css_files %} {%- if css|attr("filename") %} {{ css_tag(css) }} From 84c6d693f43dc7f7b1e627b7cce91d2a9e49e5da Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Sat, 24 Oct 2020 17:20:24 +0200 Subject: [PATCH 104/124] DOC: Add favicon --- doc/_static/favicon.svg | 8 ++++++++ doc/conf.py | 1 + 2 files changed, 9 insertions(+) create mode 100644 doc/_static/favicon.svg diff --git a/doc/_static/favicon.svg b/doc/_static/favicon.svg new file mode 100644 index 000000000..c3e1acd35 --- /dev/null +++ b/doc/_static/favicon.svg @@ -0,0 +1,8 @@ + + + + diff --git a/doc/conf.py b/doc/conf.py index 74e5a8b80..8b242dc7e 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -28,6 +28,7 @@ html_sidebars = {'index': ['indexsidebar.html', 'searchbox.html']} html_additional_pages = {'index': 'index.html'} html_use_opensearch = 'https://www.sphinx-doc.org/en/master' html_baseurl = 'https://www.sphinx-doc.org/en/master/' +html_favicon = '_static/favicon.svg' htmlhelp_basename = 'Sphinxdoc' From 554bb5e9b988f794c58faaaca1680045f34a1743 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Sat, 24 Oct 2020 09:32:52 -0700 Subject: [PATCH 105/124] =?UTF-8?q?Fix=20docs=20type:=20"the=20builder=20b?= =?UTF-8?q?uilders"=20=E2=86=92=20"builders"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/glossary.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/glossary.rst b/doc/glossary.rst index d3367e5df..87b7014b6 100644 --- a/doc/glossary.rst +++ b/doc/glossary.rst @@ -9,8 +9,8 @@ Glossary A class (inheriting from :class:`~sphinx.builders.Builder`) that takes parsed documents and performs an action on them. Normally, builders translate the documents to an output format, but it is also possible to - use the builder builders that e.g. check for broken links in the - documentation, or build coverage information. + use builders that e.g. check for broken links in the documentation, or + build coverage information. See :doc:`/usage/builders/index` for an overview over Sphinx's built-in builders. From da4f091c211ccf30a8a7591c4881027fe1d74c35 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Sat, 24 Oct 2020 20:55:06 +0200 Subject: [PATCH 106/124] autodoc: check whether __slots__ is a str Closes #8294. --- sphinx/ext/autodoc/importer.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py index 133ce1439..52b07639a 100644 --- a/sphinx/ext/autodoc/importer.py +++ b/sphinx/ext/autodoc/importer.py @@ -206,7 +206,10 @@ def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable, if isclass(subject) and getattr(subject, '__slots__', None) is not None: from sphinx.ext.autodoc import SLOTSATTR - for name in subject.__slots__: + slots = subject.__slots__ + if isinstance(slots, str): + slots = [slots] + for name in slots: members[name] = Attribute(name, True, SLOTSATTR) # other members From 82c83ed478618c9b97f1cbf7a24214ee433fa891 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Sun, 25 Oct 2020 10:27:43 +0100 Subject: [PATCH 107/124] autodoc: Add test for single-string __slots__ --- tests/roots/test-ext-autodoc/target/slots.py | 4 ++++ tests/test_ext_autodoc.py | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/tests/roots/test-ext-autodoc/target/slots.py b/tests/roots/test-ext-autodoc/target/slots.py index 44e750320..17e469cac 100644 --- a/tests/roots/test-ext-autodoc/target/slots.py +++ b/tests/roots/test-ext-autodoc/target/slots.py @@ -2,6 +2,10 @@ class Foo: __slots__ = ['attr'] +class FooSingleString: + __slots__ = 'attr' + + class Bar: __slots__ = {'attr1': 'docstring of attr1', 'attr2': 'docstring of attr2', diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index 9cb54de5b..c0676f23f 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -1205,6 +1205,14 @@ def test_slots(app): ' .. py:attribute:: Foo.attr', ' :module: target.slots', '', + '', + '.. py:class:: FooSingleString()', + ' :module: target.slots', + '', + '', + ' .. py:attribute:: FooSingleString.attr', + ' :module: target.slots', + '', ] From 746842f4fc298c08a3dc864da069c38668fed44d Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 25 Oct 2020 18:52:45 +0900 Subject: [PATCH 108/124] Update CHANGES for PR #8323 --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 8cf598cca..976e8f1fe 100644 --- a/CHANGES +++ b/CHANGES @@ -60,6 +60,8 @@ Bugs fixed * #8268: linkcheck: Report HTTP errors when ``linkcheck_anchors`` is ``True`` * #8245: linkcheck: take source directory into account for local files * #8321: linkcheck: ``tel:`` schema hyperlinks are detected as errors +* #8323: linkcheck: An exit status is incorrect when links having unsupported + schema found * #6914: figure numbers are unexpectedly assigned to uncaptioned items * #8320: make "inline" line numbers un-selectable From ad7c09ef10038c6147f373f1edf8db2c5e2160d1 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 25 Oct 2020 18:59:33 +0900 Subject: [PATCH 109/124] Update CHANGES for PR #8338 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 976e8f1fe..8e87f5538 100644 --- a/CHANGES +++ b/CHANGES @@ -45,6 +45,7 @@ Bugs fixed * #7964: autodoc: Tuple in default value is wrongly rendered * #8200: autodoc: type aliases break type formatting of autoattribute * #7786: autodoc: can't detect overloaded methods defined in other file +* #8294: autodoc: single-string __slots__ is not handled correctly * #8192: napoleon: description is disappeared when it contains inline literals * #8142: napoleon: Potential of regex denial of service in google style docs * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex From 35725f02d9fc42d711d8a377fd97e07aa8015958 Mon Sep 17 00:00:00 2001 From: "oleg.hoefling" Date: Thu, 8 Oct 2020 17:08:18 +0200 Subject: [PATCH 110/124] move registration of public markers to sphinx.testing.fixtures Signed-off-by: oleg.hoefling --- setup.cfg | 2 -- sphinx/testing/fixtures.py | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 37e42df84..abda98124 100644 --- a/setup.cfg +++ b/setup.cfg @@ -57,10 +57,8 @@ filterwarnings = ignore::DeprecationWarning:pyximport.pyximport ignore::PendingDeprecationWarning:sphinx.util.pycompat markers = - sphinx apidoc setup_command - test_params testpaths = tests [coverage:run] diff --git a/sphinx/testing/fixtures.py b/sphinx/testing/fixtures.py index 9197014bf..cacbb04bf 100644 --- a/sphinx/testing/fixtures.py +++ b/sphinx/testing/fixtures.py @@ -22,6 +22,21 @@ from sphinx.testing import util from sphinx.testing.util import SphinxTestApp, SphinxTestAppWrapperForSkipBuilding +markers = [ + ( + 'sphinx(builder, testroot=None, freshenv=False, confoverrides=None, tags=None,' + ' docutilsconf=None, parallel=0): arguments to initialize the sphinx test application.' + ), + 'test_params(shared_result=...): test parameters.', +] + + +def pytest_configure(config): + # register custom markers + for marker in markers: + config.addinivalue_line('markers', marker) + + @pytest.fixture(scope='session') def rootdir() -> str: return None From 3c3216fa40a8d30b5dd9bc97be7273c99394483b Mon Sep 17 00:00:00 2001 From: "oleg.hoefling" Date: Sun, 25 Oct 2020 11:36:40 +0100 Subject: [PATCH 111/124] more meaningful name for the public markers list Signed-off-by: oleg.hoefling --- sphinx/testing/fixtures.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx/testing/fixtures.py b/sphinx/testing/fixtures.py index cacbb04bf..cd296e71c 100644 --- a/sphinx/testing/fixtures.py +++ b/sphinx/testing/fixtures.py @@ -22,7 +22,7 @@ from sphinx.testing import util from sphinx.testing.util import SphinxTestApp, SphinxTestAppWrapperForSkipBuilding -markers = [ +PUBLIC_MARKERS = [ ( 'sphinx(builder, testroot=None, freshenv=False, confoverrides=None, tags=None,' ' docutilsconf=None, parallel=0): arguments to initialize the sphinx test application.' @@ -33,7 +33,7 @@ markers = [ def pytest_configure(config): # register custom markers - for marker in markers: + for marker in PUBLIC_MARKERS: config.addinivalue_line('markers', marker) From 30f3ac6fe7ec426eef07811c445aae217ee4d725 Mon Sep 17 00:00:00 2001 From: "oleg.hoefling" Date: Sun, 25 Oct 2020 11:44:39 +0100 Subject: [PATCH 112/124] rename public markers to default markers Signed-off-by: oleg.hoefling --- sphinx/testing/fixtures.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx/testing/fixtures.py b/sphinx/testing/fixtures.py index cd296e71c..5e72ed530 100644 --- a/sphinx/testing/fixtures.py +++ b/sphinx/testing/fixtures.py @@ -22,7 +22,7 @@ from sphinx.testing import util from sphinx.testing.util import SphinxTestApp, SphinxTestAppWrapperForSkipBuilding -PUBLIC_MARKERS = [ +DEFAULT_MARKERS = [ ( 'sphinx(builder, testroot=None, freshenv=False, confoverrides=None, tags=None,' ' docutilsconf=None, parallel=0): arguments to initialize the sphinx test application.' @@ -33,7 +33,7 @@ PUBLIC_MARKERS = [ def pytest_configure(config): # register custom markers - for marker in PUBLIC_MARKERS: + for marker in DEFAULT_MARKERS: config.addinivalue_line('markers', marker) From f2a31185a65b31883846e5d127bf9a7dfe968db0 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 26 Oct 2020 00:59:25 +0900 Subject: [PATCH 113/124] Update CHANGES for PR #8216 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 76275d246..77cd6705d 100644 --- a/CHANGES +++ b/CHANGES @@ -49,6 +49,7 @@ Bugs fixed * #8192: napoleon: description is disappeared when it contains inline literals * #8142: napoleon: Potential of regex denial of service in google style docs * #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex +* #8215: LaTeX: 'oneside' classoption causes build warning * #8175: intersphinx: Potential of regex denial of service by broken inventory * #8277: sphinx-build: missing and redundant spacing (and etc) for console output on building From b453be75c9656bb311aa88d50b367a5ccb414e37 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 26 Oct 2020 01:12:36 +0900 Subject: [PATCH 114/124] Fix #8298: sphinx-quickstart: Add :option:`sphinx-quickstart --no-sep` option --- CHANGES | 1 + doc/man/sphinx-quickstart.rst | 4 ++++ sphinx/cmd/quickstart.py | 4 +++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 77cd6705d..e33bf3d54 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,7 @@ Features added directory on build man page * #8289: epub: Allow to suppress "duplicated ToC entry found" warnings from epub builder using :confval:`suppress_warnings`. +* #8298: sphinx-quickstart: Add :option:`sphinx-quickstart --no-sep` option Bugs fixed ---------- diff --git a/doc/man/sphinx-quickstart.rst b/doc/man/sphinx-quickstart.rst index 2407e3be7..520a420ce 100644 --- a/doc/man/sphinx-quickstart.rst +++ b/doc/man/sphinx-quickstart.rst @@ -33,6 +33,10 @@ Options If specified, separate source and build directories. +.. option:: --no-sep + + If specified, create build directroy under source directroy. + .. option:: --dot=DOT Inside the root directory, two more directories will be created; diff --git a/sphinx/cmd/quickstart.py b/sphinx/cmd/quickstart.py index cad3c65e5..2363f9fe4 100644 --- a/sphinx/cmd/quickstart.py +++ b/sphinx/cmd/quickstart.py @@ -489,8 +489,10 @@ def get_parser() -> argparse.ArgumentParser: help=__('project root')) group = parser.add_argument_group(__('Structure options')) - group.add_argument('--sep', action='store_true', default=None, + group.add_argument('--sep', action='store_true', dest='sep', default=None, help=__('if specified, separate source and build dirs')) + group.add_argument('--no-sep', action='store_false', dest='sep', + help=__('if specified, create build dir under source dir')) group.add_argument('--dot', metavar='DOT', default='_', help=__('replacement for dot in _templates etc.')) From 72397f6dcefb10f95650190991320aeb8d781cba Mon Sep 17 00:00:00 2001 From: "oleg.hoefling" Date: Sun, 25 Oct 2020 18:34:47 +0100 Subject: [PATCH 115/124] change markers list name to DEFAULT_ENABLED_MARKERS Signed-off-by: oleg.hoefling --- sphinx/testing/fixtures.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx/testing/fixtures.py b/sphinx/testing/fixtures.py index 5e72ed530..f457e3745 100644 --- a/sphinx/testing/fixtures.py +++ b/sphinx/testing/fixtures.py @@ -22,7 +22,7 @@ from sphinx.testing import util from sphinx.testing.util import SphinxTestApp, SphinxTestAppWrapperForSkipBuilding -DEFAULT_MARKERS = [ +DEFAULT_ENABLED_MARKERS = [ ( 'sphinx(builder, testroot=None, freshenv=False, confoverrides=None, tags=None,' ' docutilsconf=None, parallel=0): arguments to initialize the sphinx test application.' @@ -33,7 +33,7 @@ DEFAULT_MARKERS = [ def pytest_configure(config): # register custom markers - for marker in DEFAULT_MARKERS: + for marker in DEFAULT_ENABLED_MARKERS: config.addinivalue_line('markers', marker) From 46638bc01b4a52cd314c7d06ac110361d95b852e Mon Sep 17 00:00:00 2001 From: Jan Vojt Date: Tue, 27 Oct 2020 10:37:45 +0100 Subject: [PATCH 116/124] Fix unnecessary load of images when parsing the document text for search function. The issue was, that when searching, new element with all the HTML content was created. This caused loading of all images in the background. However, in the end, these images are stripped from search result anyway, so there is no point in loading them. In cases where images were included in HTML files in a different directory from search.html, this behaviour was even causing 404 errors because of wrong relative URLs. This commit fixes the issue by creating virtual document and using that as the owner document of temporary meta-element used for searching and parsing purposes. The virtual owner document causes browser to not load the images. --- sphinx/themes/basic/static/searchtools.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js index 970d0d975..261ecaa92 100644 --- a/sphinx/themes/basic/static/searchtools.js +++ b/sphinx/themes/basic/static/searchtools.js @@ -59,10 +59,10 @@ var Search = { _pulse_status : -1, htmlToText : function(htmlString) { - var htmlElement = document.createElement('span'); - htmlElement.innerHTML = htmlString; - $(htmlElement).find('.headerlink').remove(); - docContent = $(htmlElement).find('[role=main]')[0]; + var virtualDocument = document.implementation.createHTMLDocument('virtual'); + var htmlElement = $(htmlString, virtualDocument); + htmlElement.find('.headerlink').remove(); + docContent = htmlElement.find('[role=main]')[0]; if(docContent === undefined) { console.warn("Content block not found. Sphinx search tries to obtain it " + "via '[role=main]'. Could you check your theme or template."); From d17563987a80007e2310102cfde673c651823a39 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 27 Oct 2020 23:55:12 +0900 Subject: [PATCH 117/124] Update CHANGES for PR #8343 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 77cd6705d..a801f054a 100644 --- a/CHANGES +++ b/CHANGES @@ -56,6 +56,7 @@ Bugs fixed * #7973: imgconverter: Check availability of imagemagick many times * #8255: py domain: number in default argument value is changed from hexadecimal to decimal +* #8343: html search: Fix unnecessary load of images when parsing the document * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) * #8215: Eliminate Fancyhdr build warnings for oneside documents From 0ddfb16666a2412e4029bb91b88497f734f17e34 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 27 Oct 2020 23:59:02 +0900 Subject: [PATCH 118/124] Update CHANGES for PR #8333 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 53973822a..b9a690272 100644 --- a/CHANGES +++ b/CHANGES @@ -58,6 +58,7 @@ Bugs fixed * #8255: py domain: number in default argument value is changed from hexadecimal to decimal * #8343: html search: Fix unnecessary load of images when parsing the document +* #8254: html theme: Line numbers misalign with code lines * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) * #8215: Eliminate Fancyhdr build warnings for oneside documents From 9fc5c37817c58aaf0ad319307ba4df3586efb6f1 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Wed, 28 Oct 2020 00:02:14 +0900 Subject: [PATCH 119/124] Update CHANGES for PR #8316 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index b9a690272..d55972c8e 100644 --- a/CHANGES +++ b/CHANGES @@ -57,6 +57,7 @@ Bugs fixed * #7973: imgconverter: Check availability of imagemagick many times * #8255: py domain: number in default argument value is changed from hexadecimal to decimal +* #8316: html: Prevent arrow keys changing page when button elements are focused * #8343: html search: Fix unnecessary load of images when parsing the document * #8254: html theme: Line numbers misalign with code lines * #8093: The highlight warning has wrong location in some builders (LaTeX, From 2c2335bbb8af99fa132e1573bbf45dc91584d5a2 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Wed, 28 Oct 2020 00:04:10 +0900 Subject: [PATCH 120/124] Update CHANGES for PR #8304 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index d55972c8e..d86bd2eb6 100644 --- a/CHANGES +++ b/CHANGES @@ -29,6 +29,7 @@ Features added * #8289: epub: Allow to suppress "duplicated ToC entry found" warnings from epub builder using :confval:`suppress_warnings`. * #8298: sphinx-quickstart: Add :option:`sphinx-quickstart --no-sep` option +* #8304: sphinx.testing: Register public markers in sphinx.testing.fixtures Bugs fixed ---------- From 751b7a025117c1eaceffa2dd0855ec783f5ecd3d Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 30 Oct 2020 00:50:55 +0900 Subject: [PATCH 121/124] Update CHANGES for PR #8051 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index c280b44cc..694664f6f 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,7 @@ Features added builder using :confval:`suppress_warnings`. * #8298: sphinx-quickstart: Add :option:`sphinx-quickstart --no-sep` option * #8304: sphinx.testing: Register public markers in sphinx.testing.fixtures +* #8051: napoleon: use the obj role for all See Also items Bugs fixed ---------- From 078aaf5f13e01b99619763e4f4eae6665ec2da26 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 30 Oct 2020 00:51:47 +0900 Subject: [PATCH 122/124] napoleon: Remove unused function --- sphinx/ext/napoleon/docstring.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index b5c34a479..20d9e1b9e 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -1188,25 +1188,6 @@ class NumpyDocstring(GoogleDocstring): items.append((name, list(rest), role)) del rest[:] - def search_inventory(inventory, name, hint=None): - roles = list(inventory.keys()) - if hint is not None: - preferred = [ - role - for role in roles - if role.split(":", 1)[-1].startswith(hint) - ] - roles = preferred + [role for role in roles if role not in preferred] - - for role in roles: - objects = inventory[role] - found = objects.get(name, None) - if found is not None: - domain, role = role.split(":", 1) - return role - - return None - def translate(func, description, role): translations = self._config.napoleon_type_aliases if role is not None or not translations: From 0b200d82fd48cf60a51648a9a67eec77296cb61b Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 30 Oct 2020 00:53:59 +0900 Subject: [PATCH 123/124] napoleon: simplify seealso transformation --- sphinx/ext/napoleon/docstring.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 20d9e1b9e..bcd2d2426 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -1240,14 +1240,13 @@ class NumpyDocstring(GoogleDocstring): for func, description, role in items ] - func_role = 'obj' lines = [] # type: List[str] last_had_desc = True - for func, desc, role in items: + for name, desc, role in items: if role: - link = ':%s:`%s`' % (role, func) + link = ':%s:`%s`' % (role, name) else: - link = ':%s:`%s`' % (func_role, func) + link = ':obj:`%s`' % name if desc or last_had_desc: lines += [''] lines += [link] From 73f538da0ff0350b4e7b1f92e58a09f66074c833 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 30 Oct 2020 02:00:53 +0900 Subject: [PATCH 124/124] Update CHANGES for PR #8050 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 694664f6f..4654a2a63 100644 --- a/CHANGES +++ b/CHANGES @@ -31,6 +31,7 @@ Features added * #8298: sphinx-quickstart: Add :option:`sphinx-quickstart --no-sep` option * #8304: sphinx.testing: Register public markers in sphinx.testing.fixtures * #8051: napoleon: use the obj role for all See Also items +* #8050: napoleon: Apply :confval:`napoleon_preprocess_types` to every field Bugs fixed ----------