Skip to content

Add tool to keep test-requirements in sync with pre-commit #3234

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

Merged
merged 7 commits into from
May 11, 2025

Conversation

CoolCat467
Copy link
Member

In this pull request, we add a local pre-commit hook tool to keep the tool versions in test-requirements.txt in sync with the equivalent versions in .pre-commit-config.yaml automatically, meaning pre-commit.ci automatic updates are more seamless and there can never be cases where the test versions don't match the pre-commit versions.

@CoolCat467 CoolCat467 added project meta skip newsfragment Newsfragment is not required labels Mar 28, 2025
@CoolCat467 CoolCat467 requested a review from A5rocks March 28, 2025 04:37
Copy link

codecov bot commented Mar 28, 2025

Codecov Report

Attention: Patch coverage is 85.36585% with 12 lines in your changes missing coverage. Please review.

Project coverage is 99.93727%. Comparing base (cb16631) to head (3733c5f).

Files with missing lines Patch % Lines
src/trio/_tools/sync_requirements.py 78.57143% 10 Missing and 2 partials ⚠️
Additional details and impacted files
@@                 Coverage Diff                  @@
##                 main       #3234         +/-   ##
====================================================
- Coverage   100.00000%   99.93727%   -0.06274%     
====================================================
  Files             124         126          +2     
  Lines           19047       19129         +82     
  Branches         1287        1296          +9     
====================================================
+ Hits            19047       19117         +70     
- Misses              0          10         +10     
- Partials            0           2          +2     
Files with missing lines Coverage Δ
src/trio/_tests/tools/test_sync_requirements.py 100.00000% <100.00000%> (ø)
src/trio/_tools/sync_requirements.py 78.57143% <78.57143%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@A5rocks A5rocks left a comment

Choose a reason for hiding this comment

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

Thanks this makes sense and seems pretty simple. We could probably make it simpler too.

I wonder whether maybe this should update the pre-commit configuration too, to maximize the version (lexicographically? Or just import packaging) between both files.

Another helpful related script might be to copy the pins from the requirements.txt files to the pre-commit file.

changed = False
old_lines = requirements.read_text(encoding="utf-8").splitlines(True)

with requirements.open("w", encoding="utf-8") as file:
Copy link
Contributor

Choose a reason for hiding this comment

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

I kind of feel like a loop over the version_data dict with a regex replacement might be simpler. Though this is already plenty simple.

# Get tool versions from pre-commit
# Get correct names
pre_commit_versions = {
name.removesuffix("-mirror").removesuffix("-pre-commit"): version
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO we should just do a dict of url to package name at the top instead of trying to automatically detect it

Copy link
Member Author

Choose a reason for hiding this comment

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

I was intending for this to be general enough to work even if new hooks are added in the future, but if necessary I could change it to be a static dictionary

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this looks very general (what if the name ends with -precommit? or similar) and it's not an error if something that could be picked up automatically isn't, so I think I'd prefer a manual addition.

I don't know of anything I would add that this wouldn't work with, but I also don't know anything I would add to the pre-commit configuration to begin with!

print("Changed test requirements version to match pre-commit")
print(f"{name}=={old_version} -> {name}=={version}")
file.write(new_line)
return changed
Copy link
Contributor

Choose a reason for hiding this comment

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

This should also check whether every entry in version_data was used

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't immediately understand why this should be the case. For example, typos exists only as a pre-commit hook, and in fact I don't know if it even exists as a python package. Similar with zizmor.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah this would only make sense if #3234 (comment) was implemented.

@CoolCat467
Copy link
Member Author

I wonder whether maybe this should update the pre-commit configuration too, to maximize the version (lexicographically? Or just import packaging) between both files.

Another helpful related script might be to copy the pins from the requirements.txt files to the pre-commit file.

While this could be useful in some cases, I don't see a need for that in a regular use case. From my point of view, most of the time someone (or pre-commit.ci) would run pre-commit autoupdate and then uv pip compile --universal --python-version=3.9 test-requirements.in -o test-requirements.txt --upgrade, and then since all the pre-commit hook versions are either the original package itself or a mirror, they should have an identical version.

The primary use case for this script is so that when pre-commit ci automatically updates everything, this will automate pinning the test requirements to the same version.

Another possible solution that would sidestep needing this tool in the first place would be to just have pre-commit ci perform an upgrade on all the test requirements as well, but I don't think there is a way to specify a pre-commit hook to run that only runs on pre-commit.ci but not locally, unless one were to write a script to somehow identify something in the pre-commit.ci environment that is different from a local run.

@CoolCat467 CoolCat467 requested a review from A5rocks April 22, 2025 03:31
@CoolCat467
Copy link
Member Author

Thinking of merging this in a day or two if no other changes to make

Copy link
Contributor

@A5rocks A5rocks left a comment

Choose a reason for hiding this comment

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

Left a comment on whether we should derive the requirement manually or automatically but I'm OK with this either way; it probably wouldn't simplify much either.

@CoolCat467 CoolCat467 merged commit ac7b93f into python-trio:main May 11, 2025
41 of 43 checks passed
@CoolCat467 CoolCat467 deleted the pre-commit-tests-sync branch May 11, 2025 06:36
@A5rocks
Copy link
Contributor

A5rocks commented May 14, 2025

Oops I missed that this decreased coverage! I'll make a PR to fix that (just by adding a few coverage ignore comments...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
project meta skip newsfragment Newsfragment is not required
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants