Rename PDV checks to PD (#1288)

This commit is contained in:
Charlie Marsh 2022-12-19 00:20:28 -05:00 committed by GitHub
parent 4da2264722
commit 706d28cabc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 406 additions and 170 deletions

View File

@ -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)<!-- End auto-generated table of contents. -->
@ -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)

View File

@ -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],
}

View File

@ -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);
};

View File

@ -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<FxHashMap<&'static str, CheckCode>> = 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<FxHashMap<&'static str, &'static str>> = Lazy:
("I25", "TID25"),
("M", "RUF100"),
("M0", "RUF100"),
// TODO(charlie): Remove by 2023-02-01.
("PDV", "PD"),
("PDV0", "PD0"),
("PDV01", "PD01"),
("PDV9", "PD9"),
("PDV90", "PD90"),
])
});

View File

@ -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,

View File

@ -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<Check> {
for keyword in keywords {
let arg = keyword.node.arg.as_ref()?;
@ -27,7 +27,7 @@ pub fn inplace_argument(keywords: &[Keyword]) -> Option<Check> {
None
}
/// PDV015
/// PD015
pub fn use_of_pd_merge(func: &Expr) -> Option<Check> {
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<Check> {
None
}
/// PDV901
/// PD901
pub fn assignment_to_df(targets: &[Expr]) -> Option<Check> {
if targets.len() != 1 {
return None;

View File

@ -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<LexResult> = 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(())