Skip to content

Commit

Permalink
Merge branch '5.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed May 22, 2022
2 parents eb7f84d + 4c664ae commit fffba7b
Show file tree
Hide file tree
Showing 152 changed files with 850 additions and 622 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/coverage.yml
@@ -0,0 +1,32 @@
name: Coverage

on: [push]

jobs:
coverage:
runs-on: ubuntu-latest
if: github.repository_owner == 'sphinx-doc'

steps:
- uses: actions/checkout@v3
- name: Set up Python 3
uses: actions/setup-python@v3
with:
python-version: 3

- name: Check Python version
run: python --version

- name: Install graphviz
run: sudo apt-get install graphviz

- name: Install dependencies
run: python -m pip install -U pip tox pytest-cov

- name: Run Tox
run: tox --sitepackages -e py -- -vv
env:
PYTEST_ADDOPTS: "--cov ./ --cov-append --cov-config setup.cfg"

- name: codecov
uses: codecov/codecov-action@v3
29 changes: 0 additions & 29 deletions .github/workflows/main.yml
Expand Up @@ -56,32 +56,3 @@ jobs:
run: python -m pip install -U pip tox
- name: Run Tox
run: tox -e py -- -vv

coverage:
# only run on pushes to branches in the sphinx-doc/sphinx repo
if: github.repository_owner == 'sphinx-doc' && github.event_name == 'push'
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Python 3
uses: actions/setup-python@v3
with:
python-version: 3

- name: Check Python version
run: python --version

- name: Install graphviz
run: sudo apt-get install graphviz

- name: Install dependencies
run: python -m pip install -U pip tox pytest-cov

- name: Run Tox
run: tox --sitepackages -e py -- -vv
env:
PYTEST_ADDOPTS: "--cov ./ --cov-append --cov-config setup.cfg"

- name: codecov
uses: codecov/codecov-action@v3
12 changes: 12 additions & 0 deletions CHANGES
Expand Up @@ -58,6 +58,18 @@ Features added
Bugs fixed
----------

* #9575: autodoc: The annotation of return value should not be shown when
``autodoc_typehints="description"``
* #9648: autodoc: ``*args`` and ``**kwargs`` entries are duplicated when
``autodoc_typehints="description"``
* #8180: autodoc: Docstring metadata ignored for attributes
* #10443: epub: EPUB builder can't detect the mimetype of .webp file
* #10456: py domain: ``:meta:`` fields are displayed if docstring contains two
or more meta-field
* #9096: sphinx-build: the value of progress bar for paralle build is wrong
* #10110: sphinx-build: exit code is not changed when error is raised on
builder-finished event

Testing
--------

Expand Down
10 changes: 5 additions & 5 deletions doc/development/theming.rst
Expand Up @@ -248,11 +248,11 @@ Now, you will have access to this function in jinja like so:
Add your own static files to the build assets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you are packaging your own build assets with an extension
(e.g., a CSS or JavaScript file), you need to ensure that they are placed
in the ``_static/`` folder of HTML outputs. To do so, you may copy them directly
into a build's ``_static/`` folder at build time, generally via an event hook.
Here is some sample code to accomplish this:
By default, Sphinx copies static files on the ``static/`` directory of the template
directory. However, if your package needs to place static files outside of the
``static/`` directory for some reasons, you need to copy them to the ``_static/``
directory of HTML outputs manually at the build via an event hook. Here is an
example of code to accomplish this:

.. code-block:: python
Expand Down
17 changes: 10 additions & 7 deletions doc/usage/extensions/imgconverter.rst
Expand Up @@ -12,13 +12,14 @@ This extension converts images in your document to appropriate format for
builders. For example, it allows you to use SVG images with LaTeX builder.
As a result, you don't mind what image format the builder supports.

Internally, this extension uses Imagemagick_ to convert images.
By default the extension uses ImageMagick_ to perform conversions,
and will not work if ImageMagick is not installed.

.. _Imagemagick: https://www.imagemagick.org/script/index.php
.. _ImageMagick: https://www.imagemagick.org

.. note::

