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

[pylint] Implement empty-comment (PLR2044) #9174

Merged
merged 7 commits into from
Dec 29, 2023

Conversation

mdbernard
Copy link
Contributor

@mdbernard mdbernard commented Dec 18, 2023

Summary

Part of #970.

This adds Pylint's R0244 empty_comment lint as well as an always-safe fix.

Test Plan

The included snapshot verifies the following:

  • A line containing only a non-empty comment is not changed
  • A line containing leading whitespace before a non-empty comment is not changed
  • A line containing only an empty comment has its content deleted
  • A line containing only leading whitespace before an empty comment has its content deleted
  • A line containing only leading and trailing whitespace on an empty comment has its content deleted
  • A line containing trailing whitespace after a non-empty comment is not changed
  • A line containing only a single newline character (i.e. a blank line) is not changed
  • A line containing code followed by a non-empty comment is not changed
  • A line containing code followed by an empty comment has its content deleted after the last non-whitespace character
  • Lines containing code and no comments are not changed
  • Empty comment lines within block comments are ignored
  • Empty comments within triple-quoted sections are ignored

Comparison to Pylint

Running Ruff and Pylint 3.0.3 with Python 3.12.0 against the empty_comment.py file added in this PR, we see the following:

  • Identical behavior:

    • empty_comment.py:3:0: R2044: Line with empty comment (empty-comment)
    • empty_comment.py:4:0: R2044: Line with empty comment (empty-comment)
    • empty_comment.py:5:0: R2044: Line with empty comment (empty-comment)
    • empty_comment.py:18:0: R2044: Line with empty comment (empty-comment)
  • Differing behavior:

    • Pylint doesn't ignore empty comments in block comments commonly used for visual spacing; I decided these were fine in this implementation since many projects use these and likely do not want them removed.
      • empty_comment.py:28:0: R2044: Line with empty comment (empty-comment)
    • Pylint detects "empty comments" within the triple-quoted section at the bottom of the file, which is arguably a bug in the Pylint implementation since these are not truly comments. These are ignored by this implementation.
      • empty_comment.py:37:0: R2044: Line with empty comment (empty-comment)
      • empty_comment.py:38:0: R2044: Line with empty comment (empty-comment)
      • empty_comment.py:39:0: R2044: Line with empty comment (empty-comment)

@mdbernard mdbernard force-pushed the PLR2044-empty-comment branch 2 times, most recently from 2ef2331 to 464a094 Compare December 18, 2023 04:10
Copy link
Contributor

github-actions bot commented Dec 18, 2023

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+27 -2 violations, +0 -0 fixes in 6 projects; 35 projects unchanged)

