Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pytester: use monkeypatch.chdir() for dir changing #11315

Merged
merged 1 commit into from Sep 25, 2023

Conversation

bluetech
Copy link
Member

The current method as the following problem, described by @sadra-barikbin in #11236 (comment):

The tests that request both pytester and monkeypatch and use monkeypatch.chdir without context, relying on monkeypatch's teardown to restore cwd. This doesn't work because the following sequence of actions take place:

  • monkeypatch is set up.
  • pytester is set up. It saves the original cwd and changes it to a new one dedicated to the test function.
  • Test function calls monkeypatch.chdir() without context. monkeypatch saves cwd, which is not the original one, before changing it.
  • pytester is torn down. It restores the cwd to the original one.
  • monkeypatch is torn down. It restores cwd to what it has saved.

The solution here is to have pytester use monkeypatch.chdir() itself, then everything is handled correctly.

@bluetech bluetech marked this pull request as draft August 16, 2023 21:10
@@ -696,15 +688,14 @@ def __init__(
#: be added to the list. The type of items to add to the list depends on
#: the method using them so refer to them for details.
self.plugins: List[Union[str, _PluggyPlugin]] = []
self._cwd_snapshot = CwdSnapshot()
self._sys_path_snapshot = SysPathsSnapshot()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we log a followup to ensure sys.path/sys.modules handling in coordination with monkeypatch

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be possible but some complications:

  • SysPathSnapshot also saves sys.meta_path, monkeypatch doesn't.
  • Monkeypatch doesn't save sys.path by default, though pytester can probably force it to do it
  • SysModulesSnapshot has no equivalent in monkeypatch currenty as far as know. Also has some preserve_modules exclusion...

@bluetech bluetech marked this pull request as ready for review September 24, 2023 13:08
@bluetech
Copy link
Member Author

Updated; there were some calls to monkeypatch.undo() in the test suite which interfered with this change (and theoretically, with other things even before this change). I changed them to use monkeypatch.context().

last_reprtb = last_p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
last_lines = last_reprtb.lines
monkeypatch.undo()
with monkeypatch.context() as mp:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because others use pytester, I think it would be worth adding a trivial changelog explaining this change, in case others find/have the same pattern in their test suites.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed - added a changelog.

The current method as the following problem, described by Sadra
Barikbin:

The tests that request both `pytester` and `monkeypatch` and use
`monkeypatch.chdir` without context, relying on `monkeypatch`'s teardown
to restore cwd. This doesn't work because the following sequence of
actions take place:

- `monkeypatch` is set up.
- `pytester` is set up. It saves the original cwd and changes it to a
  new one dedicated to the test function.
- Test function calls `monkeypatch.chdir()` without context.
  `monkeypatch` saves cwd, which is not the original one, before
  changing it.
- `pytester` is torn down. It restores the cwd to the original one.
- `monkeypatch` is torn down. It restores cwd to what it has saved.

The solution here is to have pytester use `monkeypatch.chdir()` itself,
then everything is handled correctly.
@RonnyPfannschmidt
Copy link
Member

Should we deprecate monkeypatch.undo as public api now that . context is available

@bluetech bluetech merged commit 1a16bac into pytest-dev:main Sep 25, 2023
24 checks passed
@bluetech bluetech deleted the pytest-monkeypatch-chdir branch September 25, 2023 09:29
@bluetech
Copy link
Member Author

We did add a note warning about its use some time ago. I don't know if we can entirely deprecate it because it doesn't have a replacement if someone wants to undo their own MonkeyPatch instance.

@RonnyPfannschmidt
Copy link
Member

@bluetech customized contextmanager undo is controlled via ExitStack

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants