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

Add configurations and support for auto formatting tools #4654

Merged
merged 12 commits into from
Oct 22, 2023

Conversation

Serene-Arc
Copy link
Contributor

So the last couple issues that have mentioned this have been closed due to staleness so I thought I'd cautiously bring it back up. Now that beets supports Python 3.6+, the auto formatter black and isort can be used on the codebase.

These will standardise all code and hopefully make PRs and merge issues rarer, and improve readability since all formatting will be the same. I have added the tool configurations and a pre-commit file so that that tool can be used as well if desired. These tools make it easy to apply formatting checks as part of the PR workflow and pre-commit makes them run automatically as git is used, so there should be minimal disruption to actual work.

I have not actually reformatted the entire codebase yet. That can be done easily with a tox command but will almost certainly create a large amount of changes through every file, or near enough. If this PR is accepted, that can be done at the end of the process, or when most convenient.

There are some small areas of flexibility in the formatting that may be up for discussion as well. Generally black doesn't offer many choices by design, but the main one is really line length. The war over 80 vs 120 characters can continue here if there's split opinion.

@sampsyo
Copy link
Member

sampsyo commented Jan 26, 2023

Nice!!! Thank you for getting this set up. It's clear that the future is in automated formatting, and carefully handcrafted formatting is best left to the dustbin of history.

As at least a way to get started (and avoid bikeshedding too much), maybe a good initial point would be to try to match the flake8 configuration we're already using to check style? It needn't be an exact match, but we can minimize the footprint of the initial wave of changes if we make them reasonably close. That would mean starting with line_length = 79 or thereabouts and perhaps adopting some of our flake8 configuration from setup.cfg to introduce similar options for extend-ignore. What do you think of that as a starting point?

@Serene-Arc
Copy link
Contributor Author

I'll go through the bits of the flake configuration one at a time.

By default the line length in black is 88 which they believe to be the best for shorter files apparently but that is a judgement call to some degree. Since the aim of black is to reduce line diffs, there might be something to that. It can be configured to be any number of characters fairly easily. However if there's going to be a wave of changes, I think it would be better to do it all at once. Since the goal is to minimise diffs going into the future, once you choose a line length, it should be stuck to. Trying to increase the line length in the future is likely to cause a very large number of diffs so people would have to resolve those conflicts twice instead of once.

The Google style docstrings is something that black takes over, that's not really an option.

Black follows Ford's famous line: 'Any colour so long as it's black.' The idea is that there's one formatting specification that isn't messed with. For this, E121, E123, E126, E241, E305, E503, and E504 (which are all currently ignored under the flake8 configuration) would be formatted automatically and consistently. There isn't a way around this really; if you'd like these to continue to be up to the developer's preference, that kind of defeats the purpose of this tool. Black's idea is to remove preference, so if you'd like to keep those idiosyncrasies I'll have to find another tool.

The other flake8 ignored errors seem to be linter errors, which black doesn't do so no problems there.

There's also a large number of files that are ignored by flake8. That can actually be done but it is ill-advised. Using tools such as pre-commit means that the formatters are likely to be applied to every file at some point, and having some files that are exempt from a seemingly universal formatter would be only half getting into the bath. Unless the exclusions are for the linter aspects of flake8, I don't think they should apply to black and isort, but it's not my project so up to you.

The part of black's documentation that I think you're referring to with extend-ignore is not about modifying black to conform to flake8 but about making flake8 conform to black's standard. extend-ignore is a flake8 option, to stop it from causing errors and warnings about black's specification.

@sampsyo
Copy link
Member

sampsyo commented Jan 29, 2023

OK, you make a strong point about the advantages of the "change as much as possible all at once" approach! Better that than a slow progression of large-diff changes. I totally agree that we should avoid doing lots of fiddly configuration changes in Black, and that we shouldn't ignore files. (The main reason that some files are ignored now for flake8 is because of comment style, which needs a lot of intervention—and which, to be honest, hasn't been all that fun to enforce manually.)

(And sorry for misreading the docs! I totally see now I was getting the extend-ignore thing backward.)

I obviously think it's best to avoid bikeshedding style stuff as much as possible, but I can't help suggesting that we stick to 79 or 80 columns for the default. I may just be old, but I often find tall & skinny code a lot easier to navigate and edit; 80 columns is really my sweet spot for fitting multiple windows on a modestly-sized display. Anyway, happy to be overridden here, but I thought I'd just make that modest suggestion. 😃

@Serene-Arc
Copy link
Contributor Author

The comments will all be changed to match black's standard, it really is quite comprehensive.

If you'd like the line length to be stuck to, then totally up to you! There's a degree of personal preference that doesn't really matter one way or the other. I doubt that black's maintainers did a study or anything to find the sweet spot, and it's not that far off. I'll add a limit for 80 characters.

Copy link
Member

@sampsyo sampsyo left a comment

Choose a reason for hiding this comment

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

