astral-sh / ruff

An extremely fast Python linter and code formatter, written in Rust.
https://docs.astral.sh/ruff
MIT License
33.12k stars 1.11k forks source link

Possibility to implement flake8-length into ruff #4595

Open jsh9 opened 1 year ago

jsh9 commented 1 year ago

Hi,

I've found that flake8-length written by @orsinium to be one of my favorite flake8 plugins. I searched the issue pool of ruff and didn't find anyone mentioning it.

Thank you!

orsinium commented 1 year ago

image

charliermarsh commented 1 year ago

I think my preference would be to modify our existing rule rather than add multiple line-length rules within Ruff itself. Same goes for flake8-bugbear's variant that allows a 10% buffer. E.g., we do allow long lines that end in URLs, as long as the URL starts before the length limit (which differs from pycodestyle). We also allow lines that consistent of a single token without whitespace to break it up.

What other behaviors or exceptions might you find helpful in our check?

jsh9 commented 1 year ago

Hi Charlie,

Ideally for me, an "intelligent" line length checker should ignore these situations:

flake8-length can do both, which is why I like it. Also, the violation code of flake8-length is LN, which is intuitive (better than E501).

orsinium commented 1 year ago

What other behaviors or exceptions might you find helpful in our check?

Flake8-length allows:

The motivation is described in the README, but in short, these are things you want to keep unbroken for the sake of grep'ability.

It also allows certain symbols and tokens to appear after the string. So, a: f('very long text'), won't be reported () and , are allowed to go after) but f('very long text').something_else() will be reported because the something_else part goes beyond the screen but it's significant for the reader to see.

There is also a specific exception for raw SQL queries. SQL allows newlines between tokens, so they can be safely reformatted into a multiline string literal.

I guess that's it. The parser's source code is just about 100 lines.

stinodego commented 1 year ago

I have tried flake8-length before, but I found that I get pretty much the same behavior by ignoring E501 (line too long) and enabling pycodestyle's max-doc-length:



[tool.ruff]
line-length = 88

select = [
  "E", # pycodestyle
  "W", # pycodestyle
]
ignore = [
  "E501",  # Line length regulated by black
]

[tool.ruff.pycodestyle]
max-doc-length = 88
orsinium commented 1 year ago

but I found that I get pretty much the same behavior by ignoring E501 (line too long) <...>

The point of flake8-length is to not remove the line length limit for the code. From the README:

If you're about having as strict limits as possible, flake8-length is on your side. It's better to set 90 chars limit with a few reasonable exceptions rather than have 120 or more chars limit for everything.

stinodego commented 1 year ago

Yes, the point being that black already takes care of that!

It will wrap anything except for very long strings and comments. And the max-doc-length setting will then warn you about certain long strings / comments, but has reasonable exceptions built-in. So it works out to be approximately the same (in my experience) as what the flake8-length plugin is trying to achieve.

If you take black out of the picture, then it becomes a whole different conversation.

lev-blit commented 1 year ago

@stinodego I agree that black takes care of that, but it adds a large overhead. There's a project I worked on which had about 200~ files, with some of them being very large, and running ruff was shorter than a blink of an eye but running black against all those files felt like an eternity compared to that (and it was quite long without comparison too - about 8 seconds). That's just because ruff doesn't ignore comments and other examples given above regarding flake8-length.

It would be really useful for ruff to be able to support those features, then I would be able to use black only as a formatting tool and not as a linting tool just for E501.

RosanneZe commented 9 months ago

We're looking to switch from flake8 to ruff, but we would like to keep the behaviour that flake8-length gives. So I'd like to add my vote to adding it as a plugin.