Source

pytest-patches / monkeypatch-descriptors

Full commit
# HG changeset patch
# Parent d46b4480e6de290d9b965618981f9f186030380f
fix issue 156 - monkypaych undo broken for staticmethod

diff --git a/_pytest/monkeypatch.py b/_pytest/monkeypatch.py
--- a/_pytest/monkeypatch.py
+++ b/_pytest/monkeypatch.py
@@ -39,6 +39,10 @@ class monkeypatch:
         oldval = getattr(obj, name, notset)
         if raising and oldval is notset:
             raise AttributeError("%r has no attribute %r" %(obj, name))
+
+        vars = getattr(obj, '__dict__', notset)
+        if vars is not notset:
+            oldval = vars.get(name, notset)
         self._setattr.insert(0, (obj, name, oldval))
         setattr(obj, name, value)
 
diff --git a/testing/test_monkeypatch.py b/testing/test_monkeypatch.py
--- a/testing/test_monkeypatch.py
+++ b/testing/test_monkeypatch.py
@@ -206,3 +206,38 @@ def test_issue185_time_breaks(testdir):
     result.stdout.fnmatch_lines("""
         *1 passed*
     """)
+
+
+
+class SampleNew(object):
+    @staticmethod
+    def hello():
+        return True
+
+
+class SampleNewInherit(SampleNew):
+    pass
+
+
+class SampleOld:
+    #oldstyle on python2
+    @staticmethod
+    def hello():
+        return True
+
+class SampleOldInherit(SampleOld):
+    pass
+
+
+@pytest.mark.parametrize('Sample', [
+    SampleNew, SampleNewInherit,
+    SampleOld, SampleOldInherit,
+], ids=['new', 'new-inherit', 'old', 'old-inherit'])
+def test_issue156_undo_staticmethod(Sample):
+    monkeypatch = MonkeyPatch()
+
+    monkeypatch.setattr(Sample, 'hello', None)
+    assert Sample.hello is None
+
+    monkeypatch.undo()
+    assert Sample.hello()