diff --git a/CHANGELOG b/CHANGELOG index bb8395496..439a6242a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,9 @@ - fix #900: Better error message in case the target of a ``monkeypatch`` call 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 ----- diff --git a/_pytest/monkeypatch.py b/_pytest/monkeypatch.py index beaba37cc..5f9720f1f 100644 --- a/_pytest/monkeypatch.py +++ b/_pytest/monkeypatch.py @@ -126,7 +126,7 @@ class monkeypatch: # avoid class descriptors like staticmethod/classmethod if inspect.isclass(target): oldval = target.__dict__.get(name, notset) - self._setattr.insert(0, (target, name, oldval)) + self._setattr.append((target, name, oldval)) setattr(target, name, value) def delattr(self, target, name=notset, raising=True): @@ -152,13 +152,12 @@ class monkeypatch: if raising: raise AttributeError(name) else: - self._setattr.insert(0, (target, name, - getattr(target, name, notset))) + self._setattr.append((target, name, getattr(target, name, notset))) delattr(target, name) def setitem(self, dic, name, 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 def delitem(self, dic, name, raising=True): @@ -171,7 +170,7 @@ class monkeypatch: if raising: raise KeyError(name) else: - self._setitem.insert(0, (dic, name, dic.get(name, notset))) + self._setitem.append((dic, name, dic.get(name, notset))) del dic[name] def setenv(self, name, value, prepend=None): @@ -223,13 +222,13 @@ class monkeypatch: calling `undo()` will undo all of the changes made in both functions. """ - for obj, name, value in self._setattr: + for obj, name, value in reversed(self._setattr): if value is not notset: setattr(obj, name, value) else: delattr(obj, name) self._setattr[:] = [] - for dictionary, name, value in self._setitem: + for dictionary, name, value in reversed(self._setitem): if value is notset: try: del dictionary[name]