Skip to content

Commit

Permalink
Merge branch '4.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed May 22, 2021
2 parents 1514b03 + 4f5ab7c commit 1f711d0
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 51 deletions.
6 changes: 3 additions & 3 deletions .circleci/config.yml
Expand Up @@ -8,9 +8,9 @@ jobs:
working_directory: /sphinx
steps:
- checkout
- run: /python3.6/bin/pip install -U pip setuptools
- run: /python3.6/bin/pip install -U .[test]
- run: /python3.8/bin/pip install -U pip setuptools
- run: /python3.8/bin/pip install -U .[test]
- run: mkdir -p test-reports/pytest
- run: make test PYTHON=/python3.6/bin/python TEST="--junitxml=test-reports/pytest/results.xml -vv"
- run: make test PYTHON=/python3.8/bin/python TEST="--junitxml=test-reports/pytest/results.xml -vv"
- store_test_results:
path: test-reports
37 changes: 26 additions & 11 deletions CHANGES
Expand Up @@ -33,6 +33,8 @@ Incompatible changes
Deprecated
----------

* The ``app`` argument of ``sphinx.environment.BuildEnvironment`` becomes
required
* ``sphinx.application.Sphinx.html_theme``
* ``sphinx.util.docstrings.extract_metadata()``

Expand Down Expand Up @@ -60,6 +62,7 @@ Features added
text
* #9176: i18n: Emit a debug message if message catalog file not found under
:confval:`locale_dirs`
* #1874: py domain: Support union types using ``|`` in info-field-list
* #9097: Optimize the paralell build
* #9131: Add :confval:`nitpick_ignore_regex` to ignore nitpicky warnings using
regular expressions
Expand All @@ -80,23 +83,15 @@ Bugs fixed
Testing
--------

Release 4.0.2 (in development)
Release 4.0.3 (in development)
==============================

Dependencies
------------

* #9216: Support jinja2-3.0

Incompatible changes
--------------------

* #9222: Update Underscore.js to 1.13.1
* #9217: manpage: Stop creating a section directory on build manpage by default
(see :confval:`man_make_section_directory`)
* #9240: Unknown node error for pending_xref_condition is raised if an extension
that does not support the node installs a missing-reference handler

Deprecated
----------

Expand All @@ -106,11 +101,31 @@ Features added
Bugs fixed
----------

* #9210: viewcode: crashed if non importable modules found on parallel build

Testing
--------

Release 4.0.2 (released May 20, 2021)
=====================================

Dependencies
------------

* #9216: Support jinja2-3.0

Incompatible changes
--------------------

* #9222: Update Underscore.js to 1.13.1
* #9217: manpage: Stop creating a section directory on build manpage by default
(see :confval:`man_make_section_directory`)

Bugs fixed
----------

* #9210: viewcode: crashed if non importable modules found on parallel build
* #9240: Unknown node error for pending_xref_condition is raised if an extension
that does not support the node installs a missing-reference handler

Release 4.0.1 (released May 11, 2021)
=====================================

Expand Down
5 changes: 5 additions & 0 deletions doc/extdev/deprecated.rst
Expand Up @@ -22,6 +22,11 @@ The following is a list of deprecated interfaces.
- (will be) Removed
- Alternatives

* - The optional argument ``app`` for ``sphinx.environment.BuildEnvironment``
- 4.1
- 6.0
- The required argument

* - ``sphinx.application.Sphinx.html_theme``
- 4.1
- 6.0
Expand Down
13 changes: 7 additions & 6 deletions doc/usage/configuration.rst
Expand Up @@ -591,17 +591,18 @@ General configuration
.. confval:: highlight_language

The default language to highlight source code in. The default is
``'python3'``. The value should be a valid Pygments lexer name, see
``'default'``. It is similar to ``'python3'``; it is mostly a superset of
``'python'`` but it fallbacks to ``'none'`` without warning if failed.
``'python3'`` and other languages will emit warning if failed.

The value should be a valid Pygments lexer name, see
:ref:`code-examples` for more details.

.. versionadded:: 0.5

