-
Notifications
You must be signed in to change notification settings - Fork 55
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
Support ruff check --fix
as a formatter
#758
Comments
@zmeir, there's one complication we need to think about. The algorithm Darker uses to match code changes from 1) the user and 2) reformatting is not foolproof. It does a best effort of comparing and matching diff chunks, but in some edge cases it will get confused and reassemble the Python source code file in the wrong way. To mitigate this, Darker always compares the AST before and after applying the reformatted chunks, and if the AST didn't stay intact, it will run the whole diff matching again but enlarging the chunks considered to have been edited by the user. This process is repeated until the AST matches, or until the entire file is considered as edited and thus all reformatting changes are applied. Now, without investigation and testing, it's impossible to know whether the changes done by So investigation, testing and considering different mitigation strategies is needed. For earlier discussions on the diff algorithm, see:
|
Thanks for the response @akaihola ! I was aware of the AST verification Darker does, but it hadn't occurred to me that I'll try to play around with |
One obvious (but currently impossible) way to solve this would be to somehow have Darker could then start with fix 1, and only apply it if the lines it changes intersect with any of the user modified lines. Darker would track changed line numbers of user modifications (we have code for this in Graylint), and proceed to fix 2 (if fix 1 was not applied) or the new fix 1 (if the original fix 1 was applied). Unfortunately it's unrealistic to expect |
I'm experimenting with a pyupgrade formatter plugin in #755, and it has exactly the same problem. Currently I'm just sidestepping the issue by disabling AST verificating and enforcing applying all pyupgrade changes to all user-modified files. We could of course make it one notch smarter by only applying all changes to the file if at least one changed line intersects with user modifications. |
I've also pondered whether running a non-AST-preserving formatter first for the old, unmodified version of the code (e.g. But it becomes rather complicated with many moving parts, and I suspect this approach won't fly either. |
Do you mean adding That could indeed be another way to increase granularity – probably in most cases it would help only apply changes touching modified lines. But the case in which it fails is when the same fix is applied both to lines which have been modified by the user and to lines which haven't. In that case I'm afraid the best we can do is to apply all instances of the same fix inside a file. |
Yes. I was hoping to find other ruff configurations to help me narrow the scope even more, like an option to limit the line range to check, but I found nothing like this.
Obvious but impossible. That sums up what I'm looking for :)
That sounds like a great solution. This combined with some narrowing of rules using --select sounds like it could work very well.
I had a similar thought. What if we do something like this?
I'm sure there are holes in this flow. Just a thought... |
Oops @zmeir, I didn't mean to edit your comment. I must have selected the wrong drop-down menu item when I was going to do |
No worries, I restored the original comment from the edit history. As for your question:
Yeah that's a fair point. I hadn't thought about a single fix that can possibly change multiple "chunks" of code. My mental model was that a fix is completely contained in a contiguous range of code lines, but that's because I'm used to looking at code changes of formatters, not linters... |
#744 will add support for
ruff format
as a code-formatter.Ruff also supports the
ruff check --fix
in its linter command, that allows it to automatically fix some linter errors. This essentially turnsruff check
from a linter to a code-formatter.It would be nice if we could also use
ruff check --fix
as a code-formatter with Darker.There are also additional flags to control the auto-fixing behavior, that maybe need to be taken into account:
--fix-only
,--unsafe-fixes
.Graylint is a perfect solution for running linter commands that do not modify the code.
However, with
ruff check --fix
, the "linter" will automatically modify the code the fix the linter errors. This means thatruff check --fix
is not only a linter but also a code-formatter, and as such is incompatible with Graylint.The text was updated successfully, but these errors were encountered: