diff --git a/README.md b/README.md index 641c286fd5..540cb9e920 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ of [Conda](https://docs.conda.io/en/latest/): 1. [flake8-unused-arguments (ARG)](#flake8-unused-arguments-arg) 1. [flake8-datetimez (DTZ)](#flake8-datetimez-dtz) 1. [eradicate (ERA)](#eradicate-era) - 1. [pandas-vet (PDV)](#pandas-vet-pdv) + 1. [pandas-vet (PD)](#pandas-vet-pd) 1. [pygrep-hooks (PGH)](#pygrep-hooks-pgh) 1. [Pylint (PLC, PLE, PLR, PLW)](#pylint-plc-ple-plr-plw) 1. [Ruff-specific rules (RUF)](#ruff-specific-rules-ruf) @@ -891,24 +891,24 @@ For more, see [eradicate](https://pypi.org/project/eradicate/2.1.0/) on PyPI. | ---- | ---- | ------- | --- | | ERA001 | CommentedOutCode | Found commented-out code | 🛠 | -### pandas-vet (PDV) +### pandas-vet (PD) For more, see [pandas-vet](https://pypi.org/project/pandas-vet/0.2.3/) on PyPI. | Code | Name | Message | Fix | | ---- | ---- | ------- | --- | -| PDV002 | UseOfInplaceArgument | `inplace=True` should be avoided; it has inconsistent behavior | | -| PDV003 | UseOfDotIsNull | `.isna` is preferred to `.isnull`; functionality is equivalent | | -| PDV004 | UseOfDotNotNull | `.notna` is preferred to `.notnull`; functionality is equivalent | | -| PDV007 | UseOfDotIx | `.ix` is deprecated; use more explicit `.loc` or `.iloc` | | -| PDV008 | UseOfDotAt | Use `.loc` instead of `.at`. If speed is important, use numpy. | | -| PDV009 | UseOfDotIat | Use `.iloc` instead of `.iat`. If speed is important, use numpy. | | -| PDV010 | UseOfDotPivotOrUnstack | `.pivot_table` is preferred to `.pivot` or `.unstack`; provides same functionality | | -| PDV011 | UseOfDotValues | Use `.to_numpy()` instead of `.values` | | -| PDV012 | UseOfDotReadTable | `.read_csv` is preferred to `.read_table`; provides same functionality | | -| PDV013 | UseOfDotStack | `.melt` is preferred to `.stack`; provides same functionality | | -| PDV015 | UseOfPdMerge | Use `.merge` method instead of `pd.merge` function. They have equivalent functionality. | | -| PDV901 | DfIsABadVariableName | `df` is a bad variable name. Be kinder to your future self. | | +| PD002 | UseOfInplaceArgument | `inplace=True` should be avoided; it has inconsistent behavior | | +| PD003 | UseOfDotIsNull | `.isna` is preferred to `.isnull`; functionality is equivalent | | +| PD004 | UseOfDotNotNull | `.notna` is preferred to `.notnull`; functionality is equivalent | | +| PD007 | UseOfDotIx | `.ix` is deprecated; use more explicit `.loc` or `.iloc` | | +| PD008 | UseOfDotAt | Use `.loc` instead of `.at`. If speed is important, use numpy. | | +| PD009 | UseOfDotIat | Use `.iloc` instead of `.iat`. If speed is important, use numpy. | | +| PD010 | UseOfDotPivotOrUnstack | `.pivot_table` is preferred to `.pivot` or `.unstack`; provides same functionality | | +| PD011 | UseOfDotValues | Use `.to_numpy()` instead of `.values` | | +| PD012 | UseOfDotReadTable | `.read_csv` is preferred to `.read_table`; provides same functionality | | +| PD013 | UseOfDotStack | `.melt` is preferred to `.stack`; provides same functionality | | +| PD015 | UseOfPdMerge | Use `.merge` method instead of `pd.merge` function. They have equivalent functionality. | | +| PD901 | DfIsABadVariableName | `df` is a bad variable name. Be kinder to your future self. | | ### pygrep-hooks (PGH) diff --git a/flake8_to_ruff/src/plugin.rs b/flake8_to_ruff/src/plugin.rs index 6c2218cbf4..3228c94f1f 100644 --- a/flake8_to_ruff/src/plugin.rs +++ b/flake8_to_ruff/src/plugin.rs @@ -80,8 +80,7 @@ impl Plugin { Plugin::Flake8Simplify => CheckCodePrefix::SIM, Plugin::Flake8TidyImports => CheckCodePrefix::I25, Plugin::McCabe => CheckCodePrefix::C9, - // TODO(charlie): Handle rename of `PD` to `PDV`. - Plugin::PandasVet => CheckCodePrefix::PDV, + Plugin::PandasVet => CheckCodePrefix::PD, Plugin::PEP8Naming => CheckCodePrefix::N, Plugin::Pyupgrade => CheckCodePrefix::U, } @@ -121,7 +120,7 @@ impl Plugin { Plugin::Flake8Simplify => vec![CheckCodePrefix::SIM], Plugin::Flake8TidyImports => vec![CheckCodePrefix::TID], Plugin::McCabe => vec![CheckCodePrefix::C9], - Plugin::PandasVet => vec![CheckCodePrefix::PDV], + Plugin::PandasVet => vec![CheckCodePrefix::PD], Plugin::PEP8Naming => vec![CheckCodePrefix::N], Plugin::Pyupgrade => vec![CheckCodePrefix::UP], } diff --git a/src/checkers/ast.rs b/src/checkers/ast.rs index b17db8b4a1..8e8a976a9d 100644 --- a/src/checkers/ast.rs +++ b/src/checkers/ast.rs @@ -1181,7 +1181,7 @@ where self, stmt, targets, value, ); } - if self.settings.enabled.contains(&CheckCode::PDV901) { + if self.settings.enabled.contains(&CheckCode::PD901) { if let Some(check) = pandas_vet::checks::assignment_to_df(targets) { self.add_check(check); } @@ -1547,10 +1547,10 @@ where } for (code, name) in vec![ - (CheckCode::PDV007, "ix"), - (CheckCode::PDV008, "at"), - (CheckCode::PDV009, "iat"), - (CheckCode::PDV011, "values"), + (CheckCode::PD007, "ix"), + (CheckCode::PD008, "at"), + (CheckCode::PD009, "iat"), + (CheckCode::PD011, "values"), ] { if self.settings.enabled.contains(&code) { if attr == name { @@ -1932,17 +1932,17 @@ where } // pandas-vet - if self.settings.enabled.contains(&CheckCode::PDV002) { + if self.settings.enabled.contains(&CheckCode::PD002) { self.add_checks(pandas_vet::checks::inplace_argument(keywords).into_iter()); } for (code, name) in vec![ - (CheckCode::PDV003, "isnull"), - (CheckCode::PDV004, "notnull"), - (CheckCode::PDV010, "pivot"), - (CheckCode::PDV010, "unstack"), - (CheckCode::PDV012, "read_table"), - (CheckCode::PDV013, "stack"), + (CheckCode::PD003, "isnull"), + (CheckCode::PD004, "notnull"), + (CheckCode::PD010, "pivot"), + (CheckCode::PD010, "unstack"), + (CheckCode::PD012, "read_table"), + (CheckCode::PD013, "stack"), ] { if self.settings.enabled.contains(&code) { if let ExprKind::Attribute { attr, .. } = &func.node { @@ -1953,7 +1953,7 @@ where } } - if self.settings.enabled.contains(&CheckCode::PDV015) { + if self.settings.enabled.contains(&CheckCode::PD015) { if let Some(check) = pandas_vet::checks::use_of_pd_merge(func) { self.add_check(check); }; diff --git a/src/checks.rs b/src/checks.rs index 82f17d0ce3..b21d1b6c76 100644 --- a/src/checks.rs +++ b/src/checks.rs @@ -329,18 +329,18 @@ pub enum CheckCode { PGH002, PGH003, // pandas-vet - PDV002, - PDV003, - PDV004, - PDV007, - PDV008, - PDV009, - PDV010, - PDV011, - PDV012, - PDV013, - PDV015, - PDV901, + PD002, + PD003, + PD004, + PD007, + PD008, + PD009, + PD010, + PD011, + PD012, + PD013, + PD015, + PD901, // flake8-errmsg EM101, EM102, @@ -453,7 +453,7 @@ impl CheckCategory { CheckCategory::Flake8Datetimez => vec![CheckCodePrefix::DTZ], CheckCategory::Isort => vec![CheckCodePrefix::I], CheckCategory::McCabe => vec![CheckCodePrefix::C90], - CheckCategory::PandasVet => vec![CheckCodePrefix::PDV], + CheckCategory::PandasVet => vec![CheckCodePrefix::PD], CheckCategory::PEP8Naming => vec![CheckCodePrefix::N], CheckCategory::Pycodestyle => vec![CheckCodePrefix::E, CheckCodePrefix::W], CheckCategory::Pydocstyle => vec![CheckCodePrefix::D], @@ -1306,18 +1306,18 @@ impl CheckCode { CheckKind::ImportAliasIsNotConventional("...".to_string(), "...".to_string()) } // pandas-vet - CheckCode::PDV002 => CheckKind::UseOfInplaceArgument, - CheckCode::PDV003 => CheckKind::UseOfDotIsNull, - CheckCode::PDV004 => CheckKind::UseOfDotNotNull, - CheckCode::PDV007 => CheckKind::UseOfDotIx, - CheckCode::PDV008 => CheckKind::UseOfDotAt, - CheckCode::PDV009 => CheckKind::UseOfDotIat, - CheckCode::PDV010 => CheckKind::UseOfDotPivotOrUnstack, - CheckCode::PDV011 => CheckKind::UseOfDotValues, - CheckCode::PDV012 => CheckKind::UseOfDotReadTable, - CheckCode::PDV013 => CheckKind::UseOfDotStack, - CheckCode::PDV015 => CheckKind::UseOfPdMerge, - CheckCode::PDV901 => CheckKind::DfIsABadVariableName, + CheckCode::PD002 => CheckKind::UseOfInplaceArgument, + CheckCode::PD003 => CheckKind::UseOfDotIsNull, + CheckCode::PD004 => CheckKind::UseOfDotNotNull, + CheckCode::PD007 => CheckKind::UseOfDotIx, + CheckCode::PD008 => CheckKind::UseOfDotAt, + CheckCode::PD009 => CheckKind::UseOfDotIat, + CheckCode::PD010 => CheckKind::UseOfDotPivotOrUnstack, + CheckCode::PD011 => CheckKind::UseOfDotValues, + CheckCode::PD012 => CheckKind::UseOfDotReadTable, + CheckCode::PD013 => CheckKind::UseOfDotStack, + CheckCode::PD015 => CheckKind::UseOfPdMerge, + CheckCode::PD901 => CheckKind::DfIsABadVariableName, // flake8-errmsg CheckCode::EM101 => CheckKind::RawStringInException, CheckCode::EM102 => CheckKind::FStringInException, @@ -1545,18 +1545,18 @@ impl CheckCode { CheckCode::N816 => CheckCategory::PEP8Naming, CheckCode::N817 => CheckCategory::PEP8Naming, CheckCode::N818 => CheckCategory::PEP8Naming, - CheckCode::PDV002 => CheckCategory::PandasVet, - CheckCode::PDV003 => CheckCategory::PandasVet, - CheckCode::PDV004 => CheckCategory::PandasVet, - CheckCode::PDV007 => CheckCategory::PandasVet, - CheckCode::PDV008 => CheckCategory::PandasVet, - CheckCode::PDV009 => CheckCategory::PandasVet, - CheckCode::PDV010 => CheckCategory::PandasVet, - CheckCode::PDV011 => CheckCategory::PandasVet, - CheckCode::PDV012 => CheckCategory::PandasVet, - CheckCode::PDV013 => CheckCategory::PandasVet, - CheckCode::PDV015 => CheckCategory::PandasVet, - CheckCode::PDV901 => CheckCategory::PandasVet, + CheckCode::PD002 => CheckCategory::PandasVet, + CheckCode::PD003 => CheckCategory::PandasVet, + CheckCode::PD004 => CheckCategory::PandasVet, + CheckCode::PD007 => CheckCategory::PandasVet, + CheckCode::PD008 => CheckCategory::PandasVet, + CheckCode::PD009 => CheckCategory::PandasVet, + CheckCode::PD010 => CheckCategory::PandasVet, + CheckCode::PD011 => CheckCategory::PandasVet, + CheckCode::PD012 => CheckCategory::PandasVet, + CheckCode::PD013 => CheckCategory::PandasVet, + CheckCode::PD015 => CheckCategory::PandasVet, + CheckCode::PD901 => CheckCategory::PandasVet, CheckCode::PGH001 => CheckCategory::PygrepHooks, CheckCode::PGH002 => CheckCategory::PygrepHooks, CheckCode::PGH003 => CheckCategory::PygrepHooks, @@ -1914,18 +1914,18 @@ impl CheckKind { // flake8-import-conventions CheckKind::ImportAliasIsNotConventional(..) => &CheckCode::ICN001, // pandas-vet - CheckKind::UseOfInplaceArgument => &CheckCode::PDV002, - CheckKind::UseOfDotIsNull => &CheckCode::PDV003, - CheckKind::UseOfDotNotNull => &CheckCode::PDV004, - CheckKind::UseOfDotIx => &CheckCode::PDV007, - CheckKind::UseOfDotAt => &CheckCode::PDV008, - CheckKind::UseOfDotIat => &CheckCode::PDV009, - CheckKind::UseOfDotPivotOrUnstack => &CheckCode::PDV010, - CheckKind::UseOfDotValues => &CheckCode::PDV011, - CheckKind::UseOfDotReadTable => &CheckCode::PDV012, - CheckKind::UseOfDotStack => &CheckCode::PDV013, - CheckKind::UseOfPdMerge => &CheckCode::PDV015, - CheckKind::DfIsABadVariableName => &CheckCode::PDV901, + CheckKind::UseOfInplaceArgument => &CheckCode::PD002, + CheckKind::UseOfDotIsNull => &CheckCode::PD003, + CheckKind::UseOfDotNotNull => &CheckCode::PD004, + CheckKind::UseOfDotIx => &CheckCode::PD007, + CheckKind::UseOfDotAt => &CheckCode::PD008, + CheckKind::UseOfDotIat => &CheckCode::PD009, + CheckKind::UseOfDotPivotOrUnstack => &CheckCode::PD010, + CheckKind::UseOfDotValues => &CheckCode::PD011, + CheckKind::UseOfDotReadTable => &CheckCode::PD012, + CheckKind::UseOfDotStack => &CheckCode::PD013, + CheckKind::UseOfPdMerge => &CheckCode::PD015, + CheckKind::DfIsABadVariableName => &CheckCode::PD901, // flake8-errmsg CheckKind::RawStringInException => &CheckCode::EM101, CheckKind::FStringInException => &CheckCode::EM102, @@ -3065,6 +3065,19 @@ pub static CODE_REDIRECTS: Lazy> = Lazy::new( // TODO(charlie): Remove by 2023-02-01. ("I252", CheckCode::TID252), ("M001", CheckCode::RUF100), + // TODO(charlie): Remove by 2023-02-01. + ("PDV002", CheckCode::PD002), + ("PDV003", CheckCode::PD003), + ("PDV004", CheckCode::PD004), + ("PDV007", CheckCode::PD007), + ("PDV008", CheckCode::PD008), + ("PDV009", CheckCode::PD009), + ("PDV010", CheckCode::PD010), + ("PDV011", CheckCode::PD011), + ("PDV012", CheckCode::PD012), + ("PDV013", CheckCode::PD013), + ("PDV015", CheckCode::PD015), + ("PDV901", CheckCode::PD901), ]) }); @@ -3081,6 +3094,12 @@ pub static PREFIX_REDIRECTS: Lazy> = Lazy: ("I25", "TID25"), ("M", "RUF100"), ("M0", "RUF100"), + // TODO(charlie): Remove by 2023-02-01. + ("PDV", "PD"), + ("PDV0", "PD0"), + ("PDV01", "PD01"), + ("PDV9", "PD9"), + ("PDV90", "PD90"), ]) }); diff --git a/src/checks_gen.rs b/src/checks_gen.rs index 261bdc7e67..0c9b934b7d 100644 --- a/src/checks_gen.rs +++ b/src/checks_gen.rs @@ -317,9 +317,26 @@ pub enum CheckCodePrefix { N816, N817, N818, + PD, + PD0, + PD00, + PD002, + PD003, + PD004, + PD007, + PD008, + PD009, + PD01, + PD010, + PD011, + PD012, + PD013, + PD015, + PD9, + PD90, + PD901, PDV, PDV0, - PDV00, PDV002, PDV003, PDV004, @@ -1425,62 +1442,246 @@ impl CheckCodePrefix { CheckCodePrefix::N816 => vec![CheckCode::N816], CheckCodePrefix::N817 => vec![CheckCode::N817], CheckCodePrefix::N818 => vec![CheckCode::N818], - CheckCodePrefix::PDV => vec![ - CheckCode::PDV002, - CheckCode::PDV003, - CheckCode::PDV004, - CheckCode::PDV007, - CheckCode::PDV008, - CheckCode::PDV009, - CheckCode::PDV010, - CheckCode::PDV011, - CheckCode::PDV012, - CheckCode::PDV013, - CheckCode::PDV015, - CheckCode::PDV901, + CheckCodePrefix::PD => vec![ + CheckCode::PD002, + CheckCode::PD003, + CheckCode::PD004, + CheckCode::PD007, + CheckCode::PD008, + CheckCode::PD009, + CheckCode::PD010, + CheckCode::PD011, + CheckCode::PD012, + CheckCode::PD013, + CheckCode::PD015, + CheckCode::PD901, ], - CheckCodePrefix::PDV0 => vec![ - CheckCode::PDV002, - CheckCode::PDV003, - CheckCode::PDV004, - CheckCode::PDV007, - CheckCode::PDV008, - CheckCode::PDV009, - CheckCode::PDV010, - CheckCode::PDV011, - CheckCode::PDV012, - CheckCode::PDV013, - CheckCode::PDV015, + CheckCodePrefix::PD0 => vec![ + CheckCode::PD002, + CheckCode::PD003, + CheckCode::PD004, + CheckCode::PD007, + CheckCode::PD008, + CheckCode::PD009, + CheckCode::PD010, + CheckCode::PD011, + CheckCode::PD012, + CheckCode::PD013, + CheckCode::PD015, ], - CheckCodePrefix::PDV00 => vec![ - CheckCode::PDV002, - CheckCode::PDV003, - CheckCode::PDV004, - CheckCode::PDV007, - CheckCode::PDV008, - CheckCode::PDV009, + CheckCodePrefix::PD00 => vec![ + CheckCode::PD002, + CheckCode::PD003, + CheckCode::PD004, + CheckCode::PD007, + CheckCode::PD008, + CheckCode::PD009, ], - CheckCodePrefix::PDV002 => vec![CheckCode::PDV002], - CheckCodePrefix::PDV003 => vec![CheckCode::PDV003], - CheckCodePrefix::PDV004 => vec![CheckCode::PDV004], - CheckCodePrefix::PDV007 => vec![CheckCode::PDV007], - CheckCodePrefix::PDV008 => vec![CheckCode::PDV008], - CheckCodePrefix::PDV009 => vec![CheckCode::PDV009], - CheckCodePrefix::PDV01 => vec![ - CheckCode::PDV010, - CheckCode::PDV011, - CheckCode::PDV012, - CheckCode::PDV013, - CheckCode::PDV015, + CheckCodePrefix::PD002 => vec![CheckCode::PD002], + CheckCodePrefix::PD003 => vec![CheckCode::PD003], + CheckCodePrefix::PD004 => vec![CheckCode::PD004], + CheckCodePrefix::PD007 => vec![CheckCode::PD007], + CheckCodePrefix::PD008 => vec![CheckCode::PD008], + CheckCodePrefix::PD009 => vec![CheckCode::PD009], + CheckCodePrefix::PD01 => vec![ + CheckCode::PD010, + CheckCode::PD011, + CheckCode::PD012, + CheckCode::PD013, + CheckCode::PD015, ], - CheckCodePrefix::PDV010 => vec![CheckCode::PDV010], - CheckCodePrefix::PDV011 => vec![CheckCode::PDV011], - CheckCodePrefix::PDV012 => vec![CheckCode::PDV012], - CheckCodePrefix::PDV013 => vec![CheckCode::PDV013], - CheckCodePrefix::PDV015 => vec![CheckCode::PDV015], - CheckCodePrefix::PDV9 => vec![CheckCode::PDV901], - CheckCodePrefix::PDV90 => vec![CheckCode::PDV901], - CheckCodePrefix::PDV901 => vec![CheckCode::PDV901], + CheckCodePrefix::PD010 => vec![CheckCode::PD010], + CheckCodePrefix::PD011 => vec![CheckCode::PD011], + CheckCodePrefix::PD012 => vec![CheckCode::PD012], + CheckCodePrefix::PD013 => vec![CheckCode::PD013], + CheckCodePrefix::PD015 => vec![CheckCode::PD015], + CheckCodePrefix::PD9 => vec![CheckCode::PD901], + CheckCodePrefix::PD90 => vec![CheckCode::PD901], + CheckCodePrefix::PD901 => vec![CheckCode::PD901], + CheckCodePrefix::PDV => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV` has been remapped to `PD`".bold() + ); + vec![ + CheckCode::PD002, + CheckCode::PD003, + CheckCode::PD004, + CheckCode::PD007, + CheckCode::PD008, + CheckCode::PD009, + CheckCode::PD010, + CheckCode::PD011, + CheckCode::PD012, + CheckCode::PD013, + CheckCode::PD015, + CheckCode::PD901, + ] + } + CheckCodePrefix::PDV0 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV0` has been remapped to `PD0`".bold() + ); + vec![ + CheckCode::PD002, + CheckCode::PD003, + CheckCode::PD004, + CheckCode::PD007, + CheckCode::PD008, + CheckCode::PD009, + CheckCode::PD010, + CheckCode::PD011, + CheckCode::PD012, + CheckCode::PD013, + CheckCode::PD015, + ] + } + CheckCodePrefix::PDV002 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV002` has been remapped to `PD002`".bold() + ); + vec![CheckCode::PD002] + } + CheckCodePrefix::PDV003 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV003` has been remapped to `PD003`".bold() + ); + vec![CheckCode::PD003] + } + CheckCodePrefix::PDV004 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV004` has been remapped to `PD004`".bold() + ); + vec![CheckCode::PD004] + } + CheckCodePrefix::PDV007 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV007` has been remapped to `PD007`".bold() + ); + vec![CheckCode::PD007] + } + CheckCodePrefix::PDV008 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV008` has been remapped to `PD008`".bold() + ); + vec![CheckCode::PD008] + } + CheckCodePrefix::PDV009 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV009` has been remapped to `PD009`".bold() + ); + vec![CheckCode::PD009] + } + CheckCodePrefix::PDV01 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV01` has been remapped to `PD01`".bold() + ); + vec![ + CheckCode::PD010, + CheckCode::PD011, + CheckCode::PD012, + CheckCode::PD013, + CheckCode::PD015, + ] + } + CheckCodePrefix::PDV010 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV010` has been remapped to `PD010`".bold() + ); + vec![CheckCode::PD010] + } + CheckCodePrefix::PDV011 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV011` has been remapped to `PD011`".bold() + ); + vec![CheckCode::PD011] + } + CheckCodePrefix::PDV012 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV012` has been remapped to `PD012`".bold() + ); + vec![CheckCode::PD012] + } + CheckCodePrefix::PDV013 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV013` has been remapped to `PD013`".bold() + ); + vec![CheckCode::PD013] + } + CheckCodePrefix::PDV015 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV015` has been remapped to `PD015`".bold() + ); + vec![CheckCode::PD015] + } + CheckCodePrefix::PDV9 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV9` has been remapped to `PD9`".bold() + ); + vec![CheckCode::PD901] + } + CheckCodePrefix::PDV90 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV90` has been remapped to `PD90`".bold() + ); + vec![CheckCode::PD901] + } + CheckCodePrefix::PDV901 => { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "`PDV901` has been remapped to `PD901`".bold() + ); + vec![CheckCode::PD901] + } CheckCodePrefix::PGH => vec![CheckCode::PGH001, CheckCode::PGH002, CheckCode::PGH003], CheckCodePrefix::PGH0 => vec![CheckCode::PGH001, CheckCode::PGH002, CheckCode::PGH003], CheckCodePrefix::PGH00 => vec![CheckCode::PGH001, CheckCode::PGH002, CheckCode::PGH003], @@ -2308,9 +2509,26 @@ impl CheckCodePrefix { CheckCodePrefix::N816 => SuffixLength::Three, CheckCodePrefix::N817 => SuffixLength::Three, CheckCodePrefix::N818 => SuffixLength::Three, + CheckCodePrefix::PD => SuffixLength::Zero, + CheckCodePrefix::PD0 => SuffixLength::One, + CheckCodePrefix::PD00 => SuffixLength::Two, + CheckCodePrefix::PD002 => SuffixLength::Three, + CheckCodePrefix::PD003 => SuffixLength::Three, + CheckCodePrefix::PD004 => SuffixLength::Three, + CheckCodePrefix::PD007 => SuffixLength::Three, + CheckCodePrefix::PD008 => SuffixLength::Three, + CheckCodePrefix::PD009 => SuffixLength::Three, + CheckCodePrefix::PD01 => SuffixLength::Two, + CheckCodePrefix::PD010 => SuffixLength::Three, + CheckCodePrefix::PD011 => SuffixLength::Three, + CheckCodePrefix::PD012 => SuffixLength::Three, + CheckCodePrefix::PD013 => SuffixLength::Three, + CheckCodePrefix::PD015 => SuffixLength::Three, + CheckCodePrefix::PD9 => SuffixLength::One, + CheckCodePrefix::PD90 => SuffixLength::Two, + CheckCodePrefix::PD901 => SuffixLength::Three, CheckCodePrefix::PDV => SuffixLength::Zero, CheckCodePrefix::PDV0 => SuffixLength::One, - CheckCodePrefix::PDV00 => SuffixLength::Two, CheckCodePrefix::PDV002 => SuffixLength::Three, CheckCodePrefix::PDV003 => SuffixLength::Three, CheckCodePrefix::PDV004 => SuffixLength::Three, @@ -2512,7 +2730,7 @@ pub const CATEGORIES: &[CheckCodePrefix] = &[ CheckCodePrefix::I, CheckCodePrefix::ICN, CheckCodePrefix::N, - CheckCodePrefix::PDV, + CheckCodePrefix::PD, CheckCodePrefix::PGH, CheckCodePrefix::PLC, CheckCodePrefix::PLE, diff --git a/src/pandas_vet/checks.rs b/src/pandas_vet/checks.rs index 8bba432afc..e3b2886238 100644 --- a/src/pandas_vet/checks.rs +++ b/src/pandas_vet/checks.rs @@ -3,7 +3,7 @@ use rustpython_ast::{Constant, Expr, ExprKind, Keyword}; use crate::ast::types::Range; use crate::checks::{Check, CheckKind}; -/// PDV002 +/// PD002 pub fn inplace_argument(keywords: &[Keyword]) -> Option { for keyword in keywords { let arg = keyword.node.arg.as_ref()?; @@ -27,7 +27,7 @@ pub fn inplace_argument(keywords: &[Keyword]) -> Option { None } -/// PDV015 +/// PD015 pub fn use_of_pd_merge(func: &Expr) -> Option { if let ExprKind::Attribute { attr, value, .. } = &func.node { if let ExprKind::Name { id, .. } = &value.node { @@ -42,7 +42,7 @@ pub fn use_of_pd_merge(func: &Expr) -> Option { None } -/// PDV901 +/// PD901 pub fn assignment_to_df(targets: &[Expr]) -> Option { if targets.len() != 1 { return None; diff --git a/src/pandas_vet/mod.rs b/src/pandas_vet/mod.rs index 9d2bb77ce9..a0a6ad8bfe 100644 --- a/src/pandas_vet/mod.rs +++ b/src/pandas_vet/mod.rs @@ -18,7 +18,7 @@ mod tests { fn check_code(contents: &str, expected: &[CheckCode]) -> Result<()> { let contents = dedent(contents); - let settings = settings::Settings::for_rules(CheckCodePrefix::PDV.codes()); + let settings = settings::Settings::for_rules(CheckCodePrefix::PD.codes()); let tokens: Vec = rustpython_helpers::tokenize(&contents); let locator = SourceCodeLocator::new(&contents); let directives = directives::extract_directives( @@ -46,20 +46,20 @@ mod tests { Ok(()) } - #[test_case("df.drop(['a'], axis=1, inplace=False)", &[]; "PDV002_pass")] - #[test_case("df.drop(['a'], axis=1, inplace=True)", &[CheckCode::PDV002]; "PDV002_fail")] - #[test_case("nas = pd.isna(val)", &[]; "PDV003_pass")] - #[test_case("nulls = pd.isnull(val)", &[CheckCode::PDV003]; "PDV003_fail")] - #[test_case("print('bah humbug')", &[]; "PDV003_allows_other_calls")] - #[test_case("not_nas = pd.notna(val)", &[]; "PDV004_pass")] - #[test_case("not_nulls = pd.notnull(val)", &[CheckCode::PDV004]; "PDV004_fail")] - #[test_case("new_df = df.loc['d':, 'A':'C']", &[]; "PDV007_pass_loc")] - #[test_case("new_df = df.iloc[[1, 3, 5], [1, 3]]", &[]; "PDV007_pass_iloc")] - #[test_case("s = df.ix[[0, 2], 'A']", &[CheckCode::PDV007]; "PDV007_fail")] - #[test_case("index = df.loc[:, ['B', 'A']]", &[]; "PDV008_pass")] - #[test_case("index = df.at[:, ['B', 'A']]", &[CheckCode::PDV008]; "PDV008_fail")] - #[test_case("index = df.iloc[:, 1:3]", &[]; "PDV009_pass")] - #[test_case("index = df.iat[:, 1:3]", &[CheckCode::PDV009]; "PDV009_fail")] + #[test_case("df.drop(['a'], axis=1, inplace=False)", &[]; "PD002_pass")] + #[test_case("df.drop(['a'], axis=1, inplace=True)", &[CheckCode::PD002]; "PD002_fail")] + #[test_case("nas = pd.isna(val)", &[]; "PD003_pass")] + #[test_case("nulls = pd.isnull(val)", &[CheckCode::PD003]; "PD003_fail")] + #[test_case("print('bah humbug')", &[]; "PD003_allows_other_calls")] + #[test_case("not_nas = pd.notna(val)", &[]; "PD004_pass")] + #[test_case("not_nulls = pd.notnull(val)", &[CheckCode::PD004]; "PD004_fail")] + #[test_case("new_df = df.loc['d':, 'A':'C']", &[]; "PD007_pass_loc")] + #[test_case("new_df = df.iloc[[1, 3, 5], [1, 3]]", &[]; "PD007_pass_iloc")] + #[test_case("s = df.ix[[0, 2], 'A']", &[CheckCode::PD007]; "PD007_fail")] + #[test_case("index = df.loc[:, ['B', 'A']]", &[]; "PD008_pass")] + #[test_case("index = df.at[:, ['B', 'A']]", &[CheckCode::PD008]; "PD008_fail")] + #[test_case("index = df.iloc[:, 1:3]", &[]; "PD009_pass")] + #[test_case("index = df.iat[:, 1:3]", &[CheckCode::PD009]; "PD009_fail")] #[test_case(r#"table = df.pivot_table( df, values='D', @@ -68,42 +68,42 @@ mod tests { aggfunc=np.sum, fill_value=0 ) - "#, &[]; "PDV010_pass")] + "#, &[]; "PD010_pass")] #[test_case(r#"table = pd.pivot( df, index='foo', columns='bar', values='baz' ) - "#, &[CheckCode::PDV010]; "PDV010_fail_pivot")] - #[test_case("result = df.to_array()", &[]; "PDV011_pass_to_array")] - #[test_case("result = df.array", &[]; "PDV011_pass_array")] - #[test_case("result = df.values", &[CheckCode::PDV011]; "PDV011_fail_values")] - // TODO: Check that the attribute access is NOT a method call - // #[test_case("result = {}.values()", &[]; "PDV011_pass_values_call")] - #[test_case("result = values", &[]; "PDV011_pass_node_name")] - #[test_case("employees = pd.read_csv(input_file)", &[]; "PDV012_pass_read_csv")] - #[test_case("employees = pd.read_table(input_file)", &[CheckCode::PDV012]; "PDV012_fail_read_table")] - #[test_case("employees = read_table", &[]; "PDV012_node_Name_pass")] + "#, &[CheckCode::PD010]; "PD010_fail_pivot")] + #[test_case("result = df.to_array()", &[]; "PD011_pass_to_array")] + #[test_case("result = df.array", &[]; "PD011_pass_array")] + #[test_case("result = df.values", &[CheckCode::PD011]; "PD011_fail_values")] + // TODO(edgarrmondragon): Check that the attribute access is NOT a method call. + // #[test_case("result = {}.values()", &[]; "PD011_pass_values_call")] + #[test_case("result = values", &[]; "PD011_pass_node_name")] + #[test_case("employees = pd.read_csv(input_file)", &[]; "PD012_pass_read_csv")] + #[test_case("employees = pd.read_table(input_file)", &[CheckCode::PD012]; "PD012_fail_read_table")] + #[test_case("employees = read_table", &[]; "PD012_node_Name_pass")] #[test_case(r#"table = df.melt( id_vars='airline', value_vars=['ATL', 'DEN', 'DFW'], value_name='airline delay' ) - "#, &[]; "PDV013_pass")] - #[test_case("table = df.stack(level=-1, dropna=True)", &[CheckCode::PDV013]; "PDV013_fail_stack")] + "#, &[]; "PD013_pass")] + #[test_case("table = df.stack(level=-1, dropna=True)", &[CheckCode::PD013]; "PD013_fail_stack")] #[test_case("df1.merge(df2)", &[]; "PD015_pass_merge_on_dataframe")] #[test_case("df1.merge(df2, 'inner')", &[]; "PD015_pass_merge_on_dataframe_with_multiple_args")] - #[test_case("pd.merge(df1, df2)", &[CheckCode::PDV015]; "PD015_fail_merge_on_pandas_object")] + #[test_case("pd.merge(df1, df2)", &[CheckCode::PD015]; "PD015_fail_merge_on_pandas_object")] #[test_case( "pd.to_datetime(timestamp * 10 ** 9).strftime('%Y-%m-%d %H:%M:%S.%f')", &[]; "PD015_pass_other_pd_function" )] - #[test_case("employees = pd.DataFrame(employee_dict)", &[]; "PDV901_pass_non_df")] - #[test_case("employees_df = pd.DataFrame(employee_dict)", &[]; "PDV901_pass_part_df")] - #[test_case("my_function(df=data)", &[]; "PDV901_pass_df_param")] - #[test_case("df = pd.DataFrame()", &[CheckCode::PDV901]; "PDV901_fail_df_var")] + #[test_case("employees = pd.DataFrame(employee_dict)", &[]; "PD901_pass_non_df")] + #[test_case("employees_df = pd.DataFrame(employee_dict)", &[]; "PD901_pass_part_df")] + #[test_case("my_function(df=data)", &[]; "PD901_pass_df_param")] + #[test_case("df = pd.DataFrame()", &[CheckCode::PD901]; "PD901_fail_df_var")] fn test_pandas_vet(code: &str, expected: &[CheckCode]) -> Result<()> { check_code(code, expected)?; Ok(())