.. versionchanged:: 1.4
The default is now ``'default'``. It is similar to ``'python3'``;
it is mostly a superset of ``'python'`` but it fallbacks to
``'none'`` without warning if failed. ``'python3'`` and other
languages will emit warning if failed. If you prefer Python 2
only highlighting, you can set it back to ``'python'``.
The default is now ``'default'``. If you prefer Python 2 only
highlighting, you can set it back to ``'python'``.

.. confval:: highlight_options

Expand Down
3 changes: 1 addition & 2 deletions sphinx/application.py
Expand Up @@ -300,8 +300,7 @@ def _init_i18n(self) -> None:
def _init_env(self, freshenv: bool) -> None:
filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
if freshenv or not os.path.exists(filename):
self.env = BuildEnvironment()
self.env.setup(self)
self.env = BuildEnvironment(self)
self.env.find_files(self.config, self.builder)
else:
try:
Expand Down
6 changes: 1 addition & 5 deletions sphinx/domains/python.py
Expand Up @@ -304,7 +304,7 @@ def make_xref(self, rolename: str, domain: str, target: str,
def make_xrefs(self, rolename: str, domain: str, target: str,
innernode: Type[TextlikeNode] = nodes.emphasis,
contnode: Node = None, env: BuildEnvironment = None) -> List[Node]:
delims = r'(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+|\.\.\.)'
delims = r'(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+|\s*\|\s*|\.\.\.)'
delims_re = re.compile(delims)
sub_targets = re.split(delims, target)

Expand Down Expand Up @@ -1363,10 +1363,6 @@ def istyping(s: str) -> bool:

return s in typing.__all__ # type: ignore

content = find_pending_xref_condition(node, 'resolved')
if content:
contnode = content.children[0] # type: ignore

if node.get('refdomain') != 'py':
return None
elif node.get('reftype') in ('class', 'obj') and node.get('reftarget') == 'None':
Expand Down
5 changes: 5 additions & 0 deletions sphinx/environment/__init__.py
Expand Up @@ -10,6 +10,7 @@

import os
import pickle
import warnings
from collections import defaultdict
from copy import copy
from datetime import datetime
Expand All @@ -22,6 +23,7 @@

from sphinx import addnodes
from sphinx.config import Config
from sphinx.deprecation import RemovedInSphinx60Warning
from sphinx.domains import Domain
from sphinx.environment.adapters.toctree import TocTree
from sphinx.errors import BuildEnvironmentError, DocumentError, ExtensionError, SphinxError
Expand Down Expand Up @@ -181,6 +183,9 @@ def __init__(self, app: "Sphinx" = None):
# set up environment
if app:
self.setup(app)
else:
warnings.warn("The 'app' argument for BuildEnvironment() becomes required now.",
RemovedInSphinx60Warning, stacklevel=2)

def __getstate__(self) -> Dict:
"""Obtains serializable data for pickling."""
Expand Down
19 changes: 16 additions & 3 deletions sphinx/ext/autosummary/__init__.py
Expand Up @@ -80,7 +80,9 @@
from sphinx.ext.autodoc.importer import import_module
from sphinx.ext.autodoc.mock import mock
from sphinx.locale import __
from sphinx.project import Project
from sphinx.pycode import ModuleAnalyzer, PycodeError
from sphinx.registry import SphinxComponentRegistry
from sphinx.util import logging, rst
from sphinx.util.docutils import (NullReporter, SphinxDirective, SphinxRole, new_document,
switch_source_input)
Expand Down Expand Up @@ -168,13 +170,24 @@ def autosummary_table_visit_html(self: HTMLTranslator, node: autosummary_table)
_app: Sphinx = None


class FakeApplication:
def __init__(self):
self.doctreedir = None
self.events = None
self.extensions = {}
self.srcdir = None
self.config = Config()
self.project = Project(None, None)
self.registry = SphinxComponentRegistry()


class FakeDirective(DocumenterBridge):
def __init__(self) -> None:
settings = Struct(tab_width=8)
document = Struct(settings=settings)
env = BuildEnvironment()
env.config = Config()
env.config.add('autodoc_class_signature', 'mixed', True, None)
app = FakeApplication()
app.config.add('autodoc_class_signature', 'mixed', True, None)
env = BuildEnvironment(app) # type: ignore
state = Struct(document=document)
super().__init__(env, None, Options(), 0, state)

Expand Down
15 changes: 2 additions & 13 deletions sphinx/ext/intersphinx.py
Expand Up @@ -45,7 +45,6 @@
from sphinx.locale import _, __
from sphinx.util import logging, requests
from sphinx.util.inventory import InventoryFile
from sphinx.util.nodes import find_pending_xref_condition
from sphinx.util.typing import Inventory

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -287,16 +286,6 @@ def missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref,
# Since Sphinx-2.1, properties are stored as py:method
objtypes.append('py:method')

# determine the contnode by pending_xref_condition
content = find_pending_xref_condition(node, 'resolved')
if content:
# resolved condition found.
contnodes = content.children
contnode = content.children[0] # type: ignore
else:
# not resolved. Use the given contnode
contnodes = [contnode]

to_try = [(inventories.main_inventory, target)]
if domain:
full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)
Expand Down Expand Up @@ -329,7 +318,7 @@ def missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref,
newnode = nodes.reference('', '', internal=False, refuri=uri, reftitle=reftitle)
if node.get('refexplicit'):
# use whatever title was given
newnode.extend(contnodes)
newnode.append(contnode)
elif dispname == '-' or \
(domain == 'std' and node['reftype'] == 'keyword'):
# use whatever title was given, but strip prefix
Expand All @@ -338,7 +327,7 @@ def missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref,
newnode.append(contnode.__class__(title[len(in_set) + 1:],
title[len(in_set) + 1:]))
else:
newnode.extend(contnodes)
newnode.append(contnode)
else:
# else use the given display name (used for :ref:)
newnode.append(contnode.__class__(dispname, dispname))
Expand Down
34 changes: 34 additions & 0 deletions tests/test_domain_py.py
Expand Up @@ -1009,6 +1009,40 @@ def test_info_field_list(app):
**{"py:module": "example", "py:class": "Class"})


