Skip to content

Commit 0795b26

Browse files
larsonerclaude
andcommitted
refactor: cache the static-export probe instead of a module global
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 020ee67 commit 0795b26

2 files changed

Lines changed: 31 additions & 33 deletions

File tree

plotly/io/_sg_scraper.py

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -126,39 +126,35 @@ def _trailing_repr_figure(block, block_vars):
126126
return figure
127127

128128

129-
# Whether static image export works at all, probed on the first scrape so
130-
# that a build without Kaleido or a browser warns once (per worker, for
131-
# parallel sphinx-gallery builds) instead of once per figure.
132-
_export_available = None
133-
134-
129+
@functools.lru_cache(maxsize=None) # functools.cache needs Python 3.9
135130
def _static_export_available():
136-
global _export_available
137-
if _export_available is None:
131+
"""Whether static image export works, probed on the first scrape.
132+
133+
Cached so that a build without Kaleido or a browser warns once (per
134+
worker, for parallel sphinx-gallery builds) instead of once per figure.
135+
"""
136+
try:
137+
plotly.io.to_image({"data": []}, format="png", validate=False)
138+
except Exception as exc:
138139
try:
139-
plotly.io.to_image({"data": []}, format="png", validate=False)
140-
except Exception as exc:
141-
_export_available = False
142-
try:
143-
from sphinx.util.logging import getLogger
144-
145-
warn = functools.partial(
146-
getLogger(__name__).warning, type="plotly", subtype="sg_scraper"
147-
)
148-
except Exception:
149-
warn = logging.getLogger(__name__).warning
150-
warn(
151-
"plotly static image export is unavailable, so example "
152-
"thumbnails will fall back to a placeholder image. Static "
153-
"export requires Kaleido and a Chromium-based browser; see "
154-
"https://plotly.com/python/static-image-export/ for "
155-
"installation instructions. The failure was: %s: %s",
156-
type(exc).__name__,
157-
exc,
140+
from sphinx.util.logging import getLogger
141+
142+
warn = functools.partial(
143+
getLogger(__name__).warning, type="plotly", subtype="sg_scraper"
158144
)
159-
else:
160-
_export_available = True
161-
return _export_available
145+
except Exception:
146+
warn = logging.getLogger(__name__).warning
147+
warn(
148+
"plotly static image export is unavailable, so example "
149+
"thumbnails will fall back to a placeholder image. Static "
150+
"export requires Kaleido and a Chromium-based browser; see "
151+
"https://plotly.com/python/static-image-export/ for "
152+
"installation instructions. The failure was: %s: %s",
153+
type(exc).__name__,
154+
exc,
155+
)
156+
return False
157+
return True
162158

163159

164160
def _inline_html(fig_dict):

tests/test_io/test_sg_scraper.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ def gallery(tmp_path, monkeypatch):
7575
# is imported, which may have happened in another test already.
7676
monkeypatch.setattr(pio.renderers, "default", "sphinx_gallery_png")
7777
monkeypatch.setattr(pio, "write_image", dummy_image_writer())
78-
# Images come from the stand-in above, so skip the Kaleido probe.
79-
monkeypatch.setattr(sg_scraper, "_export_available", True)
78+
# Images come from the stand-in above, so the Kaleido probe must pass too
79+
monkeypatch.setattr(pio, "to_image", lambda *args, **kwargs: b"")
80+
sg_scraper._static_export_available.cache_clear()
8081

8182
example_dir = tmp_path / "auto_examples"
8283
thumb_dir = example_dir / "images" / "thumb"
@@ -114,6 +115,7 @@ def thumbnail(**file_conf):
114115
thumbnail=thumbnail,
115116
)
116117
del sphinx_gallery_figures[:]
118+
sg_scraper._static_export_available.cache_clear()
117119

118120

119121
@pytest.mark.parametrize("image_format", ["png", "svg"])
@@ -222,7 +224,7 @@ def raise_no_browser(*args, **kwargs):
222224
raise ValueError("no browser")
223225

224226
monkeypatch.setattr(pio, "to_image", raise_no_browser)
225-
monkeypatch.setattr(sg_scraper, "_export_available", None)
227+
sg_scraper._static_export_available.cache_clear()
226228
fig = go.Figure(data=[go.Scatter(x=[1, 2, 3], y=[3, 2, 1])])
227229
pio.show(fig)
228230
gallery.globals["___"] = fig

0 commit comments

Comments
 (0)