Skip to content

Commit 136fa20

Browse files
committed
MNT: don't set method objects back onto the objects
If we are monkey-patching methods then we need to be sure that when we restore the original attribute we need to make sure we don't stick the method instance in place (which creates a circular reference).
1 parent 4356b67 commit 136fa20

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

lib/matplotlib/cbook/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import types
2525
import warnings
2626
import weakref
27+
import inspect
2728

2829
import numpy as np
2930

@@ -2039,7 +2040,7 @@ def _setattr_cm(obj, **kwargs):
20392040
yield
20402041
finally:
20412042
for attr, orig in origs:
2042-
if orig is sentinel:
2043+
if orig is sentinel or inspect.ismethod(orig):
20432044
delattr(obj, attr)
20442045
else:
20452046
setattr(obj, attr, orig)

lib/matplotlib/tests/test_cbook.py

+38
Original file line numberDiff line numberDiff line change
@@ -651,3 +651,41 @@ def test_check_shape(target, test_shape):
651651
with pytest.raises(ValueError,
652652
match=error_pattern):
653653
cbook._check_shape(target, aardvark=data)
654+
655+
656+
def test_setattr_cm():
657+
class A:
658+
def __init__(self):
659+
self.aardvark = 'aardvark'
660+
self._p = 'p'
661+
662+
def meth(self):
663+
...
664+
665+
@property
666+
def prop(self):
667+
return self._p
668+
669+
@prop.setter
670+
def prop(self, val):
671+
self._p = val
672+
673+
a = A()
674+
675+
assert id(a.meth) != id(a.meth)
676+
assert id(a.aardvark) == id(a.aardvark)
677+
assert id(a.prop) == id(a.prop)
678+
679+
with cbook._setattr_cm(
680+
a,
681+
aardvark='moose', meth=lambda: None, prop='b'
682+
):
683+
assert id(a.meth) == id(a.meth)
684+
assert id(a.aardvark) == id(a.aardvark)
685+
assert a.aardvark == 'moose'
686+
assert a.prop == 'b'
687+
688+
assert id(a.meth) != id(a.meth)
689+
assert id(a.aardvark) == id(a.aardvark)
690+
assert a.aardvark == 'aardvark'
691+
assert id(a.prop) == id(a.prop)

0 commit comments

Comments
 (0)