Imagemagick rasterizes a SVG image on conversion. As a result, the image
ImageMagick rasterizes a SVG image on conversion. As a result, the image
becomes not scalable. To avoid that, please use other image converters like
`sphinxcontrib-svg2pdfconverter`__ (which uses Inkscape or
``rsvg-convert``).
Expand All @@ -31,10 +32,12 @@ Configuration

.. confval:: image_converter

A path to :command:`convert` command. By default, the imgconverter uses
A path to a conversion command. By default, the imgconverter finds
the command from search paths.

On windows platform, :command:`magick` command is used by default.
On Unix platforms, the command :command:`convert` is used by default.

On Windows, the command :command:`magick` is used by default.

.. versionchanged:: 3.1

Expand All @@ -45,8 +48,8 @@ Configuration
Additional command-line arguments to give to :command:`convert`, as a list.
The default is an empty list ``[]``.

On windows platform, it defaults to ``["convert"]``.
On Windows, it defaults to ``["convert"]``.

.. versionchanged:: 3.1

Use ``["convert"]`` by default on windows
Use ``["convert"]`` by default on Windows
57 changes: 29 additions & 28 deletions sphinx/application.py
Expand Up @@ -328,42 +328,43 @@ def build(self, force_all: bool = False, filenames: List[str] = None) -> None:
self.builder.compile_update_catalogs()
self.builder.build_update()

if self._warncount and self.keep_going:
self.statuscode = 1

status = (__('succeeded') if self.statuscode == 0
else __('finished with problems'))
if self._warncount:
if self.warningiserror:
if self._warncount == 1:
msg = __('build %s, %s warning (with warnings treated as errors).')
else:
msg = __('build %s, %s warnings (with warnings treated as errors).')
else:
if self._warncount == 1:
msg = __('build %s, %s warning.')
else:
msg = __('build %s, %s warnings.')

logger.info(bold(msg % (status, self._warncount)))
else:
logger.info(bold(__('build %s.') % status))

if self.statuscode == 0 and self.builder.epilog:
logger.info('')
logger.info(self.builder.epilog % {
'outdir': relpath(self.outdir),
'project': self.config.project
})
self.events.emit('build-finished', None)
except Exception as err:
# delete the saved env to force a fresh build next time
envfile = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
if path.isfile(envfile):
os.unlink(envfile)
self.events.emit('build-finished', err)
raise

if self._warncount and self.keep_going:
self.statuscode = 1

status = (__('succeeded') if self.statuscode == 0
else __('finished with problems'))
if self._warncount:
if self.warningiserror:
if self._warncount == 1:
msg = __('build %s, %s warning (with warnings treated as errors).')
else:
msg = __('build %s, %s warnings (with warnings treated as errors).')
else:
if self._warncount == 1:
msg = __('build %s, %s warning.')
else:
msg = __('build %s, %s warnings.')

logger.info(bold(msg % (status, self._warncount)))
else:
self.events.emit('build-finished', None)
logger.info(bold(__('build %s.') % status))

if self.statuscode == 0 and self.builder.epilog:
logger.info('')
logger.info(self.builder.epilog % {
'outdir': relpath(self.outdir),
'project': self.config.project
})

self.builder.cleanup()

# ---- general extensibility interface -------------------------------------
Expand Down
32 changes: 23 additions & 9 deletions sphinx/builders/__init__.py
Expand Up @@ -25,6 +25,7 @@
from sphinx.util.osutil import SEP, ensuredir, relative_uri, relpath
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, parallel_available
from sphinx.util.tags import Tags
from sphinx.util.typing import NoneType

# side effect: registers roles and directives
from sphinx import directives # NOQA isort:skip
Expand Down Expand Up @@ -429,6 +430,13 @@ def _read_serial(self, docnames: List[str]) -> None:
self.read_doc(docname)

def _read_parallel(self, docnames: List[str], nproc: int) -> None:
chunks = make_chunks(docnames, nproc)

# create a status_iterator to step progressbar after reading a document
# (see: ``merge()`` function)
progress = status_iterator(chunks, __('reading sources... '), "purple",
len(chunks), self.app.verbosity)

