Split up the table corresponding to the pylint rules (#1868)

This makes it easier to see which rules you're enabling when selecting
one of the pylint codes (like `PLC`). This also makes it clearer what
those abbreviations stand for. When I first saw the pylint section, I
was very confused by that, so other might be as well.

See it rendered here:
https://github.com/thomkeh/ruff/blob/patch-1/README.md#pylint-plc-ple-plr-plw
This commit is contained in:
Thomas MK 2023-01-14 14:07:02 +01:00 committed by GitHub
parent 3447dd3615
commit 9dc66b5a65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 112 additions and 63 deletions

View file

@ -581,6 +581,7 @@ For more, see [Pyflakes](https://pypi.org/project/pyflakes/2.5.0/) on PyPI.
For more, see [pycodestyle](https://pypi.org/project/pycodestyle/2.9.1/) on PyPI.
#### Error (E)
| Code | Name | Message | Fix |
| ---- | ---- | ------- | --- |
| E401 | MultipleImportsOnOneLine | Multiple imports on one line | |
@ -598,6 +599,10 @@ For more, see [pycodestyle](https://pypi.org/project/pycodestyle/2.9.1/) on PyPI
| E743 | AmbiguousFunctionName | Ambiguous function name: `...` | |
| E902 | IOError | IOError: `...` | |
| E999 | SyntaxError | SyntaxError: `...` | |
#### Warning (W)
| Code | Name | Message | Fix |
| ---- | ---- | ------- | --- |
| W292 | NoNewLineAtEndOfFile | No newline at end of file | 🛠 |
| W505 | DocLineTooLong | Doc line too long (89 > 88 characters) | |
| W605 | InvalidEscapeSequence | Invalid escape sequence: '\c' | 🛠 |
@ -979,7 +984,6 @@ For more, see [flake8-simplify](https://pypi.org/project/flake8-simplify/0.19.3/
| Code | Name | Message | Fix |
| ---- | ---- | ------- | --- |
| SIM115 | OpenFileWithContextHandler | Use context handler for opening files | |
| SIM101 | DuplicateIsinstanceCall | Multiple `isinstance` calls for `...`, merge into a single call | 🛠 |
| SIM102 | NestedIfStatements | Use a single `if` statement instead of nested `if` statements | |
| SIM103 | ReturnBoolConditionDirectly | Return the condition `...` directly | 🛠 |
@ -990,6 +994,7 @@ For more, see [flake8-simplify](https://pypi.org/project/flake8-simplify/0.19.3/
| SIM110 | ConvertLoopToAny | Use `return any(x for x in y)` instead of `for` loop | 🛠 |
| SIM111 | ConvertLoopToAll | Use `return all(x for x in y)` instead of `for` loop | 🛠 |
| SIM112 | UseCapitalEnvironmentVariables | Use capitalized environment variable `...` instead of `...` | 🛠 |
| SIM115 | OpenFileWithContextHandler | Use context handler for opening files | |
| SIM117 | MultipleWithStatements | Use a single `with` statement with multiple contexts instead of nested `with` statements | |
| SIM118 | KeyInDict | Use `key in dict` instead of `key in dict.keys()` | 🛠 |
| SIM201 | NegateEqualOp | Use `left != right` instead of `not left == right` | 🛠 |
@ -1084,20 +1089,33 @@ For more, see [pygrep-hooks](https://github.com/pre-commit/pygrep-hooks) on GitH
For more, see [Pylint](https://pypi.org/project/pylint/2.15.7/) on PyPI.
#### Convention (PLC)
| Code | Name | Message | Fix |
| ---- | ---- | ------- | --- |
| PLC0414 | UselessImportAlias | Import alias does not rename original package | 🛠 |
| PLC2201 | MisplacedComparisonConstant | Comparison should be ... | 🛠 |
| PLC3002 | UnnecessaryDirectLambdaCall | Lambda expression called directly. Execute the expression inline instead. | |
#### Error (PLE)
| Code | Name | Message | Fix |
| ---- | ---- | ------- | --- |
| PLE0117 | NonlocalWithoutBinding | Nonlocal name `...` found without binding | |
| PLE0118 | UsedPriorGlobalDeclaration | Name `...` is used prior to global declaration on line 1 | |
| PLE1142 | AwaitOutsideAsync | `await` should be used within an async function | |
#### Refactor (PLR)
| Code | Name | Message | Fix |
| ---- | ---- | ------- | --- |
| PLR0133 | ConstantComparison | Two constants compared in a comparison, consider replacing `0 == 0` | |
| PLR0206 | PropertyWithParameters | Cannot have defined parameters for properties | |
| PLR0402 | ConsiderUsingFromImport | Use `from ... import ...` in lieu of alias | |
| PLR0133 | ConstantComparison | Two constants compared in a comparison, consider replacing `0 == 0` | |
| PLR1701 | ConsiderMergingIsinstance | Merge these isinstance calls: `isinstance(..., (...))` | |
| PLR1722 | UseSysExit | Use `sys.exit()` instead of `exit` | 🛠 |
| PLR2004 | MagicValueComparison | Magic number used in comparison, consider replacing magic with a constant variable | |
#### Warning (PLW)
| Code | Name | Message | Fix |
| ---- | ---- | ------- | --- |
| PLW0120 | UselessElseOnLoop | Else clause on loop without a break statement, remove the else and de-indent all the code inside it | |
| PLW0602 | GlobalVariableNotAssigned | Using global for `...` but no assignment is done | |

View file

@ -180,7 +180,7 @@ fn test_ruff_black_compatibility() -> Result<()> {
// problem. Ruff would add a `# noqa: W292` after the first run, black introduces a
// newline, and ruff removes the `# noqa: W292` again.
.filter(|origin| *origin != RuleOrigin::Ruff)
.map(|origin| origin.codes().iter().map(AsRef::as_ref).join(","))
.map(|origin| origin.prefixes().as_list(","))
.join(",");
let ruff_args = [
"-",

View file

@ -2,8 +2,7 @@
use anyhow::Result;
use clap::Args;
use itertools::Itertools;
use ruff::registry::{RuleCode, RuleOrigin};
use ruff::registry::{Prefixes, RuleCodePrefix, RuleOrigin};
use strum::IntoEnumIterator;
use crate::utils::replace_readme_section;
@ -21,12 +20,33 @@ pub struct Cli {
pub(crate) dry_run: bool,
}
fn generate_table(table_out: &mut String, prefix: &RuleCodePrefix) {
table_out.push_str("| Code | Name | Message | Fix |");
table_out.push('\n');
table_out.push_str("| ---- | ---- | ------- | --- |");
table_out.push('\n');
for rule_code in prefix.codes() {
let kind = rule_code.kind();
let fix_token = if kind.fixable() { "🛠" } else { "" };
table_out.push_str(&format!(
"| {} | {} | {} | {} |",
kind.code().as_ref(),
kind.as_ref(),
kind.summary().replace('|', r"\|"),
fix_token
));
table_out.push('\n');
}
table_out.push('\n');
}
pub fn main(cli: &Cli) -> Result<()> {
// Generate the table string.
let mut table_out = String::new();
let mut toc_out = String::new();
for origin in RuleOrigin::iter() {
let codes_csv: String = origin.codes().iter().map(AsRef::as_ref).join(", ");
let prefixes = origin.prefixes();
let codes_csv: String = prefixes.as_list(", ");
table_out.push_str(&format!("### {} ({codes_csv})", origin.title()));
table_out.push('\n');
table_out.push('\n');
@ -50,26 +70,16 @@ pub fn main(cli: &Cli) -> Result<()> {
table_out.push('\n');
}
table_out.push_str("| Code | Name | Message | Fix |");
table_out.push('\n');
table_out.push_str("| ---- | ---- | ------- | --- |");
table_out.push('\n');
for rule_code in RuleCode::iter() {
if rule_code.origin() == origin {
let kind = rule_code.kind();
let fix_token = if kind.fixable() { "🛠" } else { "" };
table_out.push_str(&format!(
"| {} | {} | {} | {} |",
kind.code().as_ref(),
kind.as_ref(),
kind.summary().replace('|', r"\|"),
fix_token
));
table_out.push('\n');
match prefixes {
Prefixes::Single(prefix) => generate_table(&mut table_out, &prefix),
Prefixes::Multiple(entries) => {
for (prefix, category) in entries {
table_out.push_str(&format!("#### {category} ({})", prefix.as_ref()));
table_out.push('\n');
generate_table(&mut table_out, &prefix);
}
}
}
table_out.push('\n');
}
if cli.dry_run {

View file

@ -2,6 +2,7 @@
use std::fmt;
use itertools::Itertools;
use once_cell::sync::Lazy;
use ruff_macros::RuleCodePrefix;
use rustc_hash::FxHashMap;
@ -568,6 +569,23 @@ impl fmt::Display for Platform {
}
}
pub enum Prefixes {
Single(RuleCodePrefix),
Multiple(Vec<(RuleCodePrefix, &'static str)>),
}
impl Prefixes {
pub fn as_list(&self, separator: &str) -> String {
match self {
Prefixes::Single(prefix) => prefix.as_ref().to_string(),
Prefixes::Multiple(entries) => entries
.iter()
.map(|(prefix, _)| prefix.as_ref())
.join(separator),
}
}
}
impl RuleOrigin {
pub fn title(&self) -> &'static str {
match self {
@ -607,46 +625,49 @@ impl RuleOrigin {
}
}
pub fn codes(&self) -> Vec<RuleCodePrefix> {
pub fn prefixes(&self) -> Prefixes {
match self {
RuleOrigin::Eradicate => vec![RuleCodePrefix::ERA],
RuleOrigin::Flake82020 => vec![RuleCodePrefix::YTT],
RuleOrigin::Flake8Annotations => vec![RuleCodePrefix::ANN],
RuleOrigin::Flake8Bandit => vec![RuleCodePrefix::S],
RuleOrigin::Flake8BlindExcept => vec![RuleCodePrefix::BLE],
RuleOrigin::Flake8BooleanTrap => vec![RuleCodePrefix::FBT],
RuleOrigin::Flake8Bugbear => vec![RuleCodePrefix::B],
RuleOrigin::Flake8Builtins => vec![RuleCodePrefix::A],
RuleOrigin::Flake8Comprehensions => vec![RuleCodePrefix::C4],
RuleOrigin::Flake8Datetimez => vec![RuleCodePrefix::DTZ],
RuleOrigin::Flake8Debugger => vec![RuleCodePrefix::T10],
RuleOrigin::Flake8ErrMsg => vec![RuleCodePrefix::EM],
RuleOrigin::Flake8ImplicitStrConcat => vec![RuleCodePrefix::ISC],
RuleOrigin::Flake8ImportConventions => vec![RuleCodePrefix::ICN],
RuleOrigin::Flake8Print => vec![RuleCodePrefix::T20],
RuleOrigin::Flake8PytestStyle => vec![RuleCodePrefix::PT],
RuleOrigin::Flake8Quotes => vec![RuleCodePrefix::Q],
RuleOrigin::Flake8Return => vec![RuleCodePrefix::RET],
RuleOrigin::Flake8Simplify => vec![RuleCodePrefix::SIM],
RuleOrigin::Flake8TidyImports => vec![RuleCodePrefix::TID],
RuleOrigin::Flake8UnusedArguments => vec![RuleCodePrefix::ARG],
RuleOrigin::Isort => vec![RuleCodePrefix::I],
RuleOrigin::McCabe => vec![RuleCodePrefix::C90],
RuleOrigin::PEP8Naming => vec![RuleCodePrefix::N],
RuleOrigin::PandasVet => vec![RuleCodePrefix::PD],
RuleOrigin::Pycodestyle => vec![RuleCodePrefix::E, RuleCodePrefix::W],
RuleOrigin::Pydocstyle => vec![RuleCodePrefix::D],
RuleOrigin::Pyflakes => vec![RuleCodePrefix::F],
RuleOrigin::PygrepHooks => vec![RuleCodePrefix::PGH],
RuleOrigin::Pylint => vec![
RuleCodePrefix::PLC,
RuleCodePrefix::PLE,
RuleCodePrefix::PLR,
RuleCodePrefix::PLW,
],
RuleOrigin::Pyupgrade => vec![RuleCodePrefix::UP],
RuleOrigin::Flake8Pie => vec![RuleCodePrefix::PIE],
RuleOrigin::Ruff => vec![RuleCodePrefix::RUF],
RuleOrigin::Eradicate => Prefixes::Single(RuleCodePrefix::ERA),
RuleOrigin::Flake82020 => Prefixes::Single(RuleCodePrefix::YTT),
RuleOrigin::Flake8Annotations => Prefixes::Single(RuleCodePrefix::ANN),
RuleOrigin::Flake8Bandit => Prefixes::Single(RuleCodePrefix::S),
RuleOrigin::Flake8BlindExcept => Prefixes::Single(RuleCodePrefix::BLE),
RuleOrigin::Flake8BooleanTrap => Prefixes::Single(RuleCodePrefix::FBT),
RuleOrigin::Flake8Bugbear => Prefixes::Single(RuleCodePrefix::B),
RuleOrigin::Flake8Builtins => Prefixes::Single(RuleCodePrefix::A),
RuleOrigin::Flake8Comprehensions => Prefixes::Single(RuleCodePrefix::C4),
RuleOrigin::Flake8Datetimez => Prefixes::Single(RuleCodePrefix::DTZ),
RuleOrigin::Flake8Debugger => Prefixes::Single(RuleCodePrefix::T10),
RuleOrigin::Flake8ErrMsg => Prefixes::Single(RuleCodePrefix::EM),
RuleOrigin::Flake8ImplicitStrConcat => Prefixes::Single(RuleCodePrefix::ISC),
RuleOrigin::Flake8ImportConventions => Prefixes::Single(RuleCodePrefix::ICN),
RuleOrigin::Flake8Print => Prefixes::Single(RuleCodePrefix::T20),
RuleOrigin::Flake8PytestStyle => Prefixes::Single(RuleCodePrefix::PT),
RuleOrigin::Flake8Quotes => Prefixes::Single(RuleCodePrefix::Q),
RuleOrigin::Flake8Return => Prefixes::Single(RuleCodePrefix::RET),
RuleOrigin::Flake8Simplify => Prefixes::Single(RuleCodePrefix::SIM),
RuleOrigin::Flake8TidyImports => Prefixes::Single(RuleCodePrefix::TID),
RuleOrigin::Flake8UnusedArguments => Prefixes::Single(RuleCodePrefix::ARG),
RuleOrigin::Isort => Prefixes::Single(RuleCodePrefix::I),
RuleOrigin::McCabe => Prefixes::Single(RuleCodePrefix::C90),
RuleOrigin::PEP8Naming => Prefixes::Single(RuleCodePrefix::N),
RuleOrigin::PandasVet => Prefixes::Single(RuleCodePrefix::PD),
RuleOrigin::Pycodestyle => Prefixes::Multiple(vec![
(RuleCodePrefix::E, "Error"),
(RuleCodePrefix::W, "Warning"),
]),
RuleOrigin::Pydocstyle => Prefixes::Single(RuleCodePrefix::D),
RuleOrigin::Pyflakes => Prefixes::Single(RuleCodePrefix::F),
RuleOrigin::PygrepHooks => Prefixes::Single(RuleCodePrefix::PGH),
RuleOrigin::Pylint => Prefixes::Multiple(vec![
(RuleCodePrefix::PLC, "Convention"),
(RuleCodePrefix::PLE, "Error"),
(RuleCodePrefix::PLR, "Refactor"),
(RuleCodePrefix::PLW, "Warning"),
]),
RuleOrigin::Pyupgrade => Prefixes::Single(RuleCodePrefix::UP),
RuleOrigin::Flake8Pie => Prefixes::Single(RuleCodePrefix::PIE),
RuleOrigin::Ruff => Prefixes::Single(RuleCodePrefix::RUF),
}
}