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-unused-arguments (ARG)](#flake8-unused-arguments-arg)
1. [flake8-datetimez (DTZ)](#flake8-datetimez-dtz) 1. [flake8-datetimez (DTZ)](#flake8-datetimez-dtz)
1. [eradicate (ERA)](#eradicate-era) 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. [pygrep-hooks (PGH)](#pygrep-hooks-pgh)
1. [Pylint (PLC, PLE, PLR, PLW)](#pylint-plc-ple-plr-plw) 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. --> 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 | 🛠 | | 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. For more, see [pandas-vet](https://pypi.org/project/pandas-vet/0.2.3/) on PyPI.
| Code | Name | Message | Fix | | Code | Name | Message | Fix |
| ---- | ---- | ------- | --- | | ---- | ---- | ------- | --- |
| PDV002 | UseOfInplaceArgument | `inplace=True` should be avoided; it has inconsistent behavior | | | PD002 | UseOfInplaceArgument | `inplace=True` should be avoided; it has inconsistent behavior | |
| PDV003 | UseOfDotIsNull | `.isna` is preferred to `.isnull`; functionality is equivalent | | | PD003 | UseOfDotIsNull | `.isna` is preferred to `.isnull`; functionality is equivalent | |
| PDV004 | UseOfDotNotNull | `.notna` is preferred to `.notnull`; functionality is equivalent | | | PD004 | UseOfDotNotNull | `.notna` is preferred to `.notnull`; functionality is equivalent | |
| PDV007 | UseOfDotIx | `.ix` is deprecated; use more explicit `.loc` or `.iloc` | | | PD007 | UseOfDotIx | `.ix` is deprecated; use more explicit `.loc` or `.iloc` | |
| PDV008 | UseOfDotAt | Use `.loc` instead of `.at`. If speed is important, use numpy. | | | PD008 | 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. | | | PD009 | 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 | | | PD010 | UseOfDotPivotOrUnstack | `.pivot_table` is preferred to `.pivot` or `.unstack`; provides same functionality | |
| PDV011 | UseOfDotValues | Use `.to_numpy()` instead of `.values` | | | PD011 | UseOfDotValues | Use `.to_numpy()` instead of `.values` | |
| PDV012 | UseOfDotReadTable | `.read_csv` is preferred to `.read_table`; provides same functionality | | | PD012 | UseOfDotReadTable | `.read_csv` is preferred to `.read_table`; provides same functionality | |
| PDV013 | UseOfDotStack | `.melt` is preferred to `.stack`; provides same functionality | | | PD013 | UseOfDotStack | `.melt` is preferred to `.stack`; provides same functionality | |
| PDV015 | UseOfPdMerge | Use `.merge` method instead of `pd.merge` function. They have equivalent functionality. | | | PD015 | 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. | | | PD901 | DfIsABadVariableName | `df` is a bad variable name. Be kinder to your future self. | |
### pygrep-hooks (PGH) ### pygrep-hooks (PGH)

View File

@ -80,8 +80,7 @@ impl Plugin {
Plugin::Flake8Simplify => CheckCodePrefix::SIM, Plugin::Flake8Simplify => CheckCodePrefix::SIM,
Plugin::Flake8TidyImports => CheckCodePrefix::I25, Plugin::Flake8TidyImports => CheckCodePrefix::I25,
Plugin::McCabe => CheckCodePrefix::C9, Plugin::McCabe => CheckCodePrefix::C9,
// TODO(charlie): Handle rename of `PD` to `PDV`. Plugin::PandasVet => CheckCodePrefix::PD,
Plugin::PandasVet => CheckCodePrefix::PDV,
Plugin::PEP8Naming => CheckCodePrefix::N, Plugin::PEP8Naming => CheckCodePrefix::N,
Plugin::Pyupgrade => CheckCodePrefix::U, Plugin::Pyupgrade => CheckCodePrefix::U,
} }
@ -121,7 +120,7 @@ impl Plugin {
Plugin::Flake8Simplify => vec![CheckCodePrefix::SIM], Plugin::Flake8Simplify => vec![CheckCodePrefix::SIM],
Plugin::Flake8TidyImports => vec![CheckCodePrefix::TID], Plugin::Flake8TidyImports => vec![CheckCodePrefix::TID],
Plugin::McCabe => vec![CheckCodePrefix::C9], Plugin::McCabe => vec![CheckCodePrefix::C9],
Plugin::PandasVet => vec![CheckCodePrefix::PDV], Plugin::PandasVet => vec![CheckCodePrefix::PD],
Plugin::PEP8Naming => vec![CheckCodePrefix::N], Plugin::PEP8Naming => vec![CheckCodePrefix::N],
Plugin::Pyupgrade => vec![CheckCodePrefix::UP], Plugin::Pyupgrade => vec![CheckCodePrefix::UP],
} }

View File

@ -1181,7 +1181,7 @@ where
self, stmt, targets, value, 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) { if let Some(check) = pandas_vet::checks::assignment_to_df(targets) {
self.add_check(check); self.add_check(check);
} }
@ -1547,10 +1547,10 @@ where
} }
for (code, name) in vec![ for (code, name) in vec![
(CheckCode::PDV007, "ix"), (CheckCode::PD007, "ix"),
(CheckCode::PDV008, "at"), (CheckCode::PD008, "at"),
(CheckCode::PDV009, "iat"), (CheckCode::PD009, "iat"),
(CheckCode::PDV011, "values"), (CheckCode::PD011, "values"),
] { ] {
if self.settings.enabled.contains(&code) { if self.settings.enabled.contains(&code) {
if attr == name { if attr == name {
@ -1932,17 +1932,17 @@ where
} }
// pandas-vet // 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()); self.add_checks(pandas_vet::checks::inplace_argument(keywords).into_iter());
} }
for (code, name) in vec![ for (code, name) in vec![
(CheckCode::PDV003, "isnull"), (CheckCode::PD003, "isnull"),
(CheckCode::PDV004, "notnull"), (CheckCode::PD004, "notnull"),
(CheckCode::PDV010, "pivot"), (CheckCode::PD010, "pivot"),
(CheckCode::PDV010, "unstack"), (CheckCode::PD010, "unstack"),
(CheckCode::PDV012, "read_table"), (CheckCode::PD012, "read_table"),
(CheckCode::PDV013, "stack"), (CheckCode::PD013, "stack"),
] { ] {
if self.settings.enabled.contains(&code) { if self.settings.enabled.contains(&code) {
if let ExprKind::Attribute { attr, .. } = &func.node { 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) { if let Some(check) = pandas_vet::checks::use_of_pd_merge(func) {
self.add_check(check); self.add_check(check);
}; };

View File

@ -329,18 +329,18 @@ pub enum CheckCode {
PGH002, PGH002,
PGH003, PGH003,
// pandas-vet // pandas-vet
PDV002, PD002,
PDV003, PD003,
PDV004, PD004,
PDV007, PD007,
PDV008, PD008,
PDV009, PD009,
PDV010, PD010,
PDV011, PD011,
PDV012, PD012,
PDV013, PD013,
PDV015, PD015,
PDV901, PD901,
// flake8-errmsg // flake8-errmsg
EM101, EM101,
EM102, EM102,
@ -453,7 +453,7 @@ impl CheckCategory {
CheckCategory::Flake8Datetimez => vec![CheckCodePrefix::DTZ], CheckCategory::Flake8Datetimez => vec![CheckCodePrefix::DTZ],
CheckCategory::Isort => vec![CheckCodePrefix::I], CheckCategory::Isort => vec![CheckCodePrefix::I],
CheckCategory::McCabe => vec![CheckCodePrefix::C90], CheckCategory::McCabe => vec![CheckCodePrefix::C90],
CheckCategory::PandasVet => vec![CheckCodePrefix::PDV], CheckCategory::PandasVet => vec![CheckCodePrefix::PD],
CheckCategory::PEP8Naming => vec![CheckCodePrefix::N], CheckCategory::PEP8Naming => vec![CheckCodePrefix::N],
CheckCategory::Pycodestyle => vec![CheckCodePrefix::E, CheckCodePrefix::W], CheckCategory::Pycodestyle => vec![CheckCodePrefix::E, CheckCodePrefix::W],
CheckCategory::Pydocstyle => vec![CheckCodePrefix::D], CheckCategory::Pydocstyle => vec![CheckCodePrefix::D],
@ -1306,18 +1306,18 @@ impl CheckCode {
CheckKind::ImportAliasIsNotConventional("...".to_string(), "...".to_string()) CheckKind::ImportAliasIsNotConventional("...".to_string(), "...".to_string())
} }
// pandas-vet // pandas-vet
CheckCode::PDV002 => CheckKind::UseOfInplaceArgument, CheckCode::PD002 => CheckKind::UseOfInplaceArgument,
CheckCode::PDV003 => CheckKind::UseOfDotIsNull, CheckCode::PD003 => CheckKind::UseOfDotIsNull,
CheckCode::PDV004 => CheckKind::UseOfDotNotNull, CheckCode::PD004 => CheckKind::UseOfDotNotNull,
CheckCode::PDV007 => CheckKind::UseOfDotIx, CheckCode::PD007 => CheckKind::UseOfDotIx,
CheckCode::PDV008 => CheckKind::UseOfDotAt, CheckCode::PD008 => CheckKind::UseOfDotAt,
CheckCode::PDV009 => CheckKind::UseOfDotIat, CheckCode::PD009 => CheckKind::UseOfDotIat,
CheckCode::PDV010 => CheckKind::UseOfDotPivotOrUnstack, CheckCode::PD010 => CheckKind::UseOfDotPivotOrUnstack,
CheckCode::PDV011 => CheckKind::UseOfDotValues, CheckCode::PD011 => CheckKind::UseOfDotValues,
CheckCode::PDV012 => CheckKind::UseOfDotReadTable, CheckCode::PD012 => CheckKind::UseOfDotReadTable,
CheckCode::PDV013 => CheckKind::UseOfDotStack, CheckCode::PD013 => CheckKind::UseOfDotStack,
CheckCode::PDV015 => CheckKind::UseOfPdMerge, CheckCode::PD015 => CheckKind::UseOfPdMerge,
CheckCode::PDV901 => CheckKind::DfIsABadVariableName, CheckCode::PD901 => CheckKind::DfIsABadVariableName,
// flake8-errmsg // flake8-errmsg
CheckCode::EM101 => CheckKind::RawStringInException, CheckCode::EM101 => CheckKind::RawStringInException,
CheckCode::EM102 => CheckKind::FStringInException, CheckCode::EM102 => CheckKind::FStringInException,
@ -1545,18 +1545,18 @@ impl CheckCode {
CheckCode::N816 => CheckCategory::PEP8Naming, CheckCode::N816 => CheckCategory::PEP8Naming,
CheckCode::N817 => CheckCategory::PEP8Naming, CheckCode::N817 => CheckCategory::PEP8Naming,
CheckCode::N818 => CheckCategory::PEP8Naming, CheckCode::N818 => CheckCategory::PEP8Naming,
CheckCode::PDV002 => CheckCategory::PandasVet, CheckCode::PD002 => CheckCategory::PandasVet,
CheckCode::PDV003 => CheckCategory::PandasVet, CheckCode::PD003 => CheckCategory::PandasVet,
CheckCode::PDV004 => CheckCategory::PandasVet, CheckCode::PD004 => CheckCategory::PandasVet,
CheckCode::PDV007 => CheckCategory::PandasVet, CheckCode::PD007 => CheckCategory::PandasVet,
CheckCode::PDV008 => CheckCategory::PandasVet, CheckCode::PD008 => CheckCategory::PandasVet,
CheckCode::PDV009 => CheckCategory::PandasVet, CheckCode::PD009 => CheckCategory::PandasVet,
CheckCode::PDV010 => CheckCategory::PandasVet, CheckCode::PD010 => CheckCategory::PandasVet,
CheckCode::PDV011 => CheckCategory::PandasVet, CheckCode::PD011 => CheckCategory::PandasVet,
CheckCode::PDV012 => CheckCategory::PandasVet, CheckCode::PD012 => CheckCategory::PandasVet,
CheckCode::PDV013 => CheckCategory::PandasVet, CheckCode::PD013 => CheckCategory::PandasVet,
CheckCode::PDV015 => CheckCategory::PandasVet, CheckCode::PD015 => CheckCategory::PandasVet,
CheckCode::PDV901 => CheckCategory::PandasVet, CheckCode::PD901 => CheckCategory::PandasVet,
CheckCode::PGH001 => CheckCategory::PygrepHooks, CheckCode::PGH001 => CheckCategory::PygrepHooks,
CheckCode::PGH002 => CheckCategory::PygrepHooks, CheckCode::PGH002 => CheckCategory::PygrepHooks,
CheckCode::PGH003 => CheckCategory::PygrepHooks, CheckCode::PGH003 => CheckCategory::PygrepHooks,
@ -1914,18 +1914,18 @@ impl CheckKind {
// flake8-import-conventions // flake8-import-conventions
CheckKind::ImportAliasIsNotConventional(..) => &CheckCode::ICN001, CheckKind::ImportAliasIsNotConventional(..) => &CheckCode::ICN001,
// pandas-vet // pandas-vet
CheckKind::UseOfInplaceArgument => &CheckCode::PDV002, CheckKind::UseOfInplaceArgument => &CheckCode::PD002,
CheckKind::UseOfDotIsNull => &CheckCode::PDV003, CheckKind::UseOfDotIsNull => &CheckCode::PD003,
CheckKind::UseOfDotNotNull => &CheckCode::PDV004, CheckKind::UseOfDotNotNull => &CheckCode::PD004,
CheckKind::UseOfDotIx => &CheckCode::PDV007, CheckKind::UseOfDotIx => &CheckCode::PD007,
CheckKind::UseOfDotAt => &CheckCode::PDV008, CheckKind::UseOfDotAt => &CheckCode::PD008,
CheckKind::UseOfDotIat => &CheckCode::PDV009, CheckKind::UseOfDotIat => &CheckCode::PD009,
CheckKind::UseOfDotPivotOrUnstack => &CheckCode::PDV010, CheckKind::UseOfDotPivotOrUnstack => &CheckCode::PD010,
CheckKind::UseOfDotValues => &CheckCode::PDV011, CheckKind::UseOfDotValues => &CheckCode::PD011,
CheckKind::UseOfDotReadTable => &CheckCode::PDV012, CheckKind::UseOfDotReadTable => &CheckCode::PD012,
CheckKind::UseOfDotStack => &CheckCode::PDV013, CheckKind::UseOfDotStack => &CheckCode::PD013,
CheckKind::UseOfPdMerge => &CheckCode::PDV015, CheckKind::UseOfPdMerge => &CheckCode::PD015,
CheckKind::DfIsABadVariableName => &CheckCode::PDV901, CheckKind::DfIsABadVariableName => &CheckCode::PD901,
// flake8-errmsg // flake8-errmsg
CheckKind::RawStringInException => &CheckCode::EM101, CheckKind::RawStringInException => &CheckCode::EM101,
CheckKind::FStringInException => &CheckCode::EM102, 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. // TODO(charlie): Remove by 2023-02-01.
("I252", CheckCode::TID252), ("I252", CheckCode::TID252),
("M001", CheckCode::RUF100), ("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"), ("I25", "TID25"),
("M", "RUF100"), ("M", "RUF100"),
("M0", "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, N816,
N817, N817,
N818, N818,
PD,
PD0,
PD00,
PD002,
PD003,
PD004,
PD007,
PD008,
PD009,
PD01,
PD010,
PD011,
PD012,
PD013,
PD015,
PD9,
PD90,
PD901,
PDV, PDV,
PDV0, PDV0,
PDV00,
PDV002, PDV002,
PDV003, PDV003,
PDV004, PDV004,
@ -1425,62 +1442,246 @@ impl CheckCodePrefix {
CheckCodePrefix::N816 => vec![CheckCode::N816], CheckCodePrefix::N816 => vec![CheckCode::N816],
CheckCodePrefix::N817 => vec![CheckCode::N817], CheckCodePrefix::N817 => vec![CheckCode::N817],
CheckCodePrefix::N818 => vec![CheckCode::N818], CheckCodePrefix::N818 => vec![CheckCode::N818],
CheckCodePrefix::PDV => vec![ CheckCodePrefix::PD => vec![
CheckCode::PDV002, CheckCode::PD002,
CheckCode::PDV003, CheckCode::PD003,
CheckCode::PDV004, CheckCode::PD004,
CheckCode::PDV007, CheckCode::PD007,
CheckCode::PDV008, CheckCode::PD008,
CheckCode::PDV009, CheckCode::PD009,
CheckCode::PDV010, CheckCode::PD010,
CheckCode::PDV011, CheckCode::PD011,
CheckCode::PDV012, CheckCode::PD012,
CheckCode::PDV013, CheckCode::PD013,
CheckCode::PDV015, CheckCode::PD015,
CheckCode::PDV901, CheckCode::PD901,
], ],
CheckCodePrefix::PDV0 => vec![ CheckCodePrefix::PD0 => vec![
CheckCode::PDV002, CheckCode::PD002,
CheckCode::PDV003, CheckCode::PD003,
CheckCode::PDV004, CheckCode::PD004,
CheckCode::PDV007, CheckCode::PD007,
CheckCode::PDV008, CheckCode::PD008,
CheckCode::PDV009, CheckCode::PD009,
CheckCode::PDV010, CheckCode::PD010,
CheckCode::PDV011, CheckCode::PD011,
CheckCode::PDV012, CheckCode::PD012,
CheckCode::PDV013, CheckCode::PD013,
CheckCode::PDV015, CheckCode::PD015,
], ],
CheckCodePrefix::PDV00 => vec![ CheckCodePrefix::PD00 => vec![
CheckCode::PDV002, CheckCode::PD002,
CheckCode::PDV003, CheckCode::PD003,
CheckCode::PDV004, CheckCode::PD004,
CheckCode::PDV007, CheckCode::PD007,
CheckCode::PDV008, CheckCode::PD008,
CheckCode::PDV009, CheckCode::PD009,
], ],
CheckCodePrefix::PDV002 => vec![CheckCode::PDV002], CheckCodePrefix::PD002 => vec![CheckCode::PD002],
CheckCodePrefix::PDV003 => vec![CheckCode::PDV003], CheckCodePrefix::PD003 => vec![CheckCode::PD003],
CheckCodePrefix::PDV004 => vec![CheckCode::PDV004], CheckCodePrefix::PD004 => vec![CheckCode::PD004],
CheckCodePrefix::PDV007 => vec![CheckCode::PDV007], CheckCodePrefix::PD007 => vec![CheckCode::PD007],
CheckCodePrefix::PDV008 => vec![CheckCode::PDV008], CheckCodePrefix::PD008 => vec![CheckCode::PD008],
CheckCodePrefix::PDV009 => vec![CheckCode::PDV009], CheckCodePrefix::PD009 => vec![CheckCode::PD009],
CheckCodePrefix::PDV01 => vec![ CheckCodePrefix::PD01 => vec![
CheckCode::PDV010, CheckCode::PD010,
CheckCode::PDV011, CheckCode::PD011,
CheckCode::PDV012, CheckCode::PD012,
CheckCode::PDV013, CheckCode::PD013,
CheckCode::PDV015, CheckCode::PD015,
], ],
CheckCodePrefix::PDV010 => vec![CheckCode::PDV010], CheckCodePrefix::PD010 => vec![CheckCode::PD010],
CheckCodePrefix::PDV011 => vec![CheckCode::PDV011], CheckCodePrefix::PD011 => vec![CheckCode::PD011],
CheckCodePrefix::PDV012 => vec![CheckCode::PDV012], CheckCodePrefix::PD012 => vec![CheckCode::PD012],
CheckCodePrefix::PDV013 => vec![CheckCode::PDV013], CheckCodePrefix::PD013 => vec![CheckCode::PD013],
CheckCodePrefix::PDV015 => vec![CheckCode::PDV015], CheckCodePrefix::PD015 => vec![CheckCode::PD015],
CheckCodePrefix::PDV9 => vec![CheckCode::PDV901], CheckCodePrefix::PD9 => vec![CheckCode::PD901],
CheckCodePrefix::PDV90 => vec![CheckCode::PDV901], CheckCodePrefix::PD90 => vec![CheckCode::PD901],
CheckCodePrefix::PDV901 => vec![CheckCode::PDV901], 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::PGH => vec![CheckCode::PGH001, CheckCode::PGH002, CheckCode::PGH003],
CheckCodePrefix::PGH0 => 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], CheckCodePrefix::PGH00 => vec![CheckCode::PGH001, CheckCode::PGH002, CheckCode::PGH003],
@ -2308,9 +2509,26 @@ impl CheckCodePrefix {
CheckCodePrefix::N816 => SuffixLength::Three, CheckCodePrefix::N816 => SuffixLength::Three,
CheckCodePrefix::N817 => SuffixLength::Three, CheckCodePrefix::N817 => SuffixLength::Three,
CheckCodePrefix::N818 => 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::PDV => SuffixLength::Zero,
CheckCodePrefix::PDV0 => SuffixLength::One, CheckCodePrefix::PDV0 => SuffixLength::One,
CheckCodePrefix::PDV00 => SuffixLength::Two,
CheckCodePrefix::PDV002 => SuffixLength::Three, CheckCodePrefix::PDV002 => SuffixLength::Three,
CheckCodePrefix::PDV003 => SuffixLength::Three, CheckCodePrefix::PDV003 => SuffixLength::Three,
CheckCodePrefix::PDV004 => SuffixLength::Three, CheckCodePrefix::PDV004 => SuffixLength::Three,
@ -2512,7 +2730,7 @@ pub const CATEGORIES: &[CheckCodePrefix] = &[
CheckCodePrefix::I, CheckCodePrefix::I,
CheckCodePrefix::ICN, CheckCodePrefix::ICN,
CheckCodePrefix::N, CheckCodePrefix::N,
CheckCodePrefix::PDV, CheckCodePrefix::PD,
CheckCodePrefix::PGH, CheckCodePrefix::PGH,
CheckCodePrefix::PLC, CheckCodePrefix::PLC,
CheckCodePrefix::PLE, CheckCodePrefix::PLE,

View File

@ -3,7 +3,7 @@ use rustpython_ast::{Constant, Expr, ExprKind, Keyword};
use crate::ast::types::Range; use crate::ast::types::Range;
use crate::checks::{Check, CheckKind}; use crate::checks::{Check, CheckKind};
/// PDV002 /// PD002
pub fn inplace_argument(keywords: &[Keyword]) -> Option<Check> { pub fn inplace_argument(keywords: &[Keyword]) -> Option<Check> {
for keyword in keywords { for keyword in keywords {
let arg = keyword.node.arg.as_ref()?; let arg = keyword.node.arg.as_ref()?;
@ -27,7 +27,7 @@ pub fn inplace_argument(keywords: &[Keyword]) -> Option<Check> {
None None
} }
/// PDV015 /// PD015
pub fn use_of_pd_merge(func: &Expr) -> Option<Check> { pub fn use_of_pd_merge(func: &Expr) -> Option<Check> {
if let ExprKind::Attribute { attr, value, .. } = &func.node { if let ExprKind::Attribute { attr, value, .. } = &func.node {
if let ExprKind::Name { id, .. } = &value.node { if let ExprKind::Name { id, .. } = &value.node {
@ -42,7 +42,7 @@ pub fn use_of_pd_merge(func: &Expr) -> Option<Check> {
None None
} }
/// PDV901 /// PD901
pub fn assignment_to_df(targets: &[Expr]) -> Option<Check> { pub fn assignment_to_df(targets: &[Expr]) -> Option<Check> {
if targets.len() != 1 { if targets.len() != 1 {
return None; return None;

View File

@ -18,7 +18,7 @@ mod tests {
fn check_code(contents: &str, expected: &[CheckCode]) -> Result<()> { fn check_code(contents: &str, expected: &[CheckCode]) -> Result<()> {
let contents = dedent(contents); 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 tokens: Vec<LexResult> = rustpython_helpers::tokenize(&contents);
let locator = SourceCodeLocator::new(&contents); let locator = SourceCodeLocator::new(&contents);
let directives = directives::extract_directives( let directives = directives::extract_directives(
@ -46,20 +46,20 @@ mod tests {
Ok(()) Ok(())
} }
#[test_case("df.drop(['a'], axis=1, inplace=False)", &[]; "PDV002_pass")] #[test_case("df.drop(['a'], axis=1, inplace=False)", &[]; "PD002_pass")]
#[test_case("df.drop(['a'], axis=1, inplace=True)", &[CheckCode::PDV002]; "PDV002_fail")] #[test_case("df.drop(['a'], axis=1, inplace=True)", &[CheckCode::PD002]; "PD002_fail")]
#[test_case("nas = pd.isna(val)", &[]; "PDV003_pass")] #[test_case("nas = pd.isna(val)", &[]; "PD003_pass")]
#[test_case("nulls = pd.isnull(val)", &[CheckCode::PDV003]; "PDV003_fail")] #[test_case("nulls = pd.isnull(val)", &[CheckCode::PD003]; "PD003_fail")]
#[test_case("print('bah humbug')", &[]; "PDV003_allows_other_calls")] #[test_case("print('bah humbug')", &[]; "PD003_allows_other_calls")]
#[test_case("not_nas = pd.notna(val)", &[]; "PDV004_pass")] #[test_case("not_nas = pd.notna(val)", &[]; "PD004_pass")]
#[test_case("not_nulls = pd.notnull(val)", &[CheckCode::PDV004]; "PDV004_fail")] #[test_case("not_nulls = pd.notnull(val)", &[CheckCode::PD004]; "PD004_fail")]
#[test_case("new_df = df.loc['d':, 'A':'C']", &[]; "PDV007_pass_loc")] #[test_case("new_df = df.loc['d':, 'A':'C']", &[]; "PD007_pass_loc")]
#[test_case("new_df = df.iloc[[1, 3, 5], [1, 3]]", &[]; "PDV007_pass_iloc")] #[test_case("new_df = df.iloc[[1, 3, 5], [1, 3]]", &[]; "PD007_pass_iloc")]
#[test_case("s = df.ix[[0, 2], 'A']", &[CheckCode::PDV007]; "PDV007_fail")] #[test_case("s = df.ix[[0, 2], 'A']", &[CheckCode::PD007]; "PD007_fail")]
#[test_case("index = df.loc[:, ['B', 'A']]", &[]; "PDV008_pass")] #[test_case("index = df.loc[:, ['B', 'A']]", &[]; "PD008_pass")]
#[test_case("index = df.at[:, ['B', 'A']]", &[CheckCode::PDV008]; "PDV008_fail")] #[test_case("index = df.at[:, ['B', 'A']]", &[CheckCode::PD008]; "PD008_fail")]
#[test_case("index = df.iloc[:, 1:3]", &[]; "PDV009_pass")] #[test_case("index = df.iloc[:, 1:3]", &[]; "PD009_pass")]
#[test_case("index = df.iat[:, 1:3]", &[CheckCode::PDV009]; "PDV009_fail")] #[test_case("index = df.iat[:, 1:3]", &[CheckCode::PD009]; "PD009_fail")]
#[test_case(r#"table = df.pivot_table( #[test_case(r#"table = df.pivot_table(
df, df,
values='D', values='D',
@ -68,42 +68,42 @@ mod tests {
aggfunc=np.sum, aggfunc=np.sum,
fill_value=0 fill_value=0
) )
"#, &[]; "PDV010_pass")] "#, &[]; "PD010_pass")]
#[test_case(r#"table = pd.pivot( #[test_case(r#"table = pd.pivot(
df, df,
index='foo', index='foo',
columns='bar', columns='bar',
values='baz' values='baz'
) )
"#, &[CheckCode::PDV010]; "PDV010_fail_pivot")] "#, &[CheckCode::PD010]; "PD010_fail_pivot")]
#[test_case("result = df.to_array()", &[]; "PDV011_pass_to_array")] #[test_case("result = df.to_array()", &[]; "PD011_pass_to_array")]
#[test_case("result = df.array", &[]; "PDV011_pass_array")] #[test_case("result = df.array", &[]; "PD011_pass_array")]
#[test_case("result = df.values", &[CheckCode::PDV011]; "PDV011_fail_values")] #[test_case("result = df.values", &[CheckCode::PD011]; "PD011_fail_values")]
// TODO: Check that the attribute access is NOT a method call // TODO(edgarrmondragon): Check that the attribute access is NOT a method call.
// #[test_case("result = {}.values()", &[]; "PDV011_pass_values_call")] // #[test_case("result = {}.values()", &[]; "PD011_pass_values_call")]
#[test_case("result = values", &[]; "PDV011_pass_node_name")] #[test_case("result = values", &[]; "PD011_pass_node_name")]
#[test_case("employees = pd.read_csv(input_file)", &[]; "PDV012_pass_read_csv")] #[test_case("employees = pd.read_csv(input_file)", &[]; "PD012_pass_read_csv")]
#[test_case("employees = pd.read_table(input_file)", &[CheckCode::PDV012]; "PDV012_fail_read_table")] #[test_case("employees = pd.read_table(input_file)", &[CheckCode::PD012]; "PD012_fail_read_table")]
#[test_case("employees = read_table", &[]; "PDV012_node_Name_pass")] #[test_case("employees = read_table", &[]; "PD012_node_Name_pass")]
#[test_case(r#"table = df.melt( #[test_case(r#"table = df.melt(
id_vars='airline', id_vars='airline',
value_vars=['ATL', 'DEN', 'DFW'], value_vars=['ATL', 'DEN', 'DFW'],
value_name='airline delay' value_name='airline delay'
) )
"#, &[]; "PDV013_pass")] "#, &[]; "PD013_pass")]
#[test_case("table = df.stack(level=-1, dropna=True)", &[CheckCode::PDV013]; "PDV013_fail_stack")] #[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)", &[]; "PD015_pass_merge_on_dataframe")]
#[test_case("df1.merge(df2, 'inner')", &[]; "PD015_pass_merge_on_dataframe_with_multiple_args")] #[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( #[test_case(
"pd.to_datetime(timestamp * 10 ** 9).strftime('%Y-%m-%d %H:%M:%S.%f')", "pd.to_datetime(timestamp * 10 ** 9).strftime('%Y-%m-%d %H:%M:%S.%f')",
&[]; &[];
"PD015_pass_other_pd_function" "PD015_pass_other_pd_function"
)] )]
#[test_case("employees = pd.DataFrame(employee_dict)", &[]; "PDV901_pass_non_df")] #[test_case("employees = pd.DataFrame(employee_dict)", &[]; "PD901_pass_non_df")]
#[test_case("employees_df = pd.DataFrame(employee_dict)", &[]; "PDV901_pass_part_df")] #[test_case("employees_df = pd.DataFrame(employee_dict)", &[]; "PD901_pass_part_df")]
#[test_case("my_function(df=data)", &[]; "PDV901_pass_df_param")] #[test_case("my_function(df=data)", &[]; "PD901_pass_df_param")]
#[test_case("df = pd.DataFrame()", &[CheckCode::PDV901]; "PDV901_fail_df_var")] #[test_case("df = pd.DataFrame()", &[CheckCode::PD901]; "PD901_fail_df_var")]
fn test_pandas_vet(code: &str, expected: &[CheckCode]) -> Result<()> { fn test_pandas_vet(code: &str, expected: &[CheckCode]) -> Result<()> {
check_code(code, expected)?; check_code(code, expected)?;
Ok(()) Ok(())