apache/airflow (+8 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --preview --select ALL

+ docs/exts/docroles.py:20:1: PLR2044 [*] Line with empty comment
+ docs/exts/docroles.py:21:1: PLR2044 [*] Line with empty comment
+ tests/providers/common/sql/hooks/test_sql.py:18:1: PLR2044 [*] Line with empty comment
+ tests/providers/databricks/hooks/test_databricks_sql.py:18:1: PLR2044 [*] Line with empty comment
+ tests/providers/exasol/hooks/test_sql.py:18:1: PLR2044 [*] Line with empty comment
+ tests/providers/google/suite/transfers/test_gcs_to_gdrive.py:117:5: PLR2044 [*] Line with empty comment
+ tests/providers/snowflake/hooks/test_sql.py:18:1: PLR2044 [*] Line with empty comment
+ tests/system/providers/google/cloud/storage_transfer/example_cloud_storage_transfer_service_aws.py:121:5: PLR2044 [*] Line with empty comment

aws/aws-sam-cli (+1 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --preview

+ samcli/local/docker/lambda_container.py:149:9: PLR2044 [*] Line with empty comment

milvus-io/pymilvus (+4 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --preview

+ pymilvus/client/abstract.py:114:9: PLR2044 [*] Line with empty comment
+ pymilvus/client/abstract.py:18:9: PLR2044 [*] Line with empty comment
+ pymilvus/client/abstract.py:99:9: PLR2044 [*] Line with empty comment
+ pymilvus/client/types.py:133:5: PLR2044 [*] Line with empty comment

pandas-dev/pandas (+2 -2 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --preview

+ pandas/tests/extension/decimal/array.py:175:9: PLC0415 `import` should be at the top-level of a file
- pandas/tests/extension/decimal/array.py:176:9: PLC0415 `import` should be at the top-level of a file
+ pandas/tests/extension/decimal/array.py:233:9: PLR6301 Method `_formatter` could be a function, class method, or static method
- pandas/tests/extension/decimal/array.py:234:9: PLR6301 Method `_formatter` could be a function, class method, or static method

rotki/rotki (+10 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --preview

+ rotkehlchen/tests/db/test_db.py:752:48: PLR2044 [*] Line with empty comment
+ rotkehlchen/tests/db/test_db.py:757:48: PLR2044 [*] Line with empty comment
+ rotkehlchen/tests/db/test_db.py:795:52: PLR2044 [*] Line with empty comment
+ rotkehlchen/tests/db/test_db.py:797:52: PLR2044 [*] Line with empty comment
+ rotkehlchen/tests/db/test_db.py:801:52: PLR2044 [*] Line with empty comment
+ rotkehlchen/tests/db/test_db.py:834:52: PLR2044 [*] Line with empty comment
+ rotkehlchen/tests/db/test_db.py:837:52: PLR2044 [*] Line with empty comment
+ rotkehlchen/tests/db/test_db.py:843:52: PLR2044 [*] Line with empty comment
+ rotkehlchen/tests/db/test_db.py:844:52: PLR2044 [*] Line with empty comment
+ rotkehlchen/tests/db/test_db.py:845:52: PLR2044 [*] Line with empty comment

zulip/zulip (+2 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --preview --select ALL

+ zerver/lib/export.py:842:5: PLR2044 [*] Line with empty comment
+ zerver/lib/export.py:867:5: PLR2044 [*] Line with empty comment

Changes by rule (3 rules affected)

code total + violation - violation + fix - fix
PLR2044 25 25 0 0 0
PLC0415 2 1 1 0 0
PLR6301 2 1 1 0 0

Formatter (stable)

✅ ecosystem check detected no format changes.

Formatter (preview)

✅ ecosystem check detected no format changes.

@mdbernard
Copy link
Contributor Author

Looks like the ecosystem checks found some edge cases not currently covered:

  • "empty comment" lines within block comments, which add vertical whitespace for clarity, especially common as header comments for files
  • lines containing a trailing # character in multi-line comments, which should not be considered empty comments

@charliermarsh
Copy link
Member

Nice, thanks for kicking this off! Agreed on the edge cases described above.

@mdbernard mdbernard force-pushed the PLR2044-empty-comment branch from 464a094 to f26eda6 Compare December 18, 2023 06:06
@mdbernard mdbernard marked this pull request as draft December 18, 2023 06:06
Copy link
Contributor Author

@mdbernard mdbernard Dec 18, 2023

Choose a reason for hiding this comment

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

  • Add test for "empty comment" lines in multi-line strings/comments
  • Add test for "empty comment" lines in block comments

@mdbernard mdbernard force-pushed the PLR2044-empty-comment branch from f26eda6 to c2de5d1 Compare December 20, 2023 06:27
@mdbernard
Copy link
Contributor Author

mdbernard commented Dec 20, 2023

# -- Methods following the EthereumModule interface -- #

@mdbernard
Copy link
Contributor Author

mdbernard commented Dec 20, 2023

  • Account for comment style with multiple # symbols on a single line (tying in with the above comment, probably best to just lint when a comment consists of only a single # symbol followed by only whitespace through the end of the line.

@mdbernard mdbernard force-pushed the PLR2044-empty-comment branch from c2de5d1 to 3a4d1e1 Compare December 27, 2023 06:08
Copy link
Contributor Author

@mdbernard mdbernard left a comment

Choose a reason for hiding this comment

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

  • Rebase

@mdbernard mdbernard force-pushed the PLR2044-empty-comment branch 2 times, most recently from b203d24 to 09b446a Compare December 27, 2023 06:57
@mdbernard mdbernard force-pushed the PLR2044-empty-comment branch from 09b446a to 3e15b26 Compare December 27, 2023 07:05
@mdbernard mdbernard marked this pull request as ready for review December 28, 2023 02:38
@charliermarsh charliermarsh self-requested a review December 28, 2023 14:46
Copy link
Member

@charliermarsh charliermarsh left a comment

Choose a reason for hiding this comment

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

This looks great, I really like what I'm seeing in the ecosystem checks too -- thank you!

I'm going to explore making this a token-based rule rather than a physical line-based rule, just because we want to avoid using physical lines when possible, but it'll be a mostly mechanical change...

@charliermarsh
Copy link
Member

Pylint doesn't ignore empty comments in block comments commonly used for visual spacing; I decided these were fine in this implementation since many projects use these and likely do not want them removed.

I agree, we shouldn't flag these.

Pylint detects "empty comments" within the triple-quoted section at the bottom of the file, which is arguably a bug in the Pylint implementation since these are not truly comments. These are ignored by this implementation.

I agree, flagging empty comments within a multi-line string seems like a bug to me.

@mdbernard
Copy link
Contributor Author

mdbernard commented Dec 28, 2023

  • Noting that I might've missed an edge case where two empty comments exist on consecutive lines forming a "block" comment.

@mdbernard
Copy link
Contributor Author

we want to avoid using physical lines when possible

Out of curiosity, why?

@charliermarsh
Copy link
Member

Out of curiosity, why?

Primarily because physical line-based approaches tend to be slower, since we need to run the rule over every line. This rule is actually a good example: we already know the locations of all comments in the file (via CommentRanges), so iterating over every line, then checking if the line intersects with the comment ranges, is wasteful as compared to merely iterating over the comment ranges directly. In general, we often have information we've already computed and/or can exploit to limit the search space vs. iterating over the physical lines.

@charliermarsh charliermarsh added the rule Implementing or modifying a lint rule label Dec 29, 2023
@charliermarsh charliermarsh added the preview Related to preview mode features label Dec 29, 2023
@charliermarsh charliermarsh changed the title [pylint] add PLR2044 empty_comment [pylint] Implement empty-comment (PLR2044) Dec 29, 2023
Copy link
Member

@charliermarsh charliermarsh left a comment

Choose a reason for hiding this comment

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

This is great work! I ended up moving to the token checker, and added support for the case in which we have multiple consecutive empty comments.

@charliermarsh charliermarsh enabled auto-merge (squash) December 29, 2023 02:49
@charliermarsh charliermarsh merged commit 375c175 into astral-sh:main Dec 29, 2023
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
preview Related to preview mode features rule Implementing or modifying a lint rule
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants