@@ -1294,8 +1294,7 @@ def rc_file(fname):
1294
1294
rcParams .update (rc_params_from_file (fname ))
1295
1295
1296
1296
1297
- @contextlib .contextmanager
1298
- def rc_context (rc = None , fname = None ):
1297
+ class rc_context (object ):
1299
1298
"""
1300
1299
Return a context manager for managing rc settings.
1301
1300
@@ -1325,19 +1324,33 @@ def rc_context(rc=None, fname=None):
1325
1324
ax.plot(range(3), range(3))
1326
1325
fig.savefig('A.png', format='png')
1327
1326
plt.close(fig)
1328
-
1329
1327
"""
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
1330
1347
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 ):
1339
1352
# No need to revalidate the original values.
1340
- dict .update (rcParams , orig )
1353
+ dict .update (rcParams , self . _orig )
1341
1354
1342
1355
1343
1356
_use_error_msg = """
0 commit comments