@@ -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 = """
0 commit comments