Skip to content

Commit 77468b7

Browse files
Copilotxadupre
andcommitted
speedup runpython execution for graphviz: cache script results in Sphinx env
Co-authored-by: xadupre <22452781+xadupre@users.noreply.github.com>
1 parent ec87a38 commit 77468b7

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

_unittests/ut_gdot/test_gdot_extension.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,34 @@ def test_gdot4_png(self):
137137
self.assertIn("png", content)
138138

139139

140+
@ignore_warnings(PendingDeprecationWarning)
141+
def test_gdot_script_cache(self):
142+
"""Test that identical scripts are cached and produce the same output."""
143+
script = "print('digraph foo { HbarH -> HbazH; }')".replace("H", '\"')
144+
content = f"""
145+
before
146+
147+
.. gdot::
148+
:script:
149+
150+
{script}
151+
152+
middle
153+
154+
.. gdot::
155+
:script:
156+
157+
{script}
158+
159+
after
160+
"""
161+
content = rst2html(
162+
content, writer_name="rst", new_extensions=["sphinx_runpython.gdot"]
163+
)
164+
# Both gdot directives should produce the same DOT output
165+
count = content.count('digraph foo { "bar" -> "baz"; }')
166+
self.assertEqual(count, 2, f"Expected the DOT code to appear twice, got {count}")
167+
168+
140169
if __name__ == "__main__":
141170
unittest.main(verbosity=2)

sphinx_runpython/gdot/sphinx_gdot_extension.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import hashlib
12
import os
23
import logging
34
from docutils import nodes
@@ -147,7 +148,23 @@ def run(self):
147148
# executes script if any
148149
content = "\n".join(self.content)
149150
if script or script == "":
150-
stdout, stderr, _ = run_python_script(content, process=process)
151+
env = info.get("env")
152+
cache_key = hashlib.sha256(
153+
f"{content}:{process}".encode("utf-8")
154+
).hexdigest()
155+
if env is not None:
156+
if not hasattr(env, "gdot_script_cache"):
157+
env.gdot_script_cache = {}
158+
cached = env.gdot_script_cache.get(cache_key, None)
159+
else:
160+
cached = None
161+
162+
if cached is not None:
163+
stdout, stderr = cached
164+
else:
165+
stdout, stderr, _ = run_python_script(content, process=process)
166+
if env is not None:
167+
env.gdot_script_cache[cache_key] = (stdout, stderr)
151168

152169
if stderr:
153170
out = [

0 commit comments

Comments
 (0)