ruff icon indicating copy to clipboard operation
ruff copied to clipboard

Implement remaining `pycodestyle` rules

Open charliermarsh opened this issue 2 years ago • 44 comments

Note: some of the checked-off rules are still gated behind the logical_lines feature flag. To see the list of rules enabled in the current release, refer to the docs.

E1 Indentation

  • [x] E101 ("indentation contains mixed spaces and tabs")
  • [x] E111 ("indentation is not a multiple of four")
  • [x] E112 ("expected an indented block")
  • [x] E113 ("unexpected indentation")
  • [x] E114 ("indentation is not a multiple of four (comment)")
  • [x] E115 ("expected an indented block (comment)")
  • [x] E116 ("unexpected indentation (comment)")
  • [x] E117 ("over-indented")
  • [ ] E122 ("continuation line missing indentation or outdented")
  • [ ] E124 ("closing bracket does not match visual indentation")
  • [ ] E125 ("continuation line with same indent as next logical line")
  • [ ] E127 ("continuation line over-indented for visual indent")
  • [ ] E128 ("continuation line under-indented for visual indent")
  • [ ] E129 ("visually indented line with same indent as next logical line")
  • [ ] E131 ("continuation line unaligned for hanging indent")

E2 Whitespace

  • [x] E201 ("whitespace after ‘(’")
  • [x] E202 ("whitespace before ‘)’")
  • [x] E203 ("whitespace before ‘,’, ‘;’, or ‘:’")
  • [x] E211 ("whitespace before ‘(’")
  • [x] E221 ("multiple spaces before operator")
  • [x] E222 ("multiple spaces after operator")
  • [x] E223 ("tab before operator")
  • [x] E224 ("tab after operator")
  • [x] E225 ("missing whitespace around operator")
  • [x] E227 ("missing whitespace around bitwise or shift operator")
  • [x] E228 ("missing whitespace around modulo operator")
  • [x] E231 ("missing whitespace after ‘,’, ‘;’, or ‘:’")
  • [x] E251 ("unexpected spaces around keyword / parameter equals")
  • [x] E261 ("at least two spaces before inline comment")
  • [x] E262 ("inline comment should start with ‘# ‘")
  • [x] E265 ("block comment should start with ‘# ‘")
  • [x] E266 ("too many leading ‘#’ for block comment")
  • [x] E271 ("multiple spaces after keyword")
  • [x] E272 ("multiple spaces before keyword")
  • [x] E273 ("tab after keyword")
  • [x] E274 ("tab before keyword")
  • [x] E275 ("missing whitespace after keyword")

E3 Blank line

  • [x] E301 ("expected 1 blank line, found 0")
  • [x] E302 ("expected 2 blank lines, found 0")
  • [x] E303 ("too many blank lines (3)")
  • [x] E304 ("blank lines found after function decorator")
  • [x] E305 ("expected 2 blank lines after end of function or class")
  • [x] E306 ("expected 1 blank line before a nested definition")

E4 Import

  • [x] E401 ("multiple imports on one line")
  • [x] E402 ("module level import not at top of file")

E5 Line length

  • [x] E501 ("line too long (82 > 79 characters)")
  • [x] E502 ("the backslash is redundant between brackets")

E7 Statement

  • [x] E701 ("multiple statements on one line (colon)")
  • [x] E702 ("multiple statements on one line (semicolon)")
  • [x] E703 ("statement ends with a semicolon")
  • [x] E704 ("multiple statements on one line (def)")
  • [x] E711 ("comparison to None should be ‘if cond is None:’")
  • [x] E712 ("comparison to True should be ‘if cond is True:’ or ‘if cond:’")
  • [x] E713 ("test for membership should be ‘not in’")
  • [x] E714 ("test for object identity should be ‘is not’")
  • [x] E721 ("do not compare types, use ‘isinstance()’")
  • [x] E722 ("do not use bare except, specify exception instead")
  • [x] E731 ("do not assign a lambda expression, use a def")
  • [x] E741 ("do not use variables named ‘l’, ‘O’, or ‘I’")
  • [x] E742 ("do not define classes named ‘l’, ‘O’, or ‘I’")
  • [x] E743 ("do not define functions named ‘l’, ‘O’, or ‘I’")

E9 Runtime

  • [x] E901 ("SyntaxError or IndentationError")
  • [x] E902 ("IOError")

W1 Indentation warning

  • [x] W191 ("indentation contains tabs")

W2 Whitespace warning

  • [x] W291 ("trailing whitespace")
  • [x] W292 ("no newline at end of file")
  • [x] W293 ("blank line contains whitespace")

W3 Blank line warning

  • [x] W391 ("blank line at end of file")

W5. Line break warning

  • [x] W505 ("doc line too long (82 > 79 characters)")

W6 Deprecation warning

  • [x] W605 ("invalid escape sequence ‘x’")

charliermarsh avatar Jan 31 '23 17:01 charliermarsh

I'm happy to support these, but I likely won't enable them by default -- I'd like them to be opt-in.

charliermarsh avatar Jan 31 '23 17:01 charliermarsh

(Also that tabulation is incomplete, but I'll finish it up later!)

charliermarsh avatar Jan 31 '23 17:01 charliermarsh

\cc @saadmk11

charliermarsh avatar Jan 31 '23 17:01 charliermarsh

I've updated this lint to include all the current pydocstyle rules, less those that are ignored in the default configuration and those that deal with pre-Python 3.7 code.

charliermarsh avatar Jan 31 '23 22:01 charliermarsh

First we need #1130.

charliermarsh avatar Jan 31 '23 23:01 charliermarsh

So far I have seven more rules done in #1130.

charliermarsh avatar Feb 02 '23 04:02 charliermarsh

Thanks for this @charliermarsh I'm using a lot pycodestyle and pydocstyle with my students to teach them PEP8 and PEP257. Using ruff will be a great plus.

pierrepo avatar Feb 02 '23 19:02 pierrepo

#1130 is up to 14 rules. Just trying to knock out a few each days.

charliermarsh avatar Feb 05 '23 00:02 charliermarsh

Knocked out eight more rules behind the feature flag.

charliermarsh avatar Feb 08 '23 04:02 charliermarsh

Four more done.

charliermarsh avatar Feb 09 '23 03:02 charliermarsh

One more in #3225.

charliermarsh avatar Feb 26 '23 21:02 charliermarsh

One more in https://github.com/charliermarsh/ruff/pull/3249.

charliermarsh avatar Feb 27 '23 15:02 charliermarsh

One more in https://github.com/charliermarsh/ruff/pull/3344.

charliermarsh avatar Mar 05 '23 20:03 charliermarsh

rust newb, if someone wants to try this feature set, how do we build ruff with logical-line feature flag support and these style rules enabled?

[update] this seems to do it, following along on contributing.md

git clone https://github.com/charliermarsh/ruff.git
cd ruff
cargo build --all-features --release
cp target/release/ruff ~/bin

kapilt avatar Mar 14 '23 09:03 kapilt

rust newb, if someone wants to try this feature set, how do we build ruff with logical-line feature flag support and these style rules enabled?

@charliermarsh I would like to have a pip release for ruff with that special feature as pip/setup.py "package option" / "extra"/ "extras_require" enabled. So that you can call pip install ruff[logical-line] and have this enabled. Maybe it's possible to achieve that?

spaceone avatar Mar 14 '23 10:03 spaceone

I'm hoping that we can finish and release this soon enough that it's not worth shipping an extra_requires variant. (And if not, I'd probably rather ship with a command-line or feature flag rather than an extras, so that it's available regardless of how you install Ruff.)

charliermarsh avatar Mar 14 '23 19:03 charliermarsh

This conquest is awesome! I see many of these as being checked (e.g. E2 whitespace is done).

Just a friendly request that these get eventually added to the Rules in docs: https://beta.ruff.rs/docs/rules/#error-e

jamesbraza avatar Apr 27 '23 04:04 jamesbraza

Just a friendly request that these get eventually added to the Rules in docs: https://beta.ruff.rs/docs/rules/#error-e

I believe this will be added when #3689 lands, as documenting a rule before it has been enabled will potentially cause some confusion.

calumy avatar Apr 27 '23 11:04 calumy

I'll take a look at E303.

EDIT: I'm doing all of E3 Blank line since they are closely related.

hoel-bagard avatar May 24 '23 08:05 hoel-bagard

E241 and E242 is missing in the list for pycodestyle.

E241 | multiple spaces after ',' E242 | tab after ','

Can you please add it to the checks?

devbis avatar May 25 '23 06:05 devbis

I believe those are intentionally omitted -- we're not planning to implement the rules that are omitted from pycodestyle's default configuration ("not unanimously accepted, and PEP 8 does not enforce them"), at least not to start.

charliermarsh avatar May 25 '23 13:05 charliermarsh

I'm looking into E122 (and I'll follow with the other E1 rules after unless someones is working on them).

