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

Using ruff as a drop-in replacement for flake8 #414

Closed
fsouza opened this issue Oct 13, 2022 · 17 comments
Closed

Using ruff as a drop-in replacement for flake8 #414

fsouza opened this issue Oct 13, 2022 · 17 comments

Comments

@fsouza
Copy link
Contributor

fsouza commented Oct 13, 2022

I'd love to be able to replace flake8 with ruff, and while most things are compatible, one current limitation is the configuration: flake8 can be configured via setup.cfg and .flake8, and at work it's a pretty common setup. Migrating everyone to pyproject.toml will likely not happen anytime soon. So I was wondering what could be done here. I thought of two options:

  1. make ruff support all flake8 flags and configuration files
    This is probably not something you'd like to have, as it becomes a layer of configuration that you don't have support for.
  2. build a "bridge" package: something that reads flake8 configuration and invokes ruff with the proper parameters (at least the supported ones)
    This can be done by a third party (I'm happy to do it), but in order to make it happen, ruff would need to support taking the configuration in some alternative mechanism (I can think of either (1) allow all settings to be defined via command line flags or (2) add a command line flag to allow the user to override the location of pyproject.toml - that way the "bridge" tool would generate the config file and invoke ruff with that flag)

Let me know if you have any thoughts!

@charliermarsh
Copy link
Member

Making adoption + migration easier is very important to me! I'm happy to both work directly on and support efforts in this vein. (And definitely interested to learn from your experience on what would be helpful here.)

I think you're right that supporting all Flake8 flags + configuration files is less desirable. We could do it, we already mimic Flake8 configuration for certain settings... Honestly, I'm somewhat tempted to do it... But it might be a mistake.

I like the idea of making the pyproject.toml path configurable, since it's very easy and makes Ruff feel a bit more "pluggable". (Flake8, coincidentally, supports this too, as do most tools, so Ruff should allow it.) From there, we could even provide scripts to convert setup.cfg and .flake8 to pyproject.toml.

I'll start by making the pyproject.toml configurable (or you're welcome to! I won't get to it tonight).

@sobolevn
Copy link
Contributor

sobolevn commented Oct 13, 2022

I think we can provide a config converter: ruff config-convert setup.cfg or .flake8 and it will return pyproject.toml with valid configuration.

It would be a good path forward. New tools should use new pyproject.toml.

@charliermarsh
Copy link
Member

Agreed!

@fsouza
Copy link
Contributor Author

fsouza commented Oct 14, 2022

My thought was more about being able to do that on-the-fly. I want to be able to use ruff locally on projects that use flake8 and cannot be migrated x)

I'll work on something like that that leverages the new --config flag! 😁

@fsouza
Copy link
Contributor Author

fsouza commented Oct 15, 2022

@charliermarsh I'm thinking I'll take a very lazy approach with a python package that depends on flake8 and ruff. I wonder if you plan on eventually providing a Python interface to invoke ruff? Or is Rust the only language that will have access to ruff's API?

@fsouza
Copy link
Contributor Author

fsouza commented Oct 15, 2022

Wrote a rudimentary hack here: https://github.com/fsouza/flake8-ruff-wrapper

I feel like having something like this living in ruff may be easier to keep supported settings and rule in sync.

@charliermarsh
Copy link
Member

Nice! We may want two things here:

  1. A command built-in to Ruff to convert Flake8 settings to a pyproject.toml.
  2. An external tool (like above) that could leverage that command to act as an automatic wrapper (like you've done above).

Does that distinction make sense? If we had a command within Ruff that automatically generated a pyproject.toml from a Flake8 settings file, would that be sufficient to power flake8-ruff-wrapper? (My assumption is that you'd call that new Ruff command, write the pyproject.toml to a temporary location, then invoke Ruff pointed to that temporary location, which would let you configure to use Flake8 settings files without migrating to pyproject.toml as in your setup.)

@fsouza
Copy link
Contributor Author

fsouza commented Oct 15, 2022

Yeah, that would definitely work!

edit: it would be even more convenient if that command operated over stdin/stdout, this way the wrapper wouldn't have to manage too many files/make sure that the file generated by ruff gets deleted and what not

@charliermarsh
Copy link
Member

Ok cool, that work is being tracked under #423.

@fsouza
Copy link
Contributor Author

fsouza commented Nov 1, 2022

@charliermarsh hey, one difference that I noticed between ruff and flake8 is that ruff uses 0-indexed column numbers and flake8 uses 1-indexed column numbers. Somewhat redacted example from a real piece of code:

% cat sample.py | flake8 -
stdin:312:9: F841 local variable 'mock_stable_percent' is assigned to but never used
% cat sample.py | ruff -
Found 1 error(s).
-:312:8: F841 Local variable `mock_stable_percent` is assigned to but never used

Since I have this integrated in my editor, I end-up jumping to the wrong position. I can try to figure out this on my side, but I'm curious if you intended to have columns reported on a 0-index base (I know that this is somewhat controversial, so I'll adapt either way hah)?

@charliermarsh
Copy link
Member

@fsouza - Good question. RustPython used to use 1-indexing for both row and column numbers, but they recently switched to zero-indexed columns, so I reflected that change in Ruff. (This actually matches the CPython ast module, which provides a 1-indexed lineno and a 0-indexed col_offset.)

I guess editors tend to use 1-indexing, so maybe I should switch back to a 1-index for error reports, even if we're using a zero-index internally. What do you think? What's more intuitive?

@fsouza
Copy link
Contributor Author

fsouza commented Nov 1, 2022

@charliermarsh yeah I noticed that many tools do that, track columns as 0-indexed and then report it as 1-indexed. For example, mypy uses 0-based indices for the column number (https://github.com/python/mypy/blob/9227bceb629a1b566a60cbdd09fef6731f7bfcb1/mypy/errors.py#L52-L53), but then when reporting the error they make it 1-based (https://github.com/python/mypy/blob/8b825472a02f0a30419c02e285ba931107a42959/mypy/errors.py#L778)

@charliermarsh
Copy link
Member

Ah ok, cool. I'll just do that. Will make an issue.

@fsouza
Copy link
Contributor Author

fsouza commented Nov 1, 2022

Ah ok, cool. I'll just do that. Will make an issue.

Thank you! I can send a PR later today if you want!

@charliermarsh
Copy link
Member

@fsouza - Awesome! PRs always welcome!

@charliermarsh
Copy link
Member

Closing as we now have flake8-to-ruff!

@asmeurer
Copy link

Is there any reason that https://github.com/fsouza/flake8-ruff-wrapper isn't just the built-in behavior for ruff? I would love to be able to just use a single configuration but let users use whichever tool that like.

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

No branches or pull requests

4 participants