Merge pull request #4537 from chdsbd/master

Bugfix: monkeypatch.delattr handles class descriptors
This commit is contained in:
Bruno Oliveira 2019-01-16 08:09:59 -02:00 committed by GitHub
commit 1a04e8903a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 1 deletions

View File

@ -52,6 +52,7 @@ Christian Boelsen
Christian Theunert Christian Theunert
Christian Tismer Christian Tismer
Christopher Gilling Christopher Gilling
Christopher Dignam
CrazyMerlyn CrazyMerlyn
Cyrus Maden Cyrus Maden
Dhiren Serai Dhiren Serai

View File

@ -0,0 +1 @@
``monkeypatch.delattr`` handles class descriptors like ``staticmethod``/``classmethod``.

View File

@ -181,6 +181,8 @@ class MonkeyPatch(object):
attribute is missing. attribute is missing.
""" """
__tracebackhide__ = True __tracebackhide__ = True
import inspect
if name is notset: if name is notset:
if not isinstance(target, six.string_types): if not isinstance(target, six.string_types):
raise TypeError( raise TypeError(
@ -194,7 +196,11 @@ class MonkeyPatch(object):
if raising: if raising:
raise AttributeError(name) raise AttributeError(name)
else: 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) delattr(target, name)
def setitem(self, dic, name, value): def setitem(self, dic, name, value):

View File

@ -391,6 +391,33 @@ def test_issue156_undo_staticmethod(Sample):
assert Sample.hello() 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(): def test_issue1338_name_resolving():
pytest.importorskip("requests") pytest.importorskip("requests")
monkeypatch = MonkeyPatch() monkeypatch = MonkeyPatch()