def test_info_field_list_piped_type(app):
text = (".. py:module:: example\n"
".. py:class:: Class\n"
"\n"
" :param age: blah blah\n"
" :type age: int | str\n")
doctree = restructuredtext.parse(app, text)

assert_node(doctree,
(nodes.target,
addnodes.index,
addnodes.index,
[desc, ([desc_signature, ([desc_annotation, "class "],
[desc_addname, "example."],
[desc_name, "Class"])],
[desc_content, nodes.field_list, nodes.field, (nodes.field_name,
nodes.field_body)])]))
assert_node(doctree[3][1][0][0][1],
([nodes.paragraph, ([addnodes.literal_strong, "age"],
" (",
[pending_xref, addnodes.literal_emphasis, "int"],
[addnodes.literal_emphasis, " | "],
[pending_xref, addnodes.literal_emphasis, "str"],
")",
" -- ",
"blah blah")],))
assert_node(doctree[3][1][0][0][1][0][2], pending_xref,
refdomain="py", reftype="class", reftarget="int",
**{"py:module": "example", "py:class": "Class"})
assert_node(doctree[3][1][0][0][1][0][4], pending_xref,
refdomain="py", reftype="class", reftarget="str",
**{"py:module": "example", "py:class": "Class"})


def test_info_field_list_var(app):
text = (".. py:class:: Class\n"
"\n"
Expand Down
8 changes: 0 additions & 8 deletions tests/test_ext_intersphinx.py
Expand Up @@ -196,14 +196,6 @@ def test_missing_reference_pydomain(tempdir, app, status, warning):
rn = missing_reference(app, app.env, node, contnode)
assert rn.astext() == 'Foo.bar'

# pending_xref_condition="resolved"
node = addnodes.pending_xref('', reftarget='Foo.bar', refdomain='py', reftype='attr')
node['py:module'] = 'module1'
node += addnodes.pending_xref_condition('', 'Foo.bar', condition='resolved')
node += addnodes.pending_xref_condition('', 'module1.Foo.bar', condition='*')
rn = missing_reference(app, app.env, node, nodes.Text('dummy-cont-node'))
assert rn.astext() == 'Foo.bar'


def test_missing_reference_stddomain(tempdir, app, status, warning):
inv_file = tempdir / 'inventory'
Expand Down

0 comments on commit 1f711d0

Please sign in to comment.