mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:43 +00:00
Rename Checker::model
to semantic_model
(#4573)
This commit is contained in:
parent
063431cb0f
commit
cbe344f4d5
158 changed files with 1009 additions and 827 deletions
File diff suppressed because it is too large
Load diff
|
@ -122,7 +122,7 @@ fn is_sys(model: &SemanticModel, expr: &Expr, target: &str) -> bool {
|
||||||
|
|
||||||
/// YTT101, YTT102, YTT301, YTT303
|
/// YTT101, YTT102, YTT301, YTT303
|
||||||
pub(crate) fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
pub(crate) fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
||||||
if is_sys(&checker.model, value, "version") {
|
if is_sys(checker.semantic_model(), value, "version") {
|
||||||
match slice {
|
match slice {
|
||||||
Expr::Slice(ast::ExprSlice {
|
Expr::Slice(ast::ExprSlice {
|
||||||
lower: None,
|
lower: None,
|
||||||
|
@ -176,7 +176,7 @@ pub(crate) fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
||||||
pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &[Expr]) {
|
pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &[Expr]) {
|
||||||
match left {
|
match left {
|
||||||
Expr::Subscript(ast::ExprSubscript { value, slice, .. })
|
Expr::Subscript(ast::ExprSubscript { value, slice, .. })
|
||||||
if is_sys(&checker.model, value, "version_info") =>
|
if is_sys(checker.semantic_model(), value, "version_info") =>
|
||||||
{
|
{
|
||||||
if let Expr::Constant(ast::ExprConstant {
|
if let Expr::Constant(ast::ExprConstant {
|
||||||
value: Constant::Int(i),
|
value: Constant::Int(i),
|
||||||
|
@ -220,7 +220,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], compara
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr::Attribute(ast::ExprAttribute { value, attr, .. })
|
Expr::Attribute(ast::ExprAttribute { value, attr, .. })
|
||||||
if is_sys(&checker.model, value, "version_info") && attr == "minor" =>
|
if is_sys(checker.semantic_model(), value, "version_info") && attr == "minor" =>
|
||||||
{
|
{
|
||||||
if let (
|
if let (
|
||||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
||||||
|
@ -245,7 +245,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], compara
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_sys(&checker.model, left, "version") {
|
if is_sys(checker.semantic_model(), left, "version") {
|
||||||
if let (
|
if let (
|
||||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
||||||
[Expr::Constant(ast::ExprConstant {
|
[Expr::Constant(ast::ExprConstant {
|
||||||
|
@ -272,7 +272,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], compara
|
||||||
/// YTT202
|
/// YTT202
|
||||||
pub(crate) fn name_or_attribute(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn name_or_attribute(checker: &mut Checker, expr: &Expr) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(expr)
|
.resolve_call_path(expr)
|
||||||
.map_or(false, |call_path| call_path.as_slice() == ["six", "PY3"])
|
.map_or(false, |call_path| call_path.as_slice() == ["six", "PY3"])
|
||||||
{
|
{
|
||||||
|
|
|
@ -480,7 +480,7 @@ pub(crate) fn definition(
|
||||||
// unless configured to suppress ANN* for declarations that are fully untyped.
|
// unless configured to suppress ANN* for declarations that are fully untyped.
|
||||||
let mut diagnostics = Vec::new();
|
let mut diagnostics = Vec::new();
|
||||||
|
|
||||||
let is_overridden = visibility::is_override(&checker.model, decorator_list);
|
let is_overridden = visibility::is_override(checker.semantic_model(), decorator_list);
|
||||||
|
|
||||||
// ANN001, ANN401
|
// ANN001, ANN401
|
||||||
for arg in args
|
for arg in args
|
||||||
|
@ -492,7 +492,10 @@ pub(crate) fn definition(
|
||||||
// If this is a non-static method, skip `cls` or `self`.
|
// If this is a non-static method, skip `cls` or `self`.
|
||||||
usize::from(
|
usize::from(
|
||||||
is_method
|
is_method
|
||||||
&& !visibility::is_staticmethod(&checker.model, cast::decorator_list(stmt)),
|
&& !visibility::is_staticmethod(
|
||||||
|
checker.semantic_model(),
|
||||||
|
cast::decorator_list(stmt),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -501,7 +504,7 @@ pub(crate) fn definition(
|
||||||
has_any_typed_arg = true;
|
has_any_typed_arg = true;
|
||||||
if checker.settings.rules.enabled(Rule::AnyType) {
|
if checker.settings.rules.enabled(Rule::AnyType) {
|
||||||
check_dynamically_typed(
|
check_dynamically_typed(
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
annotation,
|
annotation,
|
||||||
|| arg.arg.to_string(),
|
|| arg.arg.to_string(),
|
||||||
&mut diagnostics,
|
&mut diagnostics,
|
||||||
|
@ -536,7 +539,7 @@ pub(crate) fn definition(
|
||||||
if checker.settings.rules.enabled(Rule::AnyType) {
|
if checker.settings.rules.enabled(Rule::AnyType) {
|
||||||
let name = &arg.arg;
|
let name = &arg.arg;
|
||||||
check_dynamically_typed(
|
check_dynamically_typed(
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
expr,
|
expr,
|
||||||
|| format!("*{name}"),
|
|| format!("*{name}"),
|
||||||
&mut diagnostics,
|
&mut diagnostics,
|
||||||
|
@ -568,7 +571,7 @@ pub(crate) fn definition(
|
||||||
if checker.settings.rules.enabled(Rule::AnyType) {
|
if checker.settings.rules.enabled(Rule::AnyType) {
|
||||||
let name = &arg.arg;
|
let name = &arg.arg;
|
||||||
check_dynamically_typed(
|
check_dynamically_typed(
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
expr,
|
expr,
|
||||||
|| format!("**{name}"),
|
|| format!("**{name}"),
|
||||||
&mut diagnostics,
|
&mut diagnostics,
|
||||||
|
@ -593,10 +596,13 @@ pub(crate) fn definition(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANN101, ANN102
|
// ANN101, ANN102
|
||||||
if is_method && !visibility::is_staticmethod(&checker.model, cast::decorator_list(stmt)) {
|
if is_method
|
||||||
|
&& !visibility::is_staticmethod(checker.semantic_model(), cast::decorator_list(stmt))
|
||||||
|
{
|
||||||
if let Some(arg) = args.posonlyargs.first().or_else(|| args.args.first()) {
|
if let Some(arg) = args.posonlyargs.first().or_else(|| args.args.first()) {
|
||||||
if arg.annotation.is_none() {
|
if arg.annotation.is_none() {
|
||||||
if visibility::is_classmethod(&checker.model, cast::decorator_list(stmt)) {
|
if visibility::is_classmethod(checker.semantic_model(), cast::decorator_list(stmt))
|
||||||
|
{
|
||||||
if checker.settings.rules.enabled(Rule::MissingTypeCls) {
|
if checker.settings.rules.enabled(Rule::MissingTypeCls) {
|
||||||
diagnostics.push(Diagnostic::new(
|
diagnostics.push(Diagnostic::new(
|
||||||
MissingTypeCls {
|
MissingTypeCls {
|
||||||
|
@ -626,7 +632,7 @@ pub(crate) fn definition(
|
||||||
has_typed_return = true;
|
has_typed_return = true;
|
||||||
if checker.settings.rules.enabled(Rule::AnyType) {
|
if checker.settings.rules.enabled(Rule::AnyType) {
|
||||||
check_dynamically_typed(
|
check_dynamically_typed(
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
expr,
|
expr,
|
||||||
|| name.to_string(),
|
|| name.to_string(),
|
||||||
&mut diagnostics,
|
&mut diagnostics,
|
||||||
|
@ -638,7 +644,9 @@ pub(crate) fn definition(
|
||||||
// (explicitly or implicitly).
|
// (explicitly or implicitly).
|
||||||
checker.settings.flake8_annotations.suppress_none_returning && is_none_returning(body)
|
checker.settings.flake8_annotations.suppress_none_returning && is_none_returning(body)
|
||||||
) {
|
) {
|
||||||
if is_method && visibility::is_classmethod(&checker.model, cast::decorator_list(stmt)) {
|
if is_method
|
||||||
|
&& visibility::is_classmethod(checker.semantic_model(), cast::decorator_list(stmt))
|
||||||
|
{
|
||||||
if checker
|
if checker
|
||||||
.settings
|
.settings
|
||||||
.rules
|
.rules
|
||||||
|
@ -652,7 +660,7 @@ pub(crate) fn definition(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else if is_method
|
} else if is_method
|
||||||
&& visibility::is_staticmethod(&checker.model, cast::decorator_list(stmt))
|
&& visibility::is_staticmethod(checker.semantic_model(), cast::decorator_list(stmt))
|
||||||
{
|
{
|
||||||
if checker
|
if checker
|
||||||
.settings
|
.settings
|
||||||
|
|
|
@ -66,10 +66,13 @@ const BLOCKING_HTTP_CALLS: &[&[&str]] = &[
|
||||||
|
|
||||||
/// ASYNC100
|
/// ASYNC100
|
||||||
pub(crate) fn blocking_http_call(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn blocking_http_call(checker: &mut Checker, expr: &Expr) {
|
||||||
if in_async_function(&checker.model) {
|
if in_async_function(checker.semantic_model()) {
|
||||||
if let Expr::Call(ast::ExprCall { func, .. }) = expr {
|
if let Expr::Call(ast::ExprCall { func, .. }) = expr {
|
||||||
if let Some(call_path) = checker.model.resolve_call_path(func) {
|
let call_path = checker.semantic_model().resolve_call_path(func);
|
||||||
if BLOCKING_HTTP_CALLS.contains(&call_path.as_slice()) {
|
let is_blocking =
|
||||||
|
call_path.map_or(false, |path| BLOCKING_HTTP_CALLS.contains(&path.as_slice()));
|
||||||
|
|
||||||
|
if is_blocking {
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
BlockingHttpCallInAsyncFunction,
|
BlockingHttpCallInAsyncFunction,
|
||||||
func.range(),
|
func.range(),
|
||||||
|
@ -77,7 +80,6 @@ pub(crate) fn blocking_http_call(checker: &mut Checker, expr: &Expr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
|
@ -133,10 +135,16 @@ const OPEN_SLEEP_OR_SUBPROCESS_CALL: &[&[&str]] = &[
|
||||||
|
|
||||||
/// ASYNC101
|
/// ASYNC101
|
||||||
pub(crate) fn open_sleep_or_subprocess_call(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn open_sleep_or_subprocess_call(checker: &mut Checker, expr: &Expr) {
|
||||||
if in_async_function(&checker.model) {
|
if in_async_function(checker.semantic_model()) {
|
||||||
if let Expr::Call(ast::ExprCall { func, .. }) = expr {
|
if let Expr::Call(ast::ExprCall { func, .. }) = expr {
|
||||||
if let Some(call_path) = checker.model.resolve_call_path(func) {
|
let is_open_sleep_or_subprocess_call = checker
|
||||||
if OPEN_SLEEP_OR_SUBPROCESS_CALL.contains(&call_path.as_slice()) {
|
.semantic_model()
|
||||||
|
.resolve_call_path(func)
|
||||||
|
.map_or(false, |path| {
|
||||||
|
OPEN_SLEEP_OR_SUBPROCESS_CALL.contains(&path.as_slice())
|
||||||
|
});
|
||||||
|
|
||||||
|
if is_open_sleep_or_subprocess_call {
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
OpenSleepOrSubprocessInAsyncFunction,
|
OpenSleepOrSubprocessInAsyncFunction,
|
||||||
func.range(),
|
func.range(),
|
||||||
|
@ -144,7 +152,6 @@ pub(crate) fn open_sleep_or_subprocess_call(checker: &mut Checker, expr: &Expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
|
@ -197,17 +204,20 @@ const UNSAFE_OS_METHODS: &[&[&str]] = &[
|
||||||
|
|
||||||
/// ASYNC102
|
/// ASYNC102
|
||||||
pub(crate) fn blocking_os_call(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn blocking_os_call(checker: &mut Checker, expr: &Expr) {
|
||||||
if in_async_function(&checker.model) {
|
if in_async_function(checker.semantic_model()) {
|
||||||
if let Expr::Call(ast::ExprCall { func, .. }) = expr {
|
if let Expr::Call(ast::ExprCall { func, .. }) = expr {
|
||||||
if let Some(call_path) = checker.model.resolve_call_path(func) {
|
let is_unsafe_os_method = checker
|
||||||
if UNSAFE_OS_METHODS.contains(&call_path.as_slice()) {
|
.semantic_model()
|
||||||
|
.resolve_call_path(func)
|
||||||
|
.map_or(false, |path| UNSAFE_OS_METHODS.contains(&path.as_slice()));
|
||||||
|
|
||||||
|
if is_unsafe_os_method {
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(BlockingOsCallInAsyncFunction, func.range()));
|
.push(Diagnostic::new(BlockingOsCallInAsyncFunction, func.range()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return `true` if the [`SemanticModel`] is inside an async function definition.
|
/// Return `true` if the [`SemanticModel`] is inside an async function definition.
|
||||||
|
|
|
@ -108,7 +108,7 @@ pub(crate) fn bad_file_permissions(
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| call_path.as_slice() == ["os", "chmod"])
|
.map_or(false, |call_path| call_path.as_slice() == ["os", "chmod"])
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,7 +60,7 @@ fn unparse_string_format_expression(checker: &mut Checker, expr: &Expr) -> Optio
|
||||||
op: Operator::Add | Operator::Mod,
|
op: Operator::Add | Operator::Mod,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let Some(parent) = checker.model.expr_parent() else {
|
let Some(parent) = checker.semantic_model().expr_parent() else {
|
||||||
if any_over_expr(expr, &has_string_literal) {
|
if any_over_expr(expr, &has_string_literal) {
|
||||||
return Some(checker.generator().expr(expr));
|
return Some(checker.generator().expr(expr));
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,11 @@ pub(crate) fn hashlib_insecure_hash_functions(
|
||||||
args: &[Expr],
|
args: &[Expr],
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if let Some(hashlib_call) = checker.model.resolve_call_path(func).and_then(|call_path| {
|
if let Some(hashlib_call) =
|
||||||
|
checker
|
||||||
|
.semantic_model()
|
||||||
|
.resolve_call_path(func)
|
||||||
|
.and_then(|call_path| {
|
||||||
if call_path.as_slice() == ["hashlib", "new"] {
|
if call_path.as_slice() == ["hashlib", "new"] {
|
||||||
Some(HashlibCall::New)
|
Some(HashlibCall::New)
|
||||||
} else {
|
} else {
|
||||||
|
@ -57,7 +61,8 @@ pub(crate) fn hashlib_insecure_hash_functions(
|
||||||
.find(|hash| call_path.as_slice() == ["hashlib", hash])
|
.find(|hash| call_path.as_slice() == ["hashlib", hash])
|
||||||
.map(|hash| HashlibCall::WeakHash(hash))
|
.map(|hash| HashlibCall::WeakHash(hash))
|
||||||
}
|
}
|
||||||
}) {
|
})
|
||||||
|
{
|
||||||
match hashlib_call {
|
match hashlib_call {
|
||||||
HashlibCall::New => {
|
HashlibCall::New => {
|
||||||
let call_args = SimpleCallArgs::new(args, keywords);
|
let call_args = SimpleCallArgs::new(args, keywords);
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub(crate) fn jinja2_autoescape_false(
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["jinja2", "Environment"]
|
call_path.as_slice() == ["jinja2", "Environment"]
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub(crate) fn logging_config_insecure_listen(
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["logging", "config", "listen"]
|
call_path.as_slice() == ["logging", "config", "listen"]
|
||||||
|
|
|
@ -18,7 +18,7 @@ impl Violation for ParamikoCall {
|
||||||
/// S601
|
/// S601
|
||||||
pub(crate) fn paramiko_call(checker: &mut Checker, func: &Expr) {
|
pub(crate) fn paramiko_call(checker: &mut Checker, func: &Expr) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["paramiko", "exec_command"]
|
call_path.as_slice() == ["paramiko", "exec_command"]
|
||||||
|
|
|
@ -43,7 +43,10 @@ pub(crate) fn request_with_no_cert_validation(
|
||||||
args: &[Expr],
|
args: &[Expr],
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if let Some(target) = checker.model.resolve_call_path(func).and_then(|call_path| {
|
if let Some(target) = checker
|
||||||
|
.semantic_model()
|
||||||
|
.resolve_call_path(func)
|
||||||
|
.and_then(|call_path| {
|
||||||
if call_path.len() == 2 {
|
if call_path.len() == 2 {
|
||||||
if call_path[0] == "requests" && REQUESTS_HTTP_VERBS.contains(&call_path[1]) {
|
if call_path[0] == "requests" && REQUESTS_HTTP_VERBS.contains(&call_path[1]) {
|
||||||
return Some("requests");
|
return Some("requests");
|
||||||
|
@ -53,7 +56,8 @@ pub(crate) fn request_with_no_cert_validation(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}) {
|
})
|
||||||
|
{
|
||||||
let call_args = SimpleCallArgs::new(args, keywords);
|
let call_args = SimpleCallArgs::new(args, keywords);
|
||||||
if let Some(verify_arg) = call_args.keyword_argument("verify") {
|
if let Some(verify_arg) = call_args.keyword_argument("verify") {
|
||||||
if let Expr::Constant(ast::ExprConstant {
|
if let Expr::Constant(ast::ExprConstant {
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub(crate) fn request_without_timeout(
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
HTTP_VERBS
|
HTTP_VERBS
|
||||||
|
|
|
@ -184,11 +184,11 @@ pub(crate) fn shell_injection(
|
||||||
args: &[Expr],
|
args: &[Expr],
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
let call_kind = get_call_kind(func, &checker.model);
|
let call_kind = get_call_kind(func, checker.semantic_model());
|
||||||
|
|
||||||
if matches!(call_kind, Some(CallKind::Subprocess)) {
|
if matches!(call_kind, Some(CallKind::Subprocess)) {
|
||||||
if let Some(arg) = args.first() {
|
if let Some(arg) = args.first() {
|
||||||
match find_shell_keyword(&checker.model, keywords) {
|
match find_shell_keyword(checker.semantic_model(), keywords) {
|
||||||
// S602
|
// S602
|
||||||
Some(ShellKeyword {
|
Some(ShellKeyword {
|
||||||
truthiness: Truthiness::Truthy,
|
truthiness: Truthiness::Truthy,
|
||||||
|
@ -241,7 +241,7 @@ pub(crate) fn shell_injection(
|
||||||
} else if let Some(ShellKeyword {
|
} else if let Some(ShellKeyword {
|
||||||
truthiness: Truthiness::Truthy,
|
truthiness: Truthiness::Truthy,
|
||||||
keyword,
|
keyword,
|
||||||
}) = find_shell_keyword(&checker.model, keywords)
|
}) = find_shell_keyword(checker.semantic_model(), keywords)
|
||||||
{
|
{
|
||||||
// S604
|
// S604
|
||||||
if checker
|
if checker
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub(crate) fn snmp_insecure_version(
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["pysnmp", "hlapi", "CommunityData"]
|
call_path.as_slice() == ["pysnmp", "hlapi", "CommunityData"]
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub(crate) fn snmp_weak_cryptography(
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["pysnmp", "hlapi", "UsmUserData"]
|
call_path.as_slice() == ["pysnmp", "hlapi", "UsmUserData"]
|
||||||
|
|
|
@ -470,7 +470,7 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, expr: &Expr) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(reason) = checker.model.resolve_call_path(func).and_then(|call_path| {
|
let Some(reason) = checker.semantic_model().resolve_call_path(func).and_then(|call_path| {
|
||||||
for module in SUSPICIOUS_MEMBERS {
|
for module in SUSPICIOUS_MEMBERS {
|
||||||
for member in module.members {
|
for member in module.members {
|
||||||
if call_path.as_slice() == *member {
|
if call_path.as_slice() == *member {
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub(crate) fn try_except_continue(
|
||||||
) {
|
) {
|
||||||
if body.len() == 1
|
if body.len() == 1
|
||||||
&& body[0].is_continue_stmt()
|
&& body[0].is_continue_stmt()
|
||||||
&& (check_typed_exception || is_untyped_exception(type_, &checker.model))
|
&& (check_typed_exception || is_untyped_exception(type_, checker.semantic_model()))
|
||||||
{
|
{
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub(crate) fn try_except_pass(
|
||||||
) {
|
) {
|
||||||
if body.len() == 1
|
if body.len() == 1
|
||||||
&& body[0].is_pass_stmt()
|
&& body[0].is_pass_stmt()
|
||||||
&& (check_typed_exception || is_untyped_exception(type_, &checker.model))
|
&& (check_typed_exception || is_untyped_exception(type_, checker.semantic_model()))
|
||||||
{
|
{
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
|
|
|
@ -38,14 +38,14 @@ pub(crate) fn unsafe_yaml_load(
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| call_path.as_slice() == ["yaml", "load"])
|
.map_or(false, |call_path| call_path.as_slice() == ["yaml", "load"])
|
||||||
{
|
{
|
||||||
let call_args = SimpleCallArgs::new(args, keywords);
|
let call_args = SimpleCallArgs::new(args, keywords);
|
||||||
if let Some(loader_arg) = call_args.argument("Loader", 1) {
|
if let Some(loader_arg) = call_args.argument("Loader", 1) {
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(loader_arg)
|
.resolve_call_path(loader_arg)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["yaml", "SafeLoader"]
|
call_path.as_slice() == ["yaml", "SafeLoader"]
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub(crate) fn blind_except(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
for exception in ["BaseException", "Exception"] {
|
for exception in ["BaseException", "Exception"] {
|
||||||
if id == exception && checker.model.is_builtin(exception) {
|
if id == exception && checker.semantic_model().is_builtin(exception) {
|
||||||
// If the exception is re-raised, don't flag an error.
|
// If the exception is re-raised, don't flag an error.
|
||||||
if body.iter().any(|stmt| {
|
if body.iter().any(|stmt| {
|
||||||
if let Stmt::Raise(ast::StmtRaise { exc, .. }) = stmt {
|
if let Stmt::Raise(ast::StmtRaise { exc, .. }) = stmt {
|
||||||
|
@ -58,7 +58,7 @@ pub(crate) fn blind_except(
|
||||||
if body.iter().any(|stmt| {
|
if body.iter().any(|stmt| {
|
||||||
if let Stmt::Expr(ast::StmtExpr { value, range: _ }) = stmt {
|
if let Stmt::Expr(ast::StmtExpr { value, range: _ }) = stmt {
|
||||||
if let Expr::Call(ast::ExprCall { func, keywords, .. }) = value.as_ref() {
|
if let Expr::Call(ast::ExprCall { func, keywords, .. }) = value.as_ref() {
|
||||||
if logging::is_logger_candidate(func, &checker.model) {
|
if logging::is_logger_candidate(func, checker.semantic_model()) {
|
||||||
if let Some(attribute) = func.as_attribute_expr() {
|
if let Some(attribute) = func.as_attribute_expr() {
|
||||||
let attr = attribute.attr.as_str();
|
let attr = attribute.attr.as_str();
|
||||||
if attr == "exception" {
|
if attr == "exception" {
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub(crate) fn abstract_base_class(
|
||||||
if bases.len() + keywords.len() != 1 {
|
if bases.len() + keywords.len() != 1 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !is_abc_class(&checker.model, bases, keywords) {
|
if !is_abc_class(checker.semantic_model(), bases, keywords) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ pub(crate) fn abstract_base_class(
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let has_abstract_decorator = is_abstract(&checker.model, decorator_list);
|
let has_abstract_decorator = is_abstract(checker.semantic_model(), decorator_list);
|
||||||
has_abstract_method |= has_abstract_decorator;
|
has_abstract_method |= has_abstract_decorator;
|
||||||
|
|
||||||
if !checker
|
if !checker
|
||||||
|
@ -121,7 +121,7 @@ pub(crate) fn abstract_base_class(
|
||||||
|
|
||||||
if !has_abstract_decorator
|
if !has_abstract_decorator
|
||||||
&& is_empty_body(body)
|
&& is_empty_body(body)
|
||||||
&& !is_overload(&checker.model, decorator_list)
|
&& !is_overload(checker.semantic_model(), decorator_list)
|
||||||
{
|
{
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
EmptyMethodWithoutAbstractDecorator {
|
EmptyMethodWithoutAbstractDecorator {
|
||||||
|
|
|
@ -66,7 +66,7 @@ pub(crate) fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items:
|
||||||
}
|
}
|
||||||
|
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(args.first().unwrap())
|
.resolve_call_path(args.first().unwrap())
|
||||||
.map_or(false, |call_path| call_path.as_slice() == ["", "Exception"])
|
.map_or(false, |call_path| call_path.as_slice() == ["", "Exception"])
|
||||||
{
|
{
|
||||||
|
@ -78,7 +78,7 @@ pub(crate) fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items:
|
||||||
{
|
{
|
||||||
AssertionKind::AssertRaises
|
AssertionKind::AssertRaises
|
||||||
} else if checker
|
} else if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["pytest", "raises"]
|
call_path.as_slice() == ["pytest", "raises"]
|
||||||
|
|
|
@ -28,7 +28,7 @@ fn is_cache_func(model: &SemanticModel, expr: &Expr) -> bool {
|
||||||
|
|
||||||
/// B019
|
/// B019
|
||||||
pub(crate) fn cached_instance_method(checker: &mut Checker, decorator_list: &[Expr]) {
|
pub(crate) fn cached_instance_method(checker: &mut Checker, decorator_list: &[Expr]) {
|
||||||
if !matches!(checker.model.scope().kind, ScopeKind::Class(_)) {
|
if !matches!(checker.semantic_model().scope().kind, ScopeKind::Class(_)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for decorator in decorator_list {
|
for decorator in decorator_list {
|
||||||
|
@ -42,7 +42,7 @@ pub(crate) fn cached_instance_method(checker: &mut Checker, decorator_list: &[Ex
|
||||||
}
|
}
|
||||||
for decorator in decorator_list {
|
for decorator in decorator_list {
|
||||||
if is_cache_func(
|
if is_cache_func(
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
match decorator {
|
match decorator {
|
||||||
Expr::Call(ast::ExprCall { func, .. }) => func,
|
Expr::Call(ast::ExprCall { func, .. }) => func,
|
||||||
_ => decorator,
|
_ => decorator,
|
||||||
|
|
|
@ -149,7 +149,8 @@ pub(crate) fn function_call_argument_default(checker: &mut Checker, arguments: &
|
||||||
.map(|target| from_qualified_name(target))
|
.map(|target| from_qualified_name(target))
|
||||||
.collect();
|
.collect();
|
||||||
let diagnostics = {
|
let diagnostics = {
|
||||||
let mut visitor = ArgumentDefaultVisitor::new(&checker.model, extend_immutable_calls);
|
let mut visitor =
|
||||||
|
ArgumentDefaultVisitor::new(checker.semantic_model(), extend_immutable_calls);
|
||||||
for expr in arguments
|
for expr in arguments
|
||||||
.defaults
|
.defaults
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -64,11 +64,10 @@ pub(crate) fn mutable_argument_default(checker: &mut Checker, arguments: &Argume
|
||||||
.zip(arguments.defaults.iter().rev()),
|
.zip(arguments.defaults.iter().rev()),
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if is_mutable_expr(&checker.model, default)
|
if is_mutable_expr(checker.semantic_model(), default)
|
||||||
&& !arg
|
&& !arg.annotation.as_ref().map_or(false, |expr| {
|
||||||
.annotation
|
is_immutable_annotation(checker.semantic_model(), expr)
|
||||||
.as_ref()
|
})
|
||||||
.map_or(false, |expr| is_immutable_annotation(&checker.model, expr))
|
|
||||||
{
|
{
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub(crate) fn no_explicit_stacklevel(
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["warnings", "warn"]
|
call_path.as_slice() == ["warnings", "warn"]
|
||||||
|
|
|
@ -342,7 +342,7 @@ pub(crate) fn reuse_of_groupby_generator(
|
||||||
};
|
};
|
||||||
// Check if the function call is `itertools.groupby`
|
// Check if the function call is `itertools.groupby`
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["itertools", "groupby"]
|
call_path.as_slice() == ["itertools", "groupby"]
|
||||||
|
|
|
@ -75,7 +75,7 @@ pub(crate) fn setattr_with_constant(
|
||||||
if let Stmt::Expr(ast::StmtExpr {
|
if let Stmt::Expr(ast::StmtExpr {
|
||||||
value: child,
|
value: child,
|
||||||
range: _,
|
range: _,
|
||||||
}) = &checker.model.stmt()
|
}) = checker.semantic_model().stmt()
|
||||||
{
|
{
|
||||||
if expr == child.as_ref() {
|
if expr == child.as_ref() {
|
||||||
let mut diagnostic = Diagnostic::new(SetAttrWithConstant, expr.range());
|
let mut diagnostic = Diagnostic::new(SetAttrWithConstant, expr.range());
|
||||||
|
|
|
@ -129,7 +129,7 @@ pub(crate) fn unused_loop_control_variable(checker: &mut Checker, target: &Expr,
|
||||||
|
|
||||||
// Avoid fixing any variables that _may_ be used, but undetectably so.
|
// Avoid fixing any variables that _may_ be used, but undetectably so.
|
||||||
let certainty = Certainty::from(!helpers::uses_magic_variable_access(body, |id| {
|
let certainty = Certainty::from(!helpers::uses_magic_variable_access(body, |id| {
|
||||||
checker.model.is_builtin(id)
|
checker.semantic_model().is_builtin(id)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Attempt to rename the variable by prepending an underscore, but avoid
|
// Attempt to rename the variable by prepending an underscore, but avoid
|
||||||
|
@ -153,11 +153,11 @@ pub(crate) fn unused_loop_control_variable(checker: &mut Checker, target: &Expr,
|
||||||
if let Some(rename) = rename {
|
if let Some(rename) = rename {
|
||||||
if certainty.into() && checker.patch(diagnostic.kind.rule()) {
|
if certainty.into() && checker.patch(diagnostic.kind.rule()) {
|
||||||
// Find the `BindingKind::LoopVar` corresponding to the name.
|
// Find the `BindingKind::LoopVar` corresponding to the name.
|
||||||
let scope = checker.model.scope();
|
let scope = checker.semantic_model().scope();
|
||||||
let binding = scope.bindings_for_name(name).find_map(|index| {
|
let binding = scope.bindings_for_name(name).find_map(|index| {
|
||||||
let binding = &checker.model.bindings[*index];
|
let binding = &checker.semantic_model().bindings[*index];
|
||||||
binding.source.and_then(|source| {
|
binding.source.and_then(|source| {
|
||||||
(Some(source) == checker.model.stmt_id).then_some(binding)
|
(Some(source) == checker.semantic_model().stmt_id).then_some(binding)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
if let Some(binding) = binding {
|
if let Some(binding) = binding {
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub(crate) fn useless_contextlib_suppress(
|
||||||
) {
|
) {
|
||||||
if args.is_empty()
|
if args.is_empty()
|
||||||
&& checker
|
&& checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["contextlib", "suppress"]
|
call_path.as_slice() == ["contextlib", "suppress"]
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub(crate) fn useless_expression(checker: &mut Checker, value: &Expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore statements that have side effects.
|
// Ignore statements that have side effects.
|
||||||
if contains_effect(value, |id| checker.model.is_builtin(id)) {
|
if contains_effect(value, |id| checker.semantic_model().is_builtin(id)) {
|
||||||
// Flag attributes as useless expressions, even if they're attached to calls or other
|
// Flag attributes as useless expressions, even if they're attached to calls or other
|
||||||
// expressions.
|
// expressions.
|
||||||
if matches!(value, Expr::Attribute(_)) {
|
if matches!(value, Expr::Attribute(_)) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub(crate) fn zip_without_explicit_strict(
|
||||||
) {
|
) {
|
||||||
if let Expr::Name(ast::ExprName { id, .. }) = func {
|
if let Expr::Name(ast::ExprName { id, .. }) = func {
|
||||||
if id == "zip"
|
if id == "zip"
|
||||||
&& checker.model.is_builtin("zip")
|
&& checker.semantic_model().is_builtin("zip")
|
||||||
&& !kwargs
|
&& !kwargs
|
||||||
.iter()
|
.iter()
|
||||||
.any(|keyword| keyword.arg.as_ref().map_or(false, |name| name == "strict"))
|
.any(|keyword| keyword.arg.as_ref().map_or(false, |name| name == "strict"))
|
||||||
|
|
|
@ -75,7 +75,7 @@ pub(crate) fn unnecessary_call_around_sorted(
|
||||||
if inner != "sorted" {
|
if inner != "sorted" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !checker.model.is_builtin(inner) || !checker.model.is_builtin(outer) {
|
if !checker.semantic_model().is_builtin(inner) || !checker.semantic_model().is_builtin(outer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub(crate) fn unnecessary_collection_call(
|
||||||
}
|
}
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin(id) {
|
if !checker.semantic_model().is_builtin(id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
|
|
|
@ -56,7 +56,7 @@ fn add_diagnostic(checker: &mut Checker, expr: &Expr) {
|
||||||
Expr::DictComp(_) => "dict",
|
Expr::DictComp(_) => "dict",
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin(id) {
|
if !checker.semantic_model().is_builtin(id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
|
|
|
@ -76,7 +76,7 @@ pub(crate) fn unnecessary_comprehension_any_all(
|
||||||
if is_async_generator(elt) {
|
if is_async_generator(elt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !checker.model.is_builtin(id) {
|
if !checker.semantic_model().is_builtin(id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut diagnostic = Diagnostic::new(UnnecessaryComprehensionAnyAll, args[0].range());
|
let mut diagnostic = Diagnostic::new(UnnecessaryComprehensionAnyAll, args[0].range());
|
||||||
|
|
|
@ -90,7 +90,7 @@ pub(crate) fn unnecessary_double_cast_or_process(
|
||||||
let Some(inner) = helpers::expr_name(func) else {
|
let Some(inner) = helpers::expr_name(func) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin(inner) || !checker.model.is_builtin(outer) {
|
if !checker.semantic_model().is_builtin(inner) || !checker.semantic_model().is_builtin(outer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub(crate) fn unnecessary_generator_list(
|
||||||
let Some(argument) = helpers::exactly_one_argument_with_matching_function("list", func, args, keywords) else {
|
let Some(argument) = helpers::exactly_one_argument_with_matching_function("list", func, args, keywords) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin("list") {
|
if !checker.semantic_model().is_builtin("list") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Expr::GeneratorExp(_) = argument {
|
if let Expr::GeneratorExp(_) = argument {
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub(crate) fn unnecessary_generator_set(
|
||||||
let Some(argument) = helpers::exactly_one_argument_with_matching_function("set", func, args, keywords) else {
|
let Some(argument) = helpers::exactly_one_argument_with_matching_function("set", func, args, keywords) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin("set") {
|
if !checker.semantic_model().is_builtin("set") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Expr::GeneratorExp(_) = argument {
|
if let Expr::GeneratorExp(_) = argument {
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub(crate) fn unnecessary_list_call(
|
||||||
let Some(argument) = helpers::first_argument_with_matching_function("list", func, args) else {
|
let Some(argument) = helpers::first_argument_with_matching_function("list", func, args) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin("list") {
|
if !checker.semantic_model().is_builtin("list") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !argument.is_list_comp_expr() {
|
if !argument.is_list_comp_expr() {
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub(crate) fn unnecessary_list_comprehension_dict(
|
||||||
let Some(argument) = helpers::exactly_one_argument_with_matching_function("dict", func, args, keywords) else {
|
let Some(argument) = helpers::exactly_one_argument_with_matching_function("dict", func, args, keywords) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin("dict") {
|
if !checker.semantic_model().is_builtin("dict") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Expr::ListComp(ast::ExprListComp { elt, .. }) = argument else {
|
let Expr::ListComp(ast::ExprListComp { elt, .. }) = argument else {
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub(crate) fn unnecessary_list_comprehension_set(
|
||||||
let Some(argument) = helpers::exactly_one_argument_with_matching_function("set", func, args, keywords) else {
|
let Some(argument) = helpers::exactly_one_argument_with_matching_function("set", func, args, keywords) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin("set") {
|
if !checker.semantic_model().is_builtin("set") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if argument.is_list_comp_expr() {
|
if argument.is_list_comp_expr() {
|
||||||
|
|
|
@ -57,7 +57,7 @@ pub(crate) fn unnecessary_literal_dict(
|
||||||
let Some(argument) = helpers::exactly_one_argument_with_matching_function("dict", func, args, keywords) else {
|
let Some(argument) = helpers::exactly_one_argument_with_matching_function("dict", func, args, keywords) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin("dict") {
|
if !checker.semantic_model().is_builtin("dict") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (kind, elts) = match argument {
|
let (kind, elts) = match argument {
|
||||||
|
|
|
@ -58,7 +58,7 @@ pub(crate) fn unnecessary_literal_set(
|
||||||
let Some(argument) = helpers::exactly_one_argument_with_matching_function("set", func, args, keywords) else {
|
let Some(argument) = helpers::exactly_one_argument_with_matching_function("set", func, args, keywords) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin("set") {
|
if !checker.semantic_model().is_builtin("set") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let kind = match argument {
|
let kind = match argument {
|
||||||
|
|
|
@ -76,7 +76,7 @@ pub(crate) fn unnecessary_literal_within_dict_call(
|
||||||
let Some(argument) = helpers::first_argument_with_matching_function("dict", func, args) else {
|
let Some(argument) = helpers::first_argument_with_matching_function("dict", func, args) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin("dict") {
|
if !checker.semantic_model().is_builtin("dict") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let argument_kind = match argument {
|
let argument_kind = match argument {
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub(crate) fn unnecessary_literal_within_list_call(
|
||||||
let Some(argument) = helpers::first_argument_with_matching_function("list", func, args) else {
|
let Some(argument) = helpers::first_argument_with_matching_function("list", func, args) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin("list") {
|
if !checker.semantic_model().is_builtin("list") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let argument_kind = match argument {
|
let argument_kind = match argument {
|
||||||
|
|
|
@ -80,7 +80,7 @@ pub(crate) fn unnecessary_literal_within_tuple_call(
|
||||||
let Some(argument) = helpers::first_argument_with_matching_function("tuple", func, args) else {
|
let Some(argument) = helpers::first_argument_with_matching_function("tuple", func, args) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker.model.is_builtin("tuple") {
|
if !checker.semantic_model().is_builtin("tuple") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let argument_kind = match argument {
|
let argument_kind = match argument {
|
||||||
|
|
|
@ -88,7 +88,7 @@ pub(crate) fn unnecessary_map(
|
||||||
};
|
};
|
||||||
match id {
|
match id {
|
||||||
"map" => {
|
"map" => {
|
||||||
if !checker.model.is_builtin(id) {
|
if !checker.semantic_model().is_builtin(id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ pub(crate) fn unnecessary_map(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"list" | "set" => {
|
"list" | "set" => {
|
||||||
if !checker.model.is_builtin(id) {
|
if !checker.semantic_model().is_builtin(id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ pub(crate) fn unnecessary_map(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"dict" => {
|
"dict" => {
|
||||||
if !checker.model.is_builtin(id) {
|
if !checker.semantic_model().is_builtin(id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ pub(crate) fn unnecessary_subscript_reversal(
|
||||||
if !(id == "set" || id == "sorted" || id == "reversed") {
|
if !(id == "set" || id == "sorted" || id == "reversed") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !checker.model.is_builtin(id) {
|
if !checker.semantic_model().is_builtin(id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Expr::Subscript(ast::ExprSubscript { slice, .. }) = first_arg else {
|
let Expr::Subscript(ast::ExprSubscript { slice, .. }) = first_arg else {
|
||||||
|
|
|
@ -125,7 +125,7 @@ pub(crate) fn call_datetime_without_tzinfo(
|
||||||
location: TextRange,
|
location: TextRange,
|
||||||
) {
|
) {
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["datetime", "datetime"]
|
call_path.as_slice() == ["datetime", "datetime"]
|
||||||
|
@ -158,7 +158,7 @@ pub(crate) fn call_datetime_without_tzinfo(
|
||||||
/// Use `datetime.datetime.now(tz=)` instead.
|
/// Use `datetime.datetime.now(tz=)` instead.
|
||||||
pub(crate) fn call_datetime_today(checker: &mut Checker, func: &Expr, location: TextRange) {
|
pub(crate) fn call_datetime_today(checker: &mut Checker, func: &Expr, location: TextRange) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["datetime", "datetime", "today"]
|
call_path.as_slice() == ["datetime", "datetime", "today"]
|
||||||
|
@ -180,7 +180,7 @@ pub(crate) fn call_datetime_today(checker: &mut Checker, func: &Expr, location:
|
||||||
/// current time in UTC is by calling `datetime.now(timezone.utc)`.
|
/// current time in UTC is by calling `datetime.now(timezone.utc)`.
|
||||||
pub(crate) fn call_datetime_utcnow(checker: &mut Checker, func: &Expr, location: TextRange) {
|
pub(crate) fn call_datetime_utcnow(checker: &mut Checker, func: &Expr, location: TextRange) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["datetime", "datetime", "utcnow"]
|
call_path.as_slice() == ["datetime", "datetime", "utcnow"]
|
||||||
|
@ -207,7 +207,7 @@ pub(crate) fn call_datetime_utcfromtimestamp(
|
||||||
location: TextRange,
|
location: TextRange,
|
||||||
) {
|
) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["datetime", "datetime", "utcfromtimestamp"]
|
call_path.as_slice() == ["datetime", "datetime", "utcfromtimestamp"]
|
||||||
|
@ -228,7 +228,7 @@ pub(crate) fn call_datetime_now_without_tzinfo(
|
||||||
location: TextRange,
|
location: TextRange,
|
||||||
) {
|
) {
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["datetime", "datetime", "now"]
|
call_path.as_slice() == ["datetime", "datetime", "now"]
|
||||||
|
@ -270,7 +270,7 @@ pub(crate) fn call_datetime_fromtimestamp(
|
||||||
location: TextRange,
|
location: TextRange,
|
||||||
) {
|
) {
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["datetime", "datetime", "fromtimestamp"]
|
call_path.as_slice() == ["datetime", "datetime", "fromtimestamp"]
|
||||||
|
@ -311,7 +311,7 @@ pub(crate) fn call_datetime_strptime_without_zone(
|
||||||
location: TextRange,
|
location: TextRange,
|
||||||
) {
|
) {
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["datetime", "datetime", "strptime"]
|
call_path.as_slice() == ["datetime", "datetime", "strptime"]
|
||||||
|
@ -332,7 +332,7 @@ pub(crate) fn call_datetime_strptime_without_zone(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let (Some(grandparent), Some(parent)) = (checker.model.expr_grandparent(), checker.model.expr_parent()) else {
|
let (Some(grandparent), Some(parent)) = (checker.semantic_model().expr_grandparent(), checker.semantic_model().expr_parent()) else {
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
CallDatetimeStrptimeWithoutZone,
|
CallDatetimeStrptimeWithoutZone,
|
||||||
location,
|
location,
|
||||||
|
@ -370,7 +370,7 @@ pub(crate) fn call_datetime_strptime_without_zone(
|
||||||
/// Use `datetime.datetime.now(tz=).date()` instead.
|
/// Use `datetime.datetime.now(tz=).date()` instead.
|
||||||
pub(crate) fn call_date_today(checker: &mut Checker, func: &Expr, location: TextRange) {
|
pub(crate) fn call_date_today(checker: &mut Checker, func: &Expr, location: TextRange) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["datetime", "date", "today"]
|
call_path.as_slice() == ["datetime", "date", "today"]
|
||||||
|
@ -390,7 +390,7 @@ pub(crate) fn call_date_today(checker: &mut Checker, func: &Expr, location: Text
|
||||||
/// Use `datetime.datetime.fromtimestamp(, tz=).date()` instead.
|
/// Use `datetime.datetime.fromtimestamp(, tz=).date()` instead.
|
||||||
pub(crate) fn call_date_fromtimestamp(checker: &mut Checker, func: &Expr, location: TextRange) {
|
pub(crate) fn call_date_fromtimestamp(checker: &mut Checker, func: &Expr, location: TextRange) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["datetime", "date", "fromtimestamp"]
|
call_path.as_slice() == ["datetime", "date", "fromtimestamp"]
|
||||||
|
|
|
@ -43,11 +43,15 @@ const DEBUGGERS: &[&[&str]] = &[
|
||||||
|
|
||||||
/// Checks for the presence of a debugger call.
|
/// Checks for the presence of a debugger call.
|
||||||
pub(crate) fn debugger_call(checker: &mut Checker, expr: &Expr, func: &Expr) {
|
pub(crate) fn debugger_call(checker: &mut Checker, expr: &Expr, func: &Expr) {
|
||||||
if let Some(target) = checker.model.resolve_call_path(func).and_then(|call_path| {
|
if let Some(target) = checker
|
||||||
|
.semantic_model()
|
||||||
|
.resolve_call_path(func)
|
||||||
|
.and_then(|call_path| {
|
||||||
DEBUGGERS
|
DEBUGGERS
|
||||||
.iter()
|
.iter()
|
||||||
.find(|target| call_path.as_slice() == **target)
|
.find(|target| call_path.as_slice() == **target)
|
||||||
}) {
|
})
|
||||||
|
{
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
Debugger {
|
Debugger {
|
||||||
using_type: DebuggerUsingType::Call(format_call_path(target)),
|
using_type: DebuggerUsingType::Call(format_call_path(target)),
|
||||||
|
|
|
@ -52,7 +52,10 @@ pub(crate) fn all_with_model_form(
|
||||||
bases: &[Expr],
|
bases: &[Expr],
|
||||||
body: &[Stmt],
|
body: &[Stmt],
|
||||||
) -> Option<Diagnostic> {
|
) -> Option<Diagnostic> {
|
||||||
if !bases.iter().any(|base| is_model_form(&checker.model, base)) {
|
if !bases
|
||||||
|
.iter()
|
||||||
|
.any(|base| is_model_form(checker.semantic_model(), base))
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
for element in body.iter() {
|
for element in body.iter() {
|
||||||
|
|
|
@ -50,7 +50,10 @@ pub(crate) fn exclude_with_model_form(
|
||||||
bases: &[Expr],
|
bases: &[Expr],
|
||||||
body: &[Stmt],
|
body: &[Stmt],
|
||||||
) -> Option<Diagnostic> {
|
) -> Option<Diagnostic> {
|
||||||
if !bases.iter().any(|base| is_model_form(&checker.model, base)) {
|
if !bases
|
||||||
|
.iter()
|
||||||
|
.any(|base| is_model_form(checker.semantic_model(), base))
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
for element in body.iter() {
|
for element in body.iter() {
|
||||||
|
|
|
@ -51,7 +51,7 @@ pub(crate) fn locals_in_render_function(
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["django", "shortcuts", "render"]
|
call_path.as_slice() == ["django", "shortcuts", "render"]
|
||||||
|
@ -61,7 +61,7 @@ pub(crate) fn locals_in_render_function(
|
||||||
}
|
}
|
||||||
|
|
||||||
let locals = if args.len() >= 3 {
|
let locals = if args.len() >= 3 {
|
||||||
if !is_locals_call(&checker.model, &args[2]) {
|
if !is_locals_call(checker.semantic_model(), &args[2]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
&args[2]
|
&args[2]
|
||||||
|
@ -69,7 +69,7 @@ pub(crate) fn locals_in_render_function(
|
||||||
.iter()
|
.iter()
|
||||||
.find(|keyword| keyword.arg.as_ref().map_or(false, |arg| arg == "context"))
|
.find(|keyword| keyword.arg.as_ref().map_or(false, |arg| arg == "context"))
|
||||||
{
|
{
|
||||||
if !is_locals_call(&checker.model, &keyword.value) {
|
if !is_locals_call(checker.semantic_model(), &keyword.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
&keyword.value
|
&keyword.value
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub(crate) fn model_without_dunder_str(
|
||||||
body: &[Stmt],
|
body: &[Stmt],
|
||||||
class_location: &Stmt,
|
class_location: &Stmt,
|
||||||
) -> Option<Diagnostic> {
|
) -> Option<Diagnostic> {
|
||||||
if !checker_applies(&checker.model, bases, body) {
|
if !checker_applies(checker.semantic_model(), bases, body) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if !has_dunder_method(body) {
|
if !has_dunder_method(body) {
|
||||||
|
|
|
@ -84,7 +84,7 @@ fn is_nullable_field<'a>(checker: &'a Checker, value: &'a Expr) -> Option<&'a st
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(valid_field_name) = helpers::get_model_field_name(&checker.model, func) else {
|
let Some(valid_field_name) = helpers::get_model_field_name(checker.semantic_model(), func) else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -145,13 +145,13 @@ pub(crate) fn unordered_body_content_in_model(
|
||||||
) {
|
) {
|
||||||
if !bases
|
if !bases
|
||||||
.iter()
|
.iter()
|
||||||
.any(|base| helpers::is_model(&checker.model, base))
|
.any(|base| helpers::is_model(checker.semantic_model(), base))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut elements_type_found = Vec::new();
|
let mut elements_type_found = Vec::new();
|
||||||
for element in body.iter() {
|
for element in body.iter() {
|
||||||
let Some(current_element_type) = get_element_type(&checker.model, element) else {
|
let Some(current_element_type) = get_element_type(checker.semantic_model(), element) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let Some(&element_type) = elements_type_found
|
let Some(&element_type) = elements_type_found
|
||||||
|
|
|
@ -233,7 +233,7 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr
|
||||||
if string.len() > checker.settings.flake8_errmsg.max_string_length {
|
if string.len() > checker.settings.flake8_errmsg.max_string_length {
|
||||||
let indentation = whitespace::indentation(checker.locator, stmt)
|
let indentation = whitespace::indentation(checker.locator, stmt)
|
||||||
.and_then(|indentation| {
|
.and_then(|indentation| {
|
||||||
if checker.model.find_binding("msg").is_none() {
|
if checker.semantic_model().find_binding("msg").is_none() {
|
||||||
Some(indentation)
|
Some(indentation)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -261,7 +261,7 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr
|
||||||
if checker.settings.rules.enabled(Rule::FStringInException) {
|
if checker.settings.rules.enabled(Rule::FStringInException) {
|
||||||
let indentation = whitespace::indentation(checker.locator, stmt).and_then(
|
let indentation = whitespace::indentation(checker.locator, stmt).and_then(
|
||||||
|indentation| {
|
|indentation| {
|
||||||
if checker.model.find_binding("msg").is_none() {
|
if checker.semantic_model().find_binding("msg").is_none() {
|
||||||
Some(indentation)
|
Some(indentation)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -292,7 +292,7 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr
|
||||||
if attr == "format" && value.is_constant_expr() {
|
if attr == "format" && value.is_constant_expr() {
|
||||||
let indentation = whitespace::indentation(checker.locator, stmt)
|
let indentation = whitespace::indentation(checker.locator, stmt)
|
||||||
.and_then(|indentation| {
|
.and_then(|indentation| {
|
||||||
if checker.model.find_binding("msg").is_none() {
|
if checker.semantic_model().find_binding("msg").is_none() {
|
||||||
Some(indentation)
|
Some(indentation)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -67,11 +67,14 @@ impl Violation for MissingFutureAnnotationsImport {
|
||||||
|
|
||||||
/// FA100
|
/// FA100
|
||||||
pub(crate) fn missing_future_annotations(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn missing_future_annotations(checker: &mut Checker, expr: &Expr) {
|
||||||
if let Some(binding) = checker.model.resolve_call_path(expr) {
|
let name = checker
|
||||||
|
.semantic_model()
|
||||||
|
.resolve_call_path(expr)
|
||||||
|
.map(|binding| format_call_path(&binding));
|
||||||
|
|
||||||
|
if let Some(name) = name {
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
MissingFutureAnnotationsImport {
|
MissingFutureAnnotationsImport { name },
|
||||||
name: format_call_path(&binding),
|
|
||||||
},
|
|
||||||
expr.range(),
|
expr.range(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) {
|
||||||
}
|
}
|
||||||
Expr::Call(ast::ExprCall { func, keywords, .. }) => {
|
Expr::Call(ast::ExprCall { func, keywords, .. }) => {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| call_path.as_slice() == ["", "dict"])
|
.map_or(false, |call_path| call_path.as_slice() == ["", "dict"])
|
||||||
{
|
{
|
||||||
|
@ -151,7 +151,7 @@ pub(crate) fn logging_call(
|
||||||
args: &[Expr],
|
args: &[Expr],
|
||||||
keywords: &[Keyword],
|
keywords: &[Keyword],
|
||||||
) {
|
) {
|
||||||
if !logging::is_logger_candidate(func, &checker.model) {
|
if !logging::is_logger_candidate(func, checker.semantic_model()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ pub(crate) fn logging_call(
|
||||||
.rules
|
.rules
|
||||||
.enabled(Rule::LoggingRedundantExcInfo)
|
.enabled(Rule::LoggingRedundantExcInfo)
|
||||||
{
|
{
|
||||||
if !checker.model.in_exception_handler() {
|
if !checker.semantic_model().in_exception_handler() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(exc_info) = find_keyword(keywords, "exc_info") {
|
if let Some(exc_info) = find_keyword(keywords, "exc_info") {
|
||||||
|
@ -212,7 +212,7 @@ pub(crate) fn logging_call(
|
||||||
})
|
})
|
||||||
) || if let Expr::Call(ast::ExprCall { func, .. }) = &exc_info.value {
|
) || if let Expr::Call(ast::ExprCall { func, .. }) = &exc_info.value {
|
||||||
checker
|
checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["sys", "exc_info"]
|
call_path.as_slice() == ["sys", "exc_info"]
|
||||||
|
|
|
@ -417,7 +417,7 @@ pub(crate) fn non_unique_enums<'a, 'b>(
|
||||||
|
|
||||||
if !bases.iter().any(|expr| {
|
if !bases.iter().any(|expr| {
|
||||||
checker
|
checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(expr)
|
.resolve_call_path(expr)
|
||||||
.map_or(false, |call_path| call_path.as_slice() == ["enum", "Enum"])
|
.map_or(false, |call_path| call_path.as_slice() == ["enum", "Enum"])
|
||||||
}) {
|
}) {
|
||||||
|
@ -432,7 +432,7 @@ pub(crate) fn non_unique_enums<'a, 'b>(
|
||||||
|
|
||||||
if let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() {
|
if let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| call_path.as_slice() == ["enum", "auto"])
|
.map_or(false, |call_path| call_path.as_slice() == ["enum", "auto"])
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,7 +78,7 @@ impl Violation for PPrint {
|
||||||
/// T201, T203
|
/// T201, T203
|
||||||
pub(crate) fn print_call(checker: &mut Checker, func: &Expr, keywords: &[Keyword]) {
|
pub(crate) fn print_call(checker: &mut Checker, func: &Expr, keywords: &[Keyword]) {
|
||||||
let diagnostic = {
|
let diagnostic = {
|
||||||
let call_path = checker.model.resolve_call_path(func);
|
let call_path = checker.semantic_model().resolve_call_path(func);
|
||||||
if call_path
|
if call_path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(false, |call_path| *call_path.as_slice() == ["", "print"])
|
.map_or(false, |call_path| *call_path.as_slice() == ["", "print"])
|
||||||
|
@ -91,7 +91,7 @@ pub(crate) fn print_call(checker: &mut Checker, func: &Expr, keywords: &[Keyword
|
||||||
{
|
{
|
||||||
if !is_const_none(&keyword.value) {
|
if !is_const_none(&keyword.value) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(&keyword.value)
|
.resolve_call_path(&keyword.value)
|
||||||
.map_or(true, |call_path| {
|
.map_or(true, |call_path| {
|
||||||
call_path.as_slice() != ["sys", "stdout"]
|
call_path.as_slice() != ["sys", "stdout"]
|
||||||
|
|
|
@ -69,7 +69,7 @@ pub(crate) fn bad_version_info_comparison(
|
||||||
};
|
};
|
||||||
|
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(left)
|
.resolve_call_path(left)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["sys", "version_info"]
|
call_path.as_slice() == ["sys", "version_info"]
|
||||||
|
|
|
@ -70,12 +70,12 @@ pub(crate) fn prefix_type_params(checker: &mut Checker, value: &Expr, targets: &
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Expr::Call(ast::ExprCall { func, .. }) = value {
|
if let Expr::Call(ast::ExprCall { func, .. }) = value {
|
||||||
let Some(kind) = checker.model.resolve_call_path(func).and_then(|call_path| {
|
let Some(kind) = checker.semantic_model().resolve_call_path(func).and_then(|call_path| {
|
||||||
if checker.model.match_typing_call_path(&call_path, "ParamSpec") {
|
if checker.semantic_model().match_typing_call_path(&call_path, "ParamSpec") {
|
||||||
Some(VarKind::ParamSpec)
|
Some(VarKind::ParamSpec)
|
||||||
} else if checker.model.match_typing_call_path(&call_path, "TypeVar") {
|
} else if checker.semantic_model().match_typing_call_path(&call_path, "TypeVar") {
|
||||||
Some(VarKind::TypeVar)
|
Some(VarKind::TypeVar)
|
||||||
} else if checker.model.match_typing_call_path(&call_path, "TypeVarTuple") {
|
} else if checker.semantic_model().match_typing_call_path(&call_path, "TypeVarTuple") {
|
||||||
Some(VarKind::TypeVarTuple)
|
Some(VarKind::TypeVarTuple)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -330,7 +330,7 @@ pub(crate) fn typed_argument_simple_defaults(checker: &mut Checker, args: &Argum
|
||||||
default,
|
default,
|
||||||
true,
|
true,
|
||||||
checker.locator,
|
checker.locator,
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
) {
|
) {
|
||||||
let mut diagnostic =
|
let mut diagnostic =
|
||||||
Diagnostic::new(TypedArgumentDefaultInStub, default.range());
|
Diagnostic::new(TypedArgumentDefaultInStub, default.range());
|
||||||
|
@ -362,7 +362,7 @@ pub(crate) fn typed_argument_simple_defaults(checker: &mut Checker, args: &Argum
|
||||||
default,
|
default,
|
||||||
true,
|
true,
|
||||||
checker.locator,
|
checker.locator,
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
) {
|
) {
|
||||||
let mut diagnostic =
|
let mut diagnostic =
|
||||||
Diagnostic::new(TypedArgumentDefaultInStub, default.range());
|
Diagnostic::new(TypedArgumentDefaultInStub, default.range());
|
||||||
|
@ -397,7 +397,7 @@ pub(crate) fn argument_simple_defaults(checker: &mut Checker, args: &Arguments)
|
||||||
default,
|
default,
|
||||||
true,
|
true,
|
||||||
checker.locator,
|
checker.locator,
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
) {
|
) {
|
||||||
let mut diagnostic =
|
let mut diagnostic =
|
||||||
Diagnostic::new(ArgumentDefaultInStub, default.range());
|
Diagnostic::new(ArgumentDefaultInStub, default.range());
|
||||||
|
@ -429,7 +429,7 @@ pub(crate) fn argument_simple_defaults(checker: &mut Checker, args: &Arguments)
|
||||||
default,
|
default,
|
||||||
true,
|
true,
|
||||||
checker.locator,
|
checker.locator,
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
) {
|
) {
|
||||||
let mut diagnostic =
|
let mut diagnostic =
|
||||||
Diagnostic::new(ArgumentDefaultInStub, default.range());
|
Diagnostic::new(ArgumentDefaultInStub, default.range());
|
||||||
|
@ -459,16 +459,21 @@ pub(crate) fn assignment_default_in_stub(checker: &mut Checker, targets: &[Expr]
|
||||||
if !target.is_name_expr() {
|
if !target.is_name_expr() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_special_assignment(&checker.model, target) {
|
if is_special_assignment(checker.semantic_model(), target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_type_var_like_call(&checker.model, value) {
|
if is_type_var_like_call(checker.semantic_model(), value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_valid_default_value_without_annotation(value) {
|
if is_valid_default_value_without_annotation(value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_valid_default_value_with_annotation(value, true, checker.locator, &checker.model) {
|
if is_valid_default_value_with_annotation(
|
||||||
|
value,
|
||||||
|
true,
|
||||||
|
checker.locator,
|
||||||
|
checker.semantic_model(),
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,16 +495,24 @@ pub(crate) fn annotated_assignment_default_in_stub(
|
||||||
value: &Expr,
|
value: &Expr,
|
||||||
annotation: &Expr,
|
annotation: &Expr,
|
||||||
) {
|
) {
|
||||||
if checker.model.match_typing_expr(annotation, "TypeAlias") {
|
if checker
|
||||||
|
.semantic_model()
|
||||||
|
.match_typing_expr(annotation, "TypeAlias")
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_special_assignment(&checker.model, target) {
|
if is_special_assignment(checker.semantic_model(), target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_type_var_like_call(&checker.model, value) {
|
if is_type_var_like_call(checker.semantic_model(), value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_valid_default_value_with_annotation(value, true, checker.locator, &checker.model) {
|
if is_valid_default_value_with_annotation(
|
||||||
|
value,
|
||||||
|
true,
|
||||||
|
checker.locator,
|
||||||
|
checker.semantic_model(),
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,21 +540,26 @@ pub(crate) fn unannotated_assignment_in_stub(
|
||||||
let Expr::Name(ast::ExprName { id, .. }) = target else {
|
let Expr::Name(ast::ExprName { id, .. }) = target else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if is_special_assignment(&checker.model, target) {
|
if is_special_assignment(checker.semantic_model(), target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_type_var_like_call(&checker.model, value) {
|
if is_type_var_like_call(checker.semantic_model(), value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_valid_default_value_without_annotation(value) {
|
if is_valid_default_value_without_annotation(value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !is_valid_default_value_with_annotation(value, true, checker.locator, &checker.model) {
|
if !is_valid_default_value_with_annotation(
|
||||||
|
value,
|
||||||
|
true,
|
||||||
|
checker.locator,
|
||||||
|
checker.semantic_model(),
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ScopeKind::Class(ClassDef { bases, .. }) = &checker.model.scope().kind {
|
if let ScopeKind::Class(ClassDef { bases, .. }) = checker.semantic_model().scope().kind {
|
||||||
if is_enum(&checker.model, bases) {
|
if is_enum(checker.semantic_model(), bases) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ pub(crate) fn unrecognized_platform(
|
||||||
let diagnostic_unrecognized_platform_check =
|
let diagnostic_unrecognized_platform_check =
|
||||||
Diagnostic::new(UnrecognizedPlatformCheck, expr.range());
|
Diagnostic::new(UnrecognizedPlatformCheck, expr.range());
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(left)
|
.resolve_call_path(left)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["sys", "platform"]
|
call_path.as_slice() == ["sys", "platform"]
|
||||||
|
|
|
@ -185,9 +185,9 @@ pub(crate) fn unittest_assertion(
|
||||||
if let Ok(unittest_assert) = UnittestAssert::try_from(attr.as_str()) {
|
if let Ok(unittest_assert) = UnittestAssert::try_from(attr.as_str()) {
|
||||||
// We're converting an expression to a statement, so avoid applying the fix if
|
// We're converting an expression to a statement, so avoid applying the fix if
|
||||||
// the assertion is part of a larger expression.
|
// the assertion is part of a larger expression.
|
||||||
let fixable = checker.model.stmt().is_expr_stmt()
|
let fixable = checker.semantic_model().stmt().is_expr_stmt()
|
||||||
&& checker.model.expr_parent().is_none()
|
&& checker.semantic_model().expr_parent().is_none()
|
||||||
&& !checker.model.scope().kind.is_lambda()
|
&& !checker.semantic_model().scope().kind.is_lambda()
|
||||||
&& !has_comments_in(expr.range(), checker.locator);
|
&& !has_comments_in(expr.range(), checker.locator);
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
PytestUnittestAssertion {
|
PytestUnittestAssertion {
|
||||||
|
@ -215,7 +215,7 @@ pub(crate) fn unittest_assertion(
|
||||||
|
|
||||||
/// PT015
|
/// PT015
|
||||||
pub(crate) fn assert_falsy(checker: &mut Checker, stmt: &Stmt, test: &Expr) {
|
pub(crate) fn assert_falsy(checker: &mut Checker, stmt: &Stmt, test: &Expr) {
|
||||||
if Truthiness::from_expr(test, |id| checker.model.is_builtin(id)).is_falsey() {
|
if Truthiness::from_expr(test, |id| checker.semantic_model().is_builtin(id)).is_falsey() {
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(PytestAssertAlwaysFalse, stmt.range()));
|
.push(Diagnostic::new(PytestAssertAlwaysFalse, stmt.range()));
|
||||||
|
|
|
@ -19,7 +19,7 @@ impl Violation for PytestFailWithoutMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fail_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: &[Keyword]) {
|
pub(crate) fn fail_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: &[Keyword]) {
|
||||||
if is_pytest_fail(&checker.model, func) {
|
if is_pytest_fail(checker.semantic_model(), func) {
|
||||||
let call_args = SimpleCallArgs::new(args, keywords);
|
let call_args = SimpleCallArgs::new(args, keywords);
|
||||||
let msg = call_args.argument("msg", 0);
|
let msg = call_args.argument("msg", 0);
|
||||||
|
|
||||||
|
|
|
@ -457,7 +457,7 @@ fn check_test_function_args(checker: &mut Checker, args: &Arguments) {
|
||||||
|
|
||||||
/// PT020
|
/// PT020
|
||||||
fn check_fixture_decorator_name(checker: &mut Checker, decorator: &Expr) {
|
fn check_fixture_decorator_name(checker: &mut Checker, decorator: &Expr) {
|
||||||
if is_pytest_yield_fixture(&checker.model, decorator) {
|
if is_pytest_yield_fixture(checker.semantic_model(), decorator) {
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
PytestDeprecatedYieldFixture,
|
PytestDeprecatedYieldFixture,
|
||||||
decorator.range(),
|
decorator.range(),
|
||||||
|
@ -533,7 +533,7 @@ pub(crate) fn fixture(
|
||||||
decorators: &[Expr],
|
decorators: &[Expr],
|
||||||
body: &[Stmt],
|
body: &[Stmt],
|
||||||
) {
|
) {
|
||||||
let decorator = get_fixture_decorator(&checker.model, decorators);
|
let decorator = get_fixture_decorator(checker.semantic_model(), decorators);
|
||||||
if let Some(decorator) = decorator {
|
if let Some(decorator) = decorator {
|
||||||
if checker
|
if checker
|
||||||
.settings
|
.settings
|
||||||
|
@ -572,7 +572,7 @@ pub(crate) fn fixture(
|
||||||
.settings
|
.settings
|
||||||
.rules
|
.rules
|
||||||
.enabled(Rule::PytestUselessYieldFixture))
|
.enabled(Rule::PytestUselessYieldFixture))
|
||||||
&& !is_abstract(&checker.model, decorators)
|
&& !is_abstract(checker.semantic_model(), decorators)
|
||||||
{
|
{
|
||||||
check_fixture_returns(checker, stmt, name, body);
|
check_fixture_returns(checker, stmt, name, body);
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,7 +419,7 @@ fn handle_value_rows(
|
||||||
|
|
||||||
pub(crate) fn parametrize(checker: &mut Checker, decorators: &[Expr]) {
|
pub(crate) fn parametrize(checker: &mut Checker, decorators: &[Expr]) {
|
||||||
for decorator in decorators {
|
for decorator in decorators {
|
||||||
if is_pytest_parametrize(&checker.model, decorator) {
|
if is_pytest_parametrize(checker.semantic_model(), decorator) {
|
||||||
if let Expr::Call(ast::ExprCall { args, .. }) = decorator {
|
if let Expr::Call(ast::ExprCall { args, .. }) = decorator {
|
||||||
if checker
|
if checker
|
||||||
.settings
|
.settings
|
||||||
|
|
|
@ -64,7 +64,7 @@ const fn is_non_trivial_with_body(body: &[Stmt]) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn raises_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: &[Keyword]) {
|
pub(crate) fn raises_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: &[Keyword]) {
|
||||||
if is_pytest_raises(func, &checker.model) {
|
if is_pytest_raises(func, checker.semantic_model()) {
|
||||||
if checker
|
if checker
|
||||||
.settings
|
.settings
|
||||||
.rules
|
.rules
|
||||||
|
@ -104,7 +104,7 @@ pub(crate) fn complex_raises(
|
||||||
let mut is_too_complex = false;
|
let mut is_too_complex = false;
|
||||||
|
|
||||||
let raises_called = items.iter().any(|item| match &item.context_expr {
|
let raises_called = items.iter().any(|item| match &item.context_expr {
|
||||||
Expr::Call(ast::ExprCall { func, .. }) => is_pytest_raises(func, &checker.model),
|
Expr::Call(ast::ExprCall { func, .. }) => is_pytest_raises(func, checker.semantic_model()),
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ pub(crate) fn complex_raises(
|
||||||
/// PT011
|
/// PT011
|
||||||
fn exception_needs_match(checker: &mut Checker, exception: &Expr) {
|
fn exception_needs_match(checker: &mut Checker, exception: &Expr) {
|
||||||
if let Some(call_path) = checker
|
if let Some(call_path) = checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(exception)
|
.resolve_call_path(exception)
|
||||||
.and_then(|call_path| {
|
.and_then(|call_path| {
|
||||||
let is_broad_exception = checker
|
let is_broad_exception = checker
|
||||||
|
|
|
@ -484,7 +484,7 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) {
|
||||||
if matches!(
|
if matches!(
|
||||||
value.as_ref(),
|
value.as_ref(),
|
||||||
Expr::Call(ast::ExprCall { func, .. })
|
Expr::Call(ast::ExprCall { func, .. })
|
||||||
if is_noreturn_func(&checker.model, func)
|
if is_noreturn_func(checker.semantic_model(), func)
|
||||||
) => {}
|
) => {}
|
||||||
_ => {
|
_ => {
|
||||||
let mut diagnostic = Diagnostic::new(ImplicitReturn, stmt.range());
|
let mut diagnostic = Diagnostic::new(ImplicitReturn, stmt.range());
|
||||||
|
|
|
@ -94,7 +94,7 @@ pub(crate) fn private_member_access(checker: &mut Checker, expr: &Expr) {
|
||||||
|
|
||||||
// Ignore accesses on class members from _within_ the class.
|
// Ignore accesses on class members from _within_ the class.
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.scopes
|
.scopes
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
|
@ -104,14 +104,14 @@ pub(crate) fn private_member_access(checker: &mut Checker, expr: &Expr) {
|
||||||
})
|
})
|
||||||
.map_or(false, |class_def| {
|
.map_or(false, |class_def| {
|
||||||
if call_path.as_slice() == [class_def.name] {
|
if call_path.as_slice() == [class_def.name] {
|
||||||
checker.model.find_binding(class_def.name).map_or(
|
checker
|
||||||
false,
|
.semantic_model()
|
||||||
|binding| {
|
.find_binding(class_def.name)
|
||||||
|
.map_or(false, |binding| {
|
||||||
// TODO(charlie): Could the name ever be bound to a
|
// TODO(charlie): Could the name ever be bound to a
|
||||||
// _different_ class here?
|
// _different_ class here?
|
||||||
binding.kind.is_class_definition()
|
binding.kind.is_class_definition()
|
||||||
},
|
})
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,7 +271,7 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
|
||||||
if func_name != "isinstance" {
|
if func_name != "isinstance" {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if !checker.model.is_builtin("isinstance") {
|
if !checker.semantic_model().is_builtin("isinstance") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
|
||||||
} else {
|
} else {
|
||||||
unreachable!("Indices should only contain `isinstance` calls")
|
unreachable!("Indices should only contain `isinstance` calls")
|
||||||
};
|
};
|
||||||
let fixable = !contains_effect(target, |id| checker.model.is_builtin(id));
|
let fixable = !contains_effect(target, |id| checker.semantic_model().is_builtin(id));
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
DuplicateIsinstanceCall {
|
DuplicateIsinstanceCall {
|
||||||
name: if let Expr::Name(ast::ExprName { id, .. }) = target {
|
name: if let Expr::Name(ast::ExprName { id, .. }) = target {
|
||||||
|
@ -425,7 +425,7 @@ pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
|
||||||
// Avoid rewriting (e.g.) `a == "foo" or a == f()`.
|
// Avoid rewriting (e.g.) `a == "foo" or a == f()`.
|
||||||
if comparators
|
if comparators
|
||||||
.iter()
|
.iter()
|
||||||
.any(|expr| contains_effect(expr, |id| checker.model.is_builtin(id)))
|
.any(|expr| contains_effect(expr, |id| checker.semantic_model().is_builtin(id)))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -516,7 +516,7 @@ pub(crate) fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if contains_effect(expr, |id| checker.model.is_builtin(id)) {
|
if contains_effect(expr, |id| checker.semantic_model().is_builtin(id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +571,7 @@ pub(crate) fn expr_or_not_expr(checker: &mut Checker, expr: &Expr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if contains_effect(expr, |id| checker.model.is_builtin(id)) {
|
if contains_effect(expr, |id| checker.semantic_model().is_builtin(id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,14 +640,15 @@ fn is_short_circuit(
|
||||||
|
|
||||||
for (index, (value, next_value)) in values.iter().tuple_windows().enumerate() {
|
for (index, (value, next_value)) in values.iter().tuple_windows().enumerate() {
|
||||||
// Keep track of the location of the furthest-right, truthy or falsey expression.
|
// Keep track of the location of the furthest-right, truthy or falsey expression.
|
||||||
let value_truthiness = Truthiness::from_expr(value, |id| checker.model.is_builtin(id));
|
let value_truthiness =
|
||||||
|
Truthiness::from_expr(value, |id| checker.semantic_model().is_builtin(id));
|
||||||
let next_value_truthiness =
|
let next_value_truthiness =
|
||||||
Truthiness::from_expr(next_value, |id| checker.model.is_builtin(id));
|
Truthiness::from_expr(next_value, |id| checker.semantic_model().is_builtin(id));
|
||||||
|
|
||||||
// Keep track of the location of the furthest-right, non-effectful expression.
|
// Keep track of the location of the furthest-right, non-effectful expression.
|
||||||
if value_truthiness.is_unknown()
|
if value_truthiness.is_unknown()
|
||||||
&& (!checker.model.in_boolean_test()
|
&& (!checker.semantic_model().in_boolean_test()
|
||||||
|| contains_effect(value, |id| checker.model.is_builtin(id)))
|
|| contains_effect(value, |id| checker.semantic_model().is_builtin(id)))
|
||||||
{
|
{
|
||||||
location = next_value.start();
|
location = next_value.start();
|
||||||
continue;
|
continue;
|
||||||
|
@ -667,7 +668,7 @@ fn is_short_circuit(
|
||||||
value,
|
value,
|
||||||
TextRange::new(location, expr.end()),
|
TextRange::new(location, expr.end()),
|
||||||
short_circuit_truthiness,
|
short_circuit_truthiness,
|
||||||
checker.model.in_boolean_test(),
|
checker.semantic_model().in_boolean_test(),
|
||||||
checker,
|
checker,
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
|
@ -685,7 +686,7 @@ fn is_short_circuit(
|
||||||
next_value,
|
next_value,
|
||||||
TextRange::new(location, expr.end()),
|
TextRange::new(location, expr.end()),
|
||||||
short_circuit_truthiness,
|
short_circuit_truthiness,
|
||||||
checker.model.in_boolean_test(),
|
checker.semantic_model().in_boolean_test(),
|
||||||
checker,
|
checker,
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -87,7 +87,7 @@ pub(crate) fn use_capital_environment_variables(checker: &mut Checker, expr: &Ex
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !checker
|
if !checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| {
|
.map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["os", "environ", "get"]
|
call_path.as_slice() == ["os", "environ", "get"]
|
||||||
|
|
|
@ -351,7 +351,7 @@ pub(crate) fn needless_bool(checker: &mut Checker, stmt: &Stmt) {
|
||||||
let fixable = matches!(if_return, Bool::True)
|
let fixable = matches!(if_return, Bool::True)
|
||||||
&& matches!(else_return, Bool::False)
|
&& matches!(else_return, Bool::False)
|
||||||
&& !has_comments(stmt, checker.locator)
|
&& !has_comments(stmt, checker.locator)
|
||||||
&& (test.is_compare_expr() || checker.model.is_builtin("bool"));
|
&& (test.is_compare_expr() || checker.semantic_model().is_builtin("bool"));
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(NeedlessBool { condition }, stmt.range());
|
let mut diagnostic = Diagnostic::new(NeedlessBool { condition }, stmt.range());
|
||||||
if fixable && checker.patch(diagnostic.kind.rule()) {
|
if fixable && checker.patch(diagnostic.kind.rule()) {
|
||||||
|
@ -447,13 +447,13 @@ pub(crate) fn use_ternary_operator(checker: &mut Checker, stmt: &Stmt, parent: O
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid suggesting ternary for `if sys.version_info >= ...`-style checks.
|
// Avoid suggesting ternary for `if sys.version_info >= ...`-style checks.
|
||||||
if contains_call_path(&checker.model, test, &["sys", "version_info"]) {
|
if contains_call_path(checker.semantic_model(), test, &["sys", "version_info"]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid suggesting ternary for `if sys.platform.startswith("...")`-style
|
// Avoid suggesting ternary for `if sys.platform.startswith("...")`-style
|
||||||
// checks.
|
// checks.
|
||||||
if contains_call_path(&checker.model, test, &["sys", "platform"]) {
|
if contains_call_path(checker.semantic_model(), test, &["sys", "platform"]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,7 +648,7 @@ pub(crate) fn manual_dict_lookup(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if value.as_ref().map_or(false, |value| {
|
if value.as_ref().map_or(false, |value| {
|
||||||
contains_effect(value, |id| checker.model.is_builtin(id))
|
contains_effect(value, |id| checker.semantic_model().is_builtin(id))
|
||||||
}) {
|
}) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -721,7 +721,7 @@ pub(crate) fn manual_dict_lookup(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if value.as_ref().map_or(false, |value| {
|
if value.as_ref().map_or(false, |value| {
|
||||||
contains_effect(value, |id| checker.model.is_builtin(id))
|
contains_effect(value, |id| checker.semantic_model().is_builtin(id))
|
||||||
}) {
|
}) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -804,7 +804,7 @@ pub(crate) fn use_dict_get_with_default(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the default value is not "complex".
|
// Check that the default value is not "complex".
|
||||||
if contains_effect(default_value, |id| checker.model.is_builtin(id)) {
|
if contains_effect(default_value, |id| checker.semantic_model().is_builtin(id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ pub(crate) fn explicit_true_false_in_ifexpr(
|
||||||
checker.generator().expr(&test.clone()),
|
checker.generator().expr(&test.clone()),
|
||||||
expr.range(),
|
expr.range(),
|
||||||
)));
|
)));
|
||||||
} else if checker.model.is_builtin("bool") {
|
} else if checker.semantic_model().is_builtin("bool") {
|
||||||
let node = ast::ExprName {
|
let node = ast::ExprName {
|
||||||
id: "bool".into(),
|
id: "bool".into(),
|
||||||
ctx: ExprContext::Load,
|
ctx: ExprContext::Load,
|
||||||
|
|
|
@ -93,12 +93,12 @@ pub(crate) fn negation_with_equal_op(
|
||||||
if !matches!(&ops[..], [Cmpop::Eq]) {
|
if !matches!(&ops[..], [Cmpop::Eq]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_exception_check(checker.model.stmt()) {
|
if is_exception_check(checker.semantic_model().stmt()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid flagging issues in dunder implementations.
|
// Avoid flagging issues in dunder implementations.
|
||||||
if let ScopeKind::Function(def) = &checker.model.scope().kind {
|
if let ScopeKind::Function(def) = &checker.semantic_model().scope().kind {
|
||||||
if DUNDER_METHODS.contains(&def.name) {
|
if DUNDER_METHODS.contains(&def.name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -143,12 +143,12 @@ pub(crate) fn negation_with_not_equal_op(
|
||||||
if !matches!(&ops[..], [Cmpop::NotEq]) {
|
if !matches!(&ops[..], [Cmpop::NotEq]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_exception_check(checker.model.stmt()) {
|
if is_exception_check(checker.semantic_model().stmt()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid flagging issues in dunder implementations.
|
// Avoid flagging issues in dunder implementations.
|
||||||
if let ScopeKind::Function(def) = &checker.model.scope().kind {
|
if let ScopeKind::Function(def) = &checker.semantic_model().scope().kind {
|
||||||
if DUNDER_METHODS.contains(&def.name) {
|
if DUNDER_METHODS.contains(&def.name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -196,13 +196,13 @@ pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: Unaryop, o
|
||||||
expr.range(),
|
expr.range(),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if checker.model.in_boolean_test() {
|
if checker.semantic_model().in_boolean_test() {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
diagnostic.set_fix(Fix::unspecified(Edit::range_replacement(
|
diagnostic.set_fix(Fix::unspecified(Edit::range_replacement(
|
||||||
checker.generator().expr(operand),
|
checker.generator().expr(operand),
|
||||||
expr.range(),
|
expr.range(),
|
||||||
)));
|
)));
|
||||||
} else if checker.model.is_builtin("bool") {
|
} else if checker.semantic_model().is_builtin("bool") {
|
||||||
let node = ast::ExprName {
|
let node = ast::ExprName {
|
||||||
id: "bool".into(),
|
id: "bool".into(),
|
||||||
ctx: ExprContext::Load,
|
ctx: ExprContext::Load,
|
||||||
|
|
|
@ -108,23 +108,23 @@ fn match_exit_stack(model: &SemanticModel) -> bool {
|
||||||
/// SIM115
|
/// SIM115
|
||||||
pub(crate) fn open_file_with_context_handler(checker: &mut Checker, func: &Expr) {
|
pub(crate) fn open_file_with_context_handler(checker: &mut Checker, func: &Expr) {
|
||||||
if checker
|
if checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| call_path.as_slice() == ["", "open"])
|
.map_or(false, |call_path| call_path.as_slice() == ["", "open"])
|
||||||
{
|
{
|
||||||
if checker.model.is_builtin("open") {
|
if checker.semantic_model().is_builtin("open") {
|
||||||
// Ex) `with open("foo.txt") as f: ...`
|
// Ex) `with open("foo.txt") as f: ...`
|
||||||
if matches!(checker.model.stmt(), Stmt::With(_)) {
|
if matches!(checker.semantic_model().stmt(), Stmt::With(_)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ex) `with contextlib.ExitStack() as exit_stack: ...`
|
// Ex) `with contextlib.ExitStack() as exit_stack: ...`
|
||||||
if match_exit_stack(&checker.model) {
|
if match_exit_stack(checker.semantic_model()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ex) `with contextlib.AsyncExitStack() as exit_stack: ...`
|
// Ex) `with contextlib.AsyncExitStack() as exit_stack: ...`
|
||||||
if match_async_exit_stack(&checker.model) {
|
if match_async_exit_stack(checker.semantic_model()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,7 +237,9 @@ pub(crate) fn convert_for_loop_to_any_all(
|
||||||
},
|
},
|
||||||
TextRange::new(stmt.start(), loop_info.terminal),
|
TextRange::new(stmt.start(), loop_info.terminal),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule()) && checker.model.is_builtin("any") {
|
if checker.patch(diagnostic.kind.rule())
|
||||||
|
&& checker.semantic_model().is_builtin("any")
|
||||||
|
{
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
diagnostic.set_fix(Fix::unspecified(Edit::replacement(
|
diagnostic.set_fix(Fix::unspecified(Edit::replacement(
|
||||||
contents,
|
contents,
|
||||||
|
@ -327,7 +329,9 @@ pub(crate) fn convert_for_loop_to_any_all(
|
||||||
},
|
},
|
||||||
TextRange::new(stmt.start(), loop_info.terminal),
|
TextRange::new(stmt.start(), loop_info.terminal),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule()) && checker.model.is_builtin("all") {
|
if checker.patch(diagnostic.kind.rule())
|
||||||
|
&& checker.semantic_model().is_builtin("all")
|
||||||
|
{
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
diagnostic.set_fix(Fix::unspecified(Edit::replacement(
|
diagnostic.set_fix(Fix::unspecified(Edit::replacement(
|
||||||
contents,
|
contents,
|
||||||
|
|
|
@ -93,7 +93,7 @@ pub(crate) fn suppressible_exception(
|
||||||
"contextlib",
|
"contextlib",
|
||||||
"suppress",
|
"suppress",
|
||||||
stmt.start(),
|
stmt.start(),
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
&checker.importer,
|
&checker.importer,
|
||||||
checker.locator,
|
checker.locator,
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -96,11 +96,16 @@ where
|
||||||
/// TID251
|
/// TID251
|
||||||
pub(crate) fn banned_attribute_access(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn banned_attribute_access(checker: &mut Checker, expr: &Expr) {
|
||||||
let banned_api = &checker.settings.flake8_tidy_imports.banned_api;
|
let banned_api = &checker.settings.flake8_tidy_imports.banned_api;
|
||||||
if let Some((banned_path, ban)) = checker.model.resolve_call_path(expr).and_then(|call_path| {
|
if let Some((banned_path, ban)) =
|
||||||
|
checker
|
||||||
|
.semantic_model()
|
||||||
|
.resolve_call_path(expr)
|
||||||
|
.and_then(|call_path| {
|
||||||
banned_api
|
banned_api
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(banned_path, ..)| call_path == from_qualified_name(banned_path))
|
.find(|(banned_path, ..)| call_path == from_qualified_name(banned_path))
|
||||||
}) {
|
})
|
||||||
|
{
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
BannedApi {
|
BannedApi {
|
||||||
name: banned_path.to_string(),
|
name: banned_path.to_string(),
|
||||||
|
|
|
@ -60,7 +60,7 @@ pub(crate) fn empty_type_checking_block<'a, 'b>(
|
||||||
|
|
||||||
// Delete the entire type-checking block.
|
// Delete the entire type-checking block.
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
let parent = checker.model.stmts.parent(stmt);
|
let parent = checker.semantic_model().stmts.parent(stmt);
|
||||||
let deleted: Vec<&Stmt> = checker.deletions.iter().map(Into::into).collect();
|
let deleted: Vec<&Stmt> = checker.deletions.iter().map(Into::into).collect();
|
||||||
match delete_stmt(
|
match delete_stmt(
|
||||||
stmt,
|
stmt,
|
||||||
|
|
|
@ -289,7 +289,7 @@ pub(crate) fn unused_arguments(
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
match function_type::classify(
|
match function_type::classify(
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
parent,
|
parent,
|
||||||
name,
|
name,
|
||||||
decorator_list,
|
decorator_list,
|
||||||
|
@ -301,7 +301,7 @@ pub(crate) fn unused_arguments(
|
||||||
.settings
|
.settings
|
||||||
.rules
|
.rules
|
||||||
.enabled(Argumentable::Function.rule_code())
|
.enabled(Argumentable::Function.rule_code())
|
||||||
&& !visibility::is_overload(&checker.model, decorator_list)
|
&& !visibility::is_overload(checker.semantic_model(), decorator_list)
|
||||||
{
|
{
|
||||||
function(
|
function(
|
||||||
Argumentable::Function,
|
Argumentable::Function,
|
||||||
|
@ -328,9 +328,9 @@ pub(crate) fn unused_arguments(
|
||||||
|| visibility::is_init(name)
|
|| visibility::is_init(name)
|
||||||
|| visibility::is_new(name)
|
|| visibility::is_new(name)
|
||||||
|| visibility::is_call(name))
|
|| visibility::is_call(name))
|
||||||
&& !visibility::is_abstract(&checker.model, decorator_list)
|
&& !visibility::is_abstract(checker.semantic_model(), decorator_list)
|
||||||
&& !visibility::is_override(&checker.model, decorator_list)
|
&& !visibility::is_override(checker.semantic_model(), decorator_list)
|
||||||
&& !visibility::is_overload(&checker.model, decorator_list)
|
&& !visibility::is_overload(checker.semantic_model(), decorator_list)
|
||||||
{
|
{
|
||||||
method(
|
method(
|
||||||
Argumentable::Method,
|
Argumentable::Method,
|
||||||
|
@ -357,9 +357,9 @@ pub(crate) fn unused_arguments(
|
||||||
|| visibility::is_init(name)
|
|| visibility::is_init(name)
|
||||||
|| visibility::is_new(name)
|
|| visibility::is_new(name)
|
||||||
|| visibility::is_call(name))
|
|| visibility::is_call(name))
|
||||||
&& !visibility::is_abstract(&checker.model, decorator_list)
|
&& !visibility::is_abstract(checker.semantic_model(), decorator_list)
|
||||||
&& !visibility::is_override(&checker.model, decorator_list)
|
&& !visibility::is_override(checker.semantic_model(), decorator_list)
|
||||||
&& !visibility::is_overload(&checker.model, decorator_list)
|
&& !visibility::is_overload(checker.semantic_model(), decorator_list)
|
||||||
{
|
{
|
||||||
method(
|
method(
|
||||||
Argumentable::ClassMethod,
|
Argumentable::ClassMethod,
|
||||||
|
@ -386,9 +386,9 @@ pub(crate) fn unused_arguments(
|
||||||
|| visibility::is_init(name)
|
|| visibility::is_init(name)
|
||||||
|| visibility::is_new(name)
|
|| visibility::is_new(name)
|
||||||
|| visibility::is_call(name))
|
|| visibility::is_call(name))
|
||||||
&& !visibility::is_abstract(&checker.model, decorator_list)
|
&& !visibility::is_abstract(checker.semantic_model(), decorator_list)
|
||||||
&& !visibility::is_override(&checker.model, decorator_list)
|
&& !visibility::is_override(checker.semantic_model(), decorator_list)
|
||||||
&& !visibility::is_overload(&checker.model, decorator_list)
|
&& !visibility::is_overload(checker.semantic_model(), decorator_list)
|
||||||
{
|
{
|
||||||
function(
|
function(
|
||||||
Argumentable::StaticMethod,
|
Argumentable::StaticMethod,
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::settings::types::PythonVersion;
|
||||||
pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) {
|
||||||
if let Some(diagnostic_kind) =
|
if let Some(diagnostic_kind) =
|
||||||
checker
|
checker
|
||||||
.model
|
.semantic_model()
|
||||||
.resolve_call_path(expr)
|
.resolve_call_path(expr)
|
||||||
.and_then(|call_path| match call_path.as_slice() {
|
.and_then(|call_path| match call_path.as_slice() {
|
||||||
["os", "path", "abspath"] => Some(OsPathAbspath.into()),
|
["os", "path", "abspath"] => Some(OsPathAbspath.into()),
|
||||||
|
|
|
@ -48,7 +48,11 @@ impl AlwaysAutofixableViolation for NumpyDeprecatedTypeAlias {
|
||||||
|
|
||||||
/// NPY001
|
/// NPY001
|
||||||
pub(crate) fn deprecated_type_alias(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn deprecated_type_alias(checker: &mut Checker, expr: &Expr) {
|
||||||
if let Some(type_name) = checker.model.resolve_call_path(expr).and_then(|call_path| {
|
if let Some(type_name) =
|
||||||
|
checker
|
||||||
|
.semantic_model()
|
||||||
|
.resolve_call_path(expr)
|
||||||
|
.and_then(|call_path| {
|
||||||
if call_path.as_slice() == ["numpy", "bool"]
|
if call_path.as_slice() == ["numpy", "bool"]
|
||||||
|| call_path.as_slice() == ["numpy", "int"]
|
|| call_path.as_slice() == ["numpy", "int"]
|
||||||
|| call_path.as_slice() == ["numpy", "float"]
|
|| call_path.as_slice() == ["numpy", "float"]
|
||||||
|
@ -62,7 +66,8 @@ pub(crate) fn deprecated_type_alias(checker: &mut Checker, expr: &Expr) {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}) {
|
})
|
||||||
|
{
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
NumpyDeprecatedTypeAlias {
|
NumpyDeprecatedTypeAlias {
|
||||||
type_name: type_name.to_string(),
|
type_name: type_name.to_string(),
|
||||||
|
|
|
@ -58,7 +58,11 @@ impl Violation for NumpyLegacyRandom {
|
||||||
|
|
||||||
/// NPY002
|
/// NPY002
|
||||||
pub(crate) fn numpy_legacy_random(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn numpy_legacy_random(checker: &mut Checker, expr: &Expr) {
|
||||||
if let Some(method_name) = checker.model.resolve_call_path(expr).and_then(|call_path| {
|
if let Some(method_name) =
|
||||||
|
checker
|
||||||
|
.semantic_model()
|
||||||
|
.resolve_call_path(expr)
|
||||||
|
.and_then(|call_path| {
|
||||||
// seeding state
|
// seeding state
|
||||||
if call_path.as_slice() == ["numpy", "random", "seed"]
|
if call_path.as_slice() == ["numpy", "random", "seed"]
|
||||||
|| call_path.as_slice() == ["numpy", "random", "get_state"]
|
|| call_path.as_slice() == ["numpy", "random", "get_state"]
|
||||||
|
@ -116,7 +120,8 @@ pub(crate) fn numpy_legacy_random(checker: &mut Checker, expr: &Expr) {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}) {
|
})
|
||||||
|
{
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
NumpyLegacyRandom {
|
NumpyLegacyRandom {
|
||||||
method_name: method_name.to_string(),
|
method_name: method_name.to_string(),
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub(crate) fn attr(checker: &mut Checker, attr: &str, value: &Expr, attr_expr: &
|
||||||
};
|
};
|
||||||
|
|
||||||
// Avoid flagging on function calls (e.g., `df.values()`).
|
// Avoid flagging on function calls (e.g., `df.values()`).
|
||||||
if let Some(parent) = checker.model.expr_parent() {
|
if let Some(parent) = checker.semantic_model().expr_parent() {
|
||||||
if matches!(parent, Expr::Call(_)) {
|
if matches!(parent, Expr::Call(_)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ pub(crate) fn attr(checker: &mut Checker, attr: &str, value: &Expr, attr_expr: &
|
||||||
// Avoid flagging on non-DataFrames (e.g., `{"a": 1}.values`), and on irrelevant bindings
|
// Avoid flagging on non-DataFrames (e.g., `{"a": 1}.values`), and on irrelevant bindings
|
||||||
// (like imports).
|
// (like imports).
|
||||||
if !matches!(
|
if !matches!(
|
||||||
test_expression(value, &checker.model),
|
test_expression(value, checker.semantic_model()),
|
||||||
Resolution::RelevantLocal
|
Resolution::RelevantLocal
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -80,7 +80,7 @@ pub(crate) fn call(checker: &mut Checker, func: &Expr) {
|
||||||
|
|
||||||
// Ignore irrelevant bindings (like imports).
|
// Ignore irrelevant bindings (like imports).
|
||||||
if !matches!(
|
if !matches!(
|
||||||
test_expression(value, &checker.model),
|
test_expression(value, checker.semantic_model()),
|
||||||
Resolution::RelevantLocal | Resolution::PandasModule
|
Resolution::RelevantLocal | Resolution::PandasModule
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -60,11 +60,14 @@ pub(crate) fn inplace_argument(
|
||||||
let mut is_checkable = false;
|
let mut is_checkable = false;
|
||||||
let mut is_pandas = false;
|
let mut is_pandas = false;
|
||||||
|
|
||||||
if let Some(call_path) = checker.model.resolve_call_path(func) {
|
if let Some(call_path) = checker.semantic_model().resolve_call_path(func) {
|
||||||
is_checkable = true;
|
is_checkable = true;
|
||||||
|
|
||||||
let module = call_path[0];
|
let module = call_path[0];
|
||||||
is_pandas = checker.model.find_binding(module).map_or(false, |binding| {
|
is_pandas = checker
|
||||||
|
.semantic_model()
|
||||||
|
.find_binding(module)
|
||||||
|
.map_or(false, |binding| {
|
||||||
matches!(
|
matches!(
|
||||||
binding.kind,
|
binding.kind,
|
||||||
BindingKind::Importation(Importation {
|
BindingKind::Importation(Importation {
|
||||||
|
@ -99,9 +102,9 @@ pub(crate) fn inplace_argument(
|
||||||
// but we don't currently restore expression stacks when parsing deferred nodes,
|
// but we don't currently restore expression stacks when parsing deferred nodes,
|
||||||
// and so the parent is lost.
|
// and so the parent is lost.
|
||||||
let fixable = !seen_star
|
let fixable = !seen_star
|
||||||
&& checker.model.stmt().is_expr_stmt()
|
&& checker.semantic_model().stmt().is_expr_stmt()
|
||||||
&& checker.model.expr_parent().is_none()
|
&& checker.semantic_model().expr_parent().is_none()
|
||||||
&& !checker.model.scope().kind.is_lambda();
|
&& !checker.semantic_model().scope().kind.is_lambda();
|
||||||
let mut diagnostic = Diagnostic::new(PandasUseOfInplaceArgument, keyword.range());
|
let mut diagnostic = Diagnostic::new(PandasUseOfInplaceArgument, keyword.range());
|
||||||
if fixable && checker.patch(diagnostic.kind.rule()) {
|
if fixable && checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(fix) = convert_inplace_argument_to_assignment(
|
if let Some(fix) = convert_inplace_argument_to_assignment(
|
||||||
|
|
|
@ -54,7 +54,7 @@ pub(crate) fn subscript(checker: &mut Checker, value: &Expr, expr: &Expr) {
|
||||||
// Avoid flagging on non-DataFrames (e.g., `{"a": 1}.at[0]`), and on irrelevant bindings
|
// Avoid flagging on non-DataFrames (e.g., `{"a": 1}.at[0]`), and on irrelevant bindings
|
||||||
// (like imports).
|
// (like imports).
|
||||||
if !matches!(
|
if !matches!(
|
||||||
test_expression(value, &checker.model),
|
test_expression(value, checker.semantic_model()),
|
||||||
Resolution::RelevantLocal
|
Resolution::RelevantLocal
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub(crate) fn invalid_first_argument_name_for_class_method(
|
||||||
) -> Option<Diagnostic> {
|
) -> Option<Diagnostic> {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
function_type::classify(
|
function_type::classify(
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
scope,
|
scope,
|
||||||
name,
|
name,
|
||||||
decorator_list,
|
decorator_list,
|
||||||
|
|
|
@ -61,7 +61,7 @@ pub(crate) fn invalid_first_argument_name_for_method(
|
||||||
) -> Option<Diagnostic> {
|
) -> Option<Diagnostic> {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
function_type::classify(
|
function_type::classify(
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
scope,
|
scope,
|
||||||
name,
|
name,
|
||||||
decorator_list,
|
decorator_list,
|
||||||
|
|
|
@ -67,8 +67,8 @@ pub(crate) fn mixed_case_variable_in_class_scope(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if helpers::is_mixed_case(name)
|
if helpers::is_mixed_case(name)
|
||||||
&& !helpers::is_named_tuple_assignment(&checker.model, stmt)
|
&& !helpers::is_named_tuple_assignment(checker.semantic_model(), stmt)
|
||||||
&& !helpers::is_typed_dict_class(&checker.model, bases)
|
&& !helpers::is_typed_dict_class(checker.semantic_model(), bases)
|
||||||
{
|
{
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
MixedCaseVariableInClassScope {
|
MixedCaseVariableInClassScope {
|
||||||
|
|
|
@ -75,7 +75,9 @@ pub(crate) fn mixed_case_variable_in_global_scope(
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if helpers::is_mixed_case(name) && !helpers::is_named_tuple_assignment(&checker.model, stmt) {
|
if helpers::is_mixed_case(name)
|
||||||
|
&& !helpers::is_named_tuple_assignment(checker.semantic_model(), stmt)
|
||||||
|
{
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
MixedCaseVariableInGlobalScope {
|
MixedCaseVariableInGlobalScope {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
|
|
@ -66,9 +66,9 @@ pub(crate) fn non_lowercase_variable_in_function(
|
||||||
}
|
}
|
||||||
|
|
||||||
if name.to_lowercase() != name
|
if name.to_lowercase() != name
|
||||||
&& !helpers::is_named_tuple_assignment(&checker.model, stmt)
|
&& !helpers::is_named_tuple_assignment(checker.semantic_model(), stmt)
|
||||||
&& !helpers::is_typed_dict_assignment(&checker.model, stmt)
|
&& !helpers::is_typed_dict_assignment(checker.semantic_model(), stmt)
|
||||||
&& !helpers::is_type_var_assignment(&checker.model, stmt)
|
&& !helpers::is_type_var_assignment(checker.semantic_model(), stmt)
|
||||||
{
|
{
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
NonLowercaseVariableInFunction {
|
NonLowercaseVariableInFunction {
|
||||||
|
|
|
@ -88,7 +88,8 @@ pub(crate) fn module_import_not_at_top_of_file(
|
||||||
stmt: &Stmt,
|
stmt: &Stmt,
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
) {
|
) {
|
||||||
if checker.model.seen_import_boundary() && locator.is_at_start_of_line(stmt.start()) {
|
if checker.semantic_model().seen_import_boundary() && locator.is_at_start_of_line(stmt.start())
|
||||||
|
{
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(ModuleImportNotAtTopOfFile, stmt.range()));
|
.push(Diagnostic::new(ModuleImportNotAtTopOfFile, stmt.range()));
|
||||||
|
|
|
@ -72,7 +72,7 @@ pub(crate) fn lambda_assignment(
|
||||||
// package like dataclasses, which wouldn't consider the
|
// package like dataclasses, which wouldn't consider the
|
||||||
// rewritten function definition to be equivalent.
|
// rewritten function definition to be equivalent.
|
||||||
// See https://github.com/charliermarsh/ruff/issues/3046
|
// See https://github.com/charliermarsh/ruff/issues/3046
|
||||||
let fixable = !matches!(checker.model.scope().kind, ScopeKind::Class(_));
|
let fixable = !matches!(checker.semantic_model().scope().kind, ScopeKind::Class(_));
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
LambdaAssignment {
|
LambdaAssignment {
|
||||||
|
@ -90,7 +90,7 @@ pub(crate) fn lambda_assignment(
|
||||||
let indentation = &leading_space(first_line);
|
let indentation = &leading_space(first_line);
|
||||||
let mut indented = String::new();
|
let mut indented = String::new();
|
||||||
for (idx, line) in function(
|
for (idx, line) in function(
|
||||||
&checker.model,
|
checker.semantic_model(),
|
||||||
id,
|
id,
|
||||||
args,
|
args,
|
||||||
body,
|
body,
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub(crate) fn type_comparison(
|
||||||
Expr::Call(ast::ExprCall { func, args, .. }) => {
|
Expr::Call(ast::ExprCall { func, args, .. }) => {
|
||||||
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
|
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
|
||||||
// Ex) `type(False)`
|
// Ex) `type(False)`
|
||||||
if id == "type" && checker.model.is_builtin("type") {
|
if id == "type" && checker.semantic_model().is_builtin("type") {
|
||||||
if let Some(arg) = args.first() {
|
if let Some(arg) = args.first() {
|
||||||
// Allow comparison for types which are not obvious.
|
// Allow comparison for types which are not obvious.
|
||||||
if !matches!(
|
if !matches!(
|
||||||
|
@ -76,12 +76,12 @@ pub(crate) fn type_comparison(
|
||||||
if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() {
|
if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() {
|
||||||
// Ex) `types.NoneType`
|
// Ex) `types.NoneType`
|
||||||
if id == "types"
|
if id == "types"
|
||||||
&& checker
|
&& checker.semantic_model().resolve_call_path(value).map_or(
|
||||||
.model
|
false,
|
||||||
.resolve_call_path(value)
|
|call_path| {
|
||||||
.map_or(false, |call_path| {
|
|
||||||
call_path.first().map_or(false, |module| *module == "types")
|
call_path.first().map_or(false, |module| *module == "types")
|
||||||
})
|
},
|
||||||
|
)
|
||||||
{
|
{
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub(crate) fn if_needed(checker: &mut Checker, docstring: &Docstring) {
|
||||||
}) = docstring.definition else {
|
}) = docstring.definition else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !is_overload(&checker.model, cast::decorator_list(stmt)) {
|
if !is_overload(checker.semantic_model(), cast::decorator_list(stmt)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue