[flake8-errmsg] Exclude typing.cast from EM101 (#19656)

## Summary

Fixes #19596
This commit is contained in:
Dan Parizher 2025-08-01 13:37:44 -04:00 committed by GitHub
parent 06cd249a9b
commit dce25da19a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 100 additions and 71 deletions

View file

@ -88,3 +88,25 @@ def f_multi_line_string2():
example="example"
)
)
def raise_typing_cast_exception():
import typing
raise typing.cast("Exception", None)
def f_typing_cast_excluded():
from typing import cast
raise cast(RuntimeError, "This should not trigger EM101")
def f_typing_cast_excluded_import():
import typing
raise typing.cast(RuntimeError, "This should not trigger EM101")
def f_typing_cast_excluded_aliased():
from typing import cast as my_cast
raise my_cast(RuntimeError, "This should not trigger EM101")

View file

@ -182,11 +182,19 @@ impl Violation for DotFormatInException {
/// EM101, EM102, EM103
pub(crate) fn string_in_exception(checker: &Checker, stmt: &Stmt, exc: &Expr) {
if let Expr::Call(ast::ExprCall {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
}) = exc
{
else {
return;
};
if checker.semantic().match_typing_expr(func, "cast") {
return;
}
if let Some(first) = args.first() {
match first {
// Check for string literals.
@ -195,9 +203,7 @@ pub(crate) fn string_in_exception(checker: &Checker, stmt: &Stmt, exc: &Expr) {
if string.len() >= checker.settings().flake8_errmsg.max_string_length {
let mut diagnostic =
checker.report_diagnostic(RawStringInException, first.range());
if let Some(indentation) =
whitespace::indentation(checker.source(), stmt)
{
if let Some(indentation) = whitespace::indentation(checker.source(), stmt) {
diagnostic.set_fix(generate_fix(
stmt,
first,
@ -217,9 +223,7 @@ pub(crate) fn string_in_exception(checker: &Checker, stmt: &Stmt, exc: &Expr) {
{
let mut diagnostic =
checker.report_diagnostic(RawStringInException, first.range());
if let Some(indentation) =
whitespace::indentation(checker.source(), stmt)
{
if let Some(indentation) = whitespace::indentation(checker.source(), stmt) {
diagnostic.set_fix(generate_fix(
stmt,
first,
@ -250,9 +254,7 @@ pub(crate) fn string_in_exception(checker: &Checker, stmt: &Stmt, exc: &Expr) {
// Check for .format() calls.
Expr::Call(ast::ExprCall { func, .. }) => {
if checker.is_rule_enabled(Rule::DotFormatInException) {
if let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) =
func.as_ref()
{
if let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = func.as_ref() {
if attr == "format" && value.is_literal_expr() {
let mut diagnostic =
checker.report_diagnostic(DotFormatInException, first.range());
@ -275,7 +277,6 @@ pub(crate) fn string_in_exception(checker: &Checker, stmt: &Stmt, exc: &Expr) {
}
}
}
}
/// Generate the [`Fix`] for EM001, EM002, and EM003 violations.
///

View file

@ -278,3 +278,6 @@ EM.py:84:9: EM103 [*] Exception must not use a `.format()` string directly, assi
91 |+ raise RuntimeError(
92 |+ msg
93 |+ )
91 94 |
92 95 |
93 96 | def raise_typing_cast_exception():

View file

@ -343,3 +343,6 @@ EM.py:84:9: EM103 [*] Exception must not use a `.format()` string directly, assi
91 |+ raise RuntimeError(
92 |+ msg
93 |+ )
91 94 |
92 95 |
93 96 | def raise_typing_cast_exception():