Bugfix: monkeypatch.delattr handles class descriptors
Correct monkeypatch.delattr to match the correct behavior of monkeypatch.setattr when changing class descriptors
This commit is contained in:
parent
6af674a3ac
commit
f8d31d2400
1
AUTHORS
1
AUTHORS
|
@ -48,6 +48,7 @@ Christian Boelsen
|
|||
Christian Theunert
|
||||
Christian Tismer
|
||||
Christopher Gilling
|
||||
Christopher Dignam
|
||||
CrazyMerlyn
|
||||
Cyrus Maden
|
||||
Dhiren Serai
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
monkeypatch.delattr handles class descriptors like staticmethod/classmethod
|
|
@ -181,6 +181,8 @@ class MonkeyPatch(object):
|
|||
attribute is missing.
|
||||
"""
|
||||
__tracebackhide__ = True
|
||||
import inspect
|
||||
|
||||
if name is notset:
|
||||
if not isinstance(target, six.string_types):
|
||||
raise TypeError(
|
||||
|
@ -194,7 +196,11 @@ class MonkeyPatch(object):
|
|||
if raising:
|
||||
raise AttributeError(name)
|
||||
else:
|
||||
self._setattr.append((target, name, getattr(target, name, notset)))
|
||||
oldval = getattr(target, name, notset)
|
||||
# avoid class descriptors like staticmethod/classmethod
|
||||
if inspect.isclass(target):
|
||||
oldval = target.__dict__.get(name, notset)
|
||||
self._setattr.append((target, name, oldval))
|
||||
delattr(target, name)
|
||||
|
||||
def setitem(self, dic, name, value):
|
||||
|
|
|
@ -391,6 +391,33 @@ def test_issue156_undo_staticmethod(Sample):
|
|||
assert Sample.hello()
|
||||
|
||||
|
||||
def test_undo_class_descriptors_delattr():
|
||||
class SampleParent(object):
|
||||
@classmethod
|
||||
def hello(_cls):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def world():
|
||||
pass
|
||||
|
||||
class SampleChild(SampleParent):
|
||||
pass
|
||||
|
||||
monkeypatch = MonkeyPatch()
|
||||
|
||||
original_hello = SampleChild.hello
|
||||
original_world = SampleChild.world
|
||||
monkeypatch.delattr(SampleParent, "hello")
|
||||
monkeypatch.delattr(SampleParent, "world")
|
||||
assert getattr(SampleParent, "hello", None) is None
|
||||
assert getattr(SampleParent, "world", None) is None
|
||||
|
||||
monkeypatch.undo()
|
||||
assert original_hello == SampleChild.hello
|
||||
assert original_world == SampleChild.world
|
||||
|
||||
|
||||
def test_issue1338_name_resolving():
|
||||
pytest.importorskip("requests")
|
||||
monkeypatch = MonkeyPatch()
|
||||
|
|
Loading…
Reference in New Issue