-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
…7399) ## Summary This PR implements a new rule for `flake8-logging` plugin that checks for `logging.getLogger` calls with either `__file__` or `__cached__` as the first argument and generates a suggested fix to use `__name__` instead. Refer: #7248 ## Test Plan Add test cases and `cargo test`
- Loading branch information
1 parent
c907317
commit 0d1fb82
Showing
10 changed files
with
208 additions
and
0 deletions.
There are no files selected for viewing
24 changes: 24 additions & 0 deletions
24
crates/ruff/resources/test/fixtures/flake8_logging/LOG002.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import logging | ||
from logging import getLogger | ||
|
||
# Ok | ||
logging.getLogger(__name__) | ||
logging.getLogger(name=__name__) | ||
logging.getLogger("custom") | ||
logging.getLogger(name="custom") | ||
|
||
# LOG002 | ||
getLogger(__file__) | ||
logging.getLogger(name=__file__) | ||
|
||
logging.getLogger(__cached__) | ||
getLogger(name=__cached__) | ||
|
||
|
||
# Override `logging.getLogger` | ||
class logging: | ||
def getLogger(self): | ||
pass | ||
|
||
|
||
logging.getLogger(__file__) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
crates/ruff/src/rules/flake8_logging/rules/invalid_get_logger_argument.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; | ||
use ruff_macros::{derive_message_formats, violation}; | ||
use ruff_python_ast::{self as ast, Expr}; | ||
use ruff_text_size::Ranged; | ||
|
||
use crate::checkers::ast::Checker; | ||
use crate::registry::AsRule; | ||
|
||
/// ## What it does | ||
/// Checks for any usage of `__cached__` and `__file__` as an argument to | ||
/// `logging.getLogger()`. | ||
/// | ||
/// ## Why is this bad? | ||
/// The [logging documentation] recommends this pattern: | ||
/// | ||
/// ```python | ||
/// logging.getLogger(__name__) | ||
/// ``` | ||
/// | ||
/// Here, `__name__` is the fully qualified module name, such as `foo.bar`, | ||
/// which is the intended format for logger names. | ||
/// | ||
/// This rule detects probably-mistaken usage of similar module-level dunder constants: | ||
/// | ||
/// * `__cached__` - the pathname of the module's compiled version, such as `foo/__pycache__/bar.cpython-311.pyc`. | ||
/// * `__file__` - the pathname of the module, such as `foo/bar.py`. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// import logging | ||
/// | ||
/// logger = logging.getLogger(__file__) | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// import logging | ||
/// | ||
/// logger = logging.getLogger(__name__) | ||
/// ``` | ||
/// | ||
/// [logging documentation]: https://docs.python.org/3/library/logging.html#logger-objects | ||
#[violation] | ||
pub struct InvalidGetLoggerArgument; | ||
|
||
impl Violation for InvalidGetLoggerArgument { | ||
const AUTOFIX: AutofixKind = AutofixKind::Sometimes; | ||
|
||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
format!("Use `__name__` with `logging.getLogger()`") | ||
} | ||
|
||
fn autofix_title(&self) -> Option<String> { | ||
Some(format!("Replace with `__name__`")) | ||
} | ||
} | ||
|
||
/// LOG002 | ||
pub(crate) fn invalid_get_logger_argument(checker: &mut Checker, call: &ast::ExprCall) { | ||
let Some(Expr::Name(expr @ ast::ExprName { id, .. })) = call.arguments.find_argument("name", 0) | ||
else { | ||
return; | ||
}; | ||
|
||
if !matches!(id.as_ref(), "__file__" | "__cached__") { | ||
return; | ||
} | ||
|
||
if !checker.semantic().is_builtin(id) { | ||
return; | ||
} | ||
|
||
if !checker | ||
.semantic() | ||
.resolve_call_path(call.func.as_ref()) | ||
.is_some_and(|call_path| matches!(call_path.as_slice(), ["logging", "getLogger"])) | ||
{ | ||
return; | ||
} | ||
|
||
let mut diagnostic = Diagnostic::new(InvalidGetLoggerArgument, expr.range()); | ||
if checker.patch(diagnostic.kind.rule()) { | ||
if checker.semantic().is_builtin("__name__") { | ||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement( | ||
"__name__".to_string(), | ||
expr.range(), | ||
))); | ||
} | ||
} | ||
checker.diagnostics.push(diagnostic); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
pub(crate) use direct_logger_instantiation::*; | ||
pub(crate) use invalid_get_logger_argument::*; | ||
pub(crate) use undocumented_warn::*; | ||
|
||
mod direct_logger_instantiation; | ||
mod invalid_get_logger_argument; | ||
mod undocumented_warn; |
82 changes: 82 additions & 0 deletions
82
.../rules/flake8_logging/snapshots/ruff__rules__flake8_logging__tests__LOG002_LOG002.py.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
--- | ||
source: crates/ruff/src/rules/flake8_logging/mod.rs | ||
--- | ||
LOG002.py:11:11: LOG002 [*] Use `__name__` with `logging.getLogger()` | ||
| | ||
10 | # LOG002 | ||
11 | getLogger(__file__) | ||
| ^^^^^^^^ LOG002 | ||
12 | logging.getLogger(name=__file__) | ||
| | ||
= help: Replace with `name` | ||
|
||
ℹ Suggested fix | ||
8 8 | logging.getLogger(name="custom") | ||
9 9 | | ||
10 10 | # LOG002 | ||
11 |-getLogger(__file__) | ||
11 |+getLogger(__name__) | ||
12 12 | logging.getLogger(name=__file__) | ||
13 13 | | ||
14 14 | logging.getLogger(__cached__) | ||
|
||
LOG002.py:12:24: LOG002 [*] Use `__name__` with `logging.getLogger()` | ||
| | ||
10 | # LOG002 | ||
11 | getLogger(__file__) | ||
12 | logging.getLogger(name=__file__) | ||
| ^^^^^^^^ LOG002 | ||
13 | | ||
14 | logging.getLogger(__cached__) | ||
| | ||
= help: Replace with `name` | ||
|
||
ℹ Suggested fix | ||
9 9 | | ||
10 10 | # LOG002 | ||
11 11 | getLogger(__file__) | ||
12 |-logging.getLogger(name=__file__) | ||
12 |+logging.getLogger(name=__name__) | ||
13 13 | | ||
14 14 | logging.getLogger(__cached__) | ||
15 15 | getLogger(name=__cached__) | ||
|
||
LOG002.py:14:19: LOG002 [*] Use `__name__` with `logging.getLogger()` | ||
| | ||
12 | logging.getLogger(name=__file__) | ||
13 | | ||
14 | logging.getLogger(__cached__) | ||
| ^^^^^^^^^^ LOG002 | ||
15 | getLogger(name=__cached__) | ||
| | ||
= help: Replace with `name` | ||
|
||
ℹ Suggested fix | ||
11 11 | getLogger(__file__) | ||
12 12 | logging.getLogger(name=__file__) | ||
13 13 | | ||
14 |-logging.getLogger(__cached__) | ||
14 |+logging.getLogger(__name__) | ||
15 15 | getLogger(name=__cached__) | ||
16 16 | | ||
17 17 | | ||
|
||
LOG002.py:15:16: LOG002 [*] Use `__name__` with `logging.getLogger()` | ||
| | ||
14 | logging.getLogger(__cached__) | ||
15 | getLogger(name=__cached__) | ||
| ^^^^^^^^^^ LOG002 | ||
| | ||
= help: Replace with `name` | ||
|
||
ℹ Suggested fix | ||
12 12 | logging.getLogger(name=__file__) | ||
13 13 | | ||
14 14 | logging.getLogger(__cached__) | ||
15 |-getLogger(name=__cached__) | ||
15 |+getLogger(name=__name__) | ||
16 16 | | ||
17 17 | | ||
18 18 | # Override `logging.getLogger` | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.