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 78224ef

Browse filesBrowse files
authored
Merge pull request #10856 from anntzer/xkcdgc
Fix xkcd style garbage collection.
2 parents a81fdf5 + 60604fe commit 78224ef
Copy full SHA for 78224ef

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
@@ -1243,8 +1243,7 @@ def rc_file(fname):
12431243
rcParams.update(rc_params_from_file(fname))
12441244

12451245

1246-
@contextlib.contextmanager
1247-
def rc_context(rc=None, fname=None):
1246+
class rc_context:
12481247
"""
12491248
Return a context manager for managing rc settings.
12501249
@@ -1274,19 +1273,33 @@ def rc_context(rc=None, fname=None):
12741273
ax.plot(range(3), range(3))
12751274
fig.savefig('A.png', format='png')
12761275
plt.close(fig)
1277-
12781276
"""
1277+
# While it may seem natural to implement rc_context using
1278+
# contextlib.contextmanager, that would entail always calling the finally:
1279+
# clause of the contextmanager (which restores the original rcs) including
1280+
# during garbage collection; as a result, something like `plt.xkcd();
1281+
# gc.collect()` would result in the style being lost (as `xkcd()` is
1282+
# implemented on top of rc_context, and nothing is holding onto context
1283+
# manager except possibly circular references.
1284+
1285+
def __init__(self, rc=None, fname=None):
1286+
self._orig = rcParams.copy()
1287+
try:
1288+
if fname:
1289+
rc_file(fname)
1290+
if rc:
1291+
rcParams.update(rc)
1292+
except Exception:
1293+
# If anything goes wrong, revert to the original rcs.
1294+
dict.update(rcParams, self._orig)
1295+
raise
12791296

1280-
orig = rcParams.copy()
1281-
try:
1282-
if fname:
1283-
rc_file(fname)
1284-
if rc:
1285-
rcParams.update(rc)
1286-
yield
1287-
finally:
1297+
def __enter__(self):
1298+
return self
1299+
1300+
def __exit__(self, exc_type, exc_value, exc_tb):
12881301
# No need to revalidate the original values.
1289-
dict.update(rcParams, orig)
1302+
dict.update(rcParams, self._orig)
12901303

12911304

12921305
_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
@@ -387,7 +387,7 @@ def xkcd(scale=1, length=100, randomness=2):
387387
"xkcd mode is not compatible with text.usetex = True")
388388

389389
from matplotlib import patheffects
390-
xkcd_ctx = rc_context({
390+
return rc_context({
391391
'font.family': ['xkcd', 'Humor Sans', 'Comic Sans MS'],
392392
'font.size': 14.0,
393393
'path.sketch': (scale, length, randomness),
@@ -404,21 +404,6 @@ def xkcd(scale=1, length=100, randomness=2):
404404
'ytick.major.size': 8,
405405
'ytick.major.width': 3,
406406
})
407-
xkcd_ctx.__enter__()
408-
409-
# In order to make the call to `xkcd` that does not use a context manager
410-
# (cm) work, we need to enter into the cm ourselves, and return a dummy
411-
# cm that does nothing on entry and cleans up the xkcd context on exit.
412-
# Additionally, we need to keep a reference to the dummy cm because it
413-
# would otherwise be exited when GC'd.
414-
415-
class dummy_ctx(object):
416-
def __enter__(self):
417-
pass
418-
419-
__exit__ = xkcd_ctx.__exit__
420-
421-
return dummy_ctx()
422407

423408

424409
## 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.