# clear all outdated docs at once
for docname in docnames:
self.events.emit('env-purge-doc', self.env, docname)
Expand All @@ -445,16 +453,15 @@ def merge(docs: List[str], otherenv: bytes) -> None:
env = pickle.loads(otherenv)
self.env.merge_info_from(docs, env, self.app)

tasks = ParallelTasks(nproc)
chunks = make_chunks(docnames, nproc)
next(progress)

for chunk in status_iterator(chunks, __('reading sources... '), "purple",
len(chunks), self.app.verbosity):
tasks = ParallelTasks(nproc)
for chunk in chunks:
tasks.add_task(read_process, chunk, merge)

# make sure all threads have finished
logger.info(bold(__('waiting for workers...')))
tasks.join()
logger.info('')

def read_doc(self, docname: str) -> None:
"""Parse a file and add/update inventory entries for the doctree."""
Expand Down Expand Up @@ -563,19 +570,26 @@ def write_process(docs: List[Tuple[str, nodes.document]]) -> None:
tasks = ParallelTasks(nproc)
chunks = make_chunks(docnames, nproc)

# create a status_iterator to step progressbar after writing a document
# (see: ``on_chunk_done()`` function)
progress = status_iterator(chunks, __('writing output... '), "darkgreen",
len(chunks), self.app.verbosity)

def on_chunk_done(args: List[Tuple[str, NoneType]], result: NoneType) -> None:
next(progress)

self.app.phase = BuildPhase.RESOLVING
for chunk in status_iterator(chunks, __('writing output... '), "darkgreen",
len(chunks), self.app.verbosity):
for chunk in chunks:
arg = []
for docname in chunk:
doctree = self.env.get_and_resolve_doctree(docname, self)
self.write_doc_serialized(docname, doctree)
arg.append((docname, doctree))
tasks.add_task(write_process, arg)
tasks.add_task(write_process, arg, on_chunk_done)

# make sure all threads have finished
logger.info(bold(__('waiting for workers...')))
tasks.join()
logger.info('')

def prepare_writing(self, docnames: Set[str]) -> None:
"""A place where you can add logic before :meth:`write_doc` is run"""
Expand Down
1 change: 1 addition & 0 deletions sphinx/builders/_epub_base.py
Expand Up @@ -56,6 +56,7 @@
'.xhtml': 'application/xhtml+xml',
'.css': 'text/css',
'.png': 'image/png',
'.webp': 'image/webp',
'.gif': 'image/gif',
'.svg': 'image/svg+xml',
'.jpg': 'image/jpeg',
Expand Down
4 changes: 2 additions & 2 deletions sphinx/domains/python.py
Expand Up @@ -1068,11 +1068,11 @@ def filter_meta_fields(app: Sphinx, domain: str, objtype: str, content: Element)
for node in content:
if isinstance(node, nodes.field_list):
fields = cast(List[nodes.field], node)
for field in fields:
# removing list items while iterating the list needs reversed()
for field in reversed(fields):
field_name = cast(nodes.field_body, field[0]).astext().strip()
if field_name == 'meta' or field_name.startswith('meta '):
node.remove(field)
break


class PythonModuleIndex(Index):
Expand Down
9 changes: 8 additions & 1 deletion sphinx/ext/autodoc/importer.py
Expand Up @@ -280,12 +280,19 @@ def get_class_members(subject: Any, objpath: List[str], attrgetter: Callable
members[name] = ObjectMember(name, INSTANCEATTR, class_=cls,
docstring=docstring)

# append instance attributes (cf. self.attr1) if analyzer knows
# append or complete instance attributes (cf. self.attr1) if analyzer knows
if analyzer:
for (ns, name), docstring in analyzer.attr_docs.items():
if ns == qualname and name not in members:
# otherwise unknown instance attribute
members[name] = ObjectMember(name, INSTANCEATTR, class_=cls,
docstring='\n'.join(docstring))
elif (ns == qualname and docstring and
isinstance(members[name], ObjectMember) and
not members[name].docstring):
# attribute is already known, because dir(subject) enumerates it.
# But it has no docstring yet
members[name].docstring = '\n'.join(docstring)
except AttributeError:
pass

Expand Down

0 comments on commit fffba7b

Please sign in to comment.