41 lines
1.4 KiB
Rust
41 lines
1.4 KiB
Rust
use rustpython_ast::{Expr, ExprKind};
|
|
|
|
use crate::ast::helpers::{compose_call_path, match_module_member};
|
|
use crate::ast::types::{Range, ScopeKind};
|
|
use crate::check_ast::Checker;
|
|
use crate::checks::{Check, CheckKind};
|
|
|
|
fn is_cache_func(checker: &Checker, expr: &Expr) -> bool {
|
|
match_module_member(expr, "functools.lru_cache", &checker.from_imports)
|
|
|| match_module_member(expr, "functools.cache", &checker.from_imports)
|
|
}
|
|
|
|
/// B019
|
|
pub fn cached_instance_method(checker: &mut Checker, decorator_list: &[Expr]) {
|
|
if matches!(checker.current_scope().kind, ScopeKind::Class(_)) {
|
|
for decorator in decorator_list {
|
|
// TODO(charlie): This should take into account `classmethod-decorators` and
|
|
// `staticmethod-decorators`.
|
|
if let Some(decorator_path) = compose_call_path(decorator) {
|
|
if decorator_path == "classmethod" || decorator_path == "staticmethod" {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
for decorator in decorator_list {
|
|
if is_cache_func(
|
|
checker,
|
|
match &decorator.node {
|
|
ExprKind::Call { func, .. } => func,
|
|
_ => decorator,
|
|
},
|
|
) {
|
|
checker.add_check(Check::new(
|
|
CheckKind::CachedInstanceMethod,
|
|
Range::from_located(decorator),
|
|
));
|
|
}
|
|
}
|
|
}
|
|
}
|