From 7841d3d9b2db9ed686fec7e2222c720dfa32c1b4 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Sat, 7 Jan 2023 22:28:45 +0000 Subject: [PATCH 1/7] Ignore more checks in Ruff 0.0.214 --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 5884b7fe329..567cf9356a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -166,6 +166,7 @@ ignore = [ "S324", # probable use of insecure hash functions # flake8-simplify "SIM102", # nested 'if' statements + "SIM103", # return condition directly "SIM105", # use contextlib.suppress "SIM108", # use ternary operator "SIM117", # use single 'with' statement From 2a7c40d07f4b0e0fd2a4bc942e74634c2df24dee Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 10 Jan 2023 14:18:46 +0000 Subject: [PATCH 2/7] Undo parallel image changes --- sphinx/builders/_epub_base.py | 11 ++++------- sphinx/builders/html/__init__.py | 19 +++++++++---------- sphinx/builders/latex/__init__.py | 11 ++++------- sphinx/builders/texinfo.py | 11 ++++------- sphinx/writers/_html4.py | 6 +++--- sphinx/writers/html5.py | 6 +++--- tests/test_build_epub.py | 5 +---- tests/test_build_html.py | 3 --- tests/test_build_latex.py | 7 +------ tests/test_build_texinfo.py | 7 +------ 10 files changed, 30 insertions(+), 56 deletions(-) diff --git a/sphinx/builders/_epub_base.py b/sphinx/builders/_epub_base.py index 7174914bb6c..ef857e9d358 100644 --- a/sphinx/builders/_epub_base.py +++ b/sphinx/builders/_epub_base.py @@ -401,12 +401,9 @@ def copy_image_files_pil(self) -> None: the format and resizing the image if necessary/possible. """ ensuredir(path.join(self.outdir, self.imagedir)) - 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] + for src in status_iterator(self.images, __('copying images... '), "brown", + len(self.images), self.app.verbosity): + dest = self.images[src] try: img = Image.open(path.join(self.srcdir, src)) except OSError: @@ -441,7 +438,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.env.images: + if self.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 063d194713d..9927790fff2 100644 --- a/sphinx/builders/html/__init__.py +++ b/sphinx/builders/html/__init__.py @@ -656,9 +656,6 @@ def get_doc_context(self, docname: str, body: str, metatags: str) -> dict[str, A } def write_doc(self, docname: str, doctree: nodes.document) -> None: - self.imgpath = relative_uri(self.get_target_uri(docname), self.imagedir) - self.post_process_images(doctree) - title_node = self.env.longtitles.get(docname) title = self.render_partial(title_node)['title'] if title_node else '' self.index_page(docname, doctree, title) @@ -668,6 +665,7 @@ def write_doc(self, docname: str, doctree: nodes.document) -> None: self.secnumbers = self.env.toc_secnumbers.get(docname, {}) self.fignumbers = self.env.toc_fignumbers.get(docname, {}) + self.imgpath = relative_uri(self.get_target_uri(docname), '_images') self.dlpath = relative_uri(self.get_target_uri(docname), '_downloads') self.current_docname = docname self.docwriter.write(doctree, destination) @@ -678,6 +676,10 @@ def write_doc(self, docname: str, doctree: nodes.document) -> None: ctx = self.get_doc_context(docname, body, metatags) self.handle_page(docname, ctx, event_arg=doctree) + def write_doc_serialized(self, docname: str, doctree: nodes.document) -> None: + self.imgpath = relative_uri(self.get_target_uri(docname), self.imagedir) + self.post_process_images(doctree) + def finish(self) -> None: self.finish_tasks.add_task(self.gen_indices) self.finish_tasks.add_task(self.gen_pages_from_extensions) @@ -764,16 +766,13 @@ def write_domain_indices(self) -> None: self.handle_page(indexname, indexcontext, 'domainindex.html') def copy_image_files(self) -> None: - if self.env.images: - converted_images = {*self.env.original_image_uri.values()} + if self.images: stringify_func = ImageAdapter(self.app.env).get_original_image_uri ensuredir(path.join(self.outdir, self.imagedir)) - for src in status_iterator(self.env.images, __('copying images... '), "brown", - len(self.env.images), self.app.verbosity, + for src in status_iterator(self.images, __('copying images... '), "brown", + len(self.images), self.app.verbosity, stringify_func=stringify_func): - if src in converted_images: - continue - _docnames, dest = self.env.images[src] + dest = self.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 0a9de19e54c..edc314dc93f 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -413,15 +413,12 @@ 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.env.images: - converted_images = {*self.env.original_image_uri.values()} + if self.images: stringify_func = ImageAdapter(self.app.env).get_original_image_uri - for src in status_iterator(self.env.images, __('copying images... '), "brown", - len(self.env.images), self.app.verbosity, + for src in status_iterator(self.images, __('copying images... '), "brown", + len(self.images), self.app.verbosity, stringify_func=stringify_func): - if src in converted_images: - continue - _docnames, dest = self.env.images[src] + dest = self.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 19aeaa5ea8e..d2ae72ef7b6 100644 --- a/sphinx/builders/texinfo.py +++ b/sphinx/builders/texinfo.py @@ -173,15 +173,12 @@ def finish(self) -> None: self.copy_support_files() def copy_image_files(self, targetname: str) -> None: - if self.env.images: - converted_images = {*self.env.original_image_uri.values()} + if self.images: stringify_func = ImageAdapter(self.app.env).get_original_image_uri - for src in status_iterator(self.env.images, __('copying images... '), "brown", - len(self.env.images), self.app.verbosity, + for src in status_iterator(self.images, __('copying images... '), "brown", + len(self.images), self.app.verbosity, stringify_func=stringify_func): - if src in converted_images: - continue - _docnames, dest = self.env.images[src] + dest = self.images[src] try: imagedir = path.join(self.outdir, targetname + '-figures') ensuredir(imagedir) diff --git a/sphinx/writers/_html4.py b/sphinx/writers/_html4.py index 3d36784cec7..7aec4c892ad 100644 --- a/sphinx/writers/_html4.py +++ b/sphinx/writers/_html4.py @@ -287,14 +287,14 @@ def append_fignumber(figtype: str, figure_id: str) -> None: else: key = figtype - if figure_id in self.builder.fignumbers.get(key, {}): # type: ignore[has-type] + if figure_id in self.builder.fignumbers.get(key, {}): self.body.append('') prefix = self.config.numfig_format.get(figtype) if prefix is None: msg = __('numfig_format is not defined for %s') % figtype logger.warning(msg) else: - numbers = self.builder.fignumbers[key][figure_id] # type: ignore[has-type] + numbers = self.builder.fignumbers[key][figure_id] self.body.append(prefix % '.'.join(map(str, numbers)) + ' ') self.body.append('') @@ -569,7 +569,7 @@ def visit_download_reference(self, node: Element) -> None: self.context.append('') elif 'filename' in node: atts['class'] += ' internal' - atts['href'] = posixpath.join(self.builder.dlpath, # type: ignore[has-type] + atts['href'] = posixpath.join(self.builder.dlpath, urllib.parse.quote(node['filename'])) self.body.append(self.starttag(node, 'a', '', **atts)) self.context.append('') diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index 7a62161b54e..edf8bdc237f 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -293,14 +293,14 @@ def append_fignumber(figtype: str, figure_id: str) -> None: else: key = figtype - if figure_id in self.builder.fignumbers.get(key, {}): # type: ignore[has-type] + if figure_id in self.builder.fignumbers.get(key, {}): self.body.append('') prefix = self.config.numfig_format.get(figtype) if prefix is None: msg = __('numfig_format is not defined for %s') % figtype logger.warning(msg) else: - numbers = self.builder.fignumbers[key][figure_id] # type: ignore[has-type] + numbers = self.builder.fignumbers[key][figure_id] self.body.append(prefix % '.'.join(map(str, numbers)) + ' ') self.body.append('') @@ -544,7 +544,7 @@ def visit_download_reference(self, node: Element) -> None: self.context.append('') elif 'filename' in node: atts['class'] += ' internal' - atts['href'] = posixpath.join(self.builder.dlpath, # type: ignore[has-type] + atts['href'] = posixpath.join(self.builder.dlpath, urllib.parse.quote(node['filename'])) self.body.append(self.starttag(node, 'a', '', **atts)) self.context.append('') diff --git a/tests/test_build_epub.py b/tests/test_build_epub.py index 86fdae0cd68..e183c9c17e1 100644 --- a/tests/test_build_epub.py +++ b/tests/test_build_epub.py @@ -399,14 +399,11 @@ def test_copy_images(app, status, warning): images_dir = Path(app.outdir) / '_images' images = {image.name for image in images_dir.rglob('*')} + images.discard('python-logo.png') 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 89350e82d0c..5a0ca59feda 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -1780,12 +1780,9 @@ def test_copy_images(app, status, warning): 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 3f1206ac8b8..99bf5acba4a 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -1682,14 +1682,9 @@ def test_copy_images(app, status, warning): image.name for image in test_dir.rglob('*') if image.suffix in {'.gif', '.pdf', '.png', '.svg'} } + images.discard('python-logo.png') 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 aae5689b709..fa23fdb5920 100644 --- a/tests/test_build_texinfo.py +++ b/tests/test_build_texinfo.py @@ -146,14 +146,9 @@ def test_copy_images(app, status, warning): images_dir = Path(app.outdir) / 'python-figures' images = {image.name for image in images_dir.rglob('*')} + images.discard('python-logo.png') assert images == { - 'img.gif', - 'img.pdf', 'img.png', - 'python-logo.png', 'rimg.png', - 'rimg1.png', - 'svgimg.pdf', - 'svgimg.svg', 'testimäge.png', } From dcb4429abacda015f98875fe9489ced696155bd7 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 10 Jan 2023 14:48:03 +0000 Subject: [PATCH 3/7] Restore Sphinx 5 ``nodes.Element`` copying behaviour --- sphinx/util/nodes.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py index 18dd94f4616..794eea255a1 100644 --- a/sphinx/util/nodes.py +++ b/sphinx/util/nodes.py @@ -608,3 +608,18 @@ def process_only_nodes(document: Node, tags: Tags) -> None: # the only node, so we make sure docutils can transfer the id to # something, even if it's just a comment and will lose the id anyway... node.replace_self(nodes.comment()) + + +def _copy_except__document(self: Element) -> Element: + """Monkey-patch ```nodes.Element.copy``` to not copy the ``_document`` + attribute. + + xref: https://github.com/sphinx-doc/sphinx/issues/11116#issuecomment-1376767086 + """ + newnode = self.__class__(rawsource=self.rawsource, **self.attributes) + newnode.source = self.source + newnode.line = self.line + return newnode + + +nodes.Element.copy = _copy_except__document # type: ignore From 31162a9b6335f2abce9ffb90b905a314f6bdfe6b Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 10 Jan 2023 15:34:55 +0000 Subject: [PATCH 4/7] Handle exceptions for ``get_node_source`` and ``get_node_line`` --- sphinx/builders/linkcheck.py | 5 ++++- sphinx/util/nodes.py | 10 +++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index 8b750df2d6b..b7baa719d3f 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -509,7 +509,10 @@ def add_uri(uri: str, node: nodes.Element) -> None: if newuri: uri = newuri - lineno = get_node_line(node) + try: + lineno = get_node_line(node) + except ValueError: + lineno = None uri_info = Hyperlink(uri, self.env.docname, lineno) if uri not in hyperlinks: hyperlinks[uri] = uri_info diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py index 794eea255a1..9599dbc236c 100644 --- a/sphinx/util/nodes.py +++ b/sphinx/util/nodes.py @@ -172,7 +172,10 @@ def apply_source_workaround(node: Element) -> None: ))): logger.debug('[i18n] PATCH: %r to have source and line: %s', get_full_module_name(node), repr_domxml(node)) - node.source = get_node_source(node) or '' + try: + node.source = get_node_source(node) + except ValueError: + node.source = '' node.line = 0 # need fix docutils to get `node.line` return @@ -561,8 +564,9 @@ def set_role_source_info(inliner: Inliner, lineno: int, node: Node) -> None: def copy_source_info(src: Element, dst: Element) -> None: - dst.source = get_node_source(src) - dst.line = get_node_line(src) + with contextlib.suppress(ValueError): + dst.source = get_node_source(src) + dst.line = get_node_line(src) NON_SMARTQUOTABLE_PARENT_NODES = ( From a2e922ac6c58134d8ad19888de93d52c8a1de669 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 10 Jan 2023 15:55:03 +0000 Subject: [PATCH 5/7] CHANGES for Sphinx 6.1.3 --- CHANGES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 222eea8d8d2..5d2eb1fe3ef 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,10 @@ Features added Bugs fixed ---------- +* #11116: Reverted to previous Sphinx 5 node copying method +* #11117: Reverted changes to parallel image processing from Sphinx 6.1.0 +* #11119: Supress ``ValueError`` in the ``linkcheck`` builder + Testing -------- From 776d01eb6229f5d5384da17fc15df9d50fa8e87a Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 10 Jan 2023 15:55:21 +0000 Subject: [PATCH 6/7] Bump to 6.1.3 final --- CHANGES | 19 ++----------------- sphinx/__init__.py | 4 ++-- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 5d2eb1fe3ef..96c0bdd1eed 100644 --- a/CHANGES +++ b/CHANGES @@ -1,17 +1,5 @@ -Release 6.1.3 (in development) -============================== - -Dependencies ------------- - -Incompatible changes --------------------- - -Deprecated ----------- - -Features added --------------- +Release 6.1.3 (released Jan 10, 2023) +===================================== Bugs fixed ---------- @@ -20,9 +8,6 @@ Bugs fixed * #11117: Reverted changes to parallel image processing from Sphinx 6.1.0 * #11119: Supress ``ValueError`` in the ``linkcheck`` builder -Testing --------- - Release 6.1.2 (released Jan 07, 2023) ===================================== diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 5c3e705e20e..6a3e1a2e3d3 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -30,11 +30,11 @@ #: #: .. versionadded:: 1.2 #: Before version 1.2, check the string ``sphinx.__version__``. -version_info = (6, 1, 3, 'beta', 0) +version_info = (6, 1, 3, 'final', 0) package_dir = path.abspath(path.dirname(__file__)) -_in_development = True +_in_development = False if _in_development: # Only import subprocess if needed import subprocess From 30f347226fa4ccf49b3f7ef860fd962af5bdf4f0 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 10 Jan 2023 15:56:43 +0000 Subject: [PATCH 7/7] Bump version --- CHANGES | 21 +++++++++++++++++++++ sphinx/__init__.py | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 96c0bdd1eed..a74121a3e1b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,24 @@ +Release 6.1.4 (in development) +============================== + +Dependencies +------------ + +Incompatible changes +-------------------- + +Deprecated +---------- + +Features added +-------------- + +Bugs fixed +---------- + +Testing +-------- + Release 6.1.3 (released Jan 10, 2023) ===================================== diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 6a3e1a2e3d3..b29114ac33c 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.3' +__version__ = '6.1.4' __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, 3, 'final', 0) +version_info = (6, 1, 4, '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