hoel-bagard avatar Jun 17 '23 07:06 hoel-bagard

Hello,

I just stumbled about a peculiar behaviour of E714. I had fixed the lint but forgot to remove the first not, i.e. I changed the first if statement to the second below and ruff (I am using ruff version v0.0.275 and v.0.0.277) didn't complain anymore.

a = 8

if not a is None:
    print(a)

if not a is not None:
    print(a)

I think the lint should also check for the second version, or am I wrong?

MartinRoth avatar Jul 06 '23 07:07 MartinRoth

I'm hoping that we can finish and release this soon enough that it's not worth shipping an extra_requires variant. (And if not, I'd probably rather ship with a command-line or feature flag rather than an extras, so that it's available regardless of how you install Ruff.)

I think this will take a lot of extra time right? Maybe it's possible to add that command line flag already?

spaceone avatar Aug 03 '23 13:08 spaceone

Gentle voice of support for E122 and E302 (the latter being included in #4694 which has been in draft for a while.) (ping @hoel-bagard, as both author of that PR and as the one who said you were looking into E122)

These are the last two rules from Matplotlib's flake8 config. Once available, I'd look into swapping over CI/pre-commit hooks to ruff (and then perhaps look into adding more checks, though for now have gone with "parity")

We do not use black, so these are checks which fall into the category of "black would just handle them".

ksunden avatar Sep 20 '23 00:09 ksunden

@ksunden Sorry for taking a long time, for E302, I have started to see if I could find a way to handle comments with the tools currently present in ruff (otherwise a new tool/way of tracking tokens will need to be implemented as suggested in the PR). I was a bit busy recently, but I should be able to spend more time on it in the near future.

For E122, I've just edited my comment saying I was looking into it. A while ago I asked a question on the discord, but did not get an answer (and then I went back to working on the E302 rule and forgot about it). I could restart working on it assuming that having a token emitted for the backslash is fine, in which case it shouldn't take too much time.

I'm looking into adding the E122 rule of pycodestyle (https://www.flake8rules.com/rules/E122.html). It's a rule that checks for indentation within continuation lines.

Implementing it using logical lines seemed natural (and that's what pycodestyle does). It seems like it would work for continuation lines made using parentheses since a NonLogicalNewline is emitted for the new line. However, when using a backslash (case covered by pycodestyle), no NonLogicalNewline token is created, rendering it impossible to know if there is a newline within the logical line.

Could a NonLogicalNewline be emitted when there is a backslash, or does the rule need to be implemented using physical lines ?

Example with parentheses:

print("E122", (
"dent"))

Example using a backslash:

if some_very_very_very_long_variable_name or var \
or another_very_long_variable_name:
    raise Exception()

hoel-bagard avatar Sep 20 '23 00:09 hoel-bagard

Is there an update on when E3 Blank line will get released?

Daku24 avatar Oct 26 '23 15:10 Daku24

I've been doing the E122 rule. I'm at a point where it's working, but I need to clean things up ~~and add the autofix~~ and the config options. I'll go back to the E3 rule once that's done.

Edit:

hoel-bagard avatar Oct 28 '23 11:10 hoel-bagard

W391 is checked but I don't see the rule in Ruff

Avasam avatar Dec 14 '23 07:12 Avasam

@charliermarsh Since #9266 got merged, the E3 rules can be checked here.

hoel-bagard avatar Feb 18 '24 10:02 hoel-bagard