From 7ef6cd00d4fd0aea2eeae0a7b467f412b3ee1854 Mon Sep 17 00:00:00 2001 From: Reiner Gerecke Date: Thu, 15 Dec 2022 20:36:57 +0100 Subject: [PATCH] Implement PGH002 - deprecated use of logging.warn Refs #980 --- README.md | 1 + .../test/fixtures/pygrep-hooks/PGH002_0.py | 8 ++++ .../test/fixtures/pygrep-hooks/PGH002_1.py | 15 ++++++++ src/checkers/ast.rs | 3 ++ src/checks.rs | 8 ++++ src/checks_gen.rs | 9 +++-- src/pygrep_hooks/mod.rs | 3 ++ src/pygrep_hooks/plugins.rs | 19 ++++++++++ ...grep_hooks__tests__PGH002_PGH002_0.py.snap | 6 +++ ...grep_hooks__tests__PGH002_PGH002_1.py.snap | 37 +++++++++++++++++++ 10 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 resources/test/fixtures/pygrep-hooks/PGH002_0.py create mode 100644 resources/test/fixtures/pygrep-hooks/PGH002_1.py create mode 100644 src/pygrep_hooks/plugins.rs create mode 100644 src/pygrep_hooks/snapshots/ruff__pygrep_hooks__tests__PGH002_PGH002_0.py.snap create mode 100644 src/pygrep_hooks/snapshots/ruff__pygrep_hooks__tests__PGH002_PGH002_1.py.snap diff --git a/README.md b/README.md index 1130d40a9f11b..ba604ac492b89 100644 --- a/README.md +++ b/README.md @@ -898,6 +898,7 @@ For more, see [pygrep-hooks](https://github.com/pre-commit/pygrep-hooks) on GitH | Code | Name | Message | Fix | | ---- | ---- | ------- | --- | | PGH001 | NoEval | No builtin `eval()` allowed | | +| PGH002 | DeprecatedLogWarn | `warn` is deprecated in favor of `warning` | | ### Pylint (PLC, PLE, PLR, PLW) diff --git a/resources/test/fixtures/pygrep-hooks/PGH002_0.py b/resources/test/fixtures/pygrep-hooks/PGH002_0.py new file mode 100644 index 0000000000000..e6aa467b13dc9 --- /dev/null +++ b/resources/test/fixtures/pygrep-hooks/PGH002_0.py @@ -0,0 +1,8 @@ +import logging +import warnings +from warnings import warn + +warnings.warn("this is ok") +warn("by itself is also ok") +logging.warning("this is fine") +log.warning("this is ok") diff --git a/resources/test/fixtures/pygrep-hooks/PGH002_1.py b/resources/test/fixtures/pygrep-hooks/PGH002_1.py new file mode 100644 index 0000000000000..861e6ed99c98e --- /dev/null +++ b/resources/test/fixtures/pygrep-hooks/PGH002_1.py @@ -0,0 +1,15 @@ +import logging +from logging import warn + +logging.warn("this is not ok") +log.warn("this is also not ok") +warn("not ok") + + +def foo(): + from logging import warn + + def warn(): + pass + + warn("has been redefined, but we will still report it") diff --git a/src/checkers/ast.rs b/src/checkers/ast.rs index 50d5f225099f0..5bf90de5d35a5 100644 --- a/src/checkers/ast.rs +++ b/src/checkers/ast.rs @@ -1959,6 +1959,9 @@ where if self.settings.enabled.contains(&CheckCode::PGH001) { pygrep_hooks::checks::no_eval(self, func); } + if self.settings.enabled.contains(&CheckCode::PGH002) { + pygrep_hooks::plugins::deprecated_log_warn(self, func); + } // pylint if self.settings.enabled.contains(&CheckCode::PLC3002) { diff --git a/src/checks.rs b/src/checks.rs index 72be66aeebced..93a3694f3f2ee 100644 --- a/src/checks.rs +++ b/src/checks.rs @@ -316,6 +316,7 @@ pub enum CheckCode { RUF100, // pygrep-hooks PGH001, + PGH002, // pandas-vet PDV002, PDV003, @@ -887,6 +888,7 @@ pub enum CheckKind { BooleanPositionalValueInFunctionCall, // pygrep-hooks NoEval, + DeprecatedLogWarn, // flake8-unused-arguments UnusedFunctionArgument(String), UnusedMethodArgument(String), @@ -1260,6 +1262,7 @@ impl CheckCode { CheckCode::FBT003 => CheckKind::BooleanPositionalValueInFunctionCall, // pygrep-hooks CheckCode::PGH001 => CheckKind::NoEval, + CheckCode::PGH002 => CheckKind::DeprecatedLogWarn, // flake8-unused-arguments CheckCode::ARG001 => CheckKind::UnusedFunctionArgument("...".to_string()), CheckCode::ARG002 => CheckKind::UnusedMethodArgument("...".to_string()), @@ -1504,6 +1507,7 @@ impl CheckCode { CheckCode::PDV015 => CheckCategory::PandasVet, CheckCode::PDV901 => CheckCategory::PandasVet, CheckCode::PGH001 => CheckCategory::PygrepHooks, + CheckCode::PGH002 => CheckCategory::PygrepHooks, CheckCode::PLC0414 => CheckCategory::Pylint, CheckCode::PLC2201 => CheckCategory::Pylint, CheckCode::PLC3002 => CheckCategory::Pylint, @@ -1847,6 +1851,7 @@ impl CheckKind { CheckKind::BooleanPositionalValueInFunctionCall => &CheckCode::FBT003, // pygrep-hooks CheckKind::NoEval => &CheckCode::PGH001, + CheckKind::DeprecatedLogWarn => &CheckCode::PGH002, // flake8-unused-arguments CheckKind::UnusedFunctionArgument(..) => &CheckCode::ARG001, CheckKind::UnusedMethodArgument(..) => &CheckCode::ARG002, @@ -2684,6 +2689,9 @@ impl CheckKind { } // pygrep-hooks CheckKind::NoEval => "No builtin `eval()` allowed".to_string(), + CheckKind::DeprecatedLogWarn => { + "`warn` is deprecated in favor of `warning`".to_string() + } // flake8-unused-arguments CheckKind::UnusedFunctionArgument(name) => { format!("Unused function argument: `{name}`") diff --git a/src/checks_gen.rs b/src/checks_gen.rs index 835bcb2c39d77..c096510251fcf 100644 --- a/src/checks_gen.rs +++ b/src/checks_gen.rs @@ -325,6 +325,7 @@ pub enum CheckCodePrefix { PGH0, PGH00, PGH001, + PGH002, PLC, PLC0, PLC04, @@ -1424,10 +1425,11 @@ impl CheckCodePrefix { CheckCodePrefix::PDV9 => vec![CheckCode::PDV901], CheckCodePrefix::PDV90 => vec![CheckCode::PDV901], CheckCodePrefix::PDV901 => vec![CheckCode::PDV901], - CheckCodePrefix::PGH => vec![CheckCode::PGH001], - CheckCodePrefix::PGH0 => vec![CheckCode::PGH001], - CheckCodePrefix::PGH00 => vec![CheckCode::PGH001], + CheckCodePrefix::PGH => vec![CheckCode::PGH001, CheckCode::PGH002], + CheckCodePrefix::PGH0 => vec![CheckCode::PGH001, CheckCode::PGH002], + CheckCodePrefix::PGH00 => vec![CheckCode::PGH001, CheckCode::PGH002], CheckCodePrefix::PGH001 => vec![CheckCode::PGH001], + CheckCodePrefix::PGH002 => vec![CheckCode::PGH002], CheckCodePrefix::PLC => { vec![CheckCode::PLC0414, CheckCode::PLC2201, CheckCode::PLC3002] } @@ -2258,6 +2260,7 @@ impl CheckCodePrefix { CheckCodePrefix::PGH0 => SuffixLength::One, CheckCodePrefix::PGH00 => SuffixLength::Two, CheckCodePrefix::PGH001 => SuffixLength::Three, + CheckCodePrefix::PGH002 => SuffixLength::Three, CheckCodePrefix::PLC => SuffixLength::Zero, CheckCodePrefix::PLC0 => SuffixLength::One, CheckCodePrefix::PLC04 => SuffixLength::Two, diff --git a/src/pygrep_hooks/mod.rs b/src/pygrep_hooks/mod.rs index 0e63daea8a2e4..48ba3032b0289 100644 --- a/src/pygrep_hooks/mod.rs +++ b/src/pygrep_hooks/mod.rs @@ -1,4 +1,5 @@ pub mod checks; +pub mod plugins; #[cfg(test)] mod tests { @@ -14,6 +15,8 @@ mod tests { #[test_case(CheckCode::PGH001, Path::new("PGH001_0.py"); "PGH001_0")] #[test_case(CheckCode::PGH001, Path::new("PGH001_1.py"); "PGH001_1")] + #[test_case(CheckCode::PGH002, Path::new("PGH002_0.py"); "PGH002_0")] + #[test_case(CheckCode::PGH002, Path::new("PGH002_1.py"); "PGH002_1")] fn checks(check_code: CheckCode, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", check_code.as_ref(), path.to_string_lossy()); let mut checks = test_path( diff --git a/src/pygrep_hooks/plugins.rs b/src/pygrep_hooks/plugins.rs new file mode 100644 index 0000000000000..45e86894e8bb3 --- /dev/null +++ b/src/pygrep_hooks/plugins.rs @@ -0,0 +1,19 @@ +use rustpython_ast::Expr; + +use crate::ast::helpers::{collect_call_paths, dealias_call_path, match_call_path}; +use crate::ast::types::Range; +use crate::checkers::ast::Checker; +use crate::checks::{Check, CheckKind}; + +/// PGH002 - deprecated use of logging.warn +pub fn deprecated_log_warn(checker: &mut Checker, func: &Expr) { + let call_path = dealias_call_path(collect_call_paths(func), &checker.import_aliases); + if call_path == ["log", "warn"] + || match_call_path(&call_path, "logging", "warn", &checker.from_imports) + { + checker.add_check(Check::new( + CheckKind::DeprecatedLogWarn, + Range::from_located(func), + )); + } +} diff --git a/src/pygrep_hooks/snapshots/ruff__pygrep_hooks__tests__PGH002_PGH002_0.py.snap b/src/pygrep_hooks/snapshots/ruff__pygrep_hooks__tests__PGH002_PGH002_0.py.snap new file mode 100644 index 0000000000000..68aa191216b4e --- /dev/null +++ b/src/pygrep_hooks/snapshots/ruff__pygrep_hooks__tests__PGH002_PGH002_0.py.snap @@ -0,0 +1,6 @@ +--- +source: src/pygrep_hooks/mod.rs +expression: checks +--- +[] + diff --git a/src/pygrep_hooks/snapshots/ruff__pygrep_hooks__tests__PGH002_PGH002_1.py.snap b/src/pygrep_hooks/snapshots/ruff__pygrep_hooks__tests__PGH002_PGH002_1.py.snap new file mode 100644 index 0000000000000..33165beaaf1ad --- /dev/null +++ b/src/pygrep_hooks/snapshots/ruff__pygrep_hooks__tests__PGH002_PGH002_1.py.snap @@ -0,0 +1,37 @@ +--- +source: src/pygrep_hooks/mod.rs +expression: checks +--- +- kind: DeprecatedLogWarn + location: + row: 4 + column: 0 + end_location: + row: 4 + column: 12 + fix: ~ +- kind: DeprecatedLogWarn + location: + row: 5 + column: 0 + end_location: + row: 5 + column: 8 + fix: ~ +- kind: DeprecatedLogWarn + location: + row: 6 + column: 0 + end_location: + row: 6 + column: 4 + fix: ~ +- kind: DeprecatedLogWarn + location: + row: 15 + column: 4 + end_location: + row: 15 + column: 8 + fix: ~ +