Awesome. This all looks great to me—I'm in favor of merging it now, which will let us experiment a bit before the big format-change commit. Does that sound good to you?

@Serene-Arc
Copy link
Contributor Author

Sure, though the tool shortcuts I added to the tox configuration format the entire codebase at once. isort and black will have to be called individually to format individual files if you want to do that for a while. If pre-commit is used, then any files subject to the commit will be formatted according to the standard.

Since the format configuration is in the pyproject.toml file, the tools will automatically read the config whenever they're called, so it should be very simple to use them once they're installed.

A thought about timing for the big commit though: I don't think there ever will be a 'perfect time' for a project like this. In a perfect world, it would be done when there are no PRs pending or any other work being done, but for a public, open-source project, that's only really the case in the beginning, when there's one person working on it. No matter when the commit is made, there's going to be some stepped-on toes and merge conflicts to be resolved, quite a few on my own PRs now. I think that, once you're fine with the tools and have finished experimenting, and are comfortable with it, the best solution is to just take the plunge and make the commit.

Unless there's going to be a push to close every outstanding PR, or at least all the major ones, before the formatters are applied, I would cautiously suggest doing it sooner rather than later. If this PR is merged, and people start using the tools, then there will be a lot of commits and PRs with large amounts of formatting changes that only affect a handful of files. That runs counter to the idea of atomic, small commits and will make it much more difficult to review new PRs simply due to the huge diffs that might be generated.

It's up to you, but I would suggest that this PR be merged publicly into the master branch close to when you'd like to make the formatting commit, just to reduce these issues as much as possible. Half-formatted code won't make it any easier for the PR reviewers and that is already a bottleneck for the beets project.

@sampsyo
Copy link
Member

sampsyo commented Jan 31, 2023

These are all really good points. I would love to resolve a couple of the big PRs to avoid some duplicated work—your new typing PRs, for example, are good candidates. Let's make an effort to do this quickly and then merge this configuration (and then do the "big commit").

@sampsyo
Copy link
Member

sampsyo commented Jan 31, 2023

One other thing: maybe this PR would be a good place to update any coding guidelines we have in the repository—in CONTRIBUTING.rst, for example—to refer to Black and the availability of pre-commit hooks?

@Serene-Arc
Copy link
Contributor Author

Sure! I'll update the contribution guidelines so that the use of these tools are required. There's also the possibility of adding another check that GitHub runs when PRs are made; this check would enforce the formatting. If the formatting is not according to the standard, the check will fail and stop the PR from being merged, or at least notify the reviewer.

@stale
Copy link

stale bot commented Jun 10, 2023

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jun 10, 2023
@Serene-Arc
Copy link
Contributor Author

Oh overeager bot, this is still relevant but basically involves changing every single line of code at once which won't be fun to deal with for PRs already in progress.

@stale stale bot removed the stale label Jun 10, 2023
@Serene-Arc
Copy link
Contributor Author

@sampsyo Would you like to pull the trigger on this soon? Not that the UI one has been merged, it might be a good time.

@sampsyo
Copy link
Member

sampsyo commented Sep 22, 2023

That's a good point. Since we bikeshedded the row-length argument to our satisfaction, and that UI PR is no longer outstanding, maybe it's time! It could be responsible to do a quick audit of open PRs to make sure we're not missing anything obvious we want to do first… but like you say, there will never be a perfectly quiescent moment to do this, so we will eventually need to just take the leap.

@Serene-Arc
Copy link
Contributor Author

Most of the PRs will be (hopefully) pretty easy to merge back in and if not...well like you said, it'll need to happen at some point. Would you like me to add a workflow to this PR? That will make it so that any PR trying to merge with the repository will be required to be fully compliant. It'll mean that once we set it to this, it will (should) never be a problem again, since everyone will have to conform to merge at all.

pyproject.toml Outdated

[tool.isort]
profile = "black"
py_version = 36
Copy link
Contributor

Choose a reason for hiding this comment

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

We should update this to 38 as the last supported version as per Status of Python versions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That depends on beets. AFAIK beets is still claiming to be backwards compatible to 3.6?

Copy link
Member

Choose a reason for hiding this comment

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

We currently claim to support Python 3.7+:

beets/setup.py

Line 183 in 7736ae7

'Programming Language :: Python :: 3.7',

But @arogl is right that we should probably drop abandoned versions of Python (and therefore move to 3.8+ now).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, I can update the configuration.

@sampsyo
Copy link
Member

sampsyo commented Sep 23, 2023

Would you like me to add a workflow to this PR?

Oh yes, that makes sense! Sorry I didn't think of this; it seems really important for keeping this maintainable. I think it would probably be important to replace the style checks from our flake8 checker, lest we get into bad situations where flake8 and Black disagree on style decisions?

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install base dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox sphinx
- name: Add problem matcher
run: echo "::add-matcher::.github/flake8-problem-matcher.json"
- name: Lint with flake8
run: tox -e py-lint

