[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" 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,60 +182,27 @@ impl Violation for DotFormatInException {
/// EM101, EM102, EM103 /// EM101, EM102, EM103
pub(crate) fn string_in_exception(checker: &Checker, stmt: &Stmt, exc: &Expr) { 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, .. }, arguments: Arguments { args, .. },
.. ..
}) = exc }) = exc
{ else {
if let Some(first) = args.first() { return;
match first { };
// Check for string literals.
Expr::StringLiteral(ast::ExprStringLiteral { value: string, .. }) => { if checker.semantic().match_typing_expr(func, "cast") {
if checker.is_rule_enabled(Rule::RawStringInException) { return;
if string.len() >= checker.settings().flake8_errmsg.max_string_length { }
let mut diagnostic =
checker.report_diagnostic(RawStringInException, first.range()); if let Some(first) = args.first() {
if let Some(indentation) = match first {
whitespace::indentation(checker.source(), stmt) // Check for string literals.
{ Expr::StringLiteral(ast::ExprStringLiteral { value: string, .. }) => {
diagnostic.set_fix(generate_fix( if checker.is_rule_enabled(Rule::RawStringInException) {
stmt, if string.len() >= checker.settings().flake8_errmsg.max_string_length {
first,
indentation,
checker.stylist(),
checker.locator(),
));
}
}
}
}
// Check for byte string literals.
Expr::BytesLiteral(ast::ExprBytesLiteral { value: bytes, .. }) => {
if checker.settings().rules.enabled(Rule::RawStringInException) {
if bytes.len() >= checker.settings().flake8_errmsg.max_string_length
&& is_raise_exception_byte_string_enabled(checker.settings())
{
let mut diagnostic =
checker.report_diagnostic(RawStringInException, first.range());
if let Some(indentation) =
whitespace::indentation(checker.source(), stmt)
{
diagnostic.set_fix(generate_fix(
stmt,
first,
indentation,
checker.stylist(),
checker.locator(),
));
}
}
}
}
// Check for f-strings.
Expr::FString(_) => {
if checker.is_rule_enabled(Rule::FStringInException) {
let mut diagnostic = let mut diagnostic =
checker.report_diagnostic(FStringInException, first.range()); 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( diagnostic.set_fix(generate_fix(
stmt, stmt,
@ -247,32 +214,66 @@ pub(crate) fn string_in_exception(checker: &Checker, stmt: &Stmt, exc: &Expr) {
} }
} }
} }
// Check for .format() calls. }
Expr::Call(ast::ExprCall { func, .. }) => { // Check for byte string literals.
if checker.is_rule_enabled(Rule::DotFormatInException) { Expr::BytesLiteral(ast::ExprBytesLiteral { value: bytes, .. }) => {
if let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = if checker.settings().rules.enabled(Rule::RawStringInException) {
func.as_ref() if bytes.len() >= checker.settings().flake8_errmsg.max_string_length
{ && is_raise_exception_byte_string_enabled(checker.settings())
if attr == "format" && value.is_literal_expr() { {
let mut diagnostic = let mut diagnostic =
checker.report_diagnostic(DotFormatInException, first.range()); checker.report_diagnostic(RawStringInException, first.range());
if let Some(indentation) = if let Some(indentation) = whitespace::indentation(checker.source(), stmt) {
whitespace::indentation(checker.source(), stmt) diagnostic.set_fix(generate_fix(
{ stmt,
diagnostic.set_fix(generate_fix( first,
stmt, indentation,
first, checker.stylist(),
indentation, checker.locator(),
checker.stylist(), ));
checker.locator(), }
)); }
} }
}
// Check for f-strings.
Expr::FString(_) => {
if checker.is_rule_enabled(Rule::FStringInException) {
let mut diagnostic =
checker.report_diagnostic(FStringInException, first.range());
if let Some(indentation) = whitespace::indentation(checker.source(), stmt) {
diagnostic.set_fix(generate_fix(
stmt,
first,
indentation,
checker.stylist(),
checker.locator(),
));
}
}
}
// 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 attr == "format" && value.is_literal_expr() {
let mut diagnostic =
checker.report_diagnostic(DotFormatInException, first.range());
if let Some(indentation) =
whitespace::indentation(checker.source(), stmt)
{
diagnostic.set_fix(generate_fix(
stmt,
first,
indentation,
checker.stylist(),
checker.locator(),
));
} }
} }
} }
} }
_ => {}
} }
_ => {}
} }
} }
} }

View file

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