Skip to content

Commit 48832dc

Browse files
committed
Do not rely on external stack frame to exist
When using matplotlib in an embedded Python interpreter (such as in Julia package PyCall.jl), stack frame may not exist outside matplotlib. Therefore, it is better to not assume `frame.f_back` to be an existing call frame. See: JuliaPy/PyPlot.jl#409
1 parent 4dbbd22 commit 48832dc

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

lib/matplotlib/cbook/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,6 +1990,8 @@ def _warn_external(message, category=None):
19901990
"""
19911991
frame = sys._getframe()
19921992
for stacklevel in itertools.count(1): # lgtm[py/unused-loop-variable]
1993+
if frame is None:
1994+
break
19931995
if not re.match(r"\A(matplotlib|mpl_toolkits)(\Z|\.)",
19941996
# Work around sphinx-gallery not setting __name__.
19951997
frame.f_globals.get("__name__", "")):

lib/matplotlib/tests/test_cbook.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import pickle
33
from weakref import ref
44
import warnings
5+
from unittest.mock import patch, Mock
56

67
from datetime import datetime
78

@@ -350,6 +351,15 @@ def test_normalize_kwargs_pass(inp, expected, kwargs_to_norm):
350351
assert len(w) == 0
351352

352353

354+
def test_warn_external_frame_embedded_python():
355+
with patch.object(cbook, "sys") as mock_sys:
356+
mock_sys._getframe = Mock(return_value=None)
357+
with warnings.catch_warnings(record=True) as w:
358+
cbook._warn_external("dummy")
359+
assert len(w) == 1
360+
assert str(w[0].message) == "dummy"
361+
362+
353363
def test_to_prestep():
354364
x = np.arange(4)
355365
y1 = np.arange(4)

0 commit comments

Comments
 (0)