From 5008291b3d2ab92309f1dbc087b0c0b1c7f4e29f Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Sat, 7 Jan 2023 15:08:04 +0000 Subject: [PATCH 1/5] Ignore more checks in Ruff 0.0.213 --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index fa3b3bb95f5..5884b7fe329 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -162,9 +162,12 @@ ignore = [ # flake8-bandit "S101", # assert used "S105", # possible hardcoded password + "S113", # probable use of requests call without timeout + "S324", # probable use of insecure hash functions # flake8-simplify "SIM102", # nested 'if' statements "SIM105", # use contextlib.suppress + "SIM108", # use ternary operator "SIM117", # use single 'with' statement ] external = [ # Whitelist for RUF100 unkown code warnings From a1cd19e601f89e1796d1992cbeaf6b476e2be6a0 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Sat, 7 Jan 2023 17:35:21 +0000 Subject: [PATCH 2/5] Fix copying images under parallel execution (#11100) --- sphinx/builders/_epub_base.py | 11 +++++++---- sphinx/builders/html/__init__.py | 11 +++++++---- sphinx/builders/latex/__init__.py | 11 +++++++---- sphinx/builders/texinfo.py | 11 +++++++---- tests/test_build_epub.py | 20 ++++++++++++++++++++ tests/test_build_html.py | 19 +++++++++++++++++++ tests/test_build_latex.py | 23 +++++++++++++++++++++++ tests/test_build_texinfo.py | 20 ++++++++++++++++++++ 8 files changed, 110 insertions(+), 16 deletions(-) diff --git a/sphinx/builders/_epub_base.py b/sphinx/builders/_epub_base.py index ef857e9d358..7174914bb6c 100644 --- a/sphinx/builders/_epub_base.py +++ b/sphinx/builders/_epub_base.py @@ -401,9 +401,12 @@ def copy_image_files_pil(self) -> None: the format and resizing the image if necessary/possible. """ ensuredir(path.join(self.outdir, self.imagedir)) - for src in status_iterator(self.images, __('copying images... '), "brown", - len(self.images), self.app.verbosity): - dest = self.images[src] + converted_images = {*self.env.original_image_uri.values()} + for src in status_iterator(self.env.images, __('copying images... '), "brown", + len(self.env.images), self.app.verbosity): + if src in converted_images: + continue + _docnames, dest = self.env.images[src] try: img = Image.open(path.join(self.srcdir, src)) except OSError: @@ -438,7 +441,7 @@ def copy_image_files(self) -> None: """Copy image files to destination directory. This overwritten method can use Pillow to convert image files. """ - if self.images: + if self.env.images: if self.config.epub_fix_images or self.config.epub_max_image_width: if not Image: logger.warning(__('Pillow not found - copying image files')) diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py index 0fb64decdf4..063d194713d 100644 --- a/sphinx/builders/html/__init__.py +++ b/sphinx/builders/html/__init__.py @@ -764,13 +764,16 @@ def write_domain_indices(self) -> None: self.handle_page(indexname, indexcontext, 'domainindex.html') def copy_image_files(self) -> None: - if self.images: + if self.env.images: + converted_images = {*self.env.original_image_uri.values()} stringify_func = ImageAdapter(self.app.env).get_original_image_uri ensuredir(path.join(self.outdir, self.imagedir)) - for src in status_iterator(self.images, __('copying images... '), "brown", - len(self.images), self.app.verbosity, + for src in status_iterator(self.env.images, __('copying images... '), "brown", + len(self.env.images), self.app.verbosity, stringify_func=stringify_func): - dest = self.images[src] + if src in converted_images: + continue + _docnames, dest = self.env.images[src] try: copyfile(path.join(self.srcdir, src), path.join(self.outdir, self.imagedir, dest)) diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index edc314dc93f..0a9de19e54c 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -413,12 +413,15 @@ def copy_latex_additional_files(self) -> None: copy_asset_file(path.join(self.confdir, filename), self.outdir) def copy_image_files(self) -> None: - if self.images: + if self.env.images: + converted_images = {*self.env.original_image_uri.values()} stringify_func = ImageAdapter(self.app.env).get_original_image_uri - for src in status_iterator(self.images, __('copying images... '), "brown", - len(self.images), self.app.verbosity, + for src in status_iterator(self.env.images, __('copying images... '), "brown", + len(self.env.images), self.app.verbosity, stringify_func=stringify_func): - dest = self.images[src] + if src in converted_images: + continue + _docnames, dest = self.env.images[src] try: copy_asset_file(path.join(self.srcdir, src), path.join(self.outdir, dest)) diff --git a/sphinx/builders/texinfo.py b/sphinx/builders/texinfo.py index d2ae72ef7b6..19aeaa5ea8e 100644 --- a/sphinx/builders/texinfo.py +++ b/sphinx/builders/texinfo.py @@ -173,12 +173,15 @@ def finish(self) -> None: self.copy_support_files() def copy_image_files(self, targetname: str) -> None: - if self.images: + if self.env.images: + converted_images = {*self.env.original_image_uri.values()} stringify_func = ImageAdapter(self.app.env).get_original_image_uri - for src in status_iterator(self.images, __('copying images... '), "brown", - len(self.images), self.app.verbosity, + for src in status_iterator(self.env.images, __('copying images... '), "brown", + len(self.env.images), self.app.verbosity, stringify_func=stringify_func): - dest = self.images[src] + if src in converted_images: + continue + _docnames, dest = self.env.images[src] try: imagedir = path.join(self.outdir, targetname + '-figures') ensuredir(imagedir) diff --git a/tests/test_build_epub.py b/tests/test_build_epub.py index a50c51e255f..86fdae0cd68 100644 --- a/tests/test_build_epub.py +++ b/tests/test_build_epub.py @@ -2,6 +2,7 @@ import os import subprocess +from pathlib import Path from subprocess import CalledProcessError from xml.etree import ElementTree @@ -390,3 +391,22 @@ def test_xml_name_pattern_check(): assert _XML_NAME_PATTERN.match('id-pub') assert _XML_NAME_PATTERN.match('webpage') assert not _XML_NAME_PATTERN.match('1bfda21') + + +@pytest.mark.sphinx('epub', testroot='images') +def test_copy_images(app, status, warning): + app.build() + + images_dir = Path(app.outdir) / '_images' + images = {image.name for image in images_dir.rglob('*')} + assert images == { + 'img.gif', + 'img.pdf', + 'img.png', + 'python-logo.png', + 'rimg.png', + 'rimg1.png', + 'svgimg.pdf', + 'svgimg.svg', + 'testimäge.png', + } diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 5eed5d5eaf2..89350e82d0c 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -3,6 +3,7 @@ import os import re from itertools import chain, cycle +from pathlib import Path from unittest.mock import ANY, call, patch import pytest @@ -1770,3 +1771,21 @@ def test_theme_having_multiple_stylesheets(app): assert '' in content assert '' in content + + +@pytest.mark.sphinx('html', testroot='images') +def test_copy_images(app, status, warning): + app.build() + + images_dir = Path(app.outdir) / '_images' + images = {image.name for image in images_dir.rglob('*')} + assert images == { + 'img.gif', + 'img.pdf', + 'img.png', + 'rimg.png', + 'rimg1.png', + 'svgimg.pdf', + 'svgimg.svg', + 'testimäge.png', + } diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index f20fc67c585..3f1206ac8b8 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -4,6 +4,7 @@ import re import subprocess from itertools import product +from pathlib import Path from shutil import copyfile from subprocess import CalledProcessError @@ -1670,3 +1671,25 @@ def test_latex_code_role(app): common_content + '%\n}} code block') in content assert (r'\begin{sphinxVerbatim}[commandchars=\\\{\}]' + '\n' + common_content + '\n' + r'\end{sphinxVerbatim}') in content + + +@pytest.mark.sphinx('latex', testroot='images') +def test_copy_images(app, status, warning): + app.build() + + test_dir = Path(app.outdir) + images = { + image.name for image in test_dir.rglob('*') + if image.suffix in {'.gif', '.pdf', '.png', '.svg'} + } + assert images == { + 'img.gif', + 'img.pdf', + 'img.png', + 'python-logo.png', + 'rimg.png', + 'rimg1.png', + 'svgimg.pdf', + 'svgimg.svg', + 'testimäge.png', + } diff --git a/tests/test_build_texinfo.py b/tests/test_build_texinfo.py index 974cb1965f5..aae5689b709 100644 --- a/tests/test_build_texinfo.py +++ b/tests/test_build_texinfo.py @@ -3,6 +3,7 @@ import os import re import subprocess +from pathlib import Path from subprocess import CalledProcessError from unittest.mock import Mock @@ -137,3 +138,22 @@ def test_texinfo_samp_with_variable(app, status, warning): assert '@code{@var{variable_only}}' in output assert '@code{@var{variable} and text}' in output assert '@code{Show @var{variable} in the middle}' in output + + +@pytest.mark.sphinx('texinfo', testroot='images') +def test_copy_images(app, status, warning): + app.build() + + images_dir = Path(app.outdir) / 'python-figures' + images = {image.name for image in images_dir.rglob('*')} + assert images == { + 'img.gif', + 'img.pdf', + 'img.png', + 'python-logo.png', + 'rimg.png', + 'rimg1.png', + 'svgimg.pdf', + 'svgimg.svg', + 'testimäge.png', + } From d8a5dd8364d19f693d5f017f615a8037784a0295 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Sat, 7 Jan 2023 17:37:41 +0000 Subject: [PATCH 3/5] Add note to CHANGES for PR 11100 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 51147663be4..40ad5db9af0 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Bugs fixed margin since Sphinx 5.1.0 .. _contents: https://docutils.sourceforge.io/docs/ref/rst/directives.html#table-of-contents +* #11100: Fix copying images when running under parallel mode. Release 6.1.1 (released Jan 05, 2023) ===================================== From 393b40825282311a8ba81c830ef3c6fae9335c32 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Sat, 7 Jan 2023 17:38:13 +0000 Subject: [PATCH 4/5] Bump to 6.1.2 final --- CHANGES | 4 ++-- sphinx/__init__.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 40ad5db9af0..da4573de93c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,5 @@ -Release 6.1.2 (in development) -============================== +Release 6.1.2 (released Jan 07, 2023) +===================================== Bugs fixed ---------- diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 410845f09d4..eeef3034545 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -19,7 +19,7 @@ warnings.filterwarnings('ignore', 'The frontend.Option class .*', DeprecationWarning, module='docutils.frontend') -__version__ = '6.1.1' +__version__ = '6.1.2' __display_version__ = __version__ # used for command line version #: Version info for better programmatic use. @@ -30,7 +30,7 @@ #: #: .. versionadded:: 1.2 #: Before version 1.2, check the string ``sphinx.__version__``. -version_info = (6, 1, 1, 'final', 0) +version_info = (6, 1, 2, 'final', 0) package_dir = path.abspath(path.dirname(__file__)) From ddbc5b57f467823d600341ed1cfe5bedde5d7b64 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Sat, 7 Jan 2023 17:45:46 +0000 Subject: [PATCH 5/5] Bump version --- CHANGES | 21 +++++++++++++++++++++ sphinx/__init__.py | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index da4573de93c..222eea8d8d2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,24 @@ +Release 6.1.3 (in development) +============================== + +Dependencies +------------ + +Incompatible changes +-------------------- + +Deprecated +---------- + +Features added +-------------- + +Bugs fixed +---------- + +Testing +-------- + Release 6.1.2 (released Jan 07, 2023) ===================================== diff --git a/sphinx/__init__.py b/sphinx/__init__.py index eeef3034545..5c3e705e20e 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -19,7 +19,7 @@ warnings.filterwarnings('ignore', 'The frontend.Option class .*', DeprecationWarning, module='docutils.frontend') -__version__ = '6.1.2' +__version__ = '6.1.3' __display_version__ = __version__ # used for command line version #: Version info for better programmatic use. @@ -30,11 +30,11 @@ #: #: .. versionadded:: 1.2 #: Before version 1.2, check the string ``sphinx.__version__``. -version_info = (6, 1, 2, 'final', 0) +version_info = (6, 1, 3, 'beta', 0) package_dir = path.abspath(path.dirname(__file__)) -_in_development = False +_in_development = True if _in_development: # Only import subprocess if needed import subprocess