Make monkeypatch calls O(1)

Fix #1292
This commit is contained in:
Bruno Oliveira 2015-12-29 22:02:18 -02:00
parent 0ef73ed3e0
commit 638b3f5e39
2 changed files with 9 additions and 7 deletions

View File

@ -12,6 +12,9 @@
- fix #900: Better error message in case the target of a ``monkeypatch`` call - fix #900: Better error message in case the target of a ``monkeypatch`` call
raises an ``ImportError``. raises an ``ImportError``.
- fix #1292: monkeypatch calls (setattr, setenv, etc.) are now O(1).
Thanks David R. MacIver for the report and Bruno Oliveira for the PR.
2.8.5 2.8.5
----- -----

View File

@ -126,7 +126,7 @@ class monkeypatch:
# avoid class descriptors like staticmethod/classmethod # avoid class descriptors like staticmethod/classmethod
if inspect.isclass(target): if inspect.isclass(target):
oldval = target.__dict__.get(name, notset) oldval = target.__dict__.get(name, notset)
self._setattr.insert(0, (target, name, oldval)) self._setattr.append((target, name, oldval))
setattr(target, name, value) setattr(target, name, value)
def delattr(self, target, name=notset, raising=True): def delattr(self, target, name=notset, raising=True):
@ -152,13 +152,12 @@ class monkeypatch:
if raising: if raising:
raise AttributeError(name) raise AttributeError(name)
else: else:
self._setattr.insert(0, (target, name, self._setattr.append((target, name, getattr(target, name, notset)))
getattr(target, name, notset)))
delattr(target, name) delattr(target, name)
def setitem(self, dic, name, value): def setitem(self, dic, name, value):
""" Set dictionary entry ``name`` to value. """ """ Set dictionary entry ``name`` to value. """
self._setitem.insert(0, (dic, name, dic.get(name, notset))) self._setitem.append((dic, name, dic.get(name, notset)))
dic[name] = value dic[name] = value
def delitem(self, dic, name, raising=True): def delitem(self, dic, name, raising=True):
@ -171,7 +170,7 @@ class monkeypatch:
if raising: if raising:
raise KeyError(name) raise KeyError(name)
else: else:
self._setitem.insert(0, (dic, name, dic.get(name, notset))) self._setitem.append((dic, name, dic.get(name, notset)))
del dic[name] del dic[name]
def setenv(self, name, value, prepend=None): def setenv(self, name, value, prepend=None):
@ -223,13 +222,13 @@ class monkeypatch:
calling `undo()` will undo all of the changes made in calling `undo()` will undo all of the changes made in
both functions. both functions.
""" """
for obj, name, value in self._setattr: for obj, name, value in reversed(self._setattr):
if value is not notset: if value is not notset:
setattr(obj, name, value) setattr(obj, name, value)
else: else:
delattr(obj, name) delattr(obj, name)
self._setattr[:] = [] self._setattr[:] = []
for dictionary, name, value in self._setitem: for dictionary, name, value in reversed(self._setitem):
if value is notset: if value is notset:
try: try:
del dictionary[name] del dictionary[name]