def undo(self) -> None:
        """Undo previous changes.

        This call consumes the undo stack. Calling it a second time has no
        effect unless you do more monkeypatching after the undo call.

        There is generally no need to call `undo()`, since it is
        called automatically during tear-down.

        .. note::
            The same `monkeypatch` fixture is used across a
            single test function invocation. If `monkeypatch` is used both by
            the test function itself and one of the test fixtures,
            calling `undo()` will undo all of the changes made in
            both functions.

            Prefer to use :meth:`context() <pytest.MonkeyPatch.context>` instead.
        """
        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, key, value in reversed(self._setitem):
            if value is notset:
                try:
                    # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict
                    del dictionary[key]  # type: ignore[attr-defined]
                except KeyError:
                    pass  # Was already deleted, so we have the desired state.
            else:
                # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict
                dictionary[key] = value  # type: ignore[index]
        self._setitem[:] = []
        if self._savesyspath is not None:
            sys.path[:] = self._savesyspath
            self._savesyspath = None

        if self._cwd is not None:
            os.chdir(self._cwd)
            self._cwd = None
Undo previous changes.

        This call consumes the undo stack. Calling it a second time has no
        effect unless you do more monkeypatching after the undo call.

        There is generally no need to call `undo()`, since it is
        called automatically during tear-down.

        .. note::
            The same `monkeypatch` fixture is used across a
            single test function invocation. If `monkeypatch` is used both by
            the test function itself and one of the test fixtures,
            calling `undo()` will undo all of the changes made in
            both functions.

            Prefer to use :meth:`context() <pytest.MonkeyPatch.context>` instead.
        
src/_pytest/monkeypatch.py