Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 94c63af

Browse filesBrowse files
authored
Merge pull request #10860 from matplotlib/auto-backport-of-pr-10856
Backport PR #10856 on branch v2.2.x
2 parents 6afe2f9 + 960e73e commit 94c63af
Copy full SHA for 94c63af

File tree

Expand file treeCollapse file tree

3 files changed

+31
-30
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+31
-30
lines changed

‎lib/matplotlib/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/__init__.py
+25-12Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,8 +1294,7 @@ def rc_file(fname):
12941294
rcParams.update(rc_params_from_file(fname))
12951295

12961296

1297-
@contextlib.contextmanager
1298-
def rc_context(rc=None, fname=None):
1297+
class rc_context(object):
12991298
"""
13001299
Return a context manager for managing rc settings.
13011300
@@ -1325,19 +1324,33 @@ def rc_context(rc=None, fname=None):
13251324
ax.plot(range(3), range(3))
13261325
fig.savefig('A.png', format='png')
13271326
plt.close(fig)
1328-
13291327
"""
1328+
# While it may seem natural to implement rc_context using
1329+
# contextlib.contextmanager, that would entail always calling the finally:
1330+
# clause of the contextmanager (which restores the original rcs) including
1331+
# during garbage collection; as a result, something like `plt.xkcd();
1332+
# gc.collect()` would result in the style being lost (as `xkcd()` is
1333+
# implemented on top of rc_context, and nothing is holding onto context
1334+
# manager except possibly circular references.
1335+
1336+
def __init__(self, rc=None, fname=None):
1337+
self._orig = rcParams.copy()
1338+
try:
1339+
if fname:
1340+
rc_file(fname)
1341+
if rc:
1342+
rcParams.update(rc)
1343+
except Exception:
1344+
# If anything goes wrong, revert to the original rcs.
1345+
dict.update(rcParams, self._orig)
1346+
raise
13301347

1331-
orig = rcParams.copy()
1332-
try:
1333-
if fname:
1334-
rc_file(fname)
1335-
if rc:
1336-
rcParams.update(rc)
1337-
yield
1338-
finally:
1348+
def __enter__(self):
1349+
return self
1350+
1351+
def __exit__(self, exc_type, exc_value, exc_tb):
13391352
# No need to revalidate the original values.
1340-
dict.update(rcParams, orig)
1353+
dict.update(rcParams, self._orig)
13411354

13421355

13431356
_use_error_msg = """

‎lib/matplotlib/pyplot.py

Copy file name to clipboardExpand all lines: lib/matplotlib/pyplot.py
+1-16Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ def xkcd(scale=1, length=100, randomness=2):
392392
"xkcd mode is not compatible with text.usetex = True")
393393

394394
from matplotlib import patheffects
395-
xkcd_ctx = rc_context({
395+
return rc_context({
396396
'font.family': ['xkcd', 'Humor Sans', 'Comic Sans MS'],
397397
'font.size': 14.0,
398398
'path.sketch': (scale, length, randomness),
@@ -409,21 +409,6 @@ def xkcd(scale=1, length=100, randomness=2):
409409
'ytick.major.size': 8,
410410
'ytick.major.width': 3,
411411
})
412-
xkcd_ctx.__enter__()
413-
414-
# In order to make the call to `xkcd` that does not use a context manager
415-
# (cm) work, we need to enter into the cm ourselves, and return a dummy
416-
# cm that does nothing on entry and cleans up the xkcd context on exit.
417-
# Additionally, we need to keep a reference to the dummy cm because it
418-
# would otherwise be exited when GC'd.
419-
420-
class dummy_ctx(object):
421-
def __enter__(self):
422-
pass
423-
424-
__exit__ = xkcd_ctx.__exit__
425-
426-
return dummy_ctx()
427412

428413

429414
## Figures ##

‎lib/matplotlib/tests/test_style.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_style.py
+5-2Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from __future__ import absolute_import, division, print_function
22

3+
from collections import OrderedDict
4+
from contextlib import contextmanager
5+
import gc
36
import os
47
import shutil
58
import tempfile
69
import warnings
7-
from collections import OrderedDict
8-
from contextlib import contextmanager
910

1011
import pytest
1112

@@ -163,6 +164,8 @@ def test_xkcd_no_cm():
163164
assert mpl.rcParams["path.sketch"] is None
164165
plt.xkcd()
165166
assert mpl.rcParams["path.sketch"] == (1, 100, 2)
167+
gc.collect()
168+
assert mpl.rcParams["path.sketch"] == (1, 100, 2)
166169

167170

168171
def test_xkcd_cm():

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.