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

Avoid using py.path #207

Merged
merged 2 commits into from Nov 21, 2023
Merged

Avoid using py.path #207

merged 2 commits into from Nov 21, 2023

Conversation

eerovaher
Copy link
Contributor

py.path provides classes for representing filesystem paths, but became obsolete when pathlib was added to Python standard library. pytest provides two fixtures for creating temporary directories: tmp_path, which uses pathlib, and tmpdir, which uses py.path. The recommendation is to prefer tmp_path over tmpdir, which is what the first commit here does.

Furthermore, pytest suggests calling pytest with -p no:legacypath to remove support for py.path entirely, which helps ensure tmpdir is not used at all. However, this also breaks any code accessing _pytest.nodes.Node.fspath. Because pytest-mpl accesses that then packages using it cannot turn off py.path support to guard against tmpdir usage. Although replacing accessing fspath in older versions of pytest is complicated (neither reportinfo()[0] nor location[0] work), it is very simple since pytest 7, so the second commit here allows at least the packages using recent versions of pytest to make use of the -p no:legacypath option.

Both `tmpdir` and `tmp_path` fixtures create temporary directories, but
the legacy `tmpdir` is based on third-party `py.path.local` objects
whereas `tmp_path` is based on the standard library `pathlib.Path`.
@eerovaher
Copy link
Contributor Author

There are three failures in one of the CI jobs, but the same failures are also present in main, so they are not caused by this pull request.

Copy link
Member

@ConorMacBride ConorMacBride left a comment

Choose a reason for hiding this comment

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

Thanks @eerovaher, this is great! Just one suggestion, and then hopefully we can get it merged soon so packages can disable the legacy path.

I was thinking of how we could disable legacypath in the pytest-mpl tests based on the pytest version installed, but I can't think of a simple way to do that.

pytest_mpl/plugin.py Show resolved Hide resolved
Comment on lines 68 to 71
if Version(pytest.__version__) < Version("7.0.0"):
path = Path(item.fspath)
else:
path = item.path
Copy link
Member

Choose a reason for hiding this comment

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

Do you think this would be sufficient?

Suggested change
if Version(pytest.__version__) < Version("7.0.0"):
path = Path(item.fspath)
else:
path = item.path
path = getattr(item, "path", Path(item.fspath))

Just trying to avoid parsing and comparing the versions. If you think checking the version is better can you do the comparison in a constant at the top of the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This helper function is only needed because older versions of pytest are too different from the recent ones, and having the version check made that explicit. But conveying that in a comment makes the code shorter and removes the need to import Version, so I have adopted your suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This simple getattr() call does not work. Sadly I realized this only after this pull request was already merged, so I had to open a follow-up pull request: #213.

`py.path` provides classes for representing filesystem paths, but became
obsolete when `pathlib` was added to Python standard library. `pytest`
recommends creating temporary directories with the `tmp_path` fixture,
which uses `pathlib`, instead of the older `tmpdir` fixture, which uses
`py.path`. Furthermore, it is suggested to call `pytest` with
`-p no:legacypath` to remove support for `py.path` entirely, which helps
ensure `tmpdir` is not used at all. However, this also breaks any code
accessing `_pytest.nodes.Node.fspath`. Because `pytest-mpl` includes
such code then packages using it cannot turn off `py.path` support to
guard against `tmpdir` usage. Although replacing accessing `fspath` in
older versions of `pytest` is complicated, it is very simple since
`pytest` 7, so now at least the packages using recent versions of
`pytest` can choose to make use of the `-p no:legacypath` option.
@ConorMacBride ConorMacBride merged commit 4253bef into matplotlib:main Nov 21, 2023
20 of 21 checks passed
@ConorMacBride
Copy link
Member

Thanks @eerovaher! 🚀

@matthewfeickert
Copy link

Thanks indeed!

@ConorMacBride Would it be possible to get a patch release of pytest-mpl now that this is in? I appreciate that there's been over 100 commits since v0.16.1 (v0.16.1...4253bef) and I haven't reviewed them to see if any are SemVer breaking or not, so that might be not possible until a minor release would be viewed as ready.

@ConorMacBride
Copy link
Member

@matthewfeickert Of course! We are well due a new release! There has been quite a few new features added so the next release will need to be v0.17.0. There're a couple of PRs I'd like to get in before that (https://github.com/matplotlib/pytest-mpl/milestone/2) – will hopefully get a release out some day next week

@ConorMacBride
Copy link
Member

Sorry for the delay, v0.17.0 has just been released!

@matthewfeickert
Copy link

Thanks @ConorMacBride! I appreciate it, as you've now made the pyhf HEAD of depenencies nightly tests start passing again with this release! :D

image

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

Successfully merging this pull request may close these issues.

Update to using pytest's tmp_path over legacy tmpdir
3 participants