Of course, we probably still want the pyflakes (proper linting) component of flake8…

@Serene-Arc
Copy link
Contributor Author

@sampsyo Flake8 and black are definitely compatible. IIRC both of them have options you can set so they work correctly together. I'll double check their docs and make a new workflow and modify the flake workflow if need be.

@Serene-Arc
Copy link
Contributor Author

@sampsyo This adds a workflow that simply runs the tox command/environment 'format_check' which simply checks if there are any changes that either isort or black makes. If there aren't, it passes.

Note also that the line length in flake is a limit of 88 characters. This isn't actually the line length that black will try to go to, since black itself is set to 80 characters. However the black docs states that in cases where other rules conflict with the line length, the other rules take precedence e.g. black will make longer lines to preserve readability. You can find that section here.

So I've increased the length at which flake errors will occur to account for this but no lines can manually be set to 88 characters. Since black is required to merge, this should result in all lines being as close to 80 characters as possible, and there is no user discretion in that.

If you're happy with this, I can run the formatting tools so you can see all the changes before merging.

@sampsyo
Copy link
Member

sampsyo commented Sep 27, 2023

Sounds good overall!

On the topic of flake8 & Black compatibility: it's good to know that they don't actively disagree. But I wonder if we shouldn't remove the flake8 (actually, pycodestyle) checker anyway… that is, we would be saying "the only thing that matters for formatting in the beets project is conforming to what Black would do." So developers could be certain that they only need to run one tool (which you have already helpfully put in a pre-commit hook) and be sure that their style is conformant. Does this make sense?

@Serene-Arc
Copy link
Contributor Author

Yep it does. I can remove the formatting from flake8 if you'd like, or we can phase it out at a later time when we know it won't cause any problems. There should be no change from removing flake8 at any time once black is adopted. If you'd like the continuity of making sure that both are working correctly, it can stay, but if you'd like it removed it probably won't do much differently.

I'll have to look at how to remove the formatting checks without changing the linting aspect of the tool.

@sampsyo
Copy link
Member

sampsyo commented Sep 28, 2023

Sure, sounds right to me! I'm equally happy with turning off pycodestyle in this PR or in a later one—as you say, when we're more confident it won't be disruptive to do so.

@Serene-Arc
Copy link
Contributor Author

Great! Would you like me to make the formatting commit? That's 'the big one'.

@sampsyo
Copy link
Member

sampsyo commented Sep 29, 2023

Seems like it's about time! The only thing I can imagine doing before we do the "big commit" is giving people some warning. We could tell people via a Discussions post we're going to do it in N days (where N is like 2 or 3) so they have a chance to adapt? (Not sure if the commit comes after this PR merges or before—whatever you see fit!)

@Serene-Arc
Copy link
Contributor Author

I can do it as part of this commit. I'll rebase, which won't have any conflicts, and then do the big format. If you'd like to warn people, it can wait until then!

@sampsyo
Copy link
Member

sampsyo commented Oct 2, 2023

OK, cool! Sure, why don't we do a short warning period just to minimize disruption and then include the reformat in this PR.

Would you mind making the announcement by creating a new Discussions topic and just letting people know what we are planning to do? (I would also be happy to do it, but I think it will make more sense coming from you—and it will let people know that you are in charge. 😃) You can pick any warning duration you see fit. One week from the date of the warning seems perfectly reasonable as a default, for instance.

@Serene-Arc
Copy link
Contributor Author

I'll do that right now :)

@Serene-Arc
Copy link
Contributor Author

#4931

setup.cfg Show resolved Hide resolved
pyproject.toml Show resolved Hide resolved
setup.cfg Show resolved Hide resolved
@arogl
Copy link
Contributor

arogl commented Oct 5, 2023

Should we do a release before pulling this hammer?

@Serene-Arc
Copy link
Contributor Author

No reason to. This won't impact users at all. Releases won't be affected.

@Serene-Arc
Copy link
Contributor Author

Now that the UI overhaul has been merged, should we consider pulling the trigger on this?

@sampsyo
Copy link
Member

sampsyo commented Oct 20, 2023

Yes, that sounds good to me!

@Serene-Arc
Copy link
Contributor Author

Alrighty then! Everyone prepare for merge conflicts then

@Serene-Arc
Copy link
Contributor Author

@sampsyo just so it's explicit, do you want me to make the commit and then merge the formatted code to master?

@sampsyo
Copy link
Member

sampsyo commented Oct 21, 2023

That sounds right to me! Although I admit I don't have strong feelings about the exact process, as long as we end up with "green" CI in the end. 😃

@Serene-Arc
Copy link
Contributor Author

Then here it gooooooes.

@Serene-Arc Serene-Arc merged commit 2115369 into beetbox:master Oct 22, 2023
11 of 12 checks passed
@Serene-Arc Serene-Arc deleted the auto_formatters branch October 22, 2023 00:12
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.

3 participants