From a862b11c1e9ecbaf638032a308eba82564ae79c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:25:38 +0000 Subject: [PATCH 1/5] Initial plan From 3f968accffdb95c050b53e30aaae238361041fd7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:31:01 +0000 Subject: [PATCH 2/5] Disable gdot graphviz call when UNITTEST_GOING=1, replace with dummy SVG Co-authored-by: xadupre <22452781+xadupre@users.noreply.github.com> --- _unittests/ut_gdot/test_gdot_extension.py | 64 +++++++++++++++++++ .../gdot/sphinx_gdot_extension.py | 20 ++++++ 2 files changed, 84 insertions(+) diff --git a/_unittests/ut_gdot/test_gdot_extension.py b/_unittests/ut_gdot/test_gdot_extension.py index d1ee7a3..2e74dc9 100644 --- a/_unittests/ut_gdot/test_gdot_extension.py +++ b/_unittests/ut_gdot/test_gdot_extension.py @@ -1,6 +1,8 @@ import unittest import logging +import os import sys +from contextlib import contextmanager from sphinx_runpython.process_rst import rst2html from sphinx_runpython.ext_test_case import ( ExtTestCase, @@ -10,6 +12,20 @@ ) +@contextmanager +def unittest_going(): + """Context manager that sets UNITTEST_GOING=1 for the duration of the block.""" + old = os.environ.get("UNITTEST_GOING", None) + os.environ["UNITTEST_GOING"] = "1" + try: + yield + finally: + if old is None: + os.environ.pop("UNITTEST_GOING", None) + else: + os.environ["UNITTEST_GOING"] = old + + class TestGDotExtension(ExtTestCase): def setUp(self): logger = logging.getLogger("gdot") @@ -146,6 +162,54 @@ def test_gdot4_png(self): return self.assertIn("png", content) + @ignore_warnings(PendingDeprecationWarning) + def test_gdot_unittest_going_svg(self): + """When UNITTEST_GOING=1, a dummy SVG is rendered instead of calling graphviz.""" + content = """ + before + + .. gdot:: + :format: svg + + digraph foo { + "bar" -> "baz"; + } + + after + """.replace(" ", "") + + with unittest_going(): + html = rst2html( + content, writer_name="html", new_extensions=["sphinx_runpython.gdot"] + ) + + self.assertIn("dummy", html) + self.assertIn("svg", html) + + @ignore_warnings(PendingDeprecationWarning) + def test_gdot_unittest_going_png(self): + """When UNITTEST_GOING=1, a dummy SVG is rendered for png format too.""" + content = """ + before + + .. gdot:: + :format: png + + digraph foo { + "bar" -> "baz"; + } + + after + """.replace(" ", "") + + with unittest_going(): + html = rst2html( + content, writer_name="html", new_extensions=["sphinx_runpython.gdot"] + ) + + self.assertIn("dummy", html) + self.assertIn("svg", html) + if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/sphinx_runpython/gdot/sphinx_gdot_extension.py b/sphinx_runpython/gdot/sphinx_gdot_extension.py index 05b7eca..c0d29cd 100644 --- a/sphinx_runpython/gdot/sphinx_gdot_extension.py +++ b/sphinx_runpython/gdot/sphinx_gdot_extension.py @@ -216,6 +216,21 @@ def depart_gdot_node_rst(self, node): self.end_state(wrap=False) +_DUMMY_SVG = ( + '' + 'dummy' + "" +) + + +def _emit_dummy_svg(self): + """Emit a placeholder SVG when ``UNITTEST_GOING=1`` is set.""" + self.body.append('
') + self.body.append(_DUMMY_SVG) + self.body.append("
\n") + raise nodes.SkipNode + + def render_dot_html( self, node: gdot_node, @@ -227,6 +242,9 @@ def render_dot_html( filename: str | None = None, format: str = "svg", ) -> tuple[str, str]: + if os.environ.get("UNITTEST_GOING", "0") == "1": + _emit_dummy_svg(self) + if format not in {"png", "svg"}: logger = logging.getLogger(__name__) logger.warning(__("format must be either 'png' or 'svg', but is %r"), format) @@ -362,6 +380,8 @@ def visit_gdot_node_html(self, node): and the :epkg:`SVG` format. """ if node["format"].lower() == "png": + if os.environ.get("UNITTEST_GOING", "0") == "1": + _emit_dummy_svg(self) from sphinx.ext.graphviz import html_visit_graphviz return html_visit_graphviz(self, node) From 30bbe655d724cb575f4a8f85393603fa4dc15282 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:43:08 +0000 Subject: [PATCH 3/5] Differentiate dummy SVG vs PNG output when UNITTEST_GOING=1, both contain DISABLED FOR TESTS Co-authored-by: xadupre <22452781+xadupre@users.noreply.github.com> --- _unittests/ut_gdot/test_gdot_extension.py | 14 +++++++------ .../gdot/sphinx_gdot_extension.py | 20 +++++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/_unittests/ut_gdot/test_gdot_extension.py b/_unittests/ut_gdot/test_gdot_extension.py index 2e74dc9..eb6d2c2 100644 --- a/_unittests/ut_gdot/test_gdot_extension.py +++ b/_unittests/ut_gdot/test_gdot_extension.py @@ -164,7 +164,7 @@ def test_gdot4_png(self): @ignore_warnings(PendingDeprecationWarning) def test_gdot_unittest_going_svg(self): - """When UNITTEST_GOING=1, a dummy SVG is rendered instead of calling graphviz.""" + """When UNITTEST_GOING=1, a dummy SVG containing 'DISABLED FOR TESTS' is rendered.""" content = """ before @@ -183,12 +183,13 @@ def test_gdot_unittest_going_svg(self): content, writer_name="html", new_extensions=["sphinx_runpython.gdot"] ) - self.assertIn("dummy", html) - self.assertIn("svg", html) + self.assertIn("DISABLED FOR TESTS", html) + self.assertIn("' - 'dummy' + 'DISABLED FOR TESTS' "" ) +_DUMMY_PNG_HTML = ( + 'DISABLED FOR TESTS' +) + -def _emit_dummy_svg(self): - """Emit a placeholder SVG when ``UNITTEST_GOING=1`` is set.""" +def _emit_dummy_output(self, format: str = "svg"): + """Emit a placeholder graphic when ``UNITTEST_GOING=1`` is set.""" self.body.append('
') - self.body.append(_DUMMY_SVG) + if format == "png": + self.body.append(_DUMMY_PNG_HTML) + else: + self.body.append(_DUMMY_SVG) self.body.append("
\n") raise nodes.SkipNode @@ -243,7 +251,7 @@ def render_dot_html( format: str = "svg", ) -> tuple[str, str]: if os.environ.get("UNITTEST_GOING", "0") == "1": - _emit_dummy_svg(self) + _emit_dummy_output(self, format=format) if format not in {"png", "svg"}: logger = logging.getLogger(__name__) @@ -381,7 +389,7 @@ def visit_gdot_node_html(self, node): """ if node["format"].lower() == "png": if os.environ.get("UNITTEST_GOING", "0") == "1": - _emit_dummy_svg(self) + _emit_dummy_output(self, format="png") from sphinx.ext.graphviz import html_visit_graphviz return html_visit_graphviz(self, node) From 5bf8a8373d8b85b58794f9f87e54bc8eb42f2644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Dupr=C3=A9?= Date: Fri, 6 Mar 2026 15:51:55 +0100 Subject: [PATCH 4/5] style --- _unittests/ut_gdot/test_gdot_extension.py | 5 ++++- sphinx_runpython/gdot/sphinx_gdot_extension.py | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/_unittests/ut_gdot/test_gdot_extension.py b/_unittests/ut_gdot/test_gdot_extension.py index eb6d2c2..dea0ff4 100644 --- a/_unittests/ut_gdot/test_gdot_extension.py +++ b/_unittests/ut_gdot/test_gdot_extension.py @@ -189,7 +189,10 @@ def test_gdot_unittest_going_svg(self): @ignore_warnings(PendingDeprecationWarning) def test_gdot_unittest_going_png(self): - """When UNITTEST_GOING=1, a dummy image containing 'DISABLED FOR TESTS' is rendered.""" + """ + When UNITTEST_GOING=1, a dummy image containing + 'DISABLED FOR TESTS' is rendered. + """ content = """ before diff --git a/sphinx_runpython/gdot/sphinx_gdot_extension.py b/sphinx_runpython/gdot/sphinx_gdot_extension.py index e939806..dd3f5e3 100644 --- a/sphinx_runpython/gdot/sphinx_gdot_extension.py +++ b/sphinx_runpython/gdot/sphinx_gdot_extension.py @@ -223,7 +223,8 @@ def depart_gdot_node_rst(self, node): ) _DUMMY_PNG_HTML = ( - 'DISABLED FOR TESTS' ) From b719b220393d4e9c5d9b9ffa939666728ff8dda5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Dupr=C3=A9?= Date: Fri, 6 Mar 2026 15:52:39 +0100 Subject: [PATCH 5/5] style --- sphinx_runpython/gdot/sphinx_gdot_extension.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx_runpython/gdot/sphinx_gdot_extension.py b/sphinx_runpython/gdot/sphinx_gdot_extension.py index dd3f5e3..da1905b 100644 --- a/sphinx_runpython/gdot/sphinx_gdot_extension.py +++ b/sphinx_runpython/gdot/sphinx_gdot_extension.py @@ -224,7 +224,7 @@ def depart_gdot_node_rst(self, node): _DUMMY_PNG_HTML = ( 'DISABLED FOR TESTS' )