mirror of https://github.com/astral-sh/ruff
Move `@functools.cache` rewrites to their own rule (#1938)
Closes #1934.
This commit is contained in:
parent
70ea4b25e8
commit
072849a8a9
|
|
@ -1,5 +1,14 @@
|
||||||
# Breaking Changes
|
# Breaking Changes
|
||||||
|
|
||||||
|
## 0.0.225
|
||||||
|
|
||||||
|
### `@functools.cache` rewrites have been moved to a standalone rule (`UP033`) ([#1938](https://github.com/charliermarsh/ruff/pull/1938))
|
||||||
|
|
||||||
|
Previously, `UP011` handled both `@functools.lru_cache()`-to-`@functools.lru_cache` conversions,
|
||||||
|
_and_ `@functools.lru_cache(maxsize=None)`-to-`@functools.cache` conversions. The latter has been
|
||||||
|
moved out to its own rule (`UP033`). As such, some `# noqa: UP011` comments may need to be updated
|
||||||
|
to reflect the change in rule code.
|
||||||
|
|
||||||
## 0.0.222
|
## 0.0.222
|
||||||
|
|
||||||
### `--max-complexity` has been removed from the CLI ([#1877](https://github.com/charliermarsh/ruff/pull/1877))
|
### `--max-complexity` has been removed from the CLI ([#1877](https://github.com/charliermarsh/ruff/pull/1877))
|
||||||
|
|
|
||||||
|
|
@ -705,7 +705,7 @@ For more, see [pyupgrade](https://pypi.org/project/pyupgrade/3.2.0/) on PyPI.
|
||||||
| UP008 | SuperCallWithParameters | Use `super()` instead of `super(__class__, self)` | 🛠 |
|
| UP008 | SuperCallWithParameters | Use `super()` instead of `super(__class__, self)` | 🛠 |
|
||||||
| UP009 | PEP3120UnnecessaryCodingComment | UTF-8 encoding declaration is unnecessary | 🛠 |
|
| UP009 | PEP3120UnnecessaryCodingComment | UTF-8 encoding declaration is unnecessary | 🛠 |
|
||||||
| UP010 | UnnecessaryFutureImport | Unnecessary `__future__` import `...` for target Python version | 🛠 |
|
| UP010 | UnnecessaryFutureImport | Unnecessary `__future__` import `...` for target Python version | 🛠 |
|
||||||
| UP011 | UnnecessaryLRUCacheParams | Unnecessary parameters to `functools.lru_cache` | 🛠 |
|
| UP011 | LRUCacheWithoutParameters | Unnecessary parameters to `functools.lru_cache` | 🛠 |
|
||||||
| UP012 | UnnecessaryEncodeUTF8 | Unnecessary call to `encode` as UTF-8 | 🛠 |
|
| UP012 | UnnecessaryEncodeUTF8 | Unnecessary call to `encode` as UTF-8 | 🛠 |
|
||||||
| UP013 | ConvertTypedDictFunctionalToClass | Convert `...` from `TypedDict` functional to class syntax | 🛠 |
|
| UP013 | ConvertTypedDictFunctionalToClass | Convert `...` from `TypedDict` functional to class syntax | 🛠 |
|
||||||
| UP014 | ConvertNamedTupleFunctionalToClass | Convert `...` from `NamedTuple` functional to class syntax | 🛠 |
|
| UP014 | ConvertNamedTupleFunctionalToClass | Convert `...` from `NamedTuple` functional to class syntax | 🛠 |
|
||||||
|
|
@ -726,6 +726,7 @@ For more, see [pyupgrade](https://pypi.org/project/pyupgrade/3.2.0/) on PyPI.
|
||||||
| UP029 | UnnecessaryBuiltinImport | Unnecessary builtin import: `...` | 🛠 |
|
| UP029 | UnnecessaryBuiltinImport | Unnecessary builtin import: `...` | 🛠 |
|
||||||
| UP030 | FormatLiterals | Use implicit references for positional format fields | 🛠 |
|
| UP030 | FormatLiterals | Use implicit references for positional format fields | 🛠 |
|
||||||
| UP032 | FString | Use f-string instead of `format` call | 🛠 |
|
| UP032 | FString | Use f-string instead of `format` call | 🛠 |
|
||||||
|
| UP033 | FunctoolsCache | Use `@functools.cache` instead of `@functools.lru_cache(maxsize=None)` | 🛠 |
|
||||||
|
|
||||||
### pep8-naming (N)
|
### pep8-naming (N)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
import functools
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache()
|
||||||
|
def fixme():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache()
|
||||||
|
def fixme():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@other_decorator
|
||||||
|
@functools.lru_cache()
|
||||||
|
def fixme():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache()
|
||||||
|
@other_decorator
|
||||||
|
def fixme():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=None)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=None)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=64)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=64)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def user_func():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(user_func)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(user_func, maxsize=None)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def lru_cache(maxsize=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=None)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
import functools
|
|
||||||
from functools import lru_cache
|
|
||||||
|
|
||||||
|
|
||||||
@lru_cache()
|
|
||||||
def fixme1():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@other_deco_after
|
|
||||||
@functools.lru_cache()
|
|
||||||
def fixme2():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@lru_cache(maxsize=None)
|
|
||||||
def fixme3():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache(maxsize=None)
|
|
||||||
@other_deco_before
|
|
||||||
def fixme4():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@lru_cache( # A
|
|
||||||
) # B
|
|
||||||
def fixme5():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@lru_cache(
|
|
||||||
# A
|
|
||||||
) # B
|
|
||||||
def fixme6():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache(
|
|
||||||
# A
|
|
||||||
maxsize = None) # B
|
|
||||||
def fixme7():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache(
|
|
||||||
# A1
|
|
||||||
maxsize = None
|
|
||||||
# A2
|
|
||||||
) # B
|
|
||||||
def fixme8():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache(
|
|
||||||
# A1
|
|
||||||
maxsize =
|
|
||||||
None
|
|
||||||
# A2
|
|
||||||
|
|
||||||
)
|
|
||||||
def fixme9():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache(
|
|
||||||
# A1
|
|
||||||
maxsize =
|
|
||||||
None
|
|
||||||
# A2
|
|
||||||
)
|
|
||||||
def fixme10():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@lru_cache
|
|
||||||
def correct1():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache
|
|
||||||
def correct2():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@functoools.lru_cache(maxsize=64)
|
|
||||||
def correct3():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def user_func():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@lru_cache(user_func)
|
|
||||||
def correct4():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@lru_cache(user_func, maxsize=None)
|
|
||||||
def correct5():
|
|
||||||
pass
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import functools
|
|
||||||
|
|
||||||
|
|
||||||
def lru_cache(maxsize=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@lru_cache()
|
|
||||||
def dont_fixme():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@lru_cache(maxsize=None)
|
|
||||||
def dont_fixme():
|
|
||||||
pass
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
import functools
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=None)
|
||||||
|
def fixme():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=None)
|
||||||
|
def fixme():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@other_decorator
|
||||||
|
@functools.lru_cache(maxsize=None)
|
||||||
|
def fixme():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=None)
|
||||||
|
@other_decorator
|
||||||
|
def fixme():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache()
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache()
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=64)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=64)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def user_func():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(user_func)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(user_func, maxsize=None)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def lru_cache(maxsize=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=None)
|
||||||
|
def ok():
|
||||||
|
pass
|
||||||
|
|
@ -1688,6 +1688,7 @@
|
||||||
"UP03",
|
"UP03",
|
||||||
"UP030",
|
"UP030",
|
||||||
"UP032",
|
"UP032",
|
||||||
|
"UP033",
|
||||||
"W",
|
"W",
|
||||||
"W2",
|
"W2",
|
||||||
"W29",
|
"W29",
|
||||||
|
|
|
||||||
|
|
@ -499,7 +499,12 @@ where
|
||||||
if self.settings.rules.enabled(&RuleCode::UP011)
|
if self.settings.rules.enabled(&RuleCode::UP011)
|
||||||
&& self.settings.target_version >= PythonVersion::Py38
|
&& self.settings.target_version >= PythonVersion::Py38
|
||||||
{
|
{
|
||||||
pyupgrade::rules::unnecessary_lru_cache_params(self, decorator_list);
|
pyupgrade::rules::lru_cache_without_parameters(self, decorator_list);
|
||||||
|
}
|
||||||
|
if self.settings.rules.enabled(&RuleCode::UP033)
|
||||||
|
&& self.settings.target_version >= PythonVersion::Py39
|
||||||
|
{
|
||||||
|
pyupgrade::rules::functools_cache(self, decorator_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.settings.rules.enabled(&RuleCode::B018) {
|
if self.settings.rules.enabled(&RuleCode::B018) {
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,7 @@ ruff_macros::define_rule_mapping!(
|
||||||
UP008 => violations::SuperCallWithParameters,
|
UP008 => violations::SuperCallWithParameters,
|
||||||
UP009 => violations::PEP3120UnnecessaryCodingComment,
|
UP009 => violations::PEP3120UnnecessaryCodingComment,
|
||||||
UP010 => violations::UnnecessaryFutureImport,
|
UP010 => violations::UnnecessaryFutureImport,
|
||||||
UP011 => violations::UnnecessaryLRUCacheParams,
|
UP011 => violations::LRUCacheWithoutParameters,
|
||||||
UP012 => violations::UnnecessaryEncodeUTF8,
|
UP012 => violations::UnnecessaryEncodeUTF8,
|
||||||
UP013 => violations::ConvertTypedDictFunctionalToClass,
|
UP013 => violations::ConvertTypedDictFunctionalToClass,
|
||||||
UP014 => violations::ConvertNamedTupleFunctionalToClass,
|
UP014 => violations::ConvertNamedTupleFunctionalToClass,
|
||||||
|
|
@ -253,6 +253,7 @@ ruff_macros::define_rule_mapping!(
|
||||||
UP029 => violations::UnnecessaryBuiltinImport,
|
UP029 => violations::UnnecessaryBuiltinImport,
|
||||||
UP030 => violations::FormatLiterals,
|
UP030 => violations::FormatLiterals,
|
||||||
UP032 => violations::FString,
|
UP032 => violations::FString,
|
||||||
|
UP033 => violations::FunctoolsCache,
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
D100 => violations::PublicModule,
|
D100 => violations::PublicModule,
|
||||||
D101 => violations::PublicClass,
|
D101 => violations::PublicClass,
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,7 @@ mod tests {
|
||||||
#[test_case(RuleCode::UP009, Path::new("UP009_3.py"); "UP009_3")]
|
#[test_case(RuleCode::UP009, Path::new("UP009_3.py"); "UP009_3")]
|
||||||
#[test_case(RuleCode::UP009, Path::new("UP009_4.py"); "UP009_4")]
|
#[test_case(RuleCode::UP009, Path::new("UP009_4.py"); "UP009_4")]
|
||||||
#[test_case(RuleCode::UP010, Path::new("UP010.py"); "UP010")]
|
#[test_case(RuleCode::UP010, Path::new("UP010.py"); "UP010")]
|
||||||
#[test_case(RuleCode::UP011, Path::new("UP011_0.py"); "UP011_0")]
|
#[test_case(RuleCode::UP011, Path::new("UP011.py"); "UP011")]
|
||||||
#[test_case(RuleCode::UP011, Path::new("UP011_1.py"); "UP011_1")]
|
|
||||||
#[test_case(RuleCode::UP012, Path::new("UP012.py"); "UP012")]
|
#[test_case(RuleCode::UP012, Path::new("UP012.py"); "UP012")]
|
||||||
#[test_case(RuleCode::UP013, Path::new("UP013.py"); "UP013")]
|
#[test_case(RuleCode::UP013, Path::new("UP013.py"); "UP013")]
|
||||||
#[test_case(RuleCode::UP014, Path::new("UP014.py"); "UP014")]
|
#[test_case(RuleCode::UP014, Path::new("UP014.py"); "UP014")]
|
||||||
|
|
@ -55,6 +54,7 @@ mod tests {
|
||||||
#[test_case(RuleCode::UP030, Path::new("UP030_0.py"); "UP030_0")]
|
#[test_case(RuleCode::UP030, Path::new("UP030_0.py"); "UP030_0")]
|
||||||
#[test_case(RuleCode::UP030, Path::new("UP030_1.py"); "UP030_1")]
|
#[test_case(RuleCode::UP030, Path::new("UP030_1.py"); "UP030_1")]
|
||||||
#[test_case(RuleCode::UP032, Path::new("UP032.py"); "UP032")]
|
#[test_case(RuleCode::UP032, Path::new("UP032.py"); "UP032")]
|
||||||
|
#[test_case(RuleCode::UP033, Path::new("UP033.py"); "UP033")]
|
||||||
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
|
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
|
||||||
let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
|
let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
|
||||||
let diagnostics = test_path(
|
let diagnostics = test_path(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
use rustpython_ast::{Constant, ExprKind, KeywordData};
|
||||||
|
use rustpython_parser::ast::Expr;
|
||||||
|
|
||||||
|
use crate::ast::helpers::{create_expr, unparse_expr};
|
||||||
|
use crate::ast::types::Range;
|
||||||
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::fix::Fix;
|
||||||
|
use crate::registry::{Diagnostic, RuleCode};
|
||||||
|
use crate::violations;
|
||||||
|
|
||||||
|
/// UP033
|
||||||
|
pub fn functools_cache(checker: &mut Checker, decorator_list: &[Expr]) {
|
||||||
|
for expr in decorator_list.iter() {
|
||||||
|
let ExprKind::Call {
|
||||||
|
func,
|
||||||
|
args,
|
||||||
|
keywords,
|
||||||
|
} = &expr.node else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Look for, e.g., `import functools; @functools.lru_cache(maxsize=None)`.
|
||||||
|
if args.is_empty()
|
||||||
|
&& keywords.len() == 1
|
||||||
|
&& checker
|
||||||
|
.resolve_call_path(func)
|
||||||
|
.map_or(false, |call_path| call_path == ["functools", "lru_cache"])
|
||||||
|
{
|
||||||
|
let KeywordData { arg, value } = &keywords[0].node;
|
||||||
|
if arg.as_ref().map_or(false, |arg| arg == "maxsize")
|
||||||
|
&& matches!(
|
||||||
|
value.node,
|
||||||
|
ExprKind::Constant {
|
||||||
|
value: Constant::None,
|
||||||
|
kind: None,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
{
|
||||||
|
let mut diagnostic = Diagnostic::new(
|
||||||
|
violations::FunctoolsCache,
|
||||||
|
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
|
||||||
|
);
|
||||||
|
if checker.patch(&RuleCode::UP033) {
|
||||||
|
if let ExprKind::Attribute { value, ctx, .. } = &func.node {
|
||||||
|
diagnostic.amend(Fix::replacement(
|
||||||
|
unparse_expr(
|
||||||
|
&create_expr(ExprKind::Attribute {
|
||||||
|
value: value.clone(),
|
||||||
|
attr: "cache".to_string(),
|
||||||
|
ctx: ctx.clone(),
|
||||||
|
}),
|
||||||
|
checker.stylist,
|
||||||
|
),
|
||||||
|
expr.location,
|
||||||
|
expr.end_location.unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checker.diagnostics.push(diagnostic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
use rustpython_ast::ExprKind;
|
||||||
|
use rustpython_parser::ast::Expr;
|
||||||
|
|
||||||
|
use crate::ast::helpers::unparse_expr;
|
||||||
|
use crate::ast::types::Range;
|
||||||
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::fix::Fix;
|
||||||
|
use crate::registry::{Diagnostic, RuleCode};
|
||||||
|
use crate::violations;
|
||||||
|
|
||||||
|
/// UP011
|
||||||
|
pub fn lru_cache_without_parameters(checker: &mut Checker, decorator_list: &[Expr]) {
|
||||||
|
for expr in decorator_list.iter() {
|
||||||
|
let ExprKind::Call {
|
||||||
|
func,
|
||||||
|
args,
|
||||||
|
keywords,
|
||||||
|
} = &expr.node else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Look for, e.g., `import functools; @functools.lru_cache()`.
|
||||||
|
if args.is_empty()
|
||||||
|
&& keywords.is_empty()
|
||||||
|
&& checker
|
||||||
|
.resolve_call_path(func)
|
||||||
|
.map_or(false, |call_path| call_path == ["functools", "lru_cache"])
|
||||||
|
{
|
||||||
|
let mut diagnostic = Diagnostic::new(
|
||||||
|
violations::LRUCacheWithoutParameters,
|
||||||
|
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
|
||||||
|
);
|
||||||
|
if checker.patch(&RuleCode::UP011) {
|
||||||
|
diagnostic.amend(Fix::replacement(
|
||||||
|
unparse_expr(func, checker.stylist),
|
||||||
|
expr.location,
|
||||||
|
expr.end_location.unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
checker.diagnostics.push(diagnostic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,8 @@ pub(crate) use datetime_utc_alias::datetime_utc_alias;
|
||||||
pub(crate) use deprecated_unittest_alias::deprecated_unittest_alias;
|
pub(crate) use deprecated_unittest_alias::deprecated_unittest_alias;
|
||||||
pub(crate) use f_strings::f_strings;
|
pub(crate) use f_strings::f_strings;
|
||||||
pub(crate) use format_literals::format_literals;
|
pub(crate) use format_literals::format_literals;
|
||||||
|
pub(crate) use functools_cache::functools_cache;
|
||||||
|
pub(crate) use lru_cache_without_parameters::lru_cache_without_parameters;
|
||||||
pub(crate) use native_literals::native_literals;
|
pub(crate) use native_literals::native_literals;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
pub(crate) use open_alias::open_alias;
|
pub(crate) use open_alias::open_alias;
|
||||||
|
|
@ -25,7 +27,6 @@ pub(crate) use typing_text_str_alias::typing_text_str_alias;
|
||||||
pub(crate) use unnecessary_builtin_import::unnecessary_builtin_import;
|
pub(crate) use unnecessary_builtin_import::unnecessary_builtin_import;
|
||||||
pub(crate) use unnecessary_encode_utf8::unnecessary_encode_utf8;
|
pub(crate) use unnecessary_encode_utf8::unnecessary_encode_utf8;
|
||||||
pub(crate) use unnecessary_future_import::unnecessary_future_import;
|
pub(crate) use unnecessary_future_import::unnecessary_future_import;
|
||||||
pub(crate) use unnecessary_lru_cache_params::unnecessary_lru_cache_params;
|
|
||||||
pub(crate) use unpack_list_comprehension::unpack_list_comprehension;
|
pub(crate) use unpack_list_comprehension::unpack_list_comprehension;
|
||||||
pub(crate) use use_pep585_annotation::use_pep585_annotation;
|
pub(crate) use use_pep585_annotation::use_pep585_annotation;
|
||||||
pub(crate) use use_pep604_annotation::use_pep604_annotation;
|
pub(crate) use use_pep604_annotation::use_pep604_annotation;
|
||||||
|
|
@ -44,6 +45,8 @@ mod datetime_utc_alias;
|
||||||
mod deprecated_unittest_alias;
|
mod deprecated_unittest_alias;
|
||||||
mod f_strings;
|
mod f_strings;
|
||||||
mod format_literals;
|
mod format_literals;
|
||||||
|
mod functools_cache;
|
||||||
|
mod lru_cache_without_parameters;
|
||||||
mod native_literals;
|
mod native_literals;
|
||||||
mod open_alias;
|
mod open_alias;
|
||||||
mod os_error_alias;
|
mod os_error_alias;
|
||||||
|
|
@ -61,7 +64,6 @@ mod typing_text_str_alias;
|
||||||
mod unnecessary_builtin_import;
|
mod unnecessary_builtin_import;
|
||||||
mod unnecessary_encode_utf8;
|
mod unnecessary_encode_utf8;
|
||||||
mod unnecessary_future_import;
|
mod unnecessary_future_import;
|
||||||
mod unnecessary_lru_cache_params;
|
|
||||||
mod unpack_list_comprehension;
|
mod unpack_list_comprehension;
|
||||||
mod use_pep585_annotation;
|
mod use_pep585_annotation;
|
||||||
mod use_pep604_annotation;
|
mod use_pep604_annotation;
|
||||||
|
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
use rustpython_ast::{Constant, ExprKind, KeywordData};
|
|
||||||
use rustpython_parser::ast::Expr;
|
|
||||||
|
|
||||||
use crate::ast::helpers::{create_expr, unparse_expr};
|
|
||||||
use crate::ast::types::Range;
|
|
||||||
use crate::checkers::ast::Checker;
|
|
||||||
use crate::fix::Fix;
|
|
||||||
use crate::registry::{Diagnostic, RuleCode};
|
|
||||||
use crate::settings::types::PythonVersion;
|
|
||||||
use crate::violations;
|
|
||||||
|
|
||||||
/// UP011
|
|
||||||
pub fn unnecessary_lru_cache_params(checker: &mut Checker, decorator_list: &[Expr]) {
|
|
||||||
for expr in decorator_list.iter() {
|
|
||||||
let ExprKind::Call {
|
|
||||||
func,
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
} = &expr.node else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Look for, e.g., `import functools; @functools.lru_cache`.
|
|
||||||
if !(args.is_empty()
|
|
||||||
&& checker
|
|
||||||
.resolve_call_path(func)
|
|
||||||
.map_or(false, |call_path| call_path == ["functools", "lru_cache"]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ex) `functools.lru_cache()`
|
|
||||||
if keywords.is_empty() {
|
|
||||||
let mut diagnostic = Diagnostic::new(
|
|
||||||
violations::UnnecessaryLRUCacheParams,
|
|
||||||
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
|
|
||||||
);
|
|
||||||
if checker.patch(&RuleCode::UP011) {
|
|
||||||
diagnostic.amend(Fix::replacement(
|
|
||||||
unparse_expr(func, checker.stylist),
|
|
||||||
expr.location,
|
|
||||||
expr.end_location.unwrap(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
checker.diagnostics.push(diagnostic);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ex) `functools.lru_cache(maxsize=None)`
|
|
||||||
if !(checker.settings.target_version >= PythonVersion::Py39 && keywords.len() == 1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let KeywordData { arg, value } = &keywords[0].node;
|
|
||||||
if !(arg.as_ref().map_or(false, |arg| arg == "maxsize")
|
|
||||||
&& matches!(
|
|
||||||
value.node,
|
|
||||||
ExprKind::Constant {
|
|
||||||
value: Constant::None,
|
|
||||||
kind: None,
|
|
||||||
}
|
|
||||||
))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(
|
|
||||||
violations::UnnecessaryLRUCacheParams,
|
|
||||||
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
|
|
||||||
);
|
|
||||||
if checker.patch(&RuleCode::UP011) {
|
|
||||||
if let ExprKind::Attribute { value, ctx, .. } = &func.node {
|
|
||||||
diagnostic.amend(Fix::replacement(
|
|
||||||
unparse_expr(
|
|
||||||
&create_expr(ExprKind::Attribute {
|
|
||||||
value: value.clone(),
|
|
||||||
attr: "cache".to_string(),
|
|
||||||
ctx: ctx.clone(),
|
|
||||||
}),
|
|
||||||
checker.stylist,
|
|
||||||
),
|
|
||||||
expr.location,
|
|
||||||
expr.end_location.unwrap(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checker.diagnostics.push(diagnostic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
---
|
||||||
|
source: src/rules/pyupgrade/mod.rs
|
||||||
|
expression: diagnostics
|
||||||
|
---
|
||||||
|
- kind:
|
||||||
|
LRUCacheWithoutParameters: ~
|
||||||
|
location:
|
||||||
|
row: 5
|
||||||
|
column: 20
|
||||||
|
end_location:
|
||||||
|
row: 5
|
||||||
|
column: 22
|
||||||
|
fix:
|
||||||
|
content: functools.lru_cache
|
||||||
|
location:
|
||||||
|
row: 5
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 5
|
||||||
|
column: 22
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
LRUCacheWithoutParameters: ~
|
||||||
|
location:
|
||||||
|
row: 10
|
||||||
|
column: 10
|
||||||
|
end_location:
|
||||||
|
row: 10
|
||||||
|
column: 12
|
||||||
|
fix:
|
||||||
|
content: lru_cache
|
||||||
|
location:
|
||||||
|
row: 10
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 10
|
||||||
|
column: 12
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
LRUCacheWithoutParameters: ~
|
||||||
|
location:
|
||||||
|
row: 16
|
||||||
|
column: 20
|
||||||
|
end_location:
|
||||||
|
row: 16
|
||||||
|
column: 22
|
||||||
|
fix:
|
||||||
|
content: functools.lru_cache
|
||||||
|
location:
|
||||||
|
row: 16
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 16
|
||||||
|
column: 22
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
LRUCacheWithoutParameters: ~
|
||||||
|
location:
|
||||||
|
row: 21
|
||||||
|
column: 20
|
||||||
|
end_location:
|
||||||
|
row: 21
|
||||||
|
column: 22
|
||||||
|
fix:
|
||||||
|
content: functools.lru_cache
|
||||||
|
location:
|
||||||
|
row: 21
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 21
|
||||||
|
column: 22
|
||||||
|
parent: ~
|
||||||
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
---
|
|
||||||
source: src/rules/pyupgrade/mod.rs
|
|
||||||
expression: diagnostics
|
|
||||||
---
|
|
||||||
- kind:
|
|
||||||
UnnecessaryLRUCacheParams: ~
|
|
||||||
location:
|
|
||||||
row: 5
|
|
||||||
column: 10
|
|
||||||
end_location:
|
|
||||||
row: 5
|
|
||||||
column: 12
|
|
||||||
fix:
|
|
||||||
content: lru_cache
|
|
||||||
location:
|
|
||||||
row: 5
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 5
|
|
||||||
column: 12
|
|
||||||
parent: ~
|
|
||||||
- kind:
|
|
||||||
UnnecessaryLRUCacheParams: ~
|
|
||||||
location:
|
|
||||||
row: 11
|
|
||||||
column: 20
|
|
||||||
end_location:
|
|
||||||
row: 11
|
|
||||||
column: 22
|
|
||||||
fix:
|
|
||||||
content: functools.lru_cache
|
|
||||||
location:
|
|
||||||
row: 11
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 11
|
|
||||||
column: 22
|
|
||||||
parent: ~
|
|
||||||
- kind:
|
|
||||||
UnnecessaryLRUCacheParams: ~
|
|
||||||
location:
|
|
||||||
row: 16
|
|
||||||
column: 10
|
|
||||||
end_location:
|
|
||||||
row: 16
|
|
||||||
column: 24
|
|
||||||
fix: ~
|
|
||||||
parent: ~
|
|
||||||
- kind:
|
|
||||||
UnnecessaryLRUCacheParams: ~
|
|
||||||
location:
|
|
||||||
row: 21
|
|
||||||
column: 20
|
|
||||||
end_location:
|
|
||||||
row: 21
|
|
||||||
column: 34
|
|
||||||
fix:
|
|
||||||
content: functools.cache
|
|
||||||
location:
|
|
||||||
row: 21
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 21
|
|
||||||
column: 34
|
|
||||||
parent: ~
|
|
||||||
- kind:
|
|
||||||
UnnecessaryLRUCacheParams: ~
|
|
||||||
location:
|
|
||||||
row: 27
|
|
||||||
column: 10
|
|
||||||
end_location:
|
|
||||||
row: 28
|
|
||||||
column: 1
|
|
||||||
fix:
|
|
||||||
content: lru_cache
|
|
||||||
location:
|
|
||||||
row: 27
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 28
|
|
||||||
column: 1
|
|
||||||
parent: ~
|
|
||||||
- kind:
|
|
||||||
UnnecessaryLRUCacheParams: ~
|
|
||||||
location:
|
|
||||||
row: 33
|
|
||||||
column: 10
|
|
||||||
end_location:
|
|
||||||
row: 35
|
|
||||||
column: 1
|
|
||||||
fix:
|
|
||||||
content: lru_cache
|
|
||||||
location:
|
|
||||||
row: 33
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 35
|
|
||||||
column: 1
|
|
||||||
parent: ~
|
|
||||||
- kind:
|
|
||||||
UnnecessaryLRUCacheParams: ~
|
|
||||||
location:
|
|
||||||
row: 40
|
|
||||||
column: 20
|
|
||||||
end_location:
|
|
||||||
row: 42
|
|
||||||
column: 19
|
|
||||||
fix:
|
|
||||||
content: functools.cache
|
|
||||||
location:
|
|
||||||
row: 40
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 42
|
|
||||||
column: 19
|
|
||||||
parent: ~
|
|
||||||
- kind:
|
|
||||||
UnnecessaryLRUCacheParams: ~
|
|
||||||
location:
|
|
||||||
row: 47
|
|
||||||
column: 20
|
|
||||||
end_location:
|
|
||||||
row: 51
|
|
||||||
column: 1
|
|
||||||
fix:
|
|
||||||
content: functools.cache
|
|
||||||
location:
|
|
||||||
row: 47
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 51
|
|
||||||
column: 1
|
|
||||||
parent: ~
|
|
||||||
- kind:
|
|
||||||
UnnecessaryLRUCacheParams: ~
|
|
||||||
location:
|
|
||||||
row: 56
|
|
||||||
column: 20
|
|
||||||
end_location:
|
|
||||||
row: 62
|
|
||||||
column: 1
|
|
||||||
fix:
|
|
||||||
content: functools.cache
|
|
||||||
location:
|
|
||||||
row: 56
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 62
|
|
||||||
column: 1
|
|
||||||
parent: ~
|
|
||||||
- kind:
|
|
||||||
UnnecessaryLRUCacheParams: ~
|
|
||||||
location:
|
|
||||||
row: 67
|
|
||||||
column: 20
|
|
||||||
end_location:
|
|
||||||
row: 72
|
|
||||||
column: 1
|
|
||||||
fix:
|
|
||||||
content: functools.cache
|
|
||||||
location:
|
|
||||||
row: 67
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 72
|
|
||||||
column: 1
|
|
||||||
parent: ~
|
|
||||||
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
---
|
|
||||||
source: src/rules/pyupgrade/mod.rs
|
|
||||||
expression: diagnostics
|
|
||||||
---
|
|
||||||
[]
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
source: src/rules/pyupgrade/mod.rs
|
||||||
|
expression: diagnostics
|
||||||
|
---
|
||||||
|
- kind:
|
||||||
|
FunctoolsCache: ~
|
||||||
|
location:
|
||||||
|
row: 5
|
||||||
|
column: 20
|
||||||
|
end_location:
|
||||||
|
row: 5
|
||||||
|
column: 34
|
||||||
|
fix:
|
||||||
|
content: functools.cache
|
||||||
|
location:
|
||||||
|
row: 5
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 5
|
||||||
|
column: 34
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
FunctoolsCache: ~
|
||||||
|
location:
|
||||||
|
row: 10
|
||||||
|
column: 10
|
||||||
|
end_location:
|
||||||
|
row: 10
|
||||||
|
column: 24
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
FunctoolsCache: ~
|
||||||
|
location:
|
||||||
|
row: 16
|
||||||
|
column: 20
|
||||||
|
end_location:
|
||||||
|
row: 16
|
||||||
|
column: 34
|
||||||
|
fix:
|
||||||
|
content: functools.cache
|
||||||
|
location:
|
||||||
|
row: 16
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 16
|
||||||
|
column: 34
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
FunctoolsCache: ~
|
||||||
|
location:
|
||||||
|
row: 21
|
||||||
|
column: 20
|
||||||
|
end_location:
|
||||||
|
row: 21
|
||||||
|
column: 34
|
||||||
|
fix:
|
||||||
|
content: functools.cache
|
||||||
|
location:
|
||||||
|
row: 21
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 21
|
||||||
|
column: 34
|
||||||
|
parent: ~
|
||||||
|
|
||||||
|
|
@ -3396,9 +3396,9 @@ impl AlwaysAutofixableViolation for UnnecessaryFutureImport {
|
||||||
}
|
}
|
||||||
|
|
||||||
define_violation!(
|
define_violation!(
|
||||||
pub struct UnnecessaryLRUCacheParams;
|
pub struct LRUCacheWithoutParameters;
|
||||||
);
|
);
|
||||||
impl AlwaysAutofixableViolation for UnnecessaryLRUCacheParams {
|
impl AlwaysAutofixableViolation for LRUCacheWithoutParameters {
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
"Unnecessary parameters to `functools.lru_cache`".to_string()
|
"Unnecessary parameters to `functools.lru_cache`".to_string()
|
||||||
}
|
}
|
||||||
|
|
@ -3408,7 +3408,7 @@ impl AlwaysAutofixableViolation for UnnecessaryLRUCacheParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn placeholder() -> Self {
|
fn placeholder() -> Self {
|
||||||
UnnecessaryLRUCacheParams
|
LRUCacheWithoutParameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3814,6 +3814,23 @@ impl AlwaysAutofixableViolation for FString {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct FunctoolsCache;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for FunctoolsCache {
|
||||||
|
fn message(&self) -> String {
|
||||||
|
"Use `@functools.cache` instead of `@functools.lru_cache(maxsize=None)`".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Rewrite with `@functools.cache".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn placeholder() -> Self {
|
||||||
|
FunctoolsCache
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
|
|
||||||
define_violation!(
|
define_violation!(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue