diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py b/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py index bdadaf9ba7..598f79b5d1 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py @@ -218,6 +218,35 @@ try: except Exception as e: logging.warning("...", exc_info=e) +try: + pass +except Exception: + logging.warn("...") + + +try: + pass +except Exception: + logging.warn("...", exc_info=False) + + +try: + pass +except Exception: + logging.warn("...", exc_info=None) + + +try: + pass +except Exception: + logging.warn("...", exc_info=True) + + +try: + pass +except Exception as e: + logging.warn("...", exc_info=e) + try: pass @@ -249,7 +278,7 @@ except Exception as e: logging.log(logging.INFO, "...", exc_info=e) -from logging import critical, error, exception, debug, info, warning, log +from logging import critical, error, exception, debug, info, warning, log, warn try: pass @@ -376,6 +405,30 @@ except Exception: warning("...", exc_info=True) +try: + pass +except Exception: + warn("...") + + +try: + pass +except Exception: + warn("...", exc_info=False) + + +try: + pass +except Exception: + warn("...", exc_info=None) + + +try: + pass +except Exception: + warn("...", exc_info=True) + + try: pass except Exception: @@ -424,6 +477,12 @@ except Exception as e: warning("...", exc_info=e) +try: + pass +except Exception as e: + warn("...", exc_info=e) + + try: pass except Exception as e: diff --git a/crates/ruff_linter/src/helpers.rs b/crates/ruff_linter/src/helpers.rs new file mode 100644 index 0000000000..ef3b2be7ff --- /dev/null +++ b/crates/ruff_linter/src/helpers.rs @@ -0,0 +1,7 @@ +#[inline] +pub(crate) fn is_logger_method_name(attr: &str) -> bool { + matches!( + attr, + "debug" | "info" | "warn" | "warning" | "error" | "critical" | "log" | "exception" + ) +} diff --git a/crates/ruff_linter/src/lib.rs b/crates/ruff_linter/src/lib.rs index 24f0808ee4..1cc37c0555 100644 --- a/crates/ruff_linter/src/lib.rs +++ b/crates/ruff_linter/src/lib.rs @@ -28,6 +28,7 @@ mod doc_lines; mod docstrings; mod fix; pub mod fs; +mod helpers; mod importer; pub mod line_width; pub mod linter; diff --git a/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs b/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs index a6a3a58425..3e485a5413 100644 --- a/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs +++ b/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs @@ -1,3 +1,4 @@ +use crate::helpers::is_logger_method_name; use ruff_macros::{ViolationMetadata, derive_message_formats}; use ruff_python_ast::helpers::Truthiness; use ruff_python_ast::statement_visitor::{StatementVisitor, walk_stmt}; @@ -129,14 +130,6 @@ pub(crate) fn blind_except( ); } -/// Returns true if the logging method accepts an `exc_info` parameter. -fn is_exc_info_compatible_log_method(method_name: &str) -> bool { - matches!( - method_name, - "debug" | "info" | "warning" | "error" | "exception" | "critical" | "log" - ) -} - /// A visitor to detect whether the exception with the given name was re-raised. struct ReraiseVisitor<'a> { name: Option<&'a str>, @@ -230,7 +223,7 @@ impl<'a> StatementVisitor<'a> for LogExceptionVisitor<'a> { ) { if match attr.as_str() { "exception" => true, - attr if is_exc_info_compatible_log_method(attr) => { + _ if is_logger_method_name(attr) => { arguments.find_keyword("exc_info").is_some_and(|keyword| { Truthiness::from_expr(&keyword.value, |id| { self.semantic.has_builtin_binding(id) @@ -249,9 +242,7 @@ impl<'a> StatementVisitor<'a> for LogExceptionVisitor<'a> { if self.semantic.resolve_qualified_name(func).is_some_and( |qualified_name| match qualified_name.segments() { ["logging", "exception"] => true, - ["logging", method] - if is_exc_info_compatible_log_method(method) => - { + ["logging", method] if is_logger_method_name(method) => { arguments.find_keyword("exc_info").is_some_and(|keyword| { Truthiness::from_expr(&keyword.value, |id| { self.semantic.has_builtin_binding(id) diff --git a/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap b/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap index 87203ef661..055cb3ba45 100644 --- a/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap +++ b/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap @@ -225,93 +225,103 @@ BLE001 Do not catch blind exception: `Exception` | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:224:8 + --> BLE.py:223:8 | -222 | try: -223 | pass -224 | except Exception: +221 | try: +222 | pass +223 | except Exception: | ^^^^^^^^^ -225 | logging.log(logging.INFO, "...") +224 | logging.warn("...") | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:230:8 + --> BLE.py:229:8 | -228 | try: -229 | pass -230 | except Exception: +227 | try: +228 | pass +229 | except Exception: | ^^^^^^^^^ -231 | logging.log(logging.INFO, "...", exc_info=False) +230 | logging.warn("...", exc_info=False) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:236:8 + --> BLE.py:235:8 | -234 | try: -235 | pass -236 | except Exception: +233 | try: +234 | pass +235 | except Exception: | ^^^^^^^^^ -237 | logging.log(logging.INFO, "...", exc_info=None) +236 | logging.warn("...", exc_info=None) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:256:8 + --> BLE.py:253:8 | -254 | try: -255 | pass -256 | except Exception: +251 | try: +252 | pass +253 | except Exception: | ^^^^^^^^^ -257 | error("...") +254 | logging.log(logging.INFO, "...") | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:262:8 + --> BLE.py:259:8 | -260 | try: -261 | pass -262 | except Exception: +257 | try: +258 | pass +259 | except Exception: | ^^^^^^^^^ -263 | error("...", exc_info=False) +260 | logging.log(logging.INFO, "...", exc_info=False) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:268:8 + --> BLE.py:265:8 | -266 | try: -267 | pass -268 | except Exception: +263 | try: +264 | pass +265 | except Exception: | ^^^^^^^^^ -269 | error("...", exc_info=None) +266 | logging.log(logging.INFO, "...", exc_info=None) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:274:8 + --> BLE.py:285:8 | -272 | try: -273 | pass -274 | except Exception: +283 | try: +284 | pass +285 | except Exception: | ^^^^^^^^^ -275 | critical("...") +286 | error("...") | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:280:8 + --> BLE.py:291:8 | -278 | try: -279 | pass -280 | except Exception: +289 | try: +290 | pass +291 | except Exception: | ^^^^^^^^^ -281 | critical("...", exc_info=False) +292 | error("...", exc_info=False) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:286:8 + --> BLE.py:297:8 | -284 | try: -285 | pass -286 | except Exception: +295 | try: +296 | pass +297 | except Exception: | ^^^^^^^^^ -287 | critical("...", exc_info=None) +298 | error("...", exc_info=None) + | + +BLE001 Do not catch blind exception: `Exception` + --> BLE.py:303:8 + | +301 | try: +302 | pass +303 | except Exception: + | ^^^^^^^^^ +304 | critical("...") | BLE001 Do not catch blind exception: `Exception` @@ -321,7 +331,7 @@ BLE001 Do not catch blind exception: `Exception` 308 | pass 309 | except Exception: | ^^^^^^^^^ -310 | debug("...") +310 | critical("...", exc_info=False) | BLE001 Do not catch blind exception: `Exception` @@ -331,205 +341,255 @@ BLE001 Do not catch blind exception: `Exception` 314 | pass 315 | except Exception: | ^^^^^^^^^ -316 | debug("...", exc_info=False) +316 | critical("...", exc_info=None) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:321:8 + --> BLE.py:338:8 | -319 | try: -320 | pass -321 | except Exception: +336 | try: +337 | pass +338 | except Exception: | ^^^^^^^^^ -322 | debug("...", exc_info=None) +339 | debug("...") | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:333:8 + --> BLE.py:344:8 | -331 | try: -332 | pass -333 | except Exception: +342 | try: +343 | pass +344 | except Exception: | ^^^^^^^^^ -334 | info("...") +345 | debug("...", exc_info=False) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:339:8 + --> BLE.py:350:8 | -337 | try: -338 | pass -339 | except Exception: +348 | try: +349 | pass +350 | except Exception: | ^^^^^^^^^ -340 | info("...", exc_info=False) +351 | debug("...", exc_info=None) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:345:8 + --> BLE.py:362:8 | -343 | try: -344 | pass -345 | except Exception: +360 | try: +361 | pass +362 | except Exception: | ^^^^^^^^^ -346 | info("...", exc_info=None) +363 | info("...") | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:357:8 + --> BLE.py:368:8 | -355 | try: -356 | pass -357 | except Exception: +366 | try: +367 | pass +368 | except Exception: | ^^^^^^^^^ -358 | warning("...") +369 | info("...", exc_info=False) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:363:8 + --> BLE.py:374:8 | -361 | try: -362 | pass -363 | except Exception: +372 | try: +373 | pass +374 | except Exception: | ^^^^^^^^^ -364 | warning("...", exc_info=False) +375 | info("...", exc_info=None) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:369:8 + --> BLE.py:386:8 | -367 | try: -368 | pass -369 | except Exception: +384 | try: +385 | pass +386 | except Exception: | ^^^^^^^^^ -370 | warning("...", exc_info=None) +387 | warning("...") | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:381:8 + --> BLE.py:392:8 | -379 | try: -380 | pass -381 | except Exception: +390 | try: +391 | pass +392 | except Exception: | ^^^^^^^^^ -382 | log(logging.INFO, "...") +393 | warning("...", exc_info=False) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:387:8 + --> BLE.py:398:8 | -385 | try: -386 | pass -387 | except Exception: +396 | try: +397 | pass +398 | except Exception: | ^^^^^^^^^ -388 | log(logging.INFO, "...", exc_info=False) +399 | warning("...", exc_info=None) | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:393:8 + --> BLE.py:410:8 | -391 | try: -392 | pass -393 | except Exception: +408 | try: +409 | pass +410 | except Exception: | ^^^^^^^^^ -394 | log(logging.INFO, "...", exc_info=None) +411 | warn("...") | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:461:9 + --> BLE.py:416:8 | -459 | try: -460 | pass -461 | except (Exception,): +414 | try: +415 | pass +416 | except Exception: + | ^^^^^^^^^ +417 | warn("...", exc_info=False) + | + +BLE001 Do not catch blind exception: `Exception` + --> BLE.py:422:8 + | +420 | try: +421 | pass +422 | except Exception: + | ^^^^^^^^^ +423 | warn("...", exc_info=None) + | + +BLE001 Do not catch blind exception: `Exception` + --> BLE.py:434:8 + | +432 | try: +433 | pass +434 | except Exception: + | ^^^^^^^^^ +435 | log(logging.INFO, "...") + | + +BLE001 Do not catch blind exception: `Exception` + --> BLE.py:440:8 + | +438 | try: +439 | pass +440 | except Exception: + | ^^^^^^^^^ +441 | log(logging.INFO, "...", exc_info=False) + | + +BLE001 Do not catch blind exception: `Exception` + --> BLE.py:446:8 + | +444 | try: +445 | pass +446 | except Exception: + | ^^^^^^^^^ +447 | log(logging.INFO, "...", exc_info=None) + | + +BLE001 Do not catch blind exception: `Exception` + --> BLE.py:520:9 + | +518 | try: +519 | pass +520 | except (Exception,): | ^^^^^^^^^ -462 | pass +521 | pass | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:466:9 + --> BLE.py:525:9 | -464 | try: -465 | pass -466 | except (Exception, ValueError): +523 | try: +524 | pass +525 | except (Exception, ValueError): | ^^^^^^^^^ -467 | pass +526 | pass | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:471:21 + --> BLE.py:530:21 | -469 | try: -470 | pass -471 | except (ValueError, Exception): +528 | try: +529 | pass +530 | except (ValueError, Exception): | ^^^^^^^^^ -472 | pass +531 | pass | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:476:21 + --> BLE.py:535:21 | -474 | try: -475 | pass -476 | except (ValueError, Exception) as e: +533 | try: +534 | pass +535 | except (ValueError, Exception) as e: | ^^^^^^^^^ -477 | print(e) +536 | print(e) | BLE001 Do not catch blind exception: `BaseException` - --> BLE.py:481:9 + --> BLE.py:540:9 | -479 | try: -480 | pass -481 | except (BaseException, TypeError): +538 | try: +539 | pass +540 | except (BaseException, TypeError): | ^^^^^^^^^^^^^ -482 | pass +541 | pass | BLE001 Do not catch blind exception: `BaseException` - --> BLE.py:486:20 + --> BLE.py:545:20 | -484 | try: -485 | pass -486 | except (TypeError, BaseException): +543 | try: +544 | pass +545 | except (TypeError, BaseException): | ^^^^^^^^^^^^^ -487 | pass +546 | pass | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:491:9 + --> BLE.py:550:9 | -489 | try: -490 | pass -491 | except (Exception, BaseException): +548 | try: +549 | pass +550 | except (Exception, BaseException): | ^^^^^^^^^ -492 | pass +551 | pass | BLE001 Do not catch blind exception: `BaseException` - --> BLE.py:496:9 + --> BLE.py:555:9 | -494 | try: -495 | pass -496 | except (BaseException, Exception): +553 | try: +554 | pass +555 | except (BaseException, Exception): | ^^^^^^^^^^^^^ -497 | pass +556 | pass | BLE001 Do not catch blind exception: `Exception` - --> BLE.py:502:10 + --> BLE.py:561:10 | -500 | try: -501 | pass -502 | except ((Exception, ValueError), TypeError): +559 | try: +560 | pass +561 | except ((Exception, ValueError), TypeError): | ^^^^^^^^^ -503 | pass +562 | pass | BLE001 Do not catch blind exception: `BaseException` - --> BLE.py:507:22 + --> BLE.py:566:22 | -505 | try: -506 | pass -507 | except (ValueError, (BaseException, TypeError)): +564 | try: +565 | pass +566 | except (ValueError, (BaseException, TypeError)): | ^^^^^^^^^^^^^ -508 | pass +567 | pass | diff --git a/crates/ruff_linter/src/rules/flake8_logging/rules/root_logger_call.rs b/crates/ruff_linter/src/rules/flake8_logging/rules/root_logger_call.rs index f7b6a55706..cd6d7b467a 100644 --- a/crates/ruff_linter/src/rules/flake8_logging/rules/root_logger_call.rs +++ b/crates/ruff_linter/src/rules/flake8_logging/rules/root_logger_call.rs @@ -1,3 +1,4 @@ +use crate::helpers::is_logger_method_name; use ruff_macros::{ViolationMetadata, derive_message_formats}; use ruff_python_ast::ExprCall; use ruff_python_semantic::Modules; @@ -66,11 +67,3 @@ pub(crate) fn root_logger_call(checker: &Checker, call: &ExprCall) { }; checker.report_diagnostic(kind, call.range); } - -#[inline] -fn is_logger_method_name(attr: &str) -> bool { - matches!( - attr, - "debug" | "info" | "warn" | "warning" | "error" | "critical" | "log" | "exception" - ) -}