Compare commits
44 Commits
micha/add-
...
micha/blan
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1c0d1baa8 | ||
|
|
d6221371f7 | ||
|
|
6fc3434397 | ||
|
|
5a40aee73f | ||
|
|
b93f8292d5 | ||
|
|
f49b10a450 | ||
|
|
796627997e | ||
|
|
396fe3f7f0 | ||
|
|
1fd0ea3f24 | ||
|
|
4c4d43d168 | ||
|
|
7672dd0889 | ||
|
|
b4809b7562 | ||
|
|
3d9fd7b4a5 | ||
|
|
2f2bcbb590 | ||
|
|
2daa9da0ca | ||
|
|
5f05012905 | ||
|
|
2cada23145 | ||
|
|
78164abd19 | ||
|
|
29a2779e8b | ||
|
|
7bc8bb277b | ||
|
|
464ea4a5e4 | ||
|
|
e9bfdfda6b | ||
|
|
7585d43b8b | ||
|
|
406402bd0c | ||
|
|
57bf330139 | ||
|
|
0ced1cb2db | ||
|
|
7690b339cf | ||
|
|
26cf0fea5b | ||
|
|
e261f633ca | ||
|
|
948435d5b3 | ||
|
|
b8f128442e | ||
|
|
85f7871754 | ||
|
|
daeb8f11f2 | ||
|
|
1898702a36 | ||
|
|
5ec7c138f6 | ||
|
|
303b061f7b | ||
|
|
f1014ce451 | ||
|
|
afb7da860f | ||
|
|
f1afd6edd8 | ||
|
|
80a3221c6a | ||
|
|
2ae5344708 | ||
|
|
6ba6cfd37c | ||
|
|
41cd905fda | ||
|
|
e4e1c58152 |
2
.github/workflows/build-docker.yml
vendored
2
.github/workflows/build-docker.yml
vendored
@@ -163,7 +163,7 @@ jobs:
|
||||
# Mapping of base image followed by a comma followed by one or more base tags (comma separated)
|
||||
# Note, org.opencontainers.image.version label will use the first base tag (use the most specific tag first)
|
||||
image-mapping:
|
||||
- alpine:3.20,alpine3.20,alpine
|
||||
- alpine:3.21,alpine3.21,alpine
|
||||
- debian:bookworm-slim,bookworm-slim,debian-slim
|
||||
- buildpack-deps:bookworm,bookworm,debian
|
||||
steps:
|
||||
|
||||
@@ -2470,7 +2470,7 @@ fn create_a005_module_structure(tempdir: &TempDir) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test A005 with `builtins-strict-checking = true`
|
||||
/// Test A005 with `strict-checking = true`
|
||||
#[test]
|
||||
fn a005_module_shadowing_strict() -> Result<()> {
|
||||
let tempdir = TempDir::new()?;
|
||||
@@ -2482,7 +2482,7 @@ fn a005_module_shadowing_strict() -> Result<()> {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.arg("--config")
|
||||
.arg(r#"lint.flake8-builtins.builtins-strict-checking = true"#)
|
||||
.arg(r#"lint.flake8-builtins.strict-checking = true"#)
|
||||
.args(["--select", "A005"])
|
||||
.current_dir(tempdir.path()),
|
||||
@r"
|
||||
@@ -2504,7 +2504,7 @@ fn a005_module_shadowing_strict() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test A005 with `builtins-strict-checking = false`
|
||||
/// Test A005 with `strict-checking = false`
|
||||
#[test]
|
||||
fn a005_module_shadowing_non_strict() -> Result<()> {
|
||||
let tempdir = TempDir::new()?;
|
||||
@@ -2516,7 +2516,7 @@ fn a005_module_shadowing_non_strict() -> Result<()> {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.arg("--config")
|
||||
.arg(r#"lint.flake8-builtins.builtins-strict-checking = false"#)
|
||||
.arg(r#"lint.flake8-builtins.strict-checking = false"#)
|
||||
.args(["--select", "A005"])
|
||||
.current_dir(tempdir.path()),
|
||||
@r"
|
||||
@@ -2535,7 +2535,7 @@ fn a005_module_shadowing_non_strict() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test A005 with `builtins-strict-checking` unset
|
||||
/// Test A005 with `strict-checking` unset
|
||||
/// TODO(brent) This should currently match the strict version, but after the next minor
|
||||
/// release it will match the non-strict version directly above
|
||||
#[test]
|
||||
@@ -2556,11 +2556,7 @@ fn a005_module_shadowing_strict_default() -> Result<()> {
|
||||
----- stdout -----
|
||||
abc/__init__.py:1:1: A005 Module `abc` shadows a Python standard-library module
|
||||
collections/__init__.py:1:1: A005 Module `collections` shadows a Python standard-library module
|
||||
collections/abc/__init__.py:1:1: A005 Module `abc` shadows a Python standard-library module
|
||||
foobar/abc/__init__.py:1:1: A005 Module `abc` shadows a Python standard-library module
|
||||
foobar/collections/__init__.py:1:1: A005 Module `collections` shadows a Python standard-library module
|
||||
foobar/collections/abc/__init__.py:1:1: A005 Module `abc` shadows a Python standard-library module
|
||||
Found 6 errors.
|
||||
Found 2 errors.
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
@@ -226,10 +226,12 @@ linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||
/dev/shm,
|
||||
]
|
||||
linter.flake8_bandit.check_typed_exception = false
|
||||
linter.flake8_bandit.extend_markup_names = []
|
||||
linter.flake8_bandit.allowed_markup_calls = []
|
||||
linter.flake8_bugbear.extend_immutable_calls = []
|
||||
linter.flake8_builtins.builtins_allowed_modules = []
|
||||
linter.flake8_builtins.builtins_ignorelist = []
|
||||
linter.flake8_builtins.builtins_strict_checking = true
|
||||
linter.flake8_builtins.allowed_modules = []
|
||||
linter.flake8_builtins.ignorelist = []
|
||||
linter.flake8_builtins.strict_checking = false
|
||||
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+((?:\(C\)|©)\s+)?\d{4}((-|,\s)\d{4})*
|
||||
linter.flake8_copyright.author = none
|
||||
@@ -369,8 +371,6 @@ linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
linter.ruff.extend_markup_names = []
|
||||
linter.ruff.allowed_markup_calls = []
|
||||
|
||||
# Formatter Settings
|
||||
formatter.exclude = []
|
||||
|
||||
@@ -2,17 +2,17 @@ import flask
|
||||
from markupsafe import Markup, escape
|
||||
|
||||
content = "<script>alert('Hello, world!')</script>"
|
||||
Markup(f"unsafe {content}") # RUF035
|
||||
flask.Markup("unsafe {}".format(content)) # RUF035
|
||||
Markup(f"unsafe {content}") # S704
|
||||
flask.Markup("unsafe {}".format(content)) # S704
|
||||
Markup("safe {}").format(content)
|
||||
flask.Markup(b"safe {}", encoding='utf-8').format(content)
|
||||
escape(content)
|
||||
Markup(content) # RUF035
|
||||
flask.Markup("unsafe %s" % content) # RUF035
|
||||
Markup(content) # S704
|
||||
flask.Markup("unsafe %s" % content) # S704
|
||||
Markup(object="safe")
|
||||
Markup(object="unsafe {}".format(content)) # Not currently detected
|
||||
|
||||
# NOTE: We may be able to get rid of these false positives with red-knot
|
||||
# if it includes comprehensive constant expression detection/evaluation.
|
||||
Markup("*" * 8) # RUF035 (false positive)
|
||||
flask.Markup("hello {}".format("world")) # RUF035 (false positive)
|
||||
Markup("*" * 8) # S704 (false positive)
|
||||
flask.Markup("hello {}".format("world")) # S704 (false positive)
|
||||
@@ -2,5 +2,5 @@ from markupsafe import Markup
|
||||
from webhelpers.html import literal
|
||||
|
||||
content = "<script>alert('Hello, world!')</script>"
|
||||
Markup(f"unsafe {content}") # RUF035
|
||||
literal(f"unsafe {content}") # RUF035
|
||||
Markup(f"unsafe {content}") # S704
|
||||
literal(f"unsafe {content}") # S704
|
||||
@@ -4,4 +4,4 @@ from webhelpers.html import literal
|
||||
# additional markup names to be skipped if we don't import either
|
||||
# markupsafe or flask first.
|
||||
content = "<script>alert('Hello, world!')</script>"
|
||||
literal(f"unsafe {content}") # RUF035
|
||||
literal(f"unsafe {content}") # S704
|
||||
@@ -6,4 +6,4 @@ Markup(clean(content))
|
||||
|
||||
# indirect assignments are currently not supported
|
||||
cleaned = clean(content)
|
||||
Markup(cleaned) # RUF035
|
||||
Markup(cleaned) # S704
|
||||
@@ -4,13 +4,6 @@ if TYPE_CHECKING:
|
||||
pass # TC005
|
||||
|
||||
|
||||
if False:
|
||||
pass # TC005
|
||||
|
||||
if 0:
|
||||
pass # TC005
|
||||
|
||||
|
||||
def example():
|
||||
if TYPE_CHECKING:
|
||||
pass # TC005
|
||||
@@ -32,13 +25,6 @@ if TYPE_CHECKING:
|
||||
x: List
|
||||
|
||||
|
||||
if False:
|
||||
x: List
|
||||
|
||||
if 0:
|
||||
x: List
|
||||
|
||||
|
||||
from typing_extensions import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
@@ -19,5 +19,6 @@ def f():
|
||||
|
||||
|
||||
def f():
|
||||
# Only `E741` should be ignored by the `noqa`.
|
||||
# Neither of these are ignored and warning is
|
||||
# logged to user
|
||||
I = 1 # noqa: E741.F841
|
||||
|
||||
@@ -428,7 +428,7 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
||||
flake8_2020::rules::name_or_attribute(checker, expr);
|
||||
}
|
||||
if checker.enabled(Rule::DatetimeMinMax) {
|
||||
flake8_datetimez::rules::datetime_max_min(checker, expr);
|
||||
flake8_datetimez::rules::datetime_min_max(checker, expr);
|
||||
}
|
||||
if checker.enabled(Rule::BannedApi) {
|
||||
flake8_tidy_imports::rules::banned_attribute_access(checker, expr);
|
||||
@@ -1129,7 +1129,7 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
||||
refurb::rules::int_on_sliced_str(checker, call);
|
||||
}
|
||||
if checker.enabled(Rule::UnsafeMarkupUse) {
|
||||
ruff::rules::unsafe_markup_call(checker, call);
|
||||
flake8_bandit::rules::unsafe_markup_call(checker, call);
|
||||
}
|
||||
if checker.enabled(Rule::MapIntVersionParsing) {
|
||||
ruff::rules::map_int_version_parsing(checker, call);
|
||||
|
||||
@@ -246,11 +246,7 @@ impl<'a> Checker<'a> {
|
||||
notebook_index: Option<&'a NotebookIndex>,
|
||||
target_version: PythonVersion,
|
||||
) -> Checker<'a> {
|
||||
let mut semantic = SemanticModel::new(&settings.typing_modules, path, module);
|
||||
if settings.preview.is_enabled() {
|
||||
// Set the feature flag to test `TYPE_CHECKING` semantic changes
|
||||
semantic.flags |= SemanticModelFlags::NEW_TYPE_CHECKING_BLOCK_DETECTION;
|
||||
}
|
||||
let semantic = SemanticModel::new(&settings.typing_modules, path, module);
|
||||
Self {
|
||||
parsed,
|
||||
parsed_type_annotation: None,
|
||||
@@ -293,7 +289,14 @@ impl<'a> Checker<'a> {
|
||||
if !self.noqa.is_enabled() {
|
||||
return false;
|
||||
}
|
||||
noqa::rule_is_ignored(code, offset, self.noqa_line_for, self.locator)
|
||||
|
||||
noqa::rule_is_ignored(
|
||||
code,
|
||||
offset,
|
||||
self.noqa_line_for,
|
||||
self.comment_ranges(),
|
||||
self.locator,
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a [`Generator`] to generate source code based on the current AST state.
|
||||
|
||||
@@ -38,7 +38,8 @@ pub(crate) fn check_noqa(
|
||||
let exemption = FileExemption::from(&file_noqa_directives);
|
||||
|
||||
// Extract all `noqa` directives.
|
||||
let mut noqa_directives = NoqaDirectives::from_commented_ranges(comment_ranges, path, locator);
|
||||
let mut noqa_directives =
|
||||
NoqaDirectives::from_commented_ranges(comment_ranges, &settings.external, path, locator);
|
||||
|
||||
// Indices of diagnostics that were ignored by a `noqa` directive.
|
||||
let mut ignored_diagnostics = vec![];
|
||||
@@ -223,7 +224,6 @@ pub(crate) fn check_noqa(
|
||||
&noqa_directives,
|
||||
locator,
|
||||
&file_noqa_directives,
|
||||
settings.preview,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Pylint, "C0208") => (RuleGroup::Stable, rules::pylint::rules::IterationOverSet),
|
||||
(Pylint, "C0414") => (RuleGroup::Stable, rules::pylint::rules::UselessImportAlias),
|
||||
(Pylint, "C0415") => (RuleGroup::Preview, rules::pylint::rules::ImportOutsideTopLevel),
|
||||
(Pylint, "C1802") => (RuleGroup::Preview, rules::pylint::rules::LenTest),
|
||||
(Pylint, "C1802") => (RuleGroup::Stable, rules::pylint::rules::LenTest),
|
||||
(Pylint, "C1901") => (RuleGroup::Preview, rules::pylint::rules::CompareToEmptyString),
|
||||
(Pylint, "C2401") => (RuleGroup::Stable, rules::pylint::rules::NonAsciiName),
|
||||
(Pylint, "C2403") => (RuleGroup::Stable, rules::pylint::rules::NonAsciiImportName),
|
||||
@@ -288,7 +288,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Pylint, "W0642") => (RuleGroup::Stable, rules::pylint::rules::SelfOrClsAssignment),
|
||||
(Pylint, "W0711") => (RuleGroup::Stable, rules::pylint::rules::BinaryOpException),
|
||||
(Pylint, "W1501") => (RuleGroup::Stable, rules::pylint::rules::BadOpenMode),
|
||||
(Pylint, "W1507") => (RuleGroup::Preview, rules::pylint::rules::ShallowCopyEnviron),
|
||||
(Pylint, "W1507") => (RuleGroup::Stable, rules::pylint::rules::ShallowCopyEnviron),
|
||||
(Pylint, "W1508") => (RuleGroup::Stable, rules::pylint::rules::InvalidEnvvarDefault),
|
||||
(Pylint, "W1509") => (RuleGroup::Stable, rules::pylint::rules::SubprocessPopenPreexecFn),
|
||||
(Pylint, "W1510") => (RuleGroup::Stable, rules::pylint::rules::SubprocessRunWithoutCheck),
|
||||
@@ -362,7 +362,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8Bugbear, "904") => (RuleGroup::Stable, rules::flake8_bugbear::rules::RaiseWithoutFromInsideExcept),
|
||||
(Flake8Bugbear, "905") => (RuleGroup::Stable, rules::flake8_bugbear::rules::ZipWithoutExplicitStrict),
|
||||
(Flake8Bugbear, "909") => (RuleGroup::Preview, rules::flake8_bugbear::rules::LoopIteratorMutation),
|
||||
(Flake8Bugbear, "911") => (RuleGroup::Preview, rules::flake8_bugbear::rules::BatchedWithoutExplicitStrict),
|
||||
(Flake8Bugbear, "911") => (RuleGroup::Stable, rules::flake8_bugbear::rules::BatchedWithoutExplicitStrict),
|
||||
|
||||
// flake8-blind-except
|
||||
(Flake8BlindExcept, "001") => (RuleGroup::Stable, rules::flake8_blind_except::rules::BlindExcept),
|
||||
@@ -386,7 +386,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8Comprehensions, "17") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryMap),
|
||||
(Flake8Comprehensions, "18") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinDictCall),
|
||||
(Flake8Comprehensions, "19") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryComprehensionInCall),
|
||||
(Flake8Comprehensions, "20") => (RuleGroup::Preview, rules::flake8_comprehensions::rules::UnnecessaryDictComprehensionForIterable),
|
||||
(Flake8Comprehensions, "20") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryDictComprehensionForIterable),
|
||||
|
||||
// flake8-debugger
|
||||
(Flake8Debugger, "0") => (RuleGroup::Stable, rules::flake8_debugger::rules::Debugger),
|
||||
@@ -489,7 +489,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8Simplify, "223") => (RuleGroup::Stable, rules::flake8_simplify::rules::ExprAndFalse),
|
||||
(Flake8Simplify, "300") => (RuleGroup::Stable, rules::flake8_simplify::rules::YodaConditions),
|
||||
(Flake8Simplify, "401") => (RuleGroup::Stable, rules::flake8_simplify::rules::IfElseBlockInsteadOfDictGet),
|
||||
(Flake8Simplify, "905") => (RuleGroup::Preview, rules::flake8_simplify::rules::SplitStaticString),
|
||||
(Flake8Simplify, "905") => (RuleGroup::Stable, rules::flake8_simplify::rules::SplitStaticString),
|
||||
(Flake8Simplify, "910") => (RuleGroup::Stable, rules::flake8_simplify::rules::DictGetWithNoneDefault),
|
||||
(Flake8Simplify, "911") => (RuleGroup::Stable, rules::flake8_simplify::rules::ZipDictKeysAndValues),
|
||||
|
||||
@@ -532,13 +532,13 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Pyupgrade, "035") => (RuleGroup::Stable, rules::pyupgrade::rules::DeprecatedImport),
|
||||
(Pyupgrade, "036") => (RuleGroup::Stable, rules::pyupgrade::rules::OutdatedVersionBlock),
|
||||
(Pyupgrade, "037") => (RuleGroup::Stable, rules::pyupgrade::rules::QuotedAnnotation),
|
||||
(Pyupgrade, "038") => (RuleGroup::Stable, rules::pyupgrade::rules::NonPEP604Isinstance),
|
||||
(Pyupgrade, "038") => (RuleGroup::Deprecated, rules::pyupgrade::rules::NonPEP604Isinstance),
|
||||
(Pyupgrade, "039") => (RuleGroup::Stable, rules::pyupgrade::rules::UnnecessaryClassParentheses),
|
||||
(Pyupgrade, "040") => (RuleGroup::Stable, rules::pyupgrade::rules::NonPEP695TypeAlias),
|
||||
(Pyupgrade, "041") => (RuleGroup::Stable, rules::pyupgrade::rules::TimeoutErrorAlias),
|
||||
(Pyupgrade, "042") => (RuleGroup::Preview, rules::pyupgrade::rules::ReplaceStrEnum),
|
||||
(Pyupgrade, "043") => (RuleGroup::Stable, rules::pyupgrade::rules::UnnecessaryDefaultTypeArgs),
|
||||
(Pyupgrade, "044") => (RuleGroup::Preview, rules::pyupgrade::rules::NonPEP646Unpack),
|
||||
(Pyupgrade, "044") => (RuleGroup::Stable, rules::pyupgrade::rules::NonPEP646Unpack),
|
||||
(Pyupgrade, "045") => (RuleGroup::Preview, rules::pyupgrade::rules::NonPEP604AnnotationOptional),
|
||||
(Pyupgrade, "046") => (RuleGroup::Preview, rules::pyupgrade::rules::NonPEP695GenericClass),
|
||||
(Pyupgrade, "047") => (RuleGroup::Preview, rules::pyupgrade::rules::NonPEP695GenericFunction),
|
||||
@@ -649,7 +649,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8Bandit, "317") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLSaxUsage),
|
||||
(Flake8Bandit, "318") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLMiniDOMUsage),
|
||||
(Flake8Bandit, "319") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLPullDOMUsage),
|
||||
(Flake8Bandit, "320") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLETreeUsage),
|
||||
(Flake8Bandit, "320") => (RuleGroup::Deprecated, rules::flake8_bandit::rules::SuspiciousXMLETreeUsage),
|
||||
(Flake8Bandit, "321") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousFTPLibUsage),
|
||||
(Flake8Bandit, "323") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousUnverifiedContextUsage),
|
||||
(Flake8Bandit, "324") => (RuleGroup::Stable, rules::flake8_bandit::rules::HashlibInsecureHashFunction),
|
||||
@@ -690,6 +690,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8Bandit, "612") => (RuleGroup::Stable, rules::flake8_bandit::rules::LoggingConfigInsecureListen),
|
||||
(Flake8Bandit, "701") => (RuleGroup::Stable, rules::flake8_bandit::rules::Jinja2AutoescapeFalse),
|
||||
(Flake8Bandit, "702") => (RuleGroup::Stable, rules::flake8_bandit::rules::MakoTemplates),
|
||||
(Flake8Bandit, "704") => (RuleGroup::Stable, rules::flake8_bandit::rules::UnsafeMarkupUse),
|
||||
|
||||
// flake8-boolean-trap
|
||||
(Flake8BooleanTrap, "001") => (RuleGroup::Stable, rules::flake8_boolean_trap::rules::BooleanTypeHintPositionalArgument),
|
||||
@@ -718,7 +719,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8Datetimez, "007") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDatetimeStrptimeWithoutZone),
|
||||
(Flake8Datetimez, "011") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDateToday),
|
||||
(Flake8Datetimez, "012") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDateFromtimestamp),
|
||||
(Flake8Datetimez, "901") => (RuleGroup::Preview, rules::flake8_datetimez::rules::DatetimeMinMax),
|
||||
(Flake8Datetimez, "901") => (RuleGroup::Stable, rules::flake8_datetimez::rules::DatetimeMinMax),
|
||||
|
||||
// pygrep-hooks
|
||||
(PygrepHooks, "001") => (RuleGroup::Removed, rules::pygrep_hooks::rules::Eval),
|
||||
@@ -870,8 +871,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8TypeChecking, "003") => (RuleGroup::Stable, rules::flake8_type_checking::rules::TypingOnlyStandardLibraryImport),
|
||||
(Flake8TypeChecking, "004") => (RuleGroup::Stable, rules::flake8_type_checking::rules::RuntimeImportInTypeCheckingBlock),
|
||||
(Flake8TypeChecking, "005") => (RuleGroup::Stable, rules::flake8_type_checking::rules::EmptyTypeCheckingBlock),
|
||||
(Flake8TypeChecking, "006") => (RuleGroup::Preview, rules::flake8_type_checking::rules::RuntimeCastValue),
|
||||
(Flake8TypeChecking, "007") => (RuleGroup::Preview, rules::flake8_type_checking::rules::UnquotedTypeAlias),
|
||||
(Flake8TypeChecking, "006") => (RuleGroup::Stable, rules::flake8_type_checking::rules::RuntimeCastValue),
|
||||
(Flake8TypeChecking, "007") => (RuleGroup::Stable, rules::flake8_type_checking::rules::UnquotedTypeAlias),
|
||||
(Flake8TypeChecking, "008") => (RuleGroup::Preview, rules::flake8_type_checking::rules::QuotedTypeAlias),
|
||||
(Flake8TypeChecking, "010") => (RuleGroup::Stable, rules::flake8_type_checking::rules::RuntimeStringUnion),
|
||||
|
||||
@@ -921,8 +922,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8UsePathlib, "205") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathGetctime),
|
||||
(Flake8UsePathlib, "206") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsSepSplit),
|
||||
(Flake8UsePathlib, "207") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::Glob),
|
||||
(Flake8UsePathlib, "208") => (RuleGroup::Preview, rules::flake8_use_pathlib::violations::OsListdir),
|
||||
(Flake8UsePathlib, "210") => (RuleGroup::Preview, rules::flake8_use_pathlib::rules::InvalidPathlibWithSuffix),
|
||||
(Flake8UsePathlib, "208") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsListdir),
|
||||
(Flake8UsePathlib, "210") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::InvalidPathlibWithSuffix),
|
||||
|
||||
// flake8-logging-format
|
||||
(Flake8LoggingFormat, "001") => (RuleGroup::Stable, rules::flake8_logging_format::violations::LoggingStringFormat),
|
||||
@@ -949,7 +950,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
// fastapi
|
||||
(FastApi, "001") => (RuleGroup::Stable, rules::fastapi::rules::FastApiRedundantResponseModel),
|
||||
(FastApi, "002") => (RuleGroup::Stable, rules::fastapi::rules::FastApiNonAnnotatedDependency),
|
||||
(FastApi, "003") => (RuleGroup::Preview, rules::fastapi::rules::FastApiUnusedPathParameter),
|
||||
(FastApi, "003") => (RuleGroup::Stable, rules::fastapi::rules::FastApiUnusedPathParameter),
|
||||
|
||||
// pydoclint
|
||||
(Pydoclint, "201") => (RuleGroup::Preview, rules::pydoclint::rules::DocstringMissingReturns),
|
||||
@@ -991,20 +992,20 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Ruff, "032") => (RuleGroup::Stable, rules::ruff::rules::DecimalFromFloatLiteral),
|
||||
(Ruff, "033") => (RuleGroup::Stable, rules::ruff::rules::PostInitDefault),
|
||||
(Ruff, "034") => (RuleGroup::Stable, rules::ruff::rules::UselessIfElse),
|
||||
(Ruff, "035") => (RuleGroup::Preview, rules::ruff::rules::UnsafeMarkupUse),
|
||||
(Ruff, "035") => (RuleGroup::Removed, rules::ruff::rules::RuffUnsafeMarkupUse),
|
||||
(Ruff, "036") => (RuleGroup::Preview, rules::ruff::rules::NoneNotAtEndOfUnion),
|
||||
(Ruff, "037") => (RuleGroup::Preview, rules::ruff::rules::UnnecessaryEmptyIterableWithinDequeCall),
|
||||
(Ruff, "038") => (RuleGroup::Preview, rules::ruff::rules::RedundantBoolLiteral),
|
||||
(Ruff, "039") => (RuleGroup::Preview, rules::ruff::rules::UnrawRePattern),
|
||||
(Ruff, "040") => (RuleGroup::Preview, rules::ruff::rules::InvalidAssertMessageLiteralArgument),
|
||||
(Ruff, "041") => (RuleGroup::Preview, rules::ruff::rules::UnnecessaryNestedLiteral),
|
||||
(Ruff, "040") => (RuleGroup::Stable, rules::ruff::rules::InvalidAssertMessageLiteralArgument),
|
||||
(Ruff, "041") => (RuleGroup::Stable, rules::ruff::rules::UnnecessaryNestedLiteral),
|
||||
(Ruff, "043") => (RuleGroup::Preview, rules::ruff::rules::PytestRaisesAmbiguousPattern),
|
||||
(Ruff, "045") => (RuleGroup::Preview, rules::ruff::rules::ImplicitClassVarInDataclass),
|
||||
(Ruff, "046") => (RuleGroup::Preview, rules::ruff::rules::UnnecessaryCastToInt),
|
||||
(Ruff, "046") => (RuleGroup::Stable, rules::ruff::rules::UnnecessaryCastToInt),
|
||||
(Ruff, "047") => (RuleGroup::Preview, rules::ruff::rules::NeedlessElse),
|
||||
(Ruff, "048") => (RuleGroup::Preview, rules::ruff::rules::MapIntVersionParsing),
|
||||
(Ruff, "048") => (RuleGroup::Stable, rules::ruff::rules::MapIntVersionParsing),
|
||||
(Ruff, "049") => (RuleGroup::Preview, rules::ruff::rules::DataclassEnum),
|
||||
(Ruff, "051") => (RuleGroup::Preview, rules::ruff::rules::IfKeyInDictDel),
|
||||
(Ruff, "051") => (RuleGroup::Stable, rules::ruff::rules::IfKeyInDictDel),
|
||||
(Ruff, "052") => (RuleGroup::Preview, rules::ruff::rules::UsedDummyVariable),
|
||||
(Ruff, "053") => (RuleGroup::Preview, rules::ruff::rules::ClassWithMixedTypeVars),
|
||||
(Ruff, "054") => (RuleGroup::Preview, rules::ruff::rules::IndentedFormFeed),
|
||||
@@ -1135,7 +1136,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8Logging, "007") => (RuleGroup::Stable, rules::flake8_logging::rules::ExceptionWithoutExcInfo),
|
||||
(Flake8Logging, "009") => (RuleGroup::Stable, rules::flake8_logging::rules::UndocumentedWarn),
|
||||
(Flake8Logging, "014") => (RuleGroup::Preview, rules::flake8_logging::rules::ExcInfoOutsideExceptHandler),
|
||||
(Flake8Logging, "015") => (RuleGroup::Preview, rules::flake8_logging::rules::RootLoggerCall),
|
||||
(Flake8Logging, "015") => (RuleGroup::Stable, rules::flake8_logging::rules::RootLoggerCall),
|
||||
|
||||
_ => return None,
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -134,6 +134,7 @@ static REDIRECTS: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(
|
||||
("TCH005", "TC005"),
|
||||
("TCH006", "TC010"),
|
||||
("TCH010", "TC010"),
|
||||
("RUF035", "S704"),
|
||||
])
|
||||
});
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ mod tests {
|
||||
#[test_case(Rule::DjangoExtra, Path::new("S610.py"))]
|
||||
#[test_case(Rule::DjangoRawSql, Path::new("S611.py"))]
|
||||
#[test_case(Rule::TarfileUnsafeMembers, Path::new("S202.py"))]
|
||||
#[test_case(Rule::UnsafeMarkupUse, Path::new("S704.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
@@ -120,6 +121,49 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::UnsafeMarkupUse, Path::new("S704_extend_markup_names.py"))]
|
||||
#[test_case(Rule::UnsafeMarkupUse, Path::new("S704_skip_early_out.py"))]
|
||||
fn extend_allowed_callable(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"extend_allow_callables__{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_bandit").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
flake8_bandit: super::settings::Settings {
|
||||
extend_markup_names: vec!["webhelpers.html.literal".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::UnsafeMarkupUse, Path::new("S704_whitelisted_markup_calls.py"))]
|
||||
fn whitelisted_markup_calls(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"whitelisted_markup_calls__{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_bandit").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
flake8_bandit: super::settings::Settings {
|
||||
allowed_markup_calls: vec!["bleach.clean".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_hardcoded_tmp_additional_dirs() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
@@ -132,7 +176,7 @@ mod tests {
|
||||
"/dev/shm".to_string(),
|
||||
"/foo".to_string(),
|
||||
],
|
||||
check_typed_exception: false,
|
||||
..Default::default()
|
||||
},
|
||||
..LinterSettings::for_rule(Rule::HardcodedTempFile)
|
||||
},
|
||||
|
||||
@@ -29,6 +29,7 @@ pub(crate) use suspicious_imports::*;
|
||||
pub(crate) use tarfile_unsafe_members::*;
|
||||
pub(crate) use try_except_continue::*;
|
||||
pub(crate) use try_except_pass::*;
|
||||
pub(crate) use unsafe_markup_use::*;
|
||||
pub(crate) use unsafe_yaml_load::*;
|
||||
pub(crate) use weak_cryptographic_key::*;
|
||||
|
||||
@@ -63,5 +64,6 @@ mod suspicious_imports;
|
||||
mod tarfile_unsafe_members;
|
||||
mod try_except_continue;
|
||||
mod try_except_pass;
|
||||
mod unsafe_markup_use;
|
||||
mod unsafe_yaml_load;
|
||||
mod weak_cryptographic_key;
|
||||
|
||||
@@ -779,6 +779,13 @@ impl Violation for SuspiciousXMLPullDOMUsage {
|
||||
}
|
||||
}
|
||||
|
||||
/// ## Deprecation
|
||||
///
|
||||
/// This rule was deprecated as the `lxml` library has been modified to address
|
||||
/// known vulnerabilities and unsafe defaults. As such, the `defusedxml`
|
||||
/// library is no longer necessary, `defusedxml` has [deprecated] its `lxml`
|
||||
/// module.
|
||||
///
|
||||
/// ## What it does
|
||||
/// Checks for uses of insecure XML parsers.
|
||||
///
|
||||
@@ -802,6 +809,7 @@ impl Violation for SuspiciousXMLPullDOMUsage {
|
||||
/// - [Common Weakness Enumeration: CWE-776](https://cwe.mitre.org/data/definitions/776.html)
|
||||
///
|
||||
/// [preview]: https://docs.astral.sh/ruff/preview/
|
||||
/// [deprecated]: https://pypi.org/project/defusedxml/0.8.0rc2/#defusedxml-lxml
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct SuspiciousXMLETreeUsage;
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
use ruff_python_ast::{Expr, ExprCall};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, ViolationMetadata};
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
use ruff_python_semantic::{Modules, SemanticModel};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::{checkers::ast::Checker, settings::LinterSettings};
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for non-literal strings being passed to [`markupsafe.Markup`][markupsafe-markup].
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// [`markupsafe.Markup`] does not perform any escaping, so passing dynamic
|
||||
/// content, like f-strings, variables or interpolated strings will potentially
|
||||
/// lead to XSS vulnerabilities.
|
||||
///
|
||||
/// Instead you should interpolate the `Markup` object.
|
||||
///
|
||||
/// Using [`lint.flake8-bandit.extend-markup-names`] additional objects can be
|
||||
/// treated like `Markup`.
|
||||
///
|
||||
/// This rule was originally inspired by [flake8-markupsafe] but doesn't carve
|
||||
/// out any exceptions for i18n related calls by default.
|
||||
///
|
||||
/// You can use [`lint.flake8-bandit.allowed-markup-calls`] to specify exceptions.
|
||||
///
|
||||
/// ## Example
|
||||
/// Given:
|
||||
/// ```python
|
||||
/// from markupsafe import Markup
|
||||
///
|
||||
/// content = "<script>alert('Hello, world!')</script>"
|
||||
/// html = Markup(f"<b>{content}</b>") # XSS
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// from markupsafe import Markup
|
||||
///
|
||||
/// content = "<script>alert('Hello, world!')</script>"
|
||||
/// html = Markup("<b>{}</b>").format(content) # Safe
|
||||
/// ```
|
||||
///
|
||||
/// Given:
|
||||
/// ```python
|
||||
/// from markupsafe import Markup
|
||||
///
|
||||
/// lines = [
|
||||
/// Markup("<b>heading</b>"),
|
||||
/// "<script>alert('XSS attempt')</script>",
|
||||
/// ]
|
||||
/// html = Markup("<br>".join(lines)) # XSS
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// from markupsafe import Markup
|
||||
///
|
||||
/// lines = [
|
||||
/// Markup("<b>heading</b>"),
|
||||
/// "<script>alert('XSS attempt')</script>",
|
||||
/// ]
|
||||
/// html = Markup("<br>").join(lines) # Safe
|
||||
/// ```
|
||||
/// ## Options
|
||||
/// - `lint.flake8-bandit.extend-markup-names`
|
||||
/// - `lint.flake8-bandit.allowed-markup-calls`
|
||||
///
|
||||
/// ## References
|
||||
/// - [MarkupSafe on PyPI](https://pypi.org/project/MarkupSafe/)
|
||||
/// - [`markupsafe.Markup` API documentation](https://markupsafe.palletsprojects.com/en/stable/escaping/#markupsafe.Markup)
|
||||
///
|
||||
/// [markupsafe-markup]: https://markupsafe.palletsprojects.com/en/stable/escaping/#markupsafe.Markup
|
||||
/// [flake8-markupsafe]: https://github.com/vmagamedov/flake8-markupsafe
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct UnsafeMarkupUse {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl Violation for UnsafeMarkupUse {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UnsafeMarkupUse { name } = self;
|
||||
format!("Unsafe use of `{name}` detected")
|
||||
}
|
||||
}
|
||||
|
||||
/// S704
|
||||
pub(crate) fn unsafe_markup_call(checker: &Checker, call: &ExprCall) {
|
||||
if checker
|
||||
.settings
|
||||
.flake8_bandit
|
||||
.extend_markup_names
|
||||
.is_empty()
|
||||
&& !(checker.semantic().seen_module(Modules::MARKUPSAFE)
|
||||
|| checker.semantic().seen_module(Modules::FLASK))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if !is_unsafe_call(call, checker.semantic(), checker.settings) {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(qualified_name) = checker.semantic().resolve_qualified_name(&call.func) else {
|
||||
return;
|
||||
};
|
||||
|
||||
if !is_markup_call(&qualified_name, checker.settings) {
|
||||
return;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
UnsafeMarkupUse {
|
||||
name: qualified_name.to_string(),
|
||||
},
|
||||
call.range(),
|
||||
));
|
||||
}
|
||||
|
||||
fn is_markup_call(qualified_name: &QualifiedName, settings: &LinterSettings) -> bool {
|
||||
matches!(
|
||||
qualified_name.segments(),
|
||||
["markupsafe" | "flask", "Markup"]
|
||||
) || settings
|
||||
.flake8_bandit
|
||||
.extend_markup_names
|
||||
.iter()
|
||||
.map(|target| QualifiedName::from_dotted_name(target))
|
||||
.any(|target| *qualified_name == target)
|
||||
}
|
||||
|
||||
fn is_unsafe_call(call: &ExprCall, semantic: &SemanticModel, settings: &LinterSettings) -> bool {
|
||||
// technically this could be circumvented by using a keyword argument
|
||||
// but without type-inference we can't really know which keyword argument
|
||||
// corresponds to the first positional argument and either way it is
|
||||
// unlikely that someone will actually use a keyword argument here
|
||||
// TODO: Eventually we may want to allow dynamic values, as long as they
|
||||
// have a __html__ attribute, since that is part of the API
|
||||
matches!(&*call.arguments.args, [first] if !first.is_string_literal_expr() && !first.is_bytes_literal_expr() && !is_whitelisted_call(first, semantic, settings))
|
||||
}
|
||||
|
||||
fn is_whitelisted_call(expr: &Expr, semantic: &SemanticModel, settings: &LinterSettings) -> bool {
|
||||
let Expr::Call(ExprCall { func, .. }) = expr else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let Some(qualified_name) = semantic.resolve_qualified_name(func) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
settings
|
||||
.flake8_bandit
|
||||
.allowed_markup_calls
|
||||
.iter()
|
||||
.map(|target| QualifiedName::from_dotted_name(target))
|
||||
.any(|target| qualified_name == target)
|
||||
}
|
||||
@@ -14,6 +14,8 @@ pub fn default_tmp_dirs() -> Vec<String> {
|
||||
pub struct Settings {
|
||||
pub hardcoded_tmp_directory: Vec<String>,
|
||||
pub check_typed_exception: bool,
|
||||
pub extend_markup_names: Vec<String>,
|
||||
pub allowed_markup_calls: Vec<String>,
|
||||
}
|
||||
|
||||
impl Default for Settings {
|
||||
@@ -21,6 +23,8 @@ impl Default for Settings {
|
||||
Self {
|
||||
hardcoded_tmp_directory: default_tmp_dirs(),
|
||||
check_typed_exception: false,
|
||||
extend_markup_names: vec![],
|
||||
allowed_markup_calls: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +36,9 @@ impl Display for Settings {
|
||||
namespace = "linter.flake8_bandit",
|
||||
fields = [
|
||||
self.hardcoded_tmp_directory | array,
|
||||
self.check_typed_exception
|
||||
self.check_typed_exception,
|
||||
self.extend_markup_names | array,
|
||||
self.allowed_markup_calls | array,
|
||||
]
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S704.py:5:1: S704 Unsafe use of `markupsafe.Markup` detected
|
||||
|
|
||||
4 | content = "<script>alert('Hello, world!')</script>"
|
||||
5 | Markup(f"unsafe {content}") # S704
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ S704
|
||||
6 | flask.Markup("unsafe {}".format(content)) # S704
|
||||
7 | Markup("safe {}").format(content)
|
||||
|
|
||||
|
||||
S704.py:6:1: S704 Unsafe use of `flask.Markup` detected
|
||||
|
|
||||
4 | content = "<script>alert('Hello, world!')</script>"
|
||||
5 | Markup(f"unsafe {content}") # S704
|
||||
6 | flask.Markup("unsafe {}".format(content)) # S704
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S704
|
||||
7 | Markup("safe {}").format(content)
|
||||
8 | flask.Markup(b"safe {}", encoding='utf-8').format(content)
|
||||
|
|
||||
|
||||
S704.py:10:1: S704 Unsafe use of `markupsafe.Markup` detected
|
||||
|
|
||||
8 | flask.Markup(b"safe {}", encoding='utf-8').format(content)
|
||||
9 | escape(content)
|
||||
10 | Markup(content) # S704
|
||||
| ^^^^^^^^^^^^^^^ S704
|
||||
11 | flask.Markup("unsafe %s" % content) # S704
|
||||
12 | Markup(object="safe")
|
||||
|
|
||||
|
||||
S704.py:11:1: S704 Unsafe use of `flask.Markup` detected
|
||||
|
|
||||
9 | escape(content)
|
||||
10 | Markup(content) # S704
|
||||
11 | flask.Markup("unsafe %s" % content) # S704
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S704
|
||||
12 | Markup(object="safe")
|
||||
13 | Markup(object="unsafe {}".format(content)) # Not currently detected
|
||||
|
|
||||
|
||||
S704.py:17:1: S704 Unsafe use of `markupsafe.Markup` detected
|
||||
|
|
||||
15 | # NOTE: We may be able to get rid of these false positives with red-knot
|
||||
16 | # if it includes comprehensive constant expression detection/evaluation.
|
||||
17 | Markup("*" * 8) # S704 (false positive)
|
||||
| ^^^^^^^^^^^^^^^ S704
|
||||
18 | flask.Markup("hello {}".format("world")) # S704 (false positive)
|
||||
|
|
||||
|
||||
S704.py:18:1: S704 Unsafe use of `flask.Markup` detected
|
||||
|
|
||||
16 | # if it includes comprehensive constant expression detection/evaluation.
|
||||
17 | Markup("*" * 8) # S704 (false positive)
|
||||
18 | flask.Markup("hello {}".format("world")) # S704 (false positive)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S704
|
||||
|
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S704_extend_markup_names.py:5:1: S704 Unsafe use of `markupsafe.Markup` detected
|
||||
|
|
||||
4 | content = "<script>alert('Hello, world!')</script>"
|
||||
5 | Markup(f"unsafe {content}") # S704
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ S704
|
||||
6 | literal(f"unsafe {content}") # S704
|
||||
|
|
||||
|
||||
S704_extend_markup_names.py:6:1: S704 Unsafe use of `webhelpers.html.literal` detected
|
||||
|
|
||||
4 | content = "<script>alert('Hello, world!')</script>"
|
||||
5 | Markup(f"unsafe {content}") # S704
|
||||
6 | literal(f"unsafe {content}") # S704
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S704
|
||||
|
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S704_skip_early_out.py:7:1: S704 Unsafe use of `webhelpers.html.literal` detected
|
||||
|
|
||||
5 | # markupsafe or flask first.
|
||||
6 | content = "<script>alert('Hello, world!')</script>"
|
||||
7 | literal(f"unsafe {content}") # S704
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S704
|
||||
|
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs
|
||||
---
|
||||
S704_whitelisted_markup_calls.py:9:1: S704 Unsafe use of `markupsafe.Markup` detected
|
||||
|
|
||||
7 | # indirect assignments are currently not supported
|
||||
8 | cleaned = clean(content)
|
||||
9 | Markup(cleaned) # S704
|
||||
| ^^^^^^^^^^^^^^^ S704
|
||||
|
|
||||
@@ -53,7 +53,7 @@ mod tests {
|
||||
Path::new("flake8_builtins").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
flake8_builtins: flake8_builtins::settings::Settings {
|
||||
builtins_strict_checking: true,
|
||||
strict_checking: true,
|
||||
..Default::default()
|
||||
},
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
@@ -83,7 +83,7 @@ mod tests {
|
||||
Path::new("flake8_builtins").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
flake8_builtins: flake8_builtins::settings::Settings {
|
||||
builtins_strict_checking: strict,
|
||||
strict_checking: strict,
|
||||
..Default::default()
|
||||
},
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
@@ -106,7 +106,7 @@ mod tests {
|
||||
&LinterSettings {
|
||||
src: vec![test_resource_path(src.join(path.parent().unwrap()))],
|
||||
flake8_builtins: flake8_builtins::settings::Settings {
|
||||
builtins_strict_checking: false,
|
||||
strict_checking: false,
|
||||
..Default::default()
|
||||
},
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
@@ -130,7 +130,7 @@ mod tests {
|
||||
&LinterSettings {
|
||||
project_root: test_resource_path(src.join(path.parent().unwrap())),
|
||||
flake8_builtins: flake8_builtins::settings::Settings {
|
||||
builtins_strict_checking: false,
|
||||
strict_checking: false,
|
||||
..Default::default()
|
||||
},
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
@@ -156,7 +156,7 @@ mod tests {
|
||||
Path::new("flake8_builtins").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
flake8_builtins: super::settings::Settings {
|
||||
builtins_ignorelist: vec!["id".to_string(), "dir".to_string()],
|
||||
ignorelist: vec!["id".to_string(), "dir".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..LinterSettings::for_rules(vec![rule_code])
|
||||
@@ -199,8 +199,8 @@ mod tests {
|
||||
Path::new("flake8_builtins").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
flake8_builtins: super::settings::Settings {
|
||||
builtins_allowed_modules: vec!["xml".to_string(), "logging".to_string()],
|
||||
builtins_strict_checking: true,
|
||||
allowed_modules: vec!["xml".to_string(), "logging".to_string()],
|
||||
strict_checking: true,
|
||||
..Default::default()
|
||||
},
|
||||
..LinterSettings::for_rules(vec![rule_code])
|
||||
|
||||
@@ -19,7 +19,7 @@ use super::super::helpers::shadows_builtin;
|
||||
/// builtin and vice versa.
|
||||
///
|
||||
/// Builtins can be marked as exceptions to this rule via the
|
||||
/// [`lint.flake8-builtins.builtins-ignorelist`] configuration option.
|
||||
/// [`lint.flake8-builtins.ignorelist`] configuration option.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
@@ -44,7 +44,7 @@ use super::super::helpers::shadows_builtin;
|
||||
/// ```
|
||||
///
|
||||
/// ## Options
|
||||
/// - `lint.flake8-builtins.builtins-ignorelist`
|
||||
/// - `lint.flake8-builtins.ignorelist`
|
||||
///
|
||||
/// ## References
|
||||
/// - [_Is it bad practice to use a built-in function name as an attribute or method identifier?_](https://stackoverflow.com/questions/9109333/is-it-bad-practice-to-use-a-built-in-function-name-as-an-attribute-or-method-ide)
|
||||
@@ -67,7 +67,7 @@ pub(crate) fn builtin_argument_shadowing(checker: &Checker, parameter: &Paramete
|
||||
if shadows_builtin(
|
||||
parameter.name(),
|
||||
checker.source_type,
|
||||
&checker.settings.flake8_builtins.builtins_ignorelist,
|
||||
&checker.settings.flake8_builtins.ignorelist,
|
||||
checker.target_version(),
|
||||
) {
|
||||
// Ignore parameters in lambda expressions.
|
||||
|
||||
@@ -37,7 +37,7 @@ use crate::rules::flake8_builtins::helpers::shadows_builtin;
|
||||
/// ```
|
||||
///
|
||||
/// Builtins can be marked as exceptions to this rule via the
|
||||
/// [`lint.flake8-builtins.builtins-ignorelist`] configuration option, or
|
||||
/// [`lint.flake8-builtins.ignorelist`] configuration option, or
|
||||
/// converted to the appropriate dunder method. Methods decorated with
|
||||
/// `@typing.override` or `@typing_extensions.override` are also
|
||||
/// ignored.
|
||||
@@ -55,7 +55,7 @@ use crate::rules::flake8_builtins::helpers::shadows_builtin;
|
||||
/// ```
|
||||
///
|
||||
/// ## Options
|
||||
/// - `lint.flake8-builtins.builtins-ignorelist`
|
||||
/// - `lint.flake8-builtins.ignorelist`
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct BuiltinAttributeShadowing {
|
||||
kind: Kind,
|
||||
@@ -98,7 +98,7 @@ pub(crate) fn builtin_attribute_shadowing(
|
||||
if shadows_builtin(
|
||||
name,
|
||||
checker.source_type,
|
||||
&checker.settings.flake8_builtins.builtins_ignorelist,
|
||||
&checker.settings.flake8_builtins.ignorelist,
|
||||
checker.target_version(),
|
||||
) {
|
||||
// Ignore explicit overrides.
|
||||
|
||||
@@ -14,7 +14,7 @@ use crate::rules::flake8_builtins::helpers::shadows_builtin;
|
||||
/// as readers may mistake the variable for the builtin and vice versa.
|
||||
///
|
||||
/// Builtins can be marked as exceptions to this rule via the
|
||||
/// [`lint.flake8-builtins.builtins-ignorelist`] configuration option.
|
||||
/// [`lint.flake8-builtins.ignorelist`] configuration option.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
@@ -38,7 +38,7 @@ use crate::rules::flake8_builtins::helpers::shadows_builtin;
|
||||
/// ```
|
||||
///
|
||||
/// ## Options
|
||||
/// - `lint.flake8-builtins.builtins-ignorelist`
|
||||
/// - `lint.flake8-builtins.ignorelist`
|
||||
/// - `target-version`
|
||||
///
|
||||
#[derive(ViolationMetadata)]
|
||||
@@ -60,7 +60,7 @@ pub(crate) fn builtin_import_shadowing(checker: &Checker, alias: &Alias) {
|
||||
if shadows_builtin(
|
||||
name.as_str(),
|
||||
checker.source_type,
|
||||
&checker.settings.flake8_builtins.builtins_ignorelist,
|
||||
&checker.settings.flake8_builtins.ignorelist,
|
||||
checker.target_version(),
|
||||
) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
|
||||
@@ -16,10 +16,10 @@ use crate::rules::flake8_builtins::helpers::shadows_builtin;
|
||||
/// builtin, and vice versa.
|
||||
///
|
||||
/// Builtins can be marked as exceptions to this rule via the
|
||||
/// [`lint.flake8-builtins.builtins-ignorelist`] configuration option.
|
||||
/// [`lint.flake8-builtins.ignorelist`] configuration option.
|
||||
///
|
||||
/// ## Options
|
||||
/// - `lint.flake8-builtins.builtins-ignorelist`
|
||||
/// - `lint.flake8-builtins.ignorelist`
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct BuiltinLambdaArgumentShadowing {
|
||||
name: String,
|
||||
@@ -43,7 +43,7 @@ pub(crate) fn builtin_lambda_argument_shadowing(checker: &Checker, lambda: &Expr
|
||||
if shadows_builtin(
|
||||
name,
|
||||
checker.source_type,
|
||||
&checker.settings.flake8_builtins.builtins_ignorelist,
|
||||
&checker.settings.flake8_builtins.ignorelist,
|
||||
checker.target_version(),
|
||||
) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
|
||||
@@ -17,7 +17,7 @@ use crate::rules::flake8_builtins::helpers::shadows_builtin;
|
||||
/// builtin and vice versa.
|
||||
///
|
||||
/// Builtins can be marked as exceptions to this rule via the
|
||||
/// [`lint.flake8-builtins.builtins-ignorelist`] configuration option.
|
||||
/// [`lint.flake8-builtins.ignorelist`] configuration option.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
@@ -40,7 +40,7 @@ use crate::rules::flake8_builtins::helpers::shadows_builtin;
|
||||
/// ```
|
||||
///
|
||||
/// ## Options
|
||||
/// - `lint.flake8-builtins.builtins-ignorelist`
|
||||
/// - `lint.flake8-builtins.ignorelist`
|
||||
///
|
||||
/// ## References
|
||||
/// - [_Why is it a bad idea to name a variable `id` in Python?_](https://stackoverflow.com/questions/77552/id-is-a-bad-variable-name-in-python)
|
||||
@@ -71,7 +71,7 @@ pub(crate) fn builtin_variable_shadowing(checker: &Checker, name: &str, range: T
|
||||
if shadows_builtin(
|
||||
name,
|
||||
checker.source_type,
|
||||
&checker.settings.flake8_builtins.builtins_ignorelist,
|
||||
&checker.settings.flake8_builtins.ignorelist,
|
||||
checker.target_version(),
|
||||
) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
|
||||
@@ -21,15 +21,14 @@ use crate::settings::LinterSettings;
|
||||
/// standard-library module and vice versa.
|
||||
///
|
||||
/// Standard-library modules can be marked as exceptions to this rule via the
|
||||
/// [`lint.flake8-builtins.builtins-allowed-modules`] configuration option.
|
||||
/// [`lint.flake8-builtins.allowed-modules`] configuration option.
|
||||
///
|
||||
/// By default, only the last component of the module name is considered, so `logging.py`,
|
||||
/// `utils/logging.py`, and `utils/logging/__init__.py` would all clash with the builtin `logging`
|
||||
/// module. With the [`lint.flake8-builtins.builtins-strict-checking`] option set to `false`, the
|
||||
/// module path is considered, so only a top-level `logging.py` or `logging/__init__.py` will
|
||||
/// trigger the rule and `utils/logging.py`, for example, would not. In preview mode, the default
|
||||
/// value of [`lint.flake8-builtins.builtins-strict-checking`] is `false` rather than `true` in
|
||||
/// stable mode.
|
||||
/// By default, the module path relative to the project root or [`src`] directories is considered,
|
||||
/// so a top-level `logging.py` or `logging/__init__.py` will clash with the builtin `logging`
|
||||
/// module, but `utils/logging.py`, for example, will not. With the
|
||||
/// [`lint.flake8-builtins.strict-checking`] option set to `true`, only the last component
|
||||
/// of the module name is considered, so `logging.py`, `utils/logging.py`, and
|
||||
/// `utils/logging/__init__.py` will all trigger the rule.
|
||||
///
|
||||
/// This rule is not applied to stub files, as the name of a stub module is out
|
||||
/// of the control of the author of the stub file. Instead, a stub should aim to
|
||||
@@ -50,8 +49,8 @@ use crate::settings::LinterSettings;
|
||||
/// ```
|
||||
///
|
||||
/// ## Options
|
||||
/// - `lint.flake8-builtins.builtins-allowed-modules`
|
||||
/// - `lint.flake8-builtins.builtins-strict-checking`
|
||||
/// - `lint.flake8-builtins.allowed-modules`
|
||||
/// - `lint.flake8-builtins.strict-checking`
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct StdlibModuleShadowing {
|
||||
name: String,
|
||||
@@ -104,7 +103,7 @@ pub(crate) fn stdlib_module_shadowing(
|
||||
}
|
||||
|
||||
// not allowed generally, but check for a parent in non-strict mode
|
||||
if !settings.flake8_builtins.builtins_strict_checking && components.next().is_some() {
|
||||
if !settings.flake8_builtins.strict_checking && components.next().is_some() {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -136,7 +135,7 @@ fn is_allowed_module(settings: &LinterSettings, version: PythonVersion, module:
|
||||
|
||||
if settings
|
||||
.flake8_builtins
|
||||
.builtins_allowed_modules
|
||||
.allowed_modules
|
||||
.iter()
|
||||
.any(|allowed_module| allowed_module == module)
|
||||
{
|
||||
|
||||
@@ -1,24 +1,14 @@
|
||||
//! Settings for the `flake8-builtins` plugin.
|
||||
|
||||
use crate::{display_settings, settings::types::PreviewMode};
|
||||
use crate::display_settings;
|
||||
use ruff_macros::CacheKey;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Debug, Clone, Default, CacheKey)]
|
||||
pub struct Settings {
|
||||
pub builtins_ignorelist: Vec<String>,
|
||||
pub builtins_allowed_modules: Vec<String>,
|
||||
pub builtins_strict_checking: bool,
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
pub fn new(preview: PreviewMode) -> Self {
|
||||
Self {
|
||||
builtins_ignorelist: Vec::new(),
|
||||
builtins_allowed_modules: Vec::new(),
|
||||
builtins_strict_checking: preview.is_disabled(),
|
||||
}
|
||||
}
|
||||
pub ignorelist: Vec<String>,
|
||||
pub allowed_modules: Vec<String>,
|
||||
pub strict_checking: bool,
|
||||
}
|
||||
|
||||
impl Display for Settings {
|
||||
@@ -27,9 +17,9 @@ impl Display for Settings {
|
||||
formatter = f,
|
||||
namespace = "linter.flake8_builtins",
|
||||
fields = [
|
||||
self.builtins_allowed_modules | array,
|
||||
self.builtins_ignorelist | array,
|
||||
self.builtins_strict_checking,
|
||||
self.allowed_modules | array,
|
||||
self.ignorelist | array,
|
||||
self.strict_checking,
|
||||
]
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -9,7 +9,6 @@ mod tests {
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::types::PreviewMode;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_messages, settings};
|
||||
|
||||
@@ -22,6 +21,7 @@ mod tests {
|
||||
#[test_case(Rule::CallDatetimeStrptimeWithoutZone, Path::new("DTZ007.py"))]
|
||||
#[test_case(Rule::CallDateToday, Path::new("DTZ011.py"))]
|
||||
#[test_case(Rule::CallDateFromtimestamp, Path::new("DTZ012.py"))]
|
||||
#[test_case(Rule::DatetimeMinMax, Path::new("DTZ901.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
@@ -31,18 +31,4 @@ mod tests {
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::DatetimeMinMax, Path::new("DTZ901.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_datetimez").join(path).as_path(),
|
||||
&settings::LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,18 +9,18 @@ use ruff_text_size::Ranged;
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for uses of `datetime.datetime.max` and `datetime.datetime.min`.
|
||||
/// Checks for uses of `datetime.datetime.min` and `datetime.datetime.max`.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// `datetime.max` and `datetime.min` are non-timezone-aware datetime objects.
|
||||
/// `datetime.min` and `datetime.max` are non-timezone-aware datetime objects.
|
||||
///
|
||||
/// As such, operations on `datetime.max` and `datetime.min` may behave
|
||||
/// As such, operations on `datetime.min` and `datetime.max` may behave
|
||||
/// unexpectedly, as in:
|
||||
///
|
||||
/// ```python
|
||||
/// # Timezone: UTC-14
|
||||
/// datetime.max.timestamp() # ValueError: year 10000 is out of range
|
||||
/// datetime.min.timestamp() # ValueError: year 0 is out of range
|
||||
/// datetime.max.timestamp() # ValueError: year 10000 is out of range
|
||||
/// ```
|
||||
///
|
||||
/// ## Example
|
||||
@@ -53,7 +53,7 @@ impl Violation for DatetimeMinMax {
|
||||
}
|
||||
|
||||
/// DTZ901
|
||||
pub(crate) fn datetime_max_min(checker: &Checker, expr: &Expr) {
|
||||
pub(crate) fn datetime_min_max(checker: &Checker, expr: &Expr) {
|
||||
let semantic = checker.semantic();
|
||||
|
||||
if !semantic.seen_module(Modules::DATETIME) {
|
||||
|
||||
@@ -156,30 +156,6 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::CustomTypeVarForSelf, Path::new("PYI019_0.py"))]
|
||||
#[test_case(Rule::CustomTypeVarForSelf, Path::new("PYI019_0.pyi"))]
|
||||
#[test_case(Rule::CustomTypeVarForSelf, Path::new("PYI019_1.pyi"))]
|
||||
fn custom_classmethod_rules_preview(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview_{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_pyi").join(path).as_path(),
|
||||
&settings::LinterSettings {
|
||||
pep8_naming: pep8_naming::settings::Settings {
|
||||
classmethod_decorators: vec!["foo_classmethod".to_string()],
|
||||
..pep8_naming::settings::Settings::default()
|
||||
},
|
||||
preview: PreviewMode::Enabled,
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::TypeAliasWithoutAnnotation, Path::new("PYI026.py"))]
|
||||
#[test_case(Rule::TypeAliasWithoutAnnotation, Path::new("PYI026.pyi"))]
|
||||
#[test_case(Rule::RedundantNoneLiteral, Path::new("PYI061.py"))]
|
||||
@@ -198,8 +174,6 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test_case(Rule::FutureAnnotationsInStub, Path::new("PYI044.pyi"))]
|
||||
#[test_case(Rule::UnusedPrivateTypeVar, Path::new("PYI018.py"))]
|
||||
#[test_case(Rule::UnusedPrivateTypeVar, Path::new("PYI018.pyi"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview__{}_{}",
|
||||
|
||||
@@ -71,20 +71,8 @@ use ruff_python_ast::PythonVersion;
|
||||
/// The fix is only marked as unsafe if there is the possibility that it might delete a comment
|
||||
/// from your code.
|
||||
///
|
||||
/// ## Preview-mode behaviour
|
||||
/// This rule's behaviour has several differences when [`preview`] mode is enabled:
|
||||
/// 1. The fix for this rule is currently only available if `preview` mode is enabled.
|
||||
/// 2. By default, this rule is only applied to methods that have return-type annotations,
|
||||
/// and the range of the diagnostic is the range of the return-type annotation.
|
||||
/// In preview mode, this rule is also applied to some methods that do not have
|
||||
/// return-type annotations. The range of the diagnostic is the range of the function
|
||||
/// header (from the end of the function name to the end of the parameters).
|
||||
/// 3. In `preview` mode, the rule uses different logic to determine whether an annotation
|
||||
/// refers to a type variable. The `preview`-mode logic is more accurate, but may lead
|
||||
/// to more methods being flagged than if `preview` mode is disabled.
|
||||
///
|
||||
/// [PEP 673]: https://peps.python.org/pep-0673/#motivation
|
||||
/// [PEP 695]: https://peps.python.org/pep-0695/
|
||||
/// [PEP-695]: https://peps.python.org/pep-0695/
|
||||
/// [PYI018]: https://docs.astral.sh/ruff/rules/unused-private-type-var/
|
||||
/// [type parameter list]: https://docs.python.org/3/reference/compound_stmts.html#type-params
|
||||
/// [Self]: https://docs.python.org/3/library/typing.html#typing.Self
|
||||
@@ -162,73 +150,33 @@ pub(crate) fn custom_type_var_instead_of_self(
|
||||
&checker.settings.pep8_naming.staticmethod_decorators,
|
||||
);
|
||||
|
||||
let function_header_end = returns
|
||||
.as_deref()
|
||||
.map(Ranged::end)
|
||||
.unwrap_or_else(|| parameters.end());
|
||||
|
||||
// In stable mode, we only emit the diagnostic on methods that have a return type annotation.
|
||||
// In preview mode, we have a more principled approach to determine if an annotation refers
|
||||
// to a type variable, and we emit the diagnostic on some methods that do not have return
|
||||
// annotations.
|
||||
let (method, diagnostic_range) = match function_kind {
|
||||
FunctionType::ClassMethod | FunctionType::NewMethod => {
|
||||
if checker.settings.preview.is_enabled() {
|
||||
(
|
||||
Method::PreviewClass(PreviewClassMethod {
|
||||
cls_annotation: self_or_cls_annotation,
|
||||
type_params,
|
||||
}),
|
||||
TextRange::new(function_name.end(), function_header_end),
|
||||
)
|
||||
} else {
|
||||
returns.as_deref().map(|returns| {
|
||||
(
|
||||
Method::Class(ClassMethod {
|
||||
cls_annotation: self_or_cls_annotation,
|
||||
returns,
|
||||
type_params,
|
||||
}),
|
||||
returns.range(),
|
||||
)
|
||||
})?
|
||||
}
|
||||
}
|
||||
FunctionType::Method => {
|
||||
if checker.settings.preview.is_enabled() {
|
||||
(
|
||||
Method::PreviewInstance(PreviewInstanceMethod {
|
||||
self_annotation: self_or_cls_annotation,
|
||||
type_params,
|
||||
}),
|
||||
TextRange::new(function_name.end(), function_header_end),
|
||||
)
|
||||
} else {
|
||||
returns.as_deref().map(|returns| {
|
||||
(
|
||||
Method::Instance(InstanceMethod {
|
||||
self_annotation: self_or_cls_annotation,
|
||||
returns,
|
||||
type_params,
|
||||
}),
|
||||
returns.range(),
|
||||
)
|
||||
})?
|
||||
}
|
||||
}
|
||||
let method = match function_kind {
|
||||
FunctionType::ClassMethod | FunctionType::NewMethod => Method::Class(ClassMethod {
|
||||
cls_annotation: self_or_cls_annotation,
|
||||
type_params,
|
||||
}),
|
||||
FunctionType::Method => Method::Instance(InstanceMethod {
|
||||
self_annotation: self_or_cls_annotation,
|
||||
type_params,
|
||||
}),
|
||||
FunctionType::Function | FunctionType::StaticMethod => return None,
|
||||
};
|
||||
|
||||
let custom_typevar = method.custom_typevar(semantic, binding.scope)?;
|
||||
|
||||
let function_header_end = returns
|
||||
.as_deref()
|
||||
.map(Ranged::end)
|
||||
.unwrap_or_else(|| parameters.end());
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
CustomTypeVarForSelf {
|
||||
typevar_name: custom_typevar.name(checker.source()).to_string(),
|
||||
},
|
||||
diagnostic_range,
|
||||
TextRange::new(function_name.end(), function_header_end),
|
||||
);
|
||||
|
||||
diagnostic.try_set_optional_fix(|| {
|
||||
diagnostic.try_set_fix(|| {
|
||||
replace_custom_typevar_with_self(
|
||||
checker,
|
||||
function_def,
|
||||
@@ -244,9 +192,7 @@ pub(crate) fn custom_type_var_instead_of_self(
|
||||
#[derive(Debug)]
|
||||
enum Method<'a> {
|
||||
Class(ClassMethod<'a>),
|
||||
PreviewClass(PreviewClassMethod<'a>),
|
||||
Instance(InstanceMethod<'a>),
|
||||
PreviewInstance(PreviewInstanceMethod<'a>),
|
||||
}
|
||||
|
||||
impl Method<'_> {
|
||||
@@ -257,9 +203,7 @@ impl Method<'_> {
|
||||
) -> Option<TypeVar<'a>> {
|
||||
match self {
|
||||
Self::Class(class_method) => class_method.custom_typevar(semantic, scope),
|
||||
Self::PreviewClass(class_method) => class_method.custom_typevar(semantic, scope),
|
||||
Self::Instance(instance_method) => instance_method.custom_typevar(semantic),
|
||||
Self::PreviewInstance(instance_method) => instance_method.custom_typevar(semantic),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -267,76 +211,10 @@ impl Method<'_> {
|
||||
#[derive(Debug)]
|
||||
struct ClassMethod<'a> {
|
||||
cls_annotation: &'a ast::Expr,
|
||||
returns: &'a ast::Expr,
|
||||
type_params: Option<&'a ast::TypeParams>,
|
||||
}
|
||||
|
||||
impl ClassMethod<'_> {
|
||||
/// Returns `Some(typevar)` if the class method is annotated with
|
||||
/// a custom `TypeVar` that is likely private.
|
||||
fn custom_typevar<'a>(
|
||||
&'a self,
|
||||
semantic: &'a SemanticModel<'a>,
|
||||
scope: ScopeId,
|
||||
) -> Option<TypeVar<'a>> {
|
||||
let ast::ExprSubscript {
|
||||
value: cls_annotation_value,
|
||||
slice: cls_annotation_typevar,
|
||||
..
|
||||
} = self.cls_annotation.as_subscript_expr()?;
|
||||
|
||||
let cls_annotation_typevar = cls_annotation_typevar.as_name_expr()?;
|
||||
let cls_annotation_typevar_name = &cls_annotation_typevar.id;
|
||||
let ast::ExprName { id, .. } = cls_annotation_value.as_name_expr()?;
|
||||
|
||||
if id != "type" {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !semantic.has_builtin_binding_in_scope("type", scope) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let return_annotation_typevar = match self.returns {
|
||||
ast::Expr::Name(ast::ExprName { id, .. }) => id,
|
||||
ast::Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => {
|
||||
let return_annotation_typevar = slice.as_name_expr()?;
|
||||
let ast::ExprName { id, .. } = value.as_name_expr()?;
|
||||
if id != "type" {
|
||||
return None;
|
||||
}
|
||||
&return_annotation_typevar.id
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
if cls_annotation_typevar_name != return_annotation_typevar {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !is_likely_private_typevar(cls_annotation_typevar_name, self.type_params) {
|
||||
return None;
|
||||
}
|
||||
|
||||
semantic
|
||||
.resolve_name(cls_annotation_typevar)
|
||||
.map(|binding_id| TypeVar(semantic.binding(binding_id)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Struct for implementing this rule as applied to classmethods in preview mode.
|
||||
///
|
||||
/// In stable mode, we only emit this diagnostic on methods that have return annotations,
|
||||
/// so the stable-mode version of this struct has a `returns: &ast::Expr` field. In preview
|
||||
/// mode, we also emit this diagnostic on methods that do not have return annotations, so
|
||||
/// the preview-mode version of this struct does not have a `returns` field.
|
||||
#[derive(Debug)]
|
||||
struct PreviewClassMethod<'a> {
|
||||
cls_annotation: &'a ast::Expr,
|
||||
type_params: Option<&'a ast::TypeParams>,
|
||||
}
|
||||
|
||||
impl PreviewClassMethod<'_> {
|
||||
/// Returns `Some(typevar)` if the class method is annotated with
|
||||
/// a custom `TypeVar` for the `cls` parameter
|
||||
fn custom_typevar<'a>(
|
||||
@@ -360,59 +238,21 @@ impl PreviewClassMethod<'_> {
|
||||
return None;
|
||||
}
|
||||
|
||||
custom_typevar_preview(cls_annotation_typevar, self.type_params, semantic)
|
||||
custom_typevar(cls_annotation_typevar, self.type_params, semantic)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InstanceMethod<'a> {
|
||||
self_annotation: &'a ast::Expr,
|
||||
returns: &'a ast::Expr,
|
||||
type_params: Option<&'a ast::TypeParams>,
|
||||
}
|
||||
|
||||
impl InstanceMethod<'_> {
|
||||
/// Returns `Some(typevar)` if the instance method is annotated with
|
||||
/// a custom `TypeVar` that is likely private.
|
||||
fn custom_typevar<'a>(&'a self, semantic: &'a SemanticModel<'a>) -> Option<TypeVar<'a>> {
|
||||
let self_annotation = self.self_annotation.as_name_expr()?;
|
||||
let first_arg_type = &self_annotation.id;
|
||||
|
||||
let ast::ExprName {
|
||||
id: return_type, ..
|
||||
} = self.returns.as_name_expr()?;
|
||||
|
||||
if first_arg_type != return_type {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !is_likely_private_typevar(first_arg_type, self.type_params) {
|
||||
return None;
|
||||
}
|
||||
|
||||
semantic
|
||||
.resolve_name(self_annotation)
|
||||
.map(|binding_id| TypeVar(semantic.binding(binding_id)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Struct for implementing this rule as applied to instance methods in preview mode.
|
||||
///
|
||||
/// In stable mode, we only emit this diagnostic on methods that have return annotations,
|
||||
/// so the stable-mode version of this struct has a `returns: &ast::Expr` field. In preview
|
||||
/// mode, we also emit this diagnostic on methods that do not have return annotations, so
|
||||
/// the preview-mode version of this struct does not have a `returns` field.
|
||||
#[derive(Debug)]
|
||||
struct PreviewInstanceMethod<'a> {
|
||||
self_annotation: &'a ast::Expr,
|
||||
type_params: Option<&'a ast::TypeParams>,
|
||||
}
|
||||
|
||||
impl PreviewInstanceMethod<'_> {
|
||||
/// Returns `Some(typevar)` if the instance method is annotated with
|
||||
/// a custom `TypeVar` for the `self` parameter
|
||||
fn custom_typevar<'a>(&'a self, semantic: &'a SemanticModel<'a>) -> Option<TypeVar<'a>> {
|
||||
custom_typevar_preview(
|
||||
custom_typevar(
|
||||
self.self_annotation.as_name_expr()?,
|
||||
self.type_params,
|
||||
semantic,
|
||||
@@ -420,30 +260,8 @@ impl PreviewInstanceMethod<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the type variable is likely private.
|
||||
///
|
||||
/// This routine is only used if `--preview` is not enabled,
|
||||
/// as it uses heuristics to determine if an annotation uses a type variable.
|
||||
/// In preview mode, we apply a more principled approach.
|
||||
fn is_likely_private_typevar(type_var_name: &str, type_params: Option<&ast::TypeParams>) -> bool {
|
||||
// Ex) `_T`
|
||||
if type_var_name.starts_with('_') {
|
||||
return true;
|
||||
}
|
||||
// Ex) `class Foo[T]: ...`
|
||||
type_params.is_some_and(|type_params| {
|
||||
type_params.iter().any(|type_param| {
|
||||
if let ast::TypeParam::TypeVar(ast::TypeParamTypeVar { name, .. }) = type_param {
|
||||
name == type_var_name
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns `Some(TypeVar)` if `typevar_expr` refers to a `TypeVar` binding
|
||||
fn custom_typevar_preview<'a>(
|
||||
fn custom_typevar<'a>(
|
||||
typevar_expr: &'a ast::ExprName,
|
||||
type_params: Option<&ast::TypeParams>,
|
||||
semantic: &'a SemanticModel<'a>,
|
||||
@@ -497,11 +315,7 @@ fn replace_custom_typevar_with_self(
|
||||
custom_typevar: TypeVar,
|
||||
self_or_cls_parameter: &ast::ParameterWithDefault,
|
||||
self_or_cls_annotation: &ast::Expr,
|
||||
) -> anyhow::Result<Option<Fix>> {
|
||||
if checker.settings.preview.is_disabled() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
) -> anyhow::Result<Fix> {
|
||||
// (1) Import `Self` (if necessary)
|
||||
let (import_edit, self_symbol_binding) = import_self(checker, function_def.start())?;
|
||||
|
||||
@@ -513,9 +327,9 @@ fn replace_custom_typevar_with_self(
|
||||
|
||||
// (3) If it was a PEP-695 type variable, remove that `TypeVar` from the PEP-695 type-parameter list
|
||||
if custom_typevar.is_pep695_typevar() {
|
||||
let Some(type_params) = function_def.type_params.as_deref() else {
|
||||
bail!("Should not be possible to have a type parameter without a type parameter list");
|
||||
};
|
||||
let type_params = function_def.type_params.as_deref().context(
|
||||
"Should not be possible to have a type parameter without a type parameter list",
|
||||
)?;
|
||||
let deletion_edit = remove_pep695_typevar_declaration(type_params, custom_typevar)
|
||||
.context("Failed to find a `TypeVar` in the type params that matches the binding")?;
|
||||
other_edits.push(deletion_edit);
|
||||
@@ -546,11 +360,11 @@ fn replace_custom_typevar_with_self(
|
||||
Applicability::Safe
|
||||
};
|
||||
|
||||
Ok(Some(Fix::applicable_edits(
|
||||
Ok(Fix::applicable_edits(
|
||||
import_edit,
|
||||
other_edits,
|
||||
applicability,
|
||||
)))
|
||||
))
|
||||
}
|
||||
|
||||
/// Attempt to create an [`Edit`] that imports `Self`.
|
||||
|
||||
@@ -26,9 +26,8 @@ use crate::fix;
|
||||
/// _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety and availability
|
||||
/// This rule's fix is available when [`preview`] mode is enabled.
|
||||
/// It is always marked as unsafe, as it would break your code if the type
|
||||
/// ## Fix safety
|
||||
/// The fix is always marked as unsafe, as it would break your code if the type
|
||||
/// variable is imported by another module.
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct UnusedPrivateTypeVar {
|
||||
@@ -225,18 +224,19 @@ pub(crate) fn unused_private_type_var(checker: &Checker, scope: &Scope) {
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let diagnostic = Diagnostic::new(
|
||||
UnusedPrivateTypeVar {
|
||||
type_var_like_name: id.to_string(),
|
||||
type_var_like_kind: type_var_like_kind.to_string(),
|
||||
},
|
||||
binding.range(),
|
||||
);
|
||||
|
||||
if checker.settings.preview.is_enabled() {
|
||||
let edit = fix::edits::delete_stmt(stmt, None, checker.locator(), checker.indexer());
|
||||
diagnostic.set_fix(Fix::unsafe_edit(edit));
|
||||
}
|
||||
)
|
||||
.with_fix(Fix::unsafe_edit(fix::edits::delete_stmt(
|
||||
stmt,
|
||||
None,
|
||||
checker.locator(),
|
||||
checker.indexer(),
|
||||
)));
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI018.py:6:1: PYI018 Private TypeVar `_T` is never used
|
||||
PYI018.py:6:1: PYI018 [*] Private TypeVar `_T` is never used
|
||||
|
|
||||
4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 |
|
||||
@@ -12,7 +12,16 @@ PYI018.py:6:1: PYI018 Private TypeVar `_T` is never used
|
||||
|
|
||||
= help: Remove unused private TypeVar `_T`
|
||||
|
||||
PYI018.py:7:1: PYI018 Private TypeVarTuple `_Ts` is never used
|
||||
ℹ Unsafe fix
|
||||
3 3 | from typing import TypeVar
|
||||
4 4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 5 |
|
||||
6 |-_T = typing.TypeVar("_T")
|
||||
7 6 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 7 | _P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
|
||||
PYI018.py:7:1: PYI018 [*] Private TypeVarTuple `_Ts` is never used
|
||||
|
|
||||
6 | _T = typing.TypeVar("_T")
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
@@ -22,7 +31,16 @@ PYI018.py:7:1: PYI018 Private TypeVarTuple `_Ts` is never used
|
||||
|
|
||||
= help: Remove unused private TypeVarTuple `_Ts`
|
||||
|
||||
PYI018.py:8:1: PYI018 Private ParamSpec `_P` is never used
|
||||
ℹ Unsafe fix
|
||||
4 4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 5 |
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 |-_Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 7 | _P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
|
||||
PYI018.py:8:1: PYI018 [*] Private ParamSpec `_P` is never used
|
||||
|
|
||||
6 | _T = typing.TypeVar("_T")
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
@@ -33,7 +51,16 @@ PYI018.py:8:1: PYI018 Private ParamSpec `_P` is never used
|
||||
|
|
||||
= help: Remove unused private ParamSpec `_P`
|
||||
|
||||
PYI018.py:9:1: PYI018 Private ParamSpec `_P2` is never used
|
||||
ℹ Unsafe fix
|
||||
5 5 |
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 |-_P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
|
||||
PYI018.py:9:1: PYI018 [*] Private ParamSpec `_P2` is never used
|
||||
|
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 | _P = ParamSpec("_P")
|
||||
@@ -43,7 +70,16 @@ PYI018.py:9:1: PYI018 Private ParamSpec `_P2` is never used
|
||||
|
|
||||
= help: Remove unused private ParamSpec `_P2`
|
||||
|
||||
PYI018.py:10:1: PYI018 Private TypeVarTuple `_Ts2` is never used
|
||||
ℹ Unsafe fix
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 8 | _P = ParamSpec("_P")
|
||||
9 |-_P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
12 11 | # OK
|
||||
|
||||
PYI018.py:10:1: PYI018 [*] Private TypeVarTuple `_Ts2` is never used
|
||||
|
|
||||
8 | _P = ParamSpec("_P")
|
||||
9 | _P2 = typing.ParamSpec("_P2")
|
||||
@@ -53,3 +89,12 @@ PYI018.py:10:1: PYI018 Private TypeVarTuple `_Ts2` is never used
|
||||
12 | # OK
|
||||
|
|
||||
= help: Remove unused private TypeVarTuple `_Ts2`
|
||||
|
||||
ℹ Unsafe fix
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 8 | _P = ParamSpec("_P")
|
||||
9 9 | _P2 = typing.ParamSpec("_P2")
|
||||
10 |-_Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
12 11 | # OK
|
||||
13 12 | _UsedTypeVar = TypeVar("_UsedTypeVar")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI018.pyi:6:1: PYI018 Private TypeVar `_T` is never used
|
||||
PYI018.pyi:6:1: PYI018 [*] Private TypeVar `_T` is never used
|
||||
|
|
||||
4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 |
|
||||
@@ -12,7 +12,16 @@ PYI018.pyi:6:1: PYI018 Private TypeVar `_T` is never used
|
||||
|
|
||||
= help: Remove unused private TypeVar `_T`
|
||||
|
||||
PYI018.pyi:7:1: PYI018 Private TypeVarTuple `_Ts` is never used
|
||||
ℹ Unsafe fix
|
||||
3 3 | from typing import TypeVar
|
||||
4 4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 5 |
|
||||
6 |-_T = typing.TypeVar("_T")
|
||||
7 6 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 7 | _P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
|
||||
PYI018.pyi:7:1: PYI018 [*] Private TypeVarTuple `_Ts` is never used
|
||||
|
|
||||
6 | _T = typing.TypeVar("_T")
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
@@ -22,7 +31,16 @@ PYI018.pyi:7:1: PYI018 Private TypeVarTuple `_Ts` is never used
|
||||
|
|
||||
= help: Remove unused private TypeVarTuple `_Ts`
|
||||
|
||||
PYI018.pyi:8:1: PYI018 Private ParamSpec `_P` is never used
|
||||
ℹ Unsafe fix
|
||||
4 4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 5 |
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 |-_Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 7 | _P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
|
||||
PYI018.pyi:8:1: PYI018 [*] Private ParamSpec `_P` is never used
|
||||
|
|
||||
6 | _T = typing.TypeVar("_T")
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
@@ -33,7 +51,16 @@ PYI018.pyi:8:1: PYI018 Private ParamSpec `_P` is never used
|
||||
|
|
||||
= help: Remove unused private ParamSpec `_P`
|
||||
|
||||
PYI018.pyi:9:1: PYI018 Private ParamSpec `_P2` is never used
|
||||
ℹ Unsafe fix
|
||||
5 5 |
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 |-_P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
|
||||
PYI018.pyi:9:1: PYI018 [*] Private ParamSpec `_P2` is never used
|
||||
|
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 | _P = ParamSpec("_P")
|
||||
@@ -43,7 +70,16 @@ PYI018.pyi:9:1: PYI018 Private ParamSpec `_P2` is never used
|
||||
|
|
||||
= help: Remove unused private ParamSpec `_P2`
|
||||
|
||||
PYI018.pyi:10:1: PYI018 Private TypeVarTuple `_Ts2` is never used
|
||||
ℹ Unsafe fix
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 8 | _P = ParamSpec("_P")
|
||||
9 |-_P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
12 11 | # OK
|
||||
|
||||
PYI018.pyi:10:1: PYI018 [*] Private TypeVarTuple `_Ts2` is never used
|
||||
|
|
||||
8 | _P = ParamSpec("_P")
|
||||
9 | _P2 = typing.ParamSpec("_P2")
|
||||
@@ -53,3 +89,12 @@ PYI018.pyi:10:1: PYI018 Private TypeVarTuple `_Ts2` is never used
|
||||
12 | # OK
|
||||
|
|
||||
= help: Remove unused private TypeVarTuple `_Ts2`
|
||||
|
||||
ℹ Unsafe fix
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 8 | _P = ParamSpec("_P")
|
||||
9 9 | _P2 = typing.ParamSpec("_P2")
|
||||
10 |-_Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
12 11 | # OK
|
||||
13 12 | _UsedTypeVar = TypeVar("_UsedTypeVar")
|
||||
|
||||
@@ -1,316 +1,692 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI019_0.py:7:62: PYI019 Use `Self` instead of custom TypeVar `_S`
|
||||
PYI019_0.py:7:16: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
6 | class BadClass:
|
||||
7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
| ^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
PYI019_0.py:10:54: PYI019 Use `Self` instead of custom TypeVar `_S`
|
||||
ℹ Safe fix
|
||||
4 4 | _S2 = TypeVar("_S2", BadClass, GoodClass)
|
||||
5 5 |
|
||||
6 6 | class BadClass:
|
||||
7 |- def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
7 |+ def __new__(cls, *args: str, **kwargs: int) -> Self: ... # PYI019
|
||||
8 8 |
|
||||
9 9 |
|
||||
10 10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
|
||||
PYI019_0.py:10:28: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
| ^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
PYI019_0.py:14:54: PYI019 Use `Self` instead of custom TypeVar `_S`
|
||||
ℹ Safe fix
|
||||
7 7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
8 8 |
|
||||
9 9 |
|
||||
10 |- def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
10 |+ def bad_instance_method(self, arg: bytes) -> Self: ... # PYI019
|
||||
11 11 |
|
||||
12 12 |
|
||||
13 13 | @classmethod
|
||||
|
||||
PYI019_0.py:14:25: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
13 | @classmethod
|
||||
14 | def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019
|
||||
| ^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
PYI019_0.py:18:55: PYI019 Use `Self` instead of custom TypeVar `_S`
|
||||
ℹ Safe fix
|
||||
11 11 |
|
||||
12 12 |
|
||||
13 13 | @classmethod
|
||||
14 |- def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019
|
||||
14 |+ def bad_class_method(cls, arg: int) -> Self: ... # PYI019
|
||||
15 15 |
|
||||
16 16 |
|
||||
17 17 | @classmethod
|
||||
|
||||
PYI019_0.py:18:33: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
17 | @classmethod
|
||||
18 | def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019
|
||||
| ^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
PYI019_0.py:39:63: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
15 15 |
|
||||
16 16 |
|
||||
17 17 | @classmethod
|
||||
18 |- def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019
|
||||
18 |+ def bad_posonly_class_method(cls, /) -> Self: ... # PYI019
|
||||
19 19 |
|
||||
20 20 |
|
||||
21 21 | @classmethod
|
||||
|
||||
PYI019_0.py:39:14: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
37 | # Python > 3.12
|
||||
38 | class PEP695BadDunderNew[T]:
|
||||
39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:42:46: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
36 36 |
|
||||
37 37 | # Python > 3.12
|
||||
38 38 | class PEP695BadDunderNew[T]:
|
||||
39 |- def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
39 |+ def __new__(cls, *args: Any, ** kwargs: Any) -> Self: ... # PYI019
|
||||
40 40 |
|
||||
41 41 |
|
||||
42 42 | def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
|
||||
PYI019_0.py:42:30: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
42 | def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:54:32: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
39 39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
40 40 |
|
||||
41 41 |
|
||||
42 |- def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
42 |+ def generic_instance_method(self) -> Self: ... # PYI019
|
||||
43 43 |
|
||||
44 44 |
|
||||
45 45 | class PEP695GoodDunderNew[T]:
|
||||
|
||||
PYI019_0.py:54:11: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
52 | # in the settings for this test:
|
||||
53 | @foo_classmethod
|
||||
54 | def foo[S](cls: type[S]) -> S: ... # PYI019
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:61:48: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
51 51 | # due to `foo_classmethod being listed in `pep8_naming.classmethod-decorators`
|
||||
52 52 | # in the settings for this test:
|
||||
53 53 | @foo_classmethod
|
||||
54 |- def foo[S](cls: type[S]) -> S: ... # PYI019
|
||||
54 |+ def foo(cls) -> Self: ... # PYI019
|
||||
55 55 |
|
||||
56 56 |
|
||||
57 57 | _S695 = TypeVar("_S695", bound="PEP695Fix")
|
||||
|
||||
PYI019_0.py:61:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
60 | class PEP695Fix:
|
||||
61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
62 |
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:63:47: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
58 58 |
|
||||
59 59 |
|
||||
60 60 | class PEP695Fix:
|
||||
61 |- def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
61 |+ def __new__(cls) -> Self: ...
|
||||
62 62 |
|
||||
63 63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 64 |
|
||||
|
||||
PYI019_0.py:63:26: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
62 |
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
64 |
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:65:43: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
60 60 | class PEP695Fix:
|
||||
61 61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
62 62 |
|
||||
63 |- def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
63 |+ def __init_subclass__(cls) -> Self: ...
|
||||
64 64 |
|
||||
65 65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 66 |
|
||||
|
||||
PYI019_0.py:65:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 |
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
66 |
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:67:32: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
62 62 |
|
||||
63 63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 64 |
|
||||
65 |- def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
65 |+ def __neg__(self) -> Self: ...
|
||||
66 66 |
|
||||
67 67 | def __pos__[S](self: S) -> S: ...
|
||||
68 68 |
|
||||
|
||||
PYI019_0.py:67:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 |
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
68 |
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:69:53: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
64 64 |
|
||||
65 65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 66 |
|
||||
67 |- def __pos__[S](self: S) -> S: ...
|
||||
67 |+ def __pos__(self) -> Self: ...
|
||||
68 68 |
|
||||
69 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 70 |
|
||||
|
||||
PYI019_0.py:69:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
68 |
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
70 |
|
||||
71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:71:42: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
66 66 |
|
||||
67 67 | def __pos__[S](self: S) -> S: ...
|
||||
68 68 |
|
||||
69 |- def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
69 |+ def __add__(self, other: Self) -> Self: ...
|
||||
70 70 |
|
||||
71 71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
72 72 |
|
||||
|
||||
PYI019_0.py:71:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 |
|
||||
71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
72 |
|
||||
73 | @classmethod
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:74:59: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
68 68 |
|
||||
69 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 70 |
|
||||
71 |- def __sub__[S](self: S, other: S) -> S: ...
|
||||
71 |+ def __sub__(self, other: Self) -> Self: ...
|
||||
72 72 |
|
||||
73 73 | @classmethod
|
||||
74 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
|
||||
PYI019_0.py:74:27: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
73 | @classmethod
|
||||
74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
75 |
|
||||
76 | @classmethod
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:77:50: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
71 71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
72 72 |
|
||||
73 73 | @classmethod
|
||||
74 |- def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
74 |+ def class_method_bound(cls) -> Self: ...
|
||||
75 75 |
|
||||
76 76 | @classmethod
|
||||
77 77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
|
||||
PYI019_0.py:77:29: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
76 | @classmethod
|
||||
77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
78 |
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:79:57: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
74 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
75 75 |
|
||||
76 76 | @classmethod
|
||||
77 |- def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
77 |+ def class_method_unbound(cls) -> Self: ...
|
||||
78 78 |
|
||||
79 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 80 |
|
||||
|
||||
PYI019_0.py:79:30: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
78 |
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
80 |
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:81:48: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
76 76 | @classmethod
|
||||
77 77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
78 78 |
|
||||
79 |- def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
79 |+ def instance_method_bound(self) -> Self: ...
|
||||
80 80 |
|
||||
81 81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 82 |
|
||||
|
||||
PYI019_0.py:81:32: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 |
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
82 |
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:83:90: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
78 78 |
|
||||
79 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 80 |
|
||||
81 |- def instance_method_unbound[S](self: S) -> S: ...
|
||||
81 |+ def instance_method_unbound(self) -> Self: ...
|
||||
82 82 |
|
||||
83 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 84 |
|
||||
|
||||
PYI019_0.py:83:53: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 |
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
84 |
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:85:81: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
80 80 |
|
||||
81 81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 82 |
|
||||
83 |- def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
83 |+ def instance_method_bound_with_another_parameter(self, other: Self) -> Self: ...
|
||||
84 84 |
|
||||
85 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 86 |
|
||||
|
||||
PYI019_0.py:85:55: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 |
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
86 |
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:87:94: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
82 82 |
|
||||
83 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 84 |
|
||||
85 |- def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
85 |+ def instance_method_unbound_with_another_parameter(self, other: Self) -> Self: ...
|
||||
86 86 |
|
||||
87 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 88 |
|
||||
|
||||
PYI019_0.py:87:27: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 |
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
88 |
|
||||
89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:89:75: PYI019 Use `Self` instead of custom TypeVar `_S695`
|
||||
ℹ Safe fix
|
||||
84 84 |
|
||||
85 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 86 |
|
||||
87 |- def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
87 |+ def multiple_type_vars[*Ts, T](self, other: Self, /, *args: *Ts, a: T, b: list[T]) -> Self: ...
|
||||
88 88 |
|
||||
89 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
90 90 |
|
||||
|
||||
PYI019_0.py:89:43: PYI019 [*] Use `Self` instead of custom TypeVar `_S695`
|
||||
|
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 |
|
||||
89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
| ^^^^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S695` with `Self`
|
||||
|
||||
PYI019_0.py:114:31: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
86 86 |
|
||||
87 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 88 |
|
||||
89 |- def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
89 |+ def mixing_old_and_new_style_type_vars[T](self, a: T, b: T) -> Self: ...
|
||||
90 90 |
|
||||
91 91 |
|
||||
92 92 | class InvalidButWeDoNotPanic:
|
||||
|
||||
PYI019_0.py:94:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
92 | class InvalidButWeDoNotPanic:
|
||||
93 | @classmethod
|
||||
94 | def m[S](cls: type[S], /) -> S[int]: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
95 | def n(self: S) -> S[int]: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
91 91 |
|
||||
92 92 | class InvalidButWeDoNotPanic:
|
||||
93 93 | @classmethod
|
||||
94 |- def m[S](cls: type[S], /) -> S[int]: ...
|
||||
94 |+ def m(cls, /) -> Self[int]: ...
|
||||
95 95 | def n(self: S) -> S[int]: ...
|
||||
96 96 |
|
||||
97 97 |
|
||||
|
||||
PYI019_0.py:114:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
112 | class SubscriptReturnType:
|
||||
113 | @classmethod
|
||||
114 | def m[S](cls: type[S]) -> type[S]: ... # PYI019
|
||||
| ^^^^^^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:129:34: PYI019 Use `Self` instead of custom TypeVar `_NotATypeVar`
|
||||
|
|
||||
127 | # but our preview-mode logic is smarter about this.
|
||||
128 | class Foo:
|
||||
129 | def x(self: _NotATypeVar) -> _NotATypeVar: ...
|
||||
| ^^^^^^^^^^^^ PYI019
|
||||
130 | @classmethod
|
||||
131 | def y(self: type[_NotATypeVar]) -> _NotATypeVar: ...
|
||||
|
|
||||
= help: Replace TypeVar `_NotATypeVar` with `Self`
|
||||
ℹ Safe fix
|
||||
111 111 |
|
||||
112 112 | class SubscriptReturnType:
|
||||
113 113 | @classmethod
|
||||
114 |- def m[S](cls: type[S]) -> type[S]: ... # PYI019
|
||||
114 |+ def m(cls) -> type[Self]: ... # PYI019
|
||||
115 115 |
|
||||
116 116 |
|
||||
117 117 | class SelfNotUsedInReturnAnnotation:
|
||||
|
||||
PYI019_0.py:131:40: PYI019 Use `Self` instead of custom TypeVar `_NotATypeVar`
|
||||
PYI019_0.py:118:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
129 | def x(self: _NotATypeVar) -> _NotATypeVar: ...
|
||||
130 | @classmethod
|
||||
131 | def y(self: type[_NotATypeVar]) -> _NotATypeVar: ...
|
||||
| ^^^^^^^^^^^^ PYI019
|
||||
117 | class SelfNotUsedInReturnAnnotation:
|
||||
118 | def m[S](self: S, other: S) -> int: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
119 | @classmethod
|
||||
120 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
|
|
||||
= help: Replace TypeVar `_NotATypeVar` with `Self`
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:140:49: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
115 115 |
|
||||
116 116 |
|
||||
117 117 | class SelfNotUsedInReturnAnnotation:
|
||||
118 |- def m[S](self: S, other: S) -> int: ...
|
||||
118 |+ def m(self, other: Self) -> int: ...
|
||||
119 119 | @classmethod
|
||||
120 120 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
121 121 |
|
||||
|
||||
PYI019_0.py:120:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
118 | def m[S](self: S, other: S) -> int: ...
|
||||
119 | @classmethod
|
||||
120 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
117 117 | class SelfNotUsedInReturnAnnotation:
|
||||
118 118 | def m[S](self: S, other: S) -> int: ...
|
||||
119 119 | @classmethod
|
||||
120 |- def n[S](cls: type[S], other: S) -> int: ...
|
||||
120 |+ def n(cls, other: Self) -> int: ...
|
||||
121 121 |
|
||||
122 122 |
|
||||
123 123 | class _NotATypeVar: ...
|
||||
|
||||
PYI019_0.py:135:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
134 | class NoReturnAnnotations:
|
||||
135 | def m[S](self: S, other: S): ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
136 | @classmethod
|
||||
137 | def n[S](cls: type[S], other: S): ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
132 132 |
|
||||
133 133 |
|
||||
134 134 | class NoReturnAnnotations:
|
||||
135 |- def m[S](self: S, other: S): ...
|
||||
135 |+ def m(self, other: Self): ...
|
||||
136 136 | @classmethod
|
||||
137 137 | def n[S](cls: type[S], other: S): ...
|
||||
138 138 |
|
||||
|
||||
PYI019_0.py:137:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
135 | def m[S](self: S, other: S): ...
|
||||
136 | @classmethod
|
||||
137 | def n[S](cls: type[S], other: S): ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
138 |
|
||||
139 | class MultipleBoundParameters:
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
134 134 | class NoReturnAnnotations:
|
||||
135 135 | def m[S](self: S, other: S): ...
|
||||
136 136 | @classmethod
|
||||
137 |- def n[S](cls: type[S], other: S): ...
|
||||
137 |+ def n(cls, other: Self): ...
|
||||
138 138 |
|
||||
139 139 | class MultipleBoundParameters:
|
||||
140 140 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
|
||||
PYI019_0.py:140:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
139 | class MultipleBoundParameters:
|
||||
140 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
141 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:141:63: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
137 137 | def n[S](cls: type[S], other: S): ...
|
||||
138 138 |
|
||||
139 139 | class MultipleBoundParameters:
|
||||
140 |- def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
140 |+ def m[T: int](self, other: T) -> Self: ...
|
||||
141 141 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
142 142 |
|
||||
143 143 | class MethodsWithBody:
|
||||
|
||||
PYI019_0.py:141:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
139 | class MultipleBoundParameters:
|
||||
140 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
141 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
142 |
|
||||
143 | class MethodsWithBody:
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:144:36: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
138 138 |
|
||||
139 139 | class MultipleBoundParameters:
|
||||
140 140 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
141 |- def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
141 |+ def n[T: (int, str)](self, other: T) -> Self: ...
|
||||
142 142 |
|
||||
143 143 | class MethodsWithBody:
|
||||
144 144 | def m[S](self: S, other: S) -> S:
|
||||
|
||||
PYI019_0.py:144:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
143 | class MethodsWithBody:
|
||||
144 | def m[S](self: S, other: S) -> S:
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
145 | x: S = other
|
||||
146 | return x
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:149:41: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
141 141 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
142 142 |
|
||||
143 143 | class MethodsWithBody:
|
||||
144 |- def m[S](self: S, other: S) -> S:
|
||||
145 |- x: S = other
|
||||
144 |+ def m(self, other: Self) -> Self:
|
||||
145 |+ x: Self = other
|
||||
146 146 | return x
|
||||
147 147 |
|
||||
148 148 | @classmethod
|
||||
|
||||
PYI019_0.py:149:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
148 | @classmethod
|
||||
149 | def n[S](cls: type[S], other: S) -> S:
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
150 | x: type[S] = type(other)
|
||||
151 | return x()
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:154:26: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
146 146 | return x
|
||||
147 147 |
|
||||
148 148 | @classmethod
|
||||
149 |- def n[S](cls: type[S], other: S) -> S:
|
||||
150 |- x: type[S] = type(other)
|
||||
149 |+ def n(cls, other: Self) -> Self:
|
||||
150 |+ x: type[Self] = type(other)
|
||||
151 151 | return x()
|
||||
152 152 |
|
||||
153 153 | class StringizedReferencesCanBeFixed:
|
||||
|
||||
PYI019_0.py:154:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
153 | class StringizedReferencesCanBeFixed:
|
||||
154 | def m[S](self: S) -> S:
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
155 | x = cast("list[tuple[S, S]]", self)
|
||||
156 | return x
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:159:28: PYI019 Use `Self` instead of custom TypeVar `_T`
|
||||
ℹ Safe fix
|
||||
151 151 | return x()
|
||||
152 152 |
|
||||
153 153 | class StringizedReferencesCanBeFixed:
|
||||
154 |- def m[S](self: S) -> S:
|
||||
155 |- x = cast("list[tuple[S, S]]", self)
|
||||
154 |+ def m(self) -> Self:
|
||||
155 |+ x = cast("list[tuple[Self, Self]]", self)
|
||||
156 156 | return x
|
||||
157 157 |
|
||||
158 158 | class ButStrangeStringizedReferencesCannotBeFixed:
|
||||
|
||||
PYI019_0.py:159:10: PYI019 Use `Self` instead of custom TypeVar `_T`
|
||||
|
|
||||
158 | class ButStrangeStringizedReferencesCannotBeFixed:
|
||||
159 | def m[_T](self: _T) -> _T:
|
||||
| ^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
160 | x = cast('list[_\x54]', self)
|
||||
161 | return x
|
||||
|
|
||||
= help: Replace TypeVar `_T` with `Self`
|
||||
|
||||
PYI019_0.py:164:26: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
PYI019_0.py:164:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
163 | class DeletionsAreNotTouched:
|
||||
164 | def m[S](self: S) -> S:
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
165 | # `S` is not a local variable here, and `del` can only be used with local variables,
|
||||
166 | # so `del S` here is not actually a reference to the type variable `S`.
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.py:173:26: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
161 161 | return x
|
||||
162 162 |
|
||||
163 163 | class DeletionsAreNotTouched:
|
||||
164 |- def m[S](self: S) -> S:
|
||||
164 |+ def m(self) -> Self:
|
||||
165 165 | # `S` is not a local variable here, and `del` can only be used with local variables,
|
||||
166 166 | # so `del S` here is not actually a reference to the type variable `S`.
|
||||
167 167 | # This `del` statement is therefore not touched by the autofix (it raises `UnboundLocalError`
|
||||
|
||||
PYI019_0.py:173:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
172 | class NamesShadowingTypeVarAreNotTouched:
|
||||
173 | def m[S](self: S) -> S:
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
174 | type S = int
|
||||
175 | print(S) # not a reference to the type variable, so not touched by the autofix
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
170 170 | return self
|
||||
171 171 |
|
||||
172 172 | class NamesShadowingTypeVarAreNotTouched:
|
||||
173 |- def m[S](self: S) -> S:
|
||||
173 |+ def m(self) -> Self:
|
||||
174 174 | type S = int
|
||||
175 175 | print(S) # not a reference to the type variable, so not touched by the autofix
|
||||
176 176 | return 42
|
||||
|
||||
@@ -1,293 +1,684 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI019_0.pyi:7:62: PYI019 Use `Self` instead of custom TypeVar `_S`
|
||||
PYI019_0.pyi:7:16: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
6 | class BadClass:
|
||||
7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
| ^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
PYI019_0.pyi:10:54: PYI019 Use `Self` instead of custom TypeVar `_S`
|
||||
ℹ Safe fix
|
||||
4 4 | _S2 = TypeVar("_S2", BadClass, GoodClass)
|
||||
5 5 |
|
||||
6 6 | class BadClass:
|
||||
7 |- def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
7 |+ def __new__(cls, *args: str, **kwargs: int) -> Self: ... # PYI019
|
||||
8 8 |
|
||||
9 9 |
|
||||
10 10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
|
||||
PYI019_0.pyi:10:28: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
| ^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
PYI019_0.pyi:14:54: PYI019 Use `Self` instead of custom TypeVar `_S`
|
||||
ℹ Safe fix
|
||||
7 7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
8 8 |
|
||||
9 9 |
|
||||
10 |- def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
10 |+ def bad_instance_method(self, arg: bytes) -> Self: ... # PYI019
|
||||
11 11 |
|
||||
12 12 |
|
||||
13 13 | @classmethod
|
||||
|
||||
PYI019_0.pyi:14:25: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
13 | @classmethod
|
||||
14 | def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019
|
||||
| ^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
PYI019_0.pyi:18:55: PYI019 Use `Self` instead of custom TypeVar `_S`
|
||||
ℹ Safe fix
|
||||
11 11 |
|
||||
12 12 |
|
||||
13 13 | @classmethod
|
||||
14 |- def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019
|
||||
14 |+ def bad_class_method(cls, arg: int) -> Self: ... # PYI019
|
||||
15 15 |
|
||||
16 16 |
|
||||
17 17 | @classmethod
|
||||
|
||||
PYI019_0.pyi:18:33: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
17 | @classmethod
|
||||
18 | def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019
|
||||
| ^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
PYI019_0.pyi:39:63: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
15 15 |
|
||||
16 16 |
|
||||
17 17 | @classmethod
|
||||
18 |- def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019
|
||||
18 |+ def bad_posonly_class_method(cls, /) -> Self: ... # PYI019
|
||||
19 19 |
|
||||
20 20 |
|
||||
21 21 | @classmethod
|
||||
|
||||
PYI019_0.pyi:39:14: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
37 | # Python > 3.12
|
||||
38 | class PEP695BadDunderNew[T]:
|
||||
39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:42:46: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
36 36 |
|
||||
37 37 | # Python > 3.12
|
||||
38 38 | class PEP695BadDunderNew[T]:
|
||||
39 |- def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
39 |+ def __new__(cls, *args: Any, ** kwargs: Any) -> Self: ... # PYI019
|
||||
40 40 |
|
||||
41 41 |
|
||||
42 42 | def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
|
||||
PYI019_0.pyi:42:30: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
42 | def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:54:32: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
39 39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
40 40 |
|
||||
41 41 |
|
||||
42 |- def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
42 |+ def generic_instance_method(self) -> Self: ... # PYI019
|
||||
43 43 |
|
||||
44 44 |
|
||||
45 45 | class PEP695GoodDunderNew[T]:
|
||||
|
||||
PYI019_0.pyi:54:11: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
52 | # in the settings for this test:
|
||||
53 | @foo_classmethod
|
||||
54 | def foo[S](cls: type[S]) -> S: ... # PYI019
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:61:48: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
51 51 | # due to `foo_classmethod being listed in `pep8_naming.classmethod-decorators`
|
||||
52 52 | # in the settings for this test:
|
||||
53 53 | @foo_classmethod
|
||||
54 |- def foo[S](cls: type[S]) -> S: ... # PYI019
|
||||
54 |+ def foo(cls) -> Self: ... # PYI019
|
||||
55 55 |
|
||||
56 56 |
|
||||
57 57 | _S695 = TypeVar("_S695", bound="PEP695Fix")
|
||||
|
||||
PYI019_0.pyi:61:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
60 | class PEP695Fix:
|
||||
61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
62 |
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:63:47: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
58 58 |
|
||||
59 59 |
|
||||
60 60 | class PEP695Fix:
|
||||
61 |- def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
61 |+ def __new__(cls) -> Self: ...
|
||||
62 62 |
|
||||
63 63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 64 |
|
||||
|
||||
PYI019_0.pyi:63:26: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
62 |
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
64 |
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:65:43: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
60 60 | class PEP695Fix:
|
||||
61 61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
62 62 |
|
||||
63 |- def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
63 |+ def __init_subclass__(cls) -> Self: ...
|
||||
64 64 |
|
||||
65 65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 66 |
|
||||
|
||||
PYI019_0.pyi:65:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 |
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
66 |
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:67:32: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
62 62 |
|
||||
63 63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 64 |
|
||||
65 |- def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
65 |+ def __neg__(self) -> Self: ...
|
||||
66 66 |
|
||||
67 67 | def __pos__[S](self: S) -> S: ...
|
||||
68 68 |
|
||||
|
||||
PYI019_0.pyi:67:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 |
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
68 |
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:69:53: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
64 64 |
|
||||
65 65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 66 |
|
||||
67 |- def __pos__[S](self: S) -> S: ...
|
||||
67 |+ def __pos__(self) -> Self: ...
|
||||
68 68 |
|
||||
69 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 70 |
|
||||
|
||||
PYI019_0.pyi:69:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
68 |
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
70 |
|
||||
71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:71:42: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
66 66 |
|
||||
67 67 | def __pos__[S](self: S) -> S: ...
|
||||
68 68 |
|
||||
69 |- def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
69 |+ def __add__(self, other: Self) -> Self: ...
|
||||
70 70 |
|
||||
71 71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
72 72 |
|
||||
|
||||
PYI019_0.pyi:71:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 |
|
||||
71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
72 |
|
||||
73 | @classmethod
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:74:59: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
68 68 |
|
||||
69 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 70 |
|
||||
71 |- def __sub__[S](self: S, other: S) -> S: ...
|
||||
71 |+ def __sub__(self, other: Self) -> Self: ...
|
||||
72 72 |
|
||||
73 73 | @classmethod
|
||||
74 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
|
||||
PYI019_0.pyi:74:27: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
73 | @classmethod
|
||||
74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
75 |
|
||||
76 | @classmethod
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:77:50: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
71 71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
72 72 |
|
||||
73 73 | @classmethod
|
||||
74 |- def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
74 |+ def class_method_bound(cls) -> Self: ...
|
||||
75 75 |
|
||||
76 76 | @classmethod
|
||||
77 77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
|
||||
PYI019_0.pyi:77:29: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
76 | @classmethod
|
||||
77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
78 |
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:79:57: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
74 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
75 75 |
|
||||
76 76 | @classmethod
|
||||
77 |- def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
77 |+ def class_method_unbound(cls) -> Self: ...
|
||||
78 78 |
|
||||
79 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 80 |
|
||||
|
||||
PYI019_0.pyi:79:30: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
78 |
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
80 |
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:81:48: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
76 76 | @classmethod
|
||||
77 77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
78 78 |
|
||||
79 |- def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
79 |+ def instance_method_bound(self) -> Self: ...
|
||||
80 80 |
|
||||
81 81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 82 |
|
||||
|
||||
PYI019_0.pyi:81:32: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 |
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
82 |
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:83:90: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
78 78 |
|
||||
79 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 80 |
|
||||
81 |- def instance_method_unbound[S](self: S) -> S: ...
|
||||
81 |+ def instance_method_unbound(self) -> Self: ...
|
||||
82 82 |
|
||||
83 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 84 |
|
||||
|
||||
PYI019_0.pyi:83:53: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 |
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
84 |
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:85:81: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
80 80 |
|
||||
81 81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 82 |
|
||||
83 |- def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
83 |+ def instance_method_bound_with_another_parameter(self, other: Self) -> Self: ...
|
||||
84 84 |
|
||||
85 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 86 |
|
||||
|
||||
PYI019_0.pyi:85:55: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 |
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
86 |
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:87:94: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
82 82 |
|
||||
83 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 84 |
|
||||
85 |- def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
85 |+ def instance_method_unbound_with_another_parameter(self, other: Self) -> Self: ...
|
||||
86 86 |
|
||||
87 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 88 |
|
||||
|
||||
PYI019_0.pyi:87:27: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 |
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
88 |
|
||||
89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:89:75: PYI019 Use `Self` instead of custom TypeVar `_S695`
|
||||
ℹ Safe fix
|
||||
84 84 |
|
||||
85 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 86 |
|
||||
87 |- def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
87 |+ def multiple_type_vars[*Ts, T](self, other: Self, /, *args: *Ts, a: T, b: list[T]) -> Self: ...
|
||||
88 88 |
|
||||
89 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
90 90 |
|
||||
|
||||
PYI019_0.pyi:89:43: PYI019 [*] Use `Self` instead of custom TypeVar `_S695`
|
||||
|
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 |
|
||||
89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
| ^^^^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S695` with `Self`
|
||||
|
||||
PYI019_0.pyi:114:31: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
86 86 |
|
||||
87 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 88 |
|
||||
89 |- def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
89 |+ def mixing_old_and_new_style_type_vars[T](self, a: T, b: T) -> Self: ...
|
||||
90 90 |
|
||||
91 91 |
|
||||
92 92 | class InvalidButWeDoNotPanic:
|
||||
|
||||
PYI019_0.pyi:94:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
92 | class InvalidButWeDoNotPanic:
|
||||
93 | @classmethod
|
||||
94 | def m[S](cls: type[S], /) -> S[int]: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
95 | def n(self: S) -> S[int]: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
91 91 |
|
||||
92 92 | class InvalidButWeDoNotPanic:
|
||||
93 93 | @classmethod
|
||||
94 |- def m[S](cls: type[S], /) -> S[int]: ...
|
||||
94 |+ def m(cls, /) -> Self[int]: ...
|
||||
95 95 | def n(self: S) -> S[int]: ...
|
||||
96 96 |
|
||||
97 97 |
|
||||
|
||||
PYI019_0.pyi:114:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
112 | class SubscriptReturnType:
|
||||
113 | @classmethod
|
||||
114 | def m[S](cls: type[S]) -> type[S]: ... # PYI019
|
||||
| ^^^^^^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:118:29: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
111 111 |
|
||||
112 112 | class SubscriptReturnType:
|
||||
113 113 | @classmethod
|
||||
114 |- def m[S](cls: type[S]) -> type[S]: ... # PYI019
|
||||
114 |+ def m(cls) -> type[Self]: ... # PYI019
|
||||
115 115 |
|
||||
116 116 |
|
||||
117 117 | class PEP695TypeParameterAtTheVeryEndOfTheList:
|
||||
|
||||
PYI019_0.pyi:118:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
117 | class PEP695TypeParameterAtTheVeryEndOfTheList:
|
||||
118 | def f[T, S](self: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:122:100: PYI019 Use `Self` instead of custom TypeVar `_S695`
|
||||
ℹ Safe fix
|
||||
115 115 |
|
||||
116 116 |
|
||||
117 117 | class PEP695TypeParameterAtTheVeryEndOfTheList:
|
||||
118 |- def f[T, S](self: S) -> S: ...
|
||||
118 |+ def f[T](self) -> Self: ...
|
||||
119 119 |
|
||||
120 120 |
|
||||
121 121 | class PEP695Again:
|
||||
|
||||
PYI019_0.pyi:122:26: PYI019 [*] Use `Self` instead of custom TypeVar `_S695`
|
||||
|
|
||||
121 | class PEP695Again:
|
||||
122 | def mixing_and_nested[T](self: _S695, a: list[_S695], b: dict[_S695, str | T | set[_S695]]) -> _S695: ...
|
||||
| ^^^^^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
123 | def also_uses_s695_but_should_not_be_edited(self, v: set[tuple[_S695]]) -> _S695: ...
|
||||
|
|
||||
= help: Replace TypeVar `_S695` with `Self`
|
||||
|
||||
PYI019_0.pyi:132:10: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
119 119 |
|
||||
120 120 |
|
||||
121 121 | class PEP695Again:
|
||||
122 |- def mixing_and_nested[T](self: _S695, a: list[_S695], b: dict[_S695, str | T | set[_S695]]) -> _S695: ...
|
||||
122 |+ def mixing_and_nested[T](self, a: list[Self], b: dict[Self, str | T | set[Self]]) -> Self: ...
|
||||
123 123 | def also_uses_s695_but_should_not_be_edited(self, v: set[tuple[_S695]]) -> _S695: ...
|
||||
124 124 |
|
||||
125 125 | @classmethod
|
||||
|
||||
PYI019_0.pyi:126:29: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
130 | a: T,
|
||||
131 | b: tuple[S, T]
|
||||
132 | ) -> S: ...
|
||||
| ^ PYI019
|
||||
125 | @classmethod
|
||||
126 | def comment_in_fix_range[T, S](
|
||||
| _____________________________^
|
||||
127 | | cls: type[ # Lorem ipsum
|
||||
128 | | S
|
||||
129 | | ],
|
||||
130 | | a: T,
|
||||
131 | | b: tuple[S, T]
|
||||
132 | | ) -> S: ...
|
||||
| |__________^ PYI019
|
||||
133 |
|
||||
134 | def comment_outside_fix_range[T, S](
|
||||
134 | def comment_outside_fix_range[T, S](
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:141:10: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Unsafe fix
|
||||
123 123 | def also_uses_s695_but_should_not_be_edited(self, v: set[tuple[_S695]]) -> _S695: ...
|
||||
124 124 |
|
||||
125 125 | @classmethod
|
||||
126 |- def comment_in_fix_range[T, S](
|
||||
127 |- cls: type[ # Lorem ipsum
|
||||
128 |- S
|
||||
129 |- ],
|
||||
126 |+ def comment_in_fix_range[T](
|
||||
127 |+ cls,
|
||||
130 128 | a: T,
|
||||
131 |- b: tuple[S, T]
|
||||
132 |- ) -> S: ...
|
||||
129 |+ b: tuple[Self, T]
|
||||
130 |+ ) -> Self: ...
|
||||
133 131 |
|
||||
134 132 | def comment_outside_fix_range[T, S](
|
||||
135 133 | self: S,
|
||||
|
||||
PYI019_0.pyi:134:34: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
139 | S, T
|
||||
140 | ]
|
||||
141 | ) -> S: ...
|
||||
| ^ PYI019
|
||||
132 | ) -> S: ...
|
||||
133 |
|
||||
134 | def comment_outside_fix_range[T, S](
|
||||
| __________________________________^
|
||||
135 | | self: S,
|
||||
136 | | a: T,
|
||||
137 | | b: tuple[
|
||||
138 | | # Lorem ipsum
|
||||
139 | | S, T
|
||||
140 | | ]
|
||||
141 | | ) -> S: ...
|
||||
| |__________^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:156:34: PYI019 Use `Self` instead of custom TypeVar `_NotATypeVar`
|
||||
|
|
||||
154 | # but our preview-mode logic is smarter about this.
|
||||
155 | class Foo:
|
||||
156 | def x(self: _NotATypeVar) -> _NotATypeVar: ...
|
||||
| ^^^^^^^^^^^^ PYI019
|
||||
157 | @classmethod
|
||||
158 | def y(self: type[_NotATypeVar]) -> _NotATypeVar: ...
|
||||
|
|
||||
= help: Replace TypeVar `_NotATypeVar` with `Self`
|
||||
ℹ Safe fix
|
||||
131 131 | b: tuple[S, T]
|
||||
132 132 | ) -> S: ...
|
||||
133 133 |
|
||||
134 |- def comment_outside_fix_range[T, S](
|
||||
135 |- self: S,
|
||||
134 |+ def comment_outside_fix_range[T](
|
||||
135 |+ self,
|
||||
136 136 | a: T,
|
||||
137 137 | b: tuple[
|
||||
138 138 | # Lorem ipsum
|
||||
139 |- S, T
|
||||
139 |+ Self, T
|
||||
140 140 | ]
|
||||
141 |- ) -> S: ...
|
||||
141 |+ ) -> Self: ...
|
||||
142 142 |
|
||||
143 143 |
|
||||
144 144 | class SelfNotUsedInReturnAnnotation:
|
||||
|
||||
PYI019_0.pyi:158:40: PYI019 Use `Self` instead of custom TypeVar `_NotATypeVar`
|
||||
PYI019_0.pyi:145:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
144 | class SelfNotUsedInReturnAnnotation:
|
||||
145 | def m[S](self: S, other: S) -> int: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
146 | @classmethod
|
||||
147 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
142 142 |
|
||||
143 143 |
|
||||
144 144 | class SelfNotUsedInReturnAnnotation:
|
||||
145 |- def m[S](self: S, other: S) -> int: ...
|
||||
145 |+ def m(self, other: Self) -> int: ...
|
||||
146 146 | @classmethod
|
||||
147 147 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
148 148 |
|
||||
|
||||
PYI019_0.pyi:147:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
145 | def m[S](self: S, other: S) -> int: ...
|
||||
146 | @classmethod
|
||||
147 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
144 144 | class SelfNotUsedInReturnAnnotation:
|
||||
145 145 | def m[S](self: S, other: S) -> int: ...
|
||||
146 146 | @classmethod
|
||||
147 |- def n[S](cls: type[S], other: S) -> int: ...
|
||||
147 |+ def n(cls, other: Self) -> int: ...
|
||||
148 148 |
|
||||
149 149 |
|
||||
150 150 | class _NotATypeVar: ...
|
||||
|
||||
PYI019_0.pyi:161:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
156 | def x(self: _NotATypeVar) -> _NotATypeVar: ...
|
||||
157 | @classmethod
|
||||
158 | def y(self: type[_NotATypeVar]) -> _NotATypeVar: ...
|
||||
| ^^^^^^^^^^^^ PYI019
|
||||
159 |
|
||||
160 | class NoReturnAnnotations:
|
||||
161 | def m[S](self: S, other: S): ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
162 | @classmethod
|
||||
163 | def n[S](cls: type[S], other: S): ...
|
||||
|
|
||||
= help: Replace TypeVar `_NotATypeVar` with `Self`
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:166:49: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
158 158 | def y(self: type[_NotATypeVar]) -> _NotATypeVar: ...
|
||||
159 159 |
|
||||
160 160 | class NoReturnAnnotations:
|
||||
161 |- def m[S](self: S, other: S): ...
|
||||
161 |+ def m(self, other: Self): ...
|
||||
162 162 | @classmethod
|
||||
163 163 | def n[S](cls: type[S], other: S): ...
|
||||
164 164 |
|
||||
|
||||
PYI019_0.pyi:163:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
161 | def m[S](self: S, other: S): ...
|
||||
162 | @classmethod
|
||||
163 | def n[S](cls: type[S], other: S): ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
164 |
|
||||
165 | class MultipleBoundParameters:
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
160 160 | class NoReturnAnnotations:
|
||||
161 161 | def m[S](self: S, other: S): ...
|
||||
162 162 | @classmethod
|
||||
163 |- def n[S](cls: type[S], other: S): ...
|
||||
163 |+ def n(cls, other: Self): ...
|
||||
164 164 |
|
||||
165 165 | class MultipleBoundParameters:
|
||||
166 166 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
|
||||
PYI019_0.pyi:166:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
165 | class MultipleBoundParameters:
|
||||
166 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
167 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
PYI019_0.pyi:167:63: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
ℹ Safe fix
|
||||
163 163 | def n[S](cls: type[S], other: S): ...
|
||||
164 164 |
|
||||
165 165 | class MultipleBoundParameters:
|
||||
166 |- def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
166 |+ def m[T: int](self, other: T) -> Self: ...
|
||||
167 167 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
168 168 |
|
||||
169 169 |
|
||||
|
||||
PYI019_0.pyi:167:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
165 | class MultipleBoundParameters:
|
||||
166 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
167 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
164 164 |
|
||||
165 165 | class MultipleBoundParameters:
|
||||
166 166 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
167 |- def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
167 |+ def n[T: (int, str)](self, other: T) -> Self: ...
|
||||
168 168 |
|
||||
169 169 |
|
||||
170 170 | MetaType = TypeVar("MetaType")
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI019_1.pyi:4:26: PYI019 Use `Self` instead of custom TypeVar `S`
|
||||
PYI019_1.pyi:4:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
3 | class F:
|
||||
4 | def m[S](self: S) -> S: ...
|
||||
| ^ PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
1 1 | import typing
|
||||
2 2 |
|
||||
3 3 | class F:
|
||||
4 |- def m[S](self: S) -> S: ...
|
||||
4 |+ def m(self) -> typing.Self: ...
|
||||
|
||||
@@ -1,692 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI019_0.py:7:16: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
6 | class BadClass:
|
||||
7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
4 4 | _S2 = TypeVar("_S2", BadClass, GoodClass)
|
||||
5 5 |
|
||||
6 6 | class BadClass:
|
||||
7 |- def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
7 |+ def __new__(cls, *args: str, **kwargs: int) -> Self: ... # PYI019
|
||||
8 8 |
|
||||
9 9 |
|
||||
10 10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
|
||||
PYI019_0.py:10:28: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
7 7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
8 8 |
|
||||
9 9 |
|
||||
10 |- def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
10 |+ def bad_instance_method(self, arg: bytes) -> Self: ... # PYI019
|
||||
11 11 |
|
||||
12 12 |
|
||||
13 13 | @classmethod
|
||||
|
||||
PYI019_0.py:14:25: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
13 | @classmethod
|
||||
14 | def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
11 11 |
|
||||
12 12 |
|
||||
13 13 | @classmethod
|
||||
14 |- def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019
|
||||
14 |+ def bad_class_method(cls, arg: int) -> Self: ... # PYI019
|
||||
15 15 |
|
||||
16 16 |
|
||||
17 17 | @classmethod
|
||||
|
||||
PYI019_0.py:18:33: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
17 | @classmethod
|
||||
18 | def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
15 15 |
|
||||
16 16 |
|
||||
17 17 | @classmethod
|
||||
18 |- def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019
|
||||
18 |+ def bad_posonly_class_method(cls, /) -> Self: ... # PYI019
|
||||
19 19 |
|
||||
20 20 |
|
||||
21 21 | @classmethod
|
||||
|
||||
PYI019_0.py:39:14: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
37 | # Python > 3.12
|
||||
38 | class PEP695BadDunderNew[T]:
|
||||
39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
36 36 |
|
||||
37 37 | # Python > 3.12
|
||||
38 38 | class PEP695BadDunderNew[T]:
|
||||
39 |- def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
39 |+ def __new__(cls, *args: Any, ** kwargs: Any) -> Self: ... # PYI019
|
||||
40 40 |
|
||||
41 41 |
|
||||
42 42 | def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
|
||||
PYI019_0.py:42:30: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
42 | def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
39 39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
40 40 |
|
||||
41 41 |
|
||||
42 |- def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
42 |+ def generic_instance_method(self) -> Self: ... # PYI019
|
||||
43 43 |
|
||||
44 44 |
|
||||
45 45 | class PEP695GoodDunderNew[T]:
|
||||
|
||||
PYI019_0.py:54:11: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
52 | # in the settings for this test:
|
||||
53 | @foo_classmethod
|
||||
54 | def foo[S](cls: type[S]) -> S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
51 51 | # due to `foo_classmethod being listed in `pep8_naming.classmethod-decorators`
|
||||
52 52 | # in the settings for this test:
|
||||
53 53 | @foo_classmethod
|
||||
54 |- def foo[S](cls: type[S]) -> S: ... # PYI019
|
||||
54 |+ def foo(cls) -> Self: ... # PYI019
|
||||
55 55 |
|
||||
56 56 |
|
||||
57 57 | _S695 = TypeVar("_S695", bound="PEP695Fix")
|
||||
|
||||
PYI019_0.py:61:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
60 | class PEP695Fix:
|
||||
61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
62 |
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
58 58 |
|
||||
59 59 |
|
||||
60 60 | class PEP695Fix:
|
||||
61 |- def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
61 |+ def __new__(cls) -> Self: ...
|
||||
62 62 |
|
||||
63 63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 64 |
|
||||
|
||||
PYI019_0.py:63:26: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
62 |
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
64 |
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
60 60 | class PEP695Fix:
|
||||
61 61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
62 62 |
|
||||
63 |- def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
63 |+ def __init_subclass__(cls) -> Self: ...
|
||||
64 64 |
|
||||
65 65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 66 |
|
||||
|
||||
PYI019_0.py:65:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 |
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
66 |
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
62 62 |
|
||||
63 63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 64 |
|
||||
65 |- def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
65 |+ def __neg__(self) -> Self: ...
|
||||
66 66 |
|
||||
67 67 | def __pos__[S](self: S) -> S: ...
|
||||
68 68 |
|
||||
|
||||
PYI019_0.py:67:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 |
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
68 |
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
64 64 |
|
||||
65 65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 66 |
|
||||
67 |- def __pos__[S](self: S) -> S: ...
|
||||
67 |+ def __pos__(self) -> Self: ...
|
||||
68 68 |
|
||||
69 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 70 |
|
||||
|
||||
PYI019_0.py:69:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
68 |
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
70 |
|
||||
71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
66 66 |
|
||||
67 67 | def __pos__[S](self: S) -> S: ...
|
||||
68 68 |
|
||||
69 |- def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
69 |+ def __add__(self, other: Self) -> Self: ...
|
||||
70 70 |
|
||||
71 71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
72 72 |
|
||||
|
||||
PYI019_0.py:71:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 |
|
||||
71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
72 |
|
||||
73 | @classmethod
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
68 68 |
|
||||
69 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 70 |
|
||||
71 |- def __sub__[S](self: S, other: S) -> S: ...
|
||||
71 |+ def __sub__(self, other: Self) -> Self: ...
|
||||
72 72 |
|
||||
73 73 | @classmethod
|
||||
74 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
|
||||
PYI019_0.py:74:27: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
73 | @classmethod
|
||||
74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
75 |
|
||||
76 | @classmethod
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
71 71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
72 72 |
|
||||
73 73 | @classmethod
|
||||
74 |- def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
74 |+ def class_method_bound(cls) -> Self: ...
|
||||
75 75 |
|
||||
76 76 | @classmethod
|
||||
77 77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
|
||||
PYI019_0.py:77:29: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
76 | @classmethod
|
||||
77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
78 |
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
74 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
75 75 |
|
||||
76 76 | @classmethod
|
||||
77 |- def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
77 |+ def class_method_unbound(cls) -> Self: ...
|
||||
78 78 |
|
||||
79 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 80 |
|
||||
|
||||
PYI019_0.py:79:30: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
78 |
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
80 |
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
76 76 | @classmethod
|
||||
77 77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
78 78 |
|
||||
79 |- def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
79 |+ def instance_method_bound(self) -> Self: ...
|
||||
80 80 |
|
||||
81 81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 82 |
|
||||
|
||||
PYI019_0.py:81:32: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 |
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
82 |
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
78 78 |
|
||||
79 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 80 |
|
||||
81 |- def instance_method_unbound[S](self: S) -> S: ...
|
||||
81 |+ def instance_method_unbound(self) -> Self: ...
|
||||
82 82 |
|
||||
83 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 84 |
|
||||
|
||||
PYI019_0.py:83:53: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 |
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
84 |
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
80 80 |
|
||||
81 81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 82 |
|
||||
83 |- def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
83 |+ def instance_method_bound_with_another_parameter(self, other: Self) -> Self: ...
|
||||
84 84 |
|
||||
85 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 86 |
|
||||
|
||||
PYI019_0.py:85:55: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 |
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
86 |
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
82 82 |
|
||||
83 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 84 |
|
||||
85 |- def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
85 |+ def instance_method_unbound_with_another_parameter(self, other: Self) -> Self: ...
|
||||
86 86 |
|
||||
87 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 88 |
|
||||
|
||||
PYI019_0.py:87:27: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 |
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
88 |
|
||||
89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
84 84 |
|
||||
85 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 86 |
|
||||
87 |- def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
87 |+ def multiple_type_vars[*Ts, T](self, other: Self, /, *args: *Ts, a: T, b: list[T]) -> Self: ...
|
||||
88 88 |
|
||||
89 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
90 90 |
|
||||
|
||||
PYI019_0.py:89:43: PYI019 [*] Use `Self` instead of custom TypeVar `_S695`
|
||||
|
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 |
|
||||
89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S695` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
86 86 |
|
||||
87 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 88 |
|
||||
89 |- def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
89 |+ def mixing_old_and_new_style_type_vars[T](self, a: T, b: T) -> Self: ...
|
||||
90 90 |
|
||||
91 91 |
|
||||
92 92 | class InvalidButWeDoNotPanic:
|
||||
|
||||
PYI019_0.py:94:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
92 | class InvalidButWeDoNotPanic:
|
||||
93 | @classmethod
|
||||
94 | def m[S](cls: type[S], /) -> S[int]: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
95 | def n(self: S) -> S[int]: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
91 91 |
|
||||
92 92 | class InvalidButWeDoNotPanic:
|
||||
93 93 | @classmethod
|
||||
94 |- def m[S](cls: type[S], /) -> S[int]: ...
|
||||
94 |+ def m(cls, /) -> Self[int]: ...
|
||||
95 95 | def n(self: S) -> S[int]: ...
|
||||
96 96 |
|
||||
97 97 |
|
||||
|
||||
PYI019_0.py:114:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
112 | class SubscriptReturnType:
|
||||
113 | @classmethod
|
||||
114 | def m[S](cls: type[S]) -> type[S]: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
111 111 |
|
||||
112 112 | class SubscriptReturnType:
|
||||
113 113 | @classmethod
|
||||
114 |- def m[S](cls: type[S]) -> type[S]: ... # PYI019
|
||||
114 |+ def m(cls) -> type[Self]: ... # PYI019
|
||||
115 115 |
|
||||
116 116 |
|
||||
117 117 | class SelfNotUsedInReturnAnnotation:
|
||||
|
||||
PYI019_0.py:118:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
117 | class SelfNotUsedInReturnAnnotation:
|
||||
118 | def m[S](self: S, other: S) -> int: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
119 | @classmethod
|
||||
120 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
115 115 |
|
||||
116 116 |
|
||||
117 117 | class SelfNotUsedInReturnAnnotation:
|
||||
118 |- def m[S](self: S, other: S) -> int: ...
|
||||
118 |+ def m(self, other: Self) -> int: ...
|
||||
119 119 | @classmethod
|
||||
120 120 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
121 121 |
|
||||
|
||||
PYI019_0.py:120:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
118 | def m[S](self: S, other: S) -> int: ...
|
||||
119 | @classmethod
|
||||
120 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
117 117 | class SelfNotUsedInReturnAnnotation:
|
||||
118 118 | def m[S](self: S, other: S) -> int: ...
|
||||
119 119 | @classmethod
|
||||
120 |- def n[S](cls: type[S], other: S) -> int: ...
|
||||
120 |+ def n(cls, other: Self) -> int: ...
|
||||
121 121 |
|
||||
122 122 |
|
||||
123 123 | class _NotATypeVar: ...
|
||||
|
||||
PYI019_0.py:135:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
134 | class NoReturnAnnotations:
|
||||
135 | def m[S](self: S, other: S): ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
136 | @classmethod
|
||||
137 | def n[S](cls: type[S], other: S): ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
132 132 |
|
||||
133 133 |
|
||||
134 134 | class NoReturnAnnotations:
|
||||
135 |- def m[S](self: S, other: S): ...
|
||||
135 |+ def m(self, other: Self): ...
|
||||
136 136 | @classmethod
|
||||
137 137 | def n[S](cls: type[S], other: S): ...
|
||||
138 138 |
|
||||
|
||||
PYI019_0.py:137:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
135 | def m[S](self: S, other: S): ...
|
||||
136 | @classmethod
|
||||
137 | def n[S](cls: type[S], other: S): ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
138 |
|
||||
139 | class MultipleBoundParameters:
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
134 134 | class NoReturnAnnotations:
|
||||
135 135 | def m[S](self: S, other: S): ...
|
||||
136 136 | @classmethod
|
||||
137 |- def n[S](cls: type[S], other: S): ...
|
||||
137 |+ def n(cls, other: Self): ...
|
||||
138 138 |
|
||||
139 139 | class MultipleBoundParameters:
|
||||
140 140 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
|
||||
PYI019_0.py:140:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
139 | class MultipleBoundParameters:
|
||||
140 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
141 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
137 137 | def n[S](cls: type[S], other: S): ...
|
||||
138 138 |
|
||||
139 139 | class MultipleBoundParameters:
|
||||
140 |- def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
140 |+ def m[T: int](self, other: T) -> Self: ...
|
||||
141 141 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
142 142 |
|
||||
143 143 | class MethodsWithBody:
|
||||
|
||||
PYI019_0.py:141:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
139 | class MultipleBoundParameters:
|
||||
140 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
141 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
142 |
|
||||
143 | class MethodsWithBody:
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
138 138 |
|
||||
139 139 | class MultipleBoundParameters:
|
||||
140 140 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
141 |- def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
141 |+ def n[T: (int, str)](self, other: T) -> Self: ...
|
||||
142 142 |
|
||||
143 143 | class MethodsWithBody:
|
||||
144 144 | def m[S](self: S, other: S) -> S:
|
||||
|
||||
PYI019_0.py:144:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
143 | class MethodsWithBody:
|
||||
144 | def m[S](self: S, other: S) -> S:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
145 | x: S = other
|
||||
146 | return x
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
141 141 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
142 142 |
|
||||
143 143 | class MethodsWithBody:
|
||||
144 |- def m[S](self: S, other: S) -> S:
|
||||
145 |- x: S = other
|
||||
144 |+ def m(self, other: Self) -> Self:
|
||||
145 |+ x: Self = other
|
||||
146 146 | return x
|
||||
147 147 |
|
||||
148 148 | @classmethod
|
||||
|
||||
PYI019_0.py:149:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
148 | @classmethod
|
||||
149 | def n[S](cls: type[S], other: S) -> S:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
150 | x: type[S] = type(other)
|
||||
151 | return x()
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
146 146 | return x
|
||||
147 147 |
|
||||
148 148 | @classmethod
|
||||
149 |- def n[S](cls: type[S], other: S) -> S:
|
||||
150 |- x: type[S] = type(other)
|
||||
149 |+ def n(cls, other: Self) -> Self:
|
||||
150 |+ x: type[Self] = type(other)
|
||||
151 151 | return x()
|
||||
152 152 |
|
||||
153 153 | class StringizedReferencesCanBeFixed:
|
||||
|
||||
PYI019_0.py:154:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
153 | class StringizedReferencesCanBeFixed:
|
||||
154 | def m[S](self: S) -> S:
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
155 | x = cast("list[tuple[S, S]]", self)
|
||||
156 | return x
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
151 151 | return x()
|
||||
152 152 |
|
||||
153 153 | class StringizedReferencesCanBeFixed:
|
||||
154 |- def m[S](self: S) -> S:
|
||||
155 |- x = cast("list[tuple[S, S]]", self)
|
||||
154 |+ def m(self) -> Self:
|
||||
155 |+ x = cast("list[tuple[Self, Self]]", self)
|
||||
156 156 | return x
|
||||
157 157 |
|
||||
158 158 | class ButStrangeStringizedReferencesCannotBeFixed:
|
||||
|
||||
PYI019_0.py:159:10: PYI019 Use `Self` instead of custom TypeVar `_T`
|
||||
|
|
||||
158 | class ButStrangeStringizedReferencesCannotBeFixed:
|
||||
159 | def m[_T](self: _T) -> _T:
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
160 | x = cast('list[_\x54]', self)
|
||||
161 | return x
|
||||
|
|
||||
= help: Replace TypeVar `_T` with `Self`
|
||||
|
||||
PYI019_0.py:164:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
163 | class DeletionsAreNotTouched:
|
||||
164 | def m[S](self: S) -> S:
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
165 | # `S` is not a local variable here, and `del` can only be used with local variables,
|
||||
166 | # so `del S` here is not actually a reference to the type variable `S`.
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
161 161 | return x
|
||||
162 162 |
|
||||
163 163 | class DeletionsAreNotTouched:
|
||||
164 |- def m[S](self: S) -> S:
|
||||
164 |+ def m(self) -> Self:
|
||||
165 165 | # `S` is not a local variable here, and `del` can only be used with local variables,
|
||||
166 166 | # so `del S` here is not actually a reference to the type variable `S`.
|
||||
167 167 | # This `del` statement is therefore not touched by the autofix (it raises `UnboundLocalError`
|
||||
|
||||
PYI019_0.py:173:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
172 | class NamesShadowingTypeVarAreNotTouched:
|
||||
173 | def m[S](self: S) -> S:
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
174 | type S = int
|
||||
175 | print(S) # not a reference to the type variable, so not touched by the autofix
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
170 170 | return self
|
||||
171 171 |
|
||||
172 172 | class NamesShadowingTypeVarAreNotTouched:
|
||||
173 |- def m[S](self: S) -> S:
|
||||
173 |+ def m(self) -> Self:
|
||||
174 174 | type S = int
|
||||
175 175 | print(S) # not a reference to the type variable, so not touched by the autofix
|
||||
176 176 | return 42
|
||||
@@ -1,684 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI019_0.pyi:7:16: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
6 | class BadClass:
|
||||
7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
4 4 | _S2 = TypeVar("_S2", BadClass, GoodClass)
|
||||
5 5 |
|
||||
6 6 | class BadClass:
|
||||
7 |- def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
7 |+ def __new__(cls, *args: str, **kwargs: int) -> Self: ... # PYI019
|
||||
8 8 |
|
||||
9 9 |
|
||||
10 10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
|
||||
PYI019_0.pyi:10:28: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
7 7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019
|
||||
8 8 |
|
||||
9 9 |
|
||||
10 |- def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019
|
||||
10 |+ def bad_instance_method(self, arg: bytes) -> Self: ... # PYI019
|
||||
11 11 |
|
||||
12 12 |
|
||||
13 13 | @classmethod
|
||||
|
||||
PYI019_0.pyi:14:25: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
13 | @classmethod
|
||||
14 | def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
11 11 |
|
||||
12 12 |
|
||||
13 13 | @classmethod
|
||||
14 |- def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019
|
||||
14 |+ def bad_class_method(cls, arg: int) -> Self: ... # PYI019
|
||||
15 15 |
|
||||
16 16 |
|
||||
17 17 | @classmethod
|
||||
|
||||
PYI019_0.pyi:18:33: PYI019 [*] Use `Self` instead of custom TypeVar `_S`
|
||||
|
|
||||
17 | @classmethod
|
||||
18 | def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
15 15 |
|
||||
16 16 |
|
||||
17 17 | @classmethod
|
||||
18 |- def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019
|
||||
18 |+ def bad_posonly_class_method(cls, /) -> Self: ... # PYI019
|
||||
19 19 |
|
||||
20 20 |
|
||||
21 21 | @classmethod
|
||||
|
||||
PYI019_0.pyi:39:14: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
37 | # Python > 3.12
|
||||
38 | class PEP695BadDunderNew[T]:
|
||||
39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
36 36 |
|
||||
37 37 | # Python > 3.12
|
||||
38 38 | class PEP695BadDunderNew[T]:
|
||||
39 |- def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
39 |+ def __new__(cls, *args: Any, ** kwargs: Any) -> Self: ... # PYI019
|
||||
40 40 |
|
||||
41 41 |
|
||||
42 42 | def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
|
||||
PYI019_0.pyi:42:30: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
42 | def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
39 39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019
|
||||
40 40 |
|
||||
41 41 |
|
||||
42 |- def generic_instance_method[S](self: S) -> S: ... # PYI019
|
||||
42 |+ def generic_instance_method(self) -> Self: ... # PYI019
|
||||
43 43 |
|
||||
44 44 |
|
||||
45 45 | class PEP695GoodDunderNew[T]:
|
||||
|
||||
PYI019_0.pyi:54:11: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
52 | # in the settings for this test:
|
||||
53 | @foo_classmethod
|
||||
54 | def foo[S](cls: type[S]) -> S: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
51 51 | # due to `foo_classmethod being listed in `pep8_naming.classmethod-decorators`
|
||||
52 52 | # in the settings for this test:
|
||||
53 53 | @foo_classmethod
|
||||
54 |- def foo[S](cls: type[S]) -> S: ... # PYI019
|
||||
54 |+ def foo(cls) -> Self: ... # PYI019
|
||||
55 55 |
|
||||
56 56 |
|
||||
57 57 | _S695 = TypeVar("_S695", bound="PEP695Fix")
|
||||
|
||||
PYI019_0.pyi:61:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
60 | class PEP695Fix:
|
||||
61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
62 |
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
58 58 |
|
||||
59 59 |
|
||||
60 60 | class PEP695Fix:
|
||||
61 |- def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
61 |+ def __new__(cls) -> Self: ...
|
||||
62 62 |
|
||||
63 63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 64 |
|
||||
|
||||
PYI019_0.pyi:63:26: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
62 |
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
64 |
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
60 60 | class PEP695Fix:
|
||||
61 61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
62 62 |
|
||||
63 |- def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
63 |+ def __init_subclass__(cls) -> Self: ...
|
||||
64 64 |
|
||||
65 65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 66 |
|
||||
|
||||
PYI019_0.pyi:65:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 |
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
66 |
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
62 62 |
|
||||
63 63 | def __init_subclass__[S](cls: type[S]) -> S: ...
|
||||
64 64 |
|
||||
65 |- def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
65 |+ def __neg__(self) -> Self: ...
|
||||
66 66 |
|
||||
67 67 | def __pos__[S](self: S) -> S: ...
|
||||
68 68 |
|
||||
|
||||
PYI019_0.pyi:67:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 |
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
68 |
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
64 64 |
|
||||
65 65 | def __neg__[S: PEP695Fix](self: S) -> S: ...
|
||||
66 66 |
|
||||
67 |- def __pos__[S](self: S) -> S: ...
|
||||
67 |+ def __pos__(self) -> Self: ...
|
||||
68 68 |
|
||||
69 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 70 |
|
||||
|
||||
PYI019_0.pyi:69:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
67 | def __pos__[S](self: S) -> S: ...
|
||||
68 |
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
70 |
|
||||
71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
66 66 |
|
||||
67 67 | def __pos__[S](self: S) -> S: ...
|
||||
68 68 |
|
||||
69 |- def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
69 |+ def __add__(self, other: Self) -> Self: ...
|
||||
70 70 |
|
||||
71 71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
72 72 |
|
||||
|
||||
PYI019_0.pyi:71:16: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 |
|
||||
71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
72 |
|
||||
73 | @classmethod
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
68 68 |
|
||||
69 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
70 70 |
|
||||
71 |- def __sub__[S](self: S, other: S) -> S: ...
|
||||
71 |+ def __sub__(self, other: Self) -> Self: ...
|
||||
72 72 |
|
||||
73 73 | @classmethod
|
||||
74 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
|
||||
PYI019_0.pyi:74:27: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
73 | @classmethod
|
||||
74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
75 |
|
||||
76 | @classmethod
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
71 71 | def __sub__[S](self: S, other: S) -> S: ...
|
||||
72 72 |
|
||||
73 73 | @classmethod
|
||||
74 |- def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
74 |+ def class_method_bound(cls) -> Self: ...
|
||||
75 75 |
|
||||
76 76 | @classmethod
|
||||
77 77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
|
||||
PYI019_0.pyi:77:29: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
76 | @classmethod
|
||||
77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
78 |
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
74 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ...
|
||||
75 75 |
|
||||
76 76 | @classmethod
|
||||
77 |- def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
77 |+ def class_method_unbound(cls) -> Self: ...
|
||||
78 78 |
|
||||
79 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 80 |
|
||||
|
||||
PYI019_0.pyi:79:30: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
78 |
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
80 |
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
76 76 | @classmethod
|
||||
77 77 | def class_method_unbound[S](cls: type[S]) -> S: ...
|
||||
78 78 |
|
||||
79 |- def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
79 |+ def instance_method_bound(self) -> Self: ...
|
||||
80 80 |
|
||||
81 81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 82 |
|
||||
|
||||
PYI019_0.pyi:81:32: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 |
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
82 |
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
78 78 |
|
||||
79 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ...
|
||||
80 80 |
|
||||
81 |- def instance_method_unbound[S](self: S) -> S: ...
|
||||
81 |+ def instance_method_unbound(self) -> Self: ...
|
||||
82 82 |
|
||||
83 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 84 |
|
||||
|
||||
PYI019_0.pyi:83:53: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 |
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
84 |
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
80 80 |
|
||||
81 81 | def instance_method_unbound[S](self: S) -> S: ...
|
||||
82 82 |
|
||||
83 |- def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
83 |+ def instance_method_bound_with_another_parameter(self, other: Self) -> Self: ...
|
||||
84 84 |
|
||||
85 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 86 |
|
||||
|
||||
PYI019_0.pyi:85:55: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 |
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
86 |
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
82 82 |
|
||||
83 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ...
|
||||
84 84 |
|
||||
85 |- def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
85 |+ def instance_method_unbound_with_another_parameter(self, other: Self) -> Self: ...
|
||||
86 86 |
|
||||
87 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 88 |
|
||||
|
||||
PYI019_0.pyi:87:27: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 |
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
88 |
|
||||
89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
84 84 |
|
||||
85 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ...
|
||||
86 86 |
|
||||
87 |- def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
87 |+ def multiple_type_vars[*Ts, T](self, other: Self, /, *args: *Ts, a: T, b: list[T]) -> Self: ...
|
||||
88 88 |
|
||||
89 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
90 90 |
|
||||
|
||||
PYI019_0.pyi:89:43: PYI019 [*] Use `Self` instead of custom TypeVar `_S695`
|
||||
|
|
||||
87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 |
|
||||
89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `_S695` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
86 86 |
|
||||
87 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ...
|
||||
88 88 |
|
||||
89 |- def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ...
|
||||
89 |+ def mixing_old_and_new_style_type_vars[T](self, a: T, b: T) -> Self: ...
|
||||
90 90 |
|
||||
91 91 |
|
||||
92 92 | class InvalidButWeDoNotPanic:
|
||||
|
||||
PYI019_0.pyi:94:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
92 | class InvalidButWeDoNotPanic:
|
||||
93 | @classmethod
|
||||
94 | def m[S](cls: type[S], /) -> S[int]: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
95 | def n(self: S) -> S[int]: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
91 91 |
|
||||
92 92 | class InvalidButWeDoNotPanic:
|
||||
93 93 | @classmethod
|
||||
94 |- def m[S](cls: type[S], /) -> S[int]: ...
|
||||
94 |+ def m(cls, /) -> Self[int]: ...
|
||||
95 95 | def n(self: S) -> S[int]: ...
|
||||
96 96 |
|
||||
97 97 |
|
||||
|
||||
PYI019_0.pyi:114:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
112 | class SubscriptReturnType:
|
||||
113 | @classmethod
|
||||
114 | def m[S](cls: type[S]) -> type[S]: ... # PYI019
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
111 111 |
|
||||
112 112 | class SubscriptReturnType:
|
||||
113 113 | @classmethod
|
||||
114 |- def m[S](cls: type[S]) -> type[S]: ... # PYI019
|
||||
114 |+ def m(cls) -> type[Self]: ... # PYI019
|
||||
115 115 |
|
||||
116 116 |
|
||||
117 117 | class PEP695TypeParameterAtTheVeryEndOfTheList:
|
||||
|
||||
PYI019_0.pyi:118:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
117 | class PEP695TypeParameterAtTheVeryEndOfTheList:
|
||||
118 | def f[T, S](self: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
115 115 |
|
||||
116 116 |
|
||||
117 117 | class PEP695TypeParameterAtTheVeryEndOfTheList:
|
||||
118 |- def f[T, S](self: S) -> S: ...
|
||||
118 |+ def f[T](self) -> Self: ...
|
||||
119 119 |
|
||||
120 120 |
|
||||
121 121 | class PEP695Again:
|
||||
|
||||
PYI019_0.pyi:122:26: PYI019 [*] Use `Self` instead of custom TypeVar `_S695`
|
||||
|
|
||||
121 | class PEP695Again:
|
||||
122 | def mixing_and_nested[T](self: _S695, a: list[_S695], b: dict[_S695, str | T | set[_S695]]) -> _S695: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
123 | def also_uses_s695_but_should_not_be_edited(self, v: set[tuple[_S695]]) -> _S695: ...
|
||||
|
|
||||
= help: Replace TypeVar `_S695` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
119 119 |
|
||||
120 120 |
|
||||
121 121 | class PEP695Again:
|
||||
122 |- def mixing_and_nested[T](self: _S695, a: list[_S695], b: dict[_S695, str | T | set[_S695]]) -> _S695: ...
|
||||
122 |+ def mixing_and_nested[T](self, a: list[Self], b: dict[Self, str | T | set[Self]]) -> Self: ...
|
||||
123 123 | def also_uses_s695_but_should_not_be_edited(self, v: set[tuple[_S695]]) -> _S695: ...
|
||||
124 124 |
|
||||
125 125 | @classmethod
|
||||
|
||||
PYI019_0.pyi:126:29: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
125 | @classmethod
|
||||
126 | def comment_in_fix_range[T, S](
|
||||
| _____________________________^
|
||||
127 | | cls: type[ # Lorem ipsum
|
||||
128 | | S
|
||||
129 | | ],
|
||||
130 | | a: T,
|
||||
131 | | b: tuple[S, T]
|
||||
132 | | ) -> S: ...
|
||||
| |__________^ PYI019
|
||||
133 |
|
||||
134 | def comment_outside_fix_range[T, S](
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Unsafe fix
|
||||
123 123 | def also_uses_s695_but_should_not_be_edited(self, v: set[tuple[_S695]]) -> _S695: ...
|
||||
124 124 |
|
||||
125 125 | @classmethod
|
||||
126 |- def comment_in_fix_range[T, S](
|
||||
127 |- cls: type[ # Lorem ipsum
|
||||
128 |- S
|
||||
129 |- ],
|
||||
126 |+ def comment_in_fix_range[T](
|
||||
127 |+ cls,
|
||||
130 128 | a: T,
|
||||
131 |- b: tuple[S, T]
|
||||
132 |- ) -> S: ...
|
||||
129 |+ b: tuple[Self, T]
|
||||
130 |+ ) -> Self: ...
|
||||
133 131 |
|
||||
134 132 | def comment_outside_fix_range[T, S](
|
||||
135 133 | self: S,
|
||||
|
||||
PYI019_0.pyi:134:34: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
132 | ) -> S: ...
|
||||
133 |
|
||||
134 | def comment_outside_fix_range[T, S](
|
||||
| __________________________________^
|
||||
135 | | self: S,
|
||||
136 | | a: T,
|
||||
137 | | b: tuple[
|
||||
138 | | # Lorem ipsum
|
||||
139 | | S, T
|
||||
140 | | ]
|
||||
141 | | ) -> S: ...
|
||||
| |__________^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
131 131 | b: tuple[S, T]
|
||||
132 132 | ) -> S: ...
|
||||
133 133 |
|
||||
134 |- def comment_outside_fix_range[T, S](
|
||||
135 |- self: S,
|
||||
134 |+ def comment_outside_fix_range[T](
|
||||
135 |+ self,
|
||||
136 136 | a: T,
|
||||
137 137 | b: tuple[
|
||||
138 138 | # Lorem ipsum
|
||||
139 |- S, T
|
||||
139 |+ Self, T
|
||||
140 140 | ]
|
||||
141 |- ) -> S: ...
|
||||
141 |+ ) -> Self: ...
|
||||
142 142 |
|
||||
143 143 |
|
||||
144 144 | class SelfNotUsedInReturnAnnotation:
|
||||
|
||||
PYI019_0.pyi:145:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
144 | class SelfNotUsedInReturnAnnotation:
|
||||
145 | def m[S](self: S, other: S) -> int: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
146 | @classmethod
|
||||
147 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
142 142 |
|
||||
143 143 |
|
||||
144 144 | class SelfNotUsedInReturnAnnotation:
|
||||
145 |- def m[S](self: S, other: S) -> int: ...
|
||||
145 |+ def m(self, other: Self) -> int: ...
|
||||
146 146 | @classmethod
|
||||
147 147 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
148 148 |
|
||||
|
||||
PYI019_0.pyi:147:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
145 | def m[S](self: S, other: S) -> int: ...
|
||||
146 | @classmethod
|
||||
147 | def n[S](cls: type[S], other: S) -> int: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
144 144 | class SelfNotUsedInReturnAnnotation:
|
||||
145 145 | def m[S](self: S, other: S) -> int: ...
|
||||
146 146 | @classmethod
|
||||
147 |- def n[S](cls: type[S], other: S) -> int: ...
|
||||
147 |+ def n(cls, other: Self) -> int: ...
|
||||
148 148 |
|
||||
149 149 |
|
||||
150 150 | class _NotATypeVar: ...
|
||||
|
||||
PYI019_0.pyi:161:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
160 | class NoReturnAnnotations:
|
||||
161 | def m[S](self: S, other: S): ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
162 | @classmethod
|
||||
163 | def n[S](cls: type[S], other: S): ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
158 158 | def y(self: type[_NotATypeVar]) -> _NotATypeVar: ...
|
||||
159 159 |
|
||||
160 160 | class NoReturnAnnotations:
|
||||
161 |- def m[S](self: S, other: S): ...
|
||||
161 |+ def m(self, other: Self): ...
|
||||
162 162 | @classmethod
|
||||
163 163 | def n[S](cls: type[S], other: S): ...
|
||||
164 164 |
|
||||
|
||||
PYI019_0.pyi:163:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
161 | def m[S](self: S, other: S): ...
|
||||
162 | @classmethod
|
||||
163 | def n[S](cls: type[S], other: S): ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
164 |
|
||||
165 | class MultipleBoundParameters:
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
160 160 | class NoReturnAnnotations:
|
||||
161 161 | def m[S](self: S, other: S): ...
|
||||
162 162 | @classmethod
|
||||
163 |- def n[S](cls: type[S], other: S): ...
|
||||
163 |+ def n(cls, other: Self): ...
|
||||
164 164 |
|
||||
165 165 | class MultipleBoundParameters:
|
||||
166 166 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
|
||||
PYI019_0.pyi:166:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
165 | class MultipleBoundParameters:
|
||||
166 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
167 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
163 163 | def n[S](cls: type[S], other: S): ...
|
||||
164 164 |
|
||||
165 165 | class MultipleBoundParameters:
|
||||
166 |- def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
166 |+ def m[T: int](self, other: T) -> Self: ...
|
||||
167 167 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
168 168 |
|
||||
169 169 |
|
||||
|
||||
PYI019_0.pyi:167:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
165 | class MultipleBoundParameters:
|
||||
166 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
167 | def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
164 164 |
|
||||
165 165 | class MultipleBoundParameters:
|
||||
166 166 | def m[S: int, T: int](self: S, other: T) -> S: ...
|
||||
167 |- def n[T: (int, str), S: (int, str)](self: S, other: T) -> S: ...
|
||||
167 |+ def n[T: (int, str)](self, other: T) -> Self: ...
|
||||
168 168 |
|
||||
169 169 |
|
||||
170 170 | MetaType = TypeVar("MetaType")
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI019_1.pyi:4:10: PYI019 [*] Use `Self` instead of custom TypeVar `S`
|
||||
|
|
||||
3 | class F:
|
||||
4 | def m[S](self: S) -> S: ...
|
||||
| ^^^^^^^^^^^^^^^^^ PYI019
|
||||
|
|
||||
= help: Replace TypeVar `S` with `Self`
|
||||
|
||||
ℹ Safe fix
|
||||
1 1 | import typing
|
||||
2 2 |
|
||||
3 3 | class F:
|
||||
4 |- def m[S](self: S) -> S: ...
|
||||
4 |+ def m(self) -> typing.Self: ...
|
||||
@@ -1,100 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI018.py:6:1: PYI018 [*] Private TypeVar `_T` is never used
|
||||
|
|
||||
4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 |
|
||||
6 | _T = typing.TypeVar("_T")
|
||||
| ^^ PYI018
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 | _P = ParamSpec("_P")
|
||||
|
|
||||
= help: Remove unused private TypeVar `_T`
|
||||
|
||||
ℹ Unsafe fix
|
||||
3 3 | from typing import TypeVar
|
||||
4 4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 5 |
|
||||
6 |-_T = typing.TypeVar("_T")
|
||||
7 6 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 7 | _P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
|
||||
PYI018.py:7:1: PYI018 [*] Private TypeVarTuple `_Ts` is never used
|
||||
|
|
||||
6 | _T = typing.TypeVar("_T")
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
| ^^^ PYI018
|
||||
8 | _P = ParamSpec("_P")
|
||||
9 | _P2 = typing.ParamSpec("_P2")
|
||||
|
|
||||
= help: Remove unused private TypeVarTuple `_Ts`
|
||||
|
||||
ℹ Unsafe fix
|
||||
4 4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 5 |
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 |-_Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 7 | _P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
|
||||
PYI018.py:8:1: PYI018 [*] Private ParamSpec `_P` is never used
|
||||
|
|
||||
6 | _T = typing.TypeVar("_T")
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 | _P = ParamSpec("_P")
|
||||
| ^^ PYI018
|
||||
9 | _P2 = typing.ParamSpec("_P2")
|
||||
10 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
|
|
||||
= help: Remove unused private ParamSpec `_P`
|
||||
|
||||
ℹ Unsafe fix
|
||||
5 5 |
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 |-_P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
|
||||
PYI018.py:9:1: PYI018 [*] Private ParamSpec `_P2` is never used
|
||||
|
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 | _P = ParamSpec("_P")
|
||||
9 | _P2 = typing.ParamSpec("_P2")
|
||||
| ^^^ PYI018
|
||||
10 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
|
|
||||
= help: Remove unused private ParamSpec `_P2`
|
||||
|
||||
ℹ Unsafe fix
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 8 | _P = ParamSpec("_P")
|
||||
9 |-_P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
12 11 | # OK
|
||||
|
||||
PYI018.py:10:1: PYI018 [*] Private TypeVarTuple `_Ts2` is never used
|
||||
|
|
||||
8 | _P = ParamSpec("_P")
|
||||
9 | _P2 = typing.ParamSpec("_P2")
|
||||
10 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
| ^^^^ PYI018
|
||||
11 |
|
||||
12 | # OK
|
||||
|
|
||||
= help: Remove unused private TypeVarTuple `_Ts2`
|
||||
|
||||
ℹ Unsafe fix
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 8 | _P = ParamSpec("_P")
|
||||
9 9 | _P2 = typing.ParamSpec("_P2")
|
||||
10 |-_Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
12 11 | # OK
|
||||
13 12 | _UsedTypeVar = TypeVar("_UsedTypeVar")
|
||||
@@ -1,100 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI018.pyi:6:1: PYI018 [*] Private TypeVar `_T` is never used
|
||||
|
|
||||
4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 |
|
||||
6 | _T = typing.TypeVar("_T")
|
||||
| ^^ PYI018
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 | _P = ParamSpec("_P")
|
||||
|
|
||||
= help: Remove unused private TypeVar `_T`
|
||||
|
||||
ℹ Unsafe fix
|
||||
3 3 | from typing import TypeVar
|
||||
4 4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 5 |
|
||||
6 |-_T = typing.TypeVar("_T")
|
||||
7 6 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 7 | _P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
|
||||
PYI018.pyi:7:1: PYI018 [*] Private TypeVarTuple `_Ts` is never used
|
||||
|
|
||||
6 | _T = typing.TypeVar("_T")
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
| ^^^ PYI018
|
||||
8 | _P = ParamSpec("_P")
|
||||
9 | _P2 = typing.ParamSpec("_P2")
|
||||
|
|
||||
= help: Remove unused private TypeVarTuple `_Ts`
|
||||
|
||||
ℹ Unsafe fix
|
||||
4 4 | from typing_extensions import ParamSpec, TypeVarTuple
|
||||
5 5 |
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 |-_Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 7 | _P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
|
||||
PYI018.pyi:8:1: PYI018 [*] Private ParamSpec `_P` is never used
|
||||
|
|
||||
6 | _T = typing.TypeVar("_T")
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 | _P = ParamSpec("_P")
|
||||
| ^^ PYI018
|
||||
9 | _P2 = typing.ParamSpec("_P2")
|
||||
10 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
|
|
||||
= help: Remove unused private ParamSpec `_P`
|
||||
|
||||
ℹ Unsafe fix
|
||||
5 5 |
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 |-_P = ParamSpec("_P")
|
||||
9 8 | _P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
|
||||
PYI018.pyi:9:1: PYI018 [*] Private ParamSpec `_P2` is never used
|
||||
|
|
||||
7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 | _P = ParamSpec("_P")
|
||||
9 | _P2 = typing.ParamSpec("_P2")
|
||||
| ^^^ PYI018
|
||||
10 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
|
|
||||
= help: Remove unused private ParamSpec `_P2`
|
||||
|
||||
ℹ Unsafe fix
|
||||
6 6 | _T = typing.TypeVar("_T")
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 8 | _P = ParamSpec("_P")
|
||||
9 |-_P2 = typing.ParamSpec("_P2")
|
||||
10 9 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
12 11 | # OK
|
||||
|
||||
PYI018.pyi:10:1: PYI018 [*] Private TypeVarTuple `_Ts2` is never used
|
||||
|
|
||||
8 | _P = ParamSpec("_P")
|
||||
9 | _P2 = typing.ParamSpec("_P2")
|
||||
10 | _Ts2 = TypeVarTuple("_Ts2")
|
||||
| ^^^^ PYI018
|
||||
11 |
|
||||
12 | # OK
|
||||
|
|
||||
= help: Remove unused private TypeVarTuple `_Ts2`
|
||||
|
||||
ℹ Unsafe fix
|
||||
7 7 | _Ts = typing_extensions.TypeVarTuple("_Ts")
|
||||
8 8 | _P = ParamSpec("_P")
|
||||
9 9 | _P2 = typing.ParamSpec("_P2")
|
||||
10 |-_Ts2 = TypeVarTuple("_Ts2")
|
||||
11 10 |
|
||||
12 11 | # OK
|
||||
13 12 | _UsedTypeVar = TypeVar("_UsedTypeVar")
|
||||
@@ -11,7 +11,7 @@ mod tests {
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::types::{IdentifierPattern, PreviewMode};
|
||||
use crate::settings::types::IdentifierPattern;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_messages, settings};
|
||||
|
||||
@@ -358,36 +358,6 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(
|
||||
Rule::PytestRaisesWithMultipleStatements,
|
||||
Path::new("PT012.py"),
|
||||
Settings::default(),
|
||||
"PT012_preview"
|
||||
)]
|
||||
#[test_case(
|
||||
Rule::PytestWarnsWithMultipleStatements,
|
||||
Path::new("PT031.py"),
|
||||
Settings::default(),
|
||||
"PT031_preview"
|
||||
)]
|
||||
fn test_pytest_style_preview(
|
||||
rule_code: Rule,
|
||||
path: &Path,
|
||||
plugin_settings: Settings,
|
||||
name: &str,
|
||||
) -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_pytest_style").join(path).as_path(),
|
||||
&settings::LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
flake8_pytest_style: plugin_settings,
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(name, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This test ensure that PT006 and PT007 don't conflict when both of them suggest a fix that
|
||||
/// edits `argvalues` for `pytest.mark.parametrize`.
|
||||
#[test]
|
||||
|
||||
@@ -13,6 +13,10 @@ use super::helpers::is_empty_or_null_string;
|
||||
/// ## What it does
|
||||
/// Checks for `pytest.raises` context managers with multiple statements.
|
||||
///
|
||||
/// This rule allows `pytest.raises` bodies to contain `for`
|
||||
/// loops with empty bodies (e.g., `pass` or `...` statements), to test
|
||||
/// iterator behavior.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// When a `pytest.raises` is used as a context manager and contains multiple
|
||||
/// statements, it can lead to the test passing when it actually should fail.
|
||||
@@ -20,10 +24,6 @@ use super::helpers::is_empty_or_null_string;
|
||||
/// A `pytest.raises` context manager should only contain a single simple
|
||||
/// statement that raises the expected exception.
|
||||
///
|
||||
/// In [preview], this rule allows `pytest.raises` bodies to contain `for`
|
||||
/// loops with empty bodies (e.g., `pass` or `...` statements), to test
|
||||
/// iterator behavior.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// import pytest
|
||||
@@ -50,8 +50,6 @@ use super::helpers::is_empty_or_null_string;
|
||||
///
|
||||
/// ## References
|
||||
/// - [`pytest` documentation: `pytest.raises`](https://docs.pytest.org/en/latest/reference/reference.html#pytest-raises)
|
||||
///
|
||||
/// [preview]: https://docs.astral.sh/ruff/preview/
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct PytestRaisesWithMultipleStatements;
|
||||
|
||||
@@ -206,14 +204,12 @@ pub(crate) fn complex_raises(checker: &Checker, stmt: &Stmt, items: &[WithItem],
|
||||
// Check body for `pytest.raises` context manager
|
||||
if raises_called {
|
||||
let is_too_complex = if let [stmt] = body {
|
||||
let in_preview = checker.settings.preview.is_enabled();
|
||||
|
||||
match stmt {
|
||||
Stmt::With(ast::StmtWith { body, .. }) => is_non_trivial_with_body(body),
|
||||
// Allow function and class definitions to test decorators.
|
||||
Stmt::ClassDef(_) | Stmt::FunctionDef(_) => false,
|
||||
// Allow empty `for` loops to test iterators.
|
||||
Stmt::For(ast::StmtFor { body, .. }) if in_preview => match &body[..] {
|
||||
Stmt::For(ast::StmtFor { body, .. }) => match &body[..] {
|
||||
[Stmt::Pass(_)] => false,
|
||||
[Stmt::Expr(ast::StmtExpr { value, .. })] => !value.is_ellipsis_literal_expr(),
|
||||
_ => true,
|
||||
|
||||
@@ -13,6 +13,10 @@ use super::helpers::is_empty_or_null_string;
|
||||
/// ## What it does
|
||||
/// Checks for `pytest.warns` context managers with multiple statements.
|
||||
///
|
||||
/// This rule allows `pytest.warns` bodies to contain `for`
|
||||
/// loops with empty bodies (e.g., `pass` or `...` statements), to test
|
||||
/// iterator behavior.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// When `pytest.warns` is used as a context manager and contains multiple
|
||||
/// statements, it can lead to the test passing when it should instead fail.
|
||||
@@ -20,9 +24,6 @@ use super::helpers::is_empty_or_null_string;
|
||||
/// A `pytest.warns` context manager should only contain a single
|
||||
/// simple statement that triggers the expected warning.
|
||||
///
|
||||
/// In [preview], this rule allows `pytest.warns` bodies to contain `for`
|
||||
/// loops with empty bodies (e.g., `pass` or `...` statements), to test
|
||||
/// iterator behavior.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
@@ -48,8 +49,6 @@ use super::helpers::is_empty_or_null_string;
|
||||
///
|
||||
/// ## References
|
||||
/// - [`pytest` documentation: `pytest.warns`](https://docs.pytest.org/en/latest/reference/reference.html#pytest-warns)
|
||||
///
|
||||
/// [preview]: https://docs.astral.sh/ruff/preview/
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct PytestWarnsWithMultipleStatements;
|
||||
|
||||
@@ -206,14 +205,12 @@ pub(crate) fn complex_warns(checker: &Checker, stmt: &Stmt, items: &[WithItem],
|
||||
// Check body for `pytest.warns` context manager
|
||||
if warns_called {
|
||||
let is_too_complex = if let [stmt] = body {
|
||||
let in_preview = checker.settings.preview.is_enabled();
|
||||
|
||||
match stmt {
|
||||
Stmt::With(ast::StmtWith { body, .. }) => is_non_trivial_with_body(body),
|
||||
// Allow function and class definitions to test decorators.
|
||||
Stmt::ClassDef(_) | Stmt::FunctionDef(_) => false,
|
||||
// Allow empty `for` loops to test iterators.
|
||||
Stmt::For(ast::StmtFor { body, .. }) if in_preview => match &body[..] {
|
||||
Stmt::For(ast::StmtFor { body, .. }) => match &body[..] {
|
||||
[Stmt::Pass(_)] => false,
|
||||
[Stmt::Expr(ast::StmtExpr { value, .. })] => !value.is_ellipsis_literal_expr(),
|
||||
_ => true,
|
||||
|
||||
@@ -124,49 +124,3 @@ PT012.py:95:5: PT012 `pytest.raises()` block should contain a single simple stat
|
||||
97 | | assert foo
|
||||
| |______________________^ PT012
|
||||
|
|
||||
|
||||
PT012.py:102:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
100 | ## No errors in preview
|
||||
101 |
|
||||
102 | / with pytest.raises(RuntimeError):
|
||||
103 | | for a in b:
|
||||
104 | | pass
|
||||
| |________________^ PT012
|
||||
105 |
|
||||
106 | with pytest.raises(RuntimeError):
|
||||
|
|
||||
|
||||
PT012.py:106:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
104 | pass
|
||||
105 |
|
||||
106 | / with pytest.raises(RuntimeError):
|
||||
107 | | for a in b:
|
||||
108 | | ...
|
||||
| |_______________^ PT012
|
||||
109 |
|
||||
110 | with pytest.raises(RuntimeError):
|
||||
|
|
||||
|
||||
PT012.py:110:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
108 | ...
|
||||
109 |
|
||||
110 | / with pytest.raises(RuntimeError):
|
||||
111 | | async for a in b:
|
||||
112 | | pass
|
||||
| |________________^ PT012
|
||||
113 |
|
||||
114 | with pytest.raises(RuntimeError):
|
||||
|
|
||||
|
||||
PT012.py:114:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
112 | pass
|
||||
113 |
|
||||
114 | / with pytest.raises(RuntimeError):
|
||||
115 | | async for a in b:
|
||||
116 | | ...
|
||||
| |_______________^ PT012
|
||||
|
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pytest_style/mod.rs
|
||||
---
|
||||
PT012.py:42:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
41 | def test_error_multiple_statements():
|
||||
42 | / with pytest.raises(AttributeError):
|
||||
43 | | len([])
|
||||
44 | | [].size
|
||||
| |_______________^ PT012
|
||||
|
|
||||
|
||||
PT012.py:48:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
47 | async def test_error_complex_statement():
|
||||
48 | / with pytest.raises(AttributeError):
|
||||
49 | | if True:
|
||||
50 | | [].size
|
||||
| |___________________^ PT012
|
||||
51 |
|
||||
52 | with pytest.raises(AttributeError):
|
||||
|
|
||||
|
||||
PT012.py:52:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
50 | [].size
|
||||
51 |
|
||||
52 | / with pytest.raises(AttributeError):
|
||||
53 | | for i in []:
|
||||
54 | | [].size
|
||||
| |___________________^ PT012
|
||||
55 |
|
||||
56 | with pytest.raises(AttributeError):
|
||||
|
|
||||
|
||||
PT012.py:56:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
54 | [].size
|
||||
55 |
|
||||
56 | / with pytest.raises(AttributeError):
|
||||
57 | | async for i in []:
|
||||
58 | | [].size
|
||||
| |___________________^ PT012
|
||||
59 |
|
||||
60 | with pytest.raises(AttributeError):
|
||||
|
|
||||
|
||||
PT012.py:60:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
58 | [].size
|
||||
59 |
|
||||
60 | / with pytest.raises(AttributeError):
|
||||
61 | | while True:
|
||||
62 | | [].size
|
||||
| |___________________^ PT012
|
||||
63 |
|
||||
64 | with pytest.raises(AttributeError):
|
||||
|
|
||||
|
||||
PT012.py:64:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
62 | [].size
|
||||
63 |
|
||||
64 | / with pytest.raises(AttributeError):
|
||||
65 | | async with context_manager_under_test():
|
||||
66 | | if True:
|
||||
67 | | raise Exception
|
||||
| |_______________________________^ PT012
|
||||
|
|
||||
|
||||
PT012.py:71:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
70 | def test_error_try():
|
||||
71 | / with pytest.raises(AttributeError):
|
||||
72 | | try:
|
||||
73 | | [].size
|
||||
74 | | except:
|
||||
75 | | raise
|
||||
| |_________________^ PT012
|
||||
|
|
||||
|
||||
PT012.py:83:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
81 | ## Errors
|
||||
82 |
|
||||
83 | / with pytest.raises(RuntimeError):
|
||||
84 | | for a in b:
|
||||
85 | | print()
|
||||
| |___________________^ PT012
|
||||
86 |
|
||||
87 | with pytest.raises(RuntimeError):
|
||||
|
|
||||
|
||||
PT012.py:87:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
85 | print()
|
||||
86 |
|
||||
87 | / with pytest.raises(RuntimeError):
|
||||
88 | | for a in b:
|
||||
89 | | assert foo
|
||||
| |______________________^ PT012
|
||||
90 |
|
||||
91 | with pytest.raises(RuntimeError):
|
||||
|
|
||||
|
||||
PT012.py:91:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
89 | assert foo
|
||||
90 |
|
||||
91 | / with pytest.raises(RuntimeError):
|
||||
92 | | async for a in b:
|
||||
93 | | print()
|
||||
| |___________________^ PT012
|
||||
94 |
|
||||
95 | with pytest.raises(RuntimeError):
|
||||
|
|
||||
|
||||
PT012.py:95:5: PT012 `pytest.raises()` block should contain a single simple statement
|
||||
|
|
||||
93 | print()
|
||||
94 |
|
||||
95 | / with pytest.raises(RuntimeError):
|
||||
96 | | async for a in b:
|
||||
97 | | assert foo
|
||||
| |______________________^ PT012
|
||||
|
|
||||
@@ -124,49 +124,3 @@ PT031.py:95:5: PT031 `pytest.warns()` block should contain a single simple state
|
||||
97 | | assert foo
|
||||
| |______________________^ PT031
|
||||
|
|
||||
|
||||
PT031.py:102:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
100 | ## No errors in preview
|
||||
101 |
|
||||
102 | / with pytest.warns(RuntimeError):
|
||||
103 | | for a in b:
|
||||
104 | | pass
|
||||
| |________________^ PT031
|
||||
105 |
|
||||
106 | with pytest.warns(RuntimeError):
|
||||
|
|
||||
|
||||
PT031.py:106:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
104 | pass
|
||||
105 |
|
||||
106 | / with pytest.warns(RuntimeError):
|
||||
107 | | for a in b:
|
||||
108 | | ...
|
||||
| |_______________^ PT031
|
||||
109 |
|
||||
110 | with pytest.warns(RuntimeError):
|
||||
|
|
||||
|
||||
PT031.py:110:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
108 | ...
|
||||
109 |
|
||||
110 | / with pytest.warns(RuntimeError):
|
||||
111 | | async for a in b:
|
||||
112 | | pass
|
||||
| |________________^ PT031
|
||||
113 |
|
||||
114 | with pytest.warns(RuntimeError):
|
||||
|
|
||||
|
||||
PT031.py:114:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
112 | pass
|
||||
113 |
|
||||
114 | / with pytest.warns(RuntimeError):
|
||||
115 | | async for a in b:
|
||||
116 | | ...
|
||||
| |_______________^ PT031
|
||||
|
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pytest_style/mod.rs
|
||||
---
|
||||
PT031.py:42:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
41 | def test_error_multiple_statements():
|
||||
42 | / with pytest.warns(UserWarning):
|
||||
43 | | foo()
|
||||
44 | | bar()
|
||||
| |_____________^ PT031
|
||||
|
|
||||
|
||||
PT031.py:48:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
47 | async def test_error_complex_statement():
|
||||
48 | / with pytest.warns(UserWarning):
|
||||
49 | | if True:
|
||||
50 | | foo()
|
||||
| |_________________^ PT031
|
||||
51 |
|
||||
52 | with pytest.warns(UserWarning):
|
||||
|
|
||||
|
||||
PT031.py:52:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
50 | foo()
|
||||
51 |
|
||||
52 | / with pytest.warns(UserWarning):
|
||||
53 | | for i in []:
|
||||
54 | | foo()
|
||||
| |_________________^ PT031
|
||||
55 |
|
||||
56 | with pytest.warns(UserWarning):
|
||||
|
|
||||
|
||||
PT031.py:56:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
54 | foo()
|
||||
55 |
|
||||
56 | / with pytest.warns(UserWarning):
|
||||
57 | | async for i in []:
|
||||
58 | | foo()
|
||||
| |_________________^ PT031
|
||||
59 |
|
||||
60 | with pytest.warns(UserWarning):
|
||||
|
|
||||
|
||||
PT031.py:60:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
58 | foo()
|
||||
59 |
|
||||
60 | / with pytest.warns(UserWarning):
|
||||
61 | | while True:
|
||||
62 | | foo()
|
||||
| |_________________^ PT031
|
||||
63 |
|
||||
64 | with pytest.warns(UserWarning):
|
||||
|
|
||||
|
||||
PT031.py:64:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
62 | foo()
|
||||
63 |
|
||||
64 | / with pytest.warns(UserWarning):
|
||||
65 | | async with context_manager_under_test():
|
||||
66 | | if True:
|
||||
67 | | foo()
|
||||
| |_____________________^ PT031
|
||||
|
|
||||
|
||||
PT031.py:71:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
70 | def test_error_try():
|
||||
71 | / with pytest.warns(UserWarning):
|
||||
72 | | try:
|
||||
73 | | foo()
|
||||
74 | | except:
|
||||
75 | | raise
|
||||
| |_________________^ PT031
|
||||
|
|
||||
|
||||
PT031.py:83:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
81 | ## Errors
|
||||
82 |
|
||||
83 | / with pytest.warns(RuntimeError):
|
||||
84 | | for a in b:
|
||||
85 | | print()
|
||||
| |___________________^ PT031
|
||||
86 |
|
||||
87 | with pytest.warns(RuntimeError):
|
||||
|
|
||||
|
||||
PT031.py:87:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
85 | print()
|
||||
86 |
|
||||
87 | / with pytest.warns(RuntimeError):
|
||||
88 | | for a in b:
|
||||
89 | | assert foo
|
||||
| |______________________^ PT031
|
||||
90 |
|
||||
91 | with pytest.warns(RuntimeError):
|
||||
|
|
||||
|
||||
PT031.py:91:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
89 | assert foo
|
||||
90 |
|
||||
91 | / with pytest.warns(RuntimeError):
|
||||
92 | | async for a in b:
|
||||
93 | | print()
|
||||
| |___________________^ PT031
|
||||
94 |
|
||||
95 | with pytest.warns(RuntimeError):
|
||||
|
|
||||
|
||||
PT031.py:95:5: PT031 `pytest.warns()` block should contain a single simple statement
|
||||
|
|
||||
93 | print()
|
||||
94 |
|
||||
95 | / with pytest.warns(RuntimeError):
|
||||
96 | | async for a in b:
|
||||
97 | | assert foo
|
||||
| |______________________^ PT031
|
||||
|
|
||||
@@ -58,7 +58,6 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::NeedlessBool, Path::new("SIM103.py"))]
|
||||
#[test_case(Rule::IfElseBlockInsteadOfIfExp, Path::new("SIM108.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
|
||||
@@ -14,7 +14,7 @@ use crate::fix::snippet::SourceCodeSnippet;
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// `if` statements that return `True` for a truthy condition and `False` for
|
||||
/// a falsey condition can be replaced with boolean casts.
|
||||
/// a falsy condition can be replaced with boolean casts.
|
||||
///
|
||||
/// ## Example
|
||||
/// Given:
|
||||
@@ -42,10 +42,6 @@ use crate::fix::snippet::SourceCodeSnippet;
|
||||
/// return x > 0
|
||||
/// ```
|
||||
///
|
||||
/// ## Preview
|
||||
/// In preview, double negations such as `not a != b`, `not a not in b`, `not a is not b`
|
||||
/// will be simplified to `a == b`, `a in b` and `a is b`, respectively.
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: Truth Value Testing](https://docs.python.org/3/library/stdtypes.html#truth-value-testing)
|
||||
#[derive(ViolationMetadata)]
|
||||
@@ -222,16 +218,15 @@ pub(crate) fn needless_bool(checker: &Checker, stmt: &Stmt) {
|
||||
left,
|
||||
comparators,
|
||||
..
|
||||
}) if checker.settings.preview.is_enabled()
|
||||
&& matches!(
|
||||
ops.as_ref(),
|
||||
[ast::CmpOp::Eq
|
||||
| ast::CmpOp::NotEq
|
||||
| ast::CmpOp::In
|
||||
| ast::CmpOp::NotIn
|
||||
| ast::CmpOp::Is
|
||||
| ast::CmpOp::IsNot]
|
||||
) =>
|
||||
}) if matches!(
|
||||
ops.as_ref(),
|
||||
[ast::CmpOp::Eq
|
||||
| ast::CmpOp::NotEq
|
||||
| ast::CmpOp::In
|
||||
| ast::CmpOp::NotIn
|
||||
| ast::CmpOp::Is
|
||||
| ast::CmpOp::IsNot]
|
||||
) =>
|
||||
{
|
||||
let ([op], [right]) = (ops.as_ref(), comparators.as_ref()) else {
|
||||
unreachable!("Single comparison with multiple comparators");
|
||||
|
||||
@@ -39,6 +39,8 @@ use crate::checkers::ast::Checker;
|
||||
/// ).split(",")
|
||||
/// ```
|
||||
///
|
||||
/// as this is converted to `["a", "b"]` without any of the comments.
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `str.split`](https://docs.python.org/3/library/stdtypes.html#str.split)
|
||||
#[derive(ViolationMetadata)]
|
||||
|
||||
@@ -252,7 +252,7 @@ SIM103.py:123:5: SIM103 [*] Return the condition `not 10 < a` directly
|
||||
127 125 |
|
||||
128 126 | def f():
|
||||
|
||||
SIM103.py:129:5: SIM103 [*] Return the condition `not 10 in a` directly
|
||||
SIM103.py:129:5: SIM103 [*] Return the condition `10 not in a` directly
|
||||
|
|
||||
128 | def f():
|
||||
129 | / if 10 in a:
|
||||
@@ -260,7 +260,7 @@ SIM103.py:129:5: SIM103 [*] Return the condition `not 10 in a` directly
|
||||
131 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return not 10 in a`
|
||||
= help: Replace with `return 10 not in a`
|
||||
|
||||
ℹ Unsafe fix
|
||||
126 126 |
|
||||
@@ -269,12 +269,12 @@ SIM103.py:129:5: SIM103 [*] Return the condition `not 10 in a` directly
|
||||
129 |- if 10 in a:
|
||||
130 |- return False
|
||||
131 |- return True
|
||||
129 |+ return not 10 in a
|
||||
129 |+ return 10 not in a
|
||||
132 130 |
|
||||
133 131 |
|
||||
134 132 | def f():
|
||||
|
||||
SIM103.py:135:5: SIM103 [*] Return the condition `not 10 not in a` directly
|
||||
SIM103.py:135:5: SIM103 [*] Return the condition `10 in a` directly
|
||||
|
|
||||
134 | def f():
|
||||
135 | / if 10 not in a:
|
||||
@@ -282,7 +282,7 @@ SIM103.py:135:5: SIM103 [*] Return the condition `not 10 not in a` directly
|
||||
137 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return not 10 not in a`
|
||||
= help: Replace with `return 10 in a`
|
||||
|
||||
ℹ Unsafe fix
|
||||
132 132 |
|
||||
@@ -291,12 +291,12 @@ SIM103.py:135:5: SIM103 [*] Return the condition `not 10 not in a` directly
|
||||
135 |- if 10 not in a:
|
||||
136 |- return False
|
||||
137 |- return True
|
||||
135 |+ return not 10 not in a
|
||||
135 |+ return 10 in a
|
||||
138 136 |
|
||||
139 137 |
|
||||
140 138 | def f():
|
||||
|
||||
SIM103.py:141:5: SIM103 [*] Return the condition `not a is 10` directly
|
||||
SIM103.py:141:5: SIM103 [*] Return the condition `a is not 10` directly
|
||||
|
|
||||
140 | def f():
|
||||
141 | / if a is 10:
|
||||
@@ -304,7 +304,7 @@ SIM103.py:141:5: SIM103 [*] Return the condition `not a is 10` directly
|
||||
143 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return not a is 10`
|
||||
= help: Replace with `return a is not 10`
|
||||
|
||||
ℹ Unsafe fix
|
||||
138 138 |
|
||||
@@ -313,12 +313,12 @@ SIM103.py:141:5: SIM103 [*] Return the condition `not a is 10` directly
|
||||
141 |- if a is 10:
|
||||
142 |- return False
|
||||
143 |- return True
|
||||
141 |+ return not a is 10
|
||||
141 |+ return a is not 10
|
||||
144 142 |
|
||||
145 143 |
|
||||
146 144 | def f():
|
||||
|
||||
SIM103.py:147:5: SIM103 [*] Return the condition `not a is not 10` directly
|
||||
SIM103.py:147:5: SIM103 [*] Return the condition `a is 10` directly
|
||||
|
|
||||
146 | def f():
|
||||
147 | / if a is not 10:
|
||||
@@ -326,7 +326,7 @@ SIM103.py:147:5: SIM103 [*] Return the condition `not a is not 10` directly
|
||||
149 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return not a is not 10`
|
||||
= help: Replace with `return a is 10`
|
||||
|
||||
ℹ Unsafe fix
|
||||
144 144 |
|
||||
@@ -335,12 +335,12 @@ SIM103.py:147:5: SIM103 [*] Return the condition `not a is not 10` directly
|
||||
147 |- if a is not 10:
|
||||
148 |- return False
|
||||
149 |- return True
|
||||
147 |+ return not a is not 10
|
||||
147 |+ return a is 10
|
||||
150 148 |
|
||||
151 149 |
|
||||
152 150 | def f():
|
||||
|
||||
SIM103.py:153:5: SIM103 [*] Return the condition `not a == 10` directly
|
||||
SIM103.py:153:5: SIM103 [*] Return the condition `a != 10` directly
|
||||
|
|
||||
152 | def f():
|
||||
153 | / if a == 10:
|
||||
@@ -348,7 +348,7 @@ SIM103.py:153:5: SIM103 [*] Return the condition `not a == 10` directly
|
||||
155 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return not a == 10`
|
||||
= help: Replace with `return a != 10`
|
||||
|
||||
ℹ Unsafe fix
|
||||
150 150 |
|
||||
@@ -357,12 +357,12 @@ SIM103.py:153:5: SIM103 [*] Return the condition `not a == 10` directly
|
||||
153 |- if a == 10:
|
||||
154 |- return False
|
||||
155 |- return True
|
||||
153 |+ return not a == 10
|
||||
153 |+ return a != 10
|
||||
156 154 |
|
||||
157 155 |
|
||||
158 156 | def f():
|
||||
|
||||
SIM103.py:159:5: SIM103 [*] Return the condition `not a != 10` directly
|
||||
SIM103.py:159:5: SIM103 [*] Return the condition `a == 10` directly
|
||||
|
|
||||
158 | def f():
|
||||
159 | / if a != 10:
|
||||
@@ -370,7 +370,7 @@ SIM103.py:159:5: SIM103 [*] Return the condition `not a != 10` directly
|
||||
161 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return not a != 10`
|
||||
= help: Replace with `return a == 10`
|
||||
|
||||
ℹ Unsafe fix
|
||||
156 156 |
|
||||
@@ -379,4 +379,4 @@ SIM103.py:159:5: SIM103 [*] Return the condition `not a != 10` directly
|
||||
159 |- if a != 10:
|
||||
160 |- return False
|
||||
161 |- return True
|
||||
159 |+ return not a != 10
|
||||
159 |+ return a == 10
|
||||
|
||||
@@ -226,6 +226,33 @@ SIM108.py:167:1: SIM108 [*] Use ternary operator `z = 1 if True else other` inst
|
||||
172 169 | if False:
|
||||
173 170 | z = 1
|
||||
|
||||
SIM108.py:172:1: SIM108 [*] Use ternary operator `z = 1 if False else other` instead of `if`-`else`-block
|
||||
|
|
||||
170 | z = other
|
||||
171 |
|
||||
172 | / if False:
|
||||
173 | | z = 1
|
||||
174 | | else:
|
||||
175 | | z = other
|
||||
| |_____________^ SIM108
|
||||
176 |
|
||||
177 | if 1:
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = 1 if False else other`
|
||||
|
||||
ℹ Unsafe fix
|
||||
169 169 | else:
|
||||
170 170 | z = other
|
||||
171 171 |
|
||||
172 |-if False:
|
||||
173 |- z = 1
|
||||
174 |-else:
|
||||
175 |- z = other
|
||||
172 |+z = 1 if False else other
|
||||
176 173 |
|
||||
177 174 | if 1:
|
||||
178 175 | z = True
|
||||
|
||||
SIM108.py:177:1: SIM108 [*] Use ternary operator `z = True if 1 else other` instead of `if`-`else`-block
|
||||
|
|
||||
175 | z = other
|
||||
|
||||
@@ -1,382 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_simplify/mod.rs
|
||||
---
|
||||
SIM103.py:3:5: SIM103 [*] Return the condition `bool(a)` directly
|
||||
|
|
||||
1 | def f():
|
||||
2 | # SIM103
|
||||
3 | / if a:
|
||||
4 | | return True
|
||||
5 | | else:
|
||||
6 | | return False
|
||||
| |____________________^ SIM103
|
||||
|
|
||||
= help: Replace with `return bool(a)`
|
||||
|
||||
ℹ Unsafe fix
|
||||
1 1 | def f():
|
||||
2 2 | # SIM103
|
||||
3 |- if a:
|
||||
4 |- return True
|
||||
5 |- else:
|
||||
6 |- return False
|
||||
3 |+ return bool(a)
|
||||
7 4 |
|
||||
8 5 |
|
||||
9 6 | def f():
|
||||
|
||||
SIM103.py:11:5: SIM103 [*] Return the condition `a == b` directly
|
||||
|
|
||||
9 | def f():
|
||||
10 | # SIM103
|
||||
11 | / if a == b:
|
||||
12 | | return True
|
||||
13 | | else:
|
||||
14 | | return False
|
||||
| |____________________^ SIM103
|
||||
|
|
||||
= help: Replace with `return a == b`
|
||||
|
||||
ℹ Unsafe fix
|
||||
8 8 |
|
||||
9 9 | def f():
|
||||
10 10 | # SIM103
|
||||
11 |- if a == b:
|
||||
12 |- return True
|
||||
13 |- else:
|
||||
14 |- return False
|
||||
11 |+ return a == b
|
||||
15 12 |
|
||||
16 13 |
|
||||
17 14 | def f():
|
||||
|
||||
SIM103.py:21:5: SIM103 [*] Return the condition `bool(b)` directly
|
||||
|
|
||||
19 | if a:
|
||||
20 | return 1
|
||||
21 | / elif b:
|
||||
22 | | return True
|
||||
23 | | else:
|
||||
24 | | return False
|
||||
| |____________________^ SIM103
|
||||
|
|
||||
= help: Replace with `return bool(b)`
|
||||
|
||||
ℹ Unsafe fix
|
||||
18 18 | # SIM103
|
||||
19 19 | if a:
|
||||
20 20 | return 1
|
||||
21 |- elif b:
|
||||
22 |- return True
|
||||
23 |- else:
|
||||
24 |- return False
|
||||
21 |+ return bool(b)
|
||||
25 22 |
|
||||
26 23 |
|
||||
27 24 | def f():
|
||||
|
||||
SIM103.py:32:9: SIM103 [*] Return the condition `bool(b)` directly
|
||||
|
|
||||
30 | return 1
|
||||
31 | else:
|
||||
32 | / if b:
|
||||
33 | | return True
|
||||
34 | | else:
|
||||
35 | | return False
|
||||
| |________________________^ SIM103
|
||||
|
|
||||
= help: Replace with `return bool(b)`
|
||||
|
||||
ℹ Unsafe fix
|
||||
29 29 | if a:
|
||||
30 30 | return 1
|
||||
31 31 | else:
|
||||
32 |- if b:
|
||||
33 |- return True
|
||||
34 |- else:
|
||||
35 |- return False
|
||||
32 |+ return bool(b)
|
||||
36 33 |
|
||||
37 34 |
|
||||
38 35 | def f():
|
||||
|
||||
SIM103.py:57:5: SIM103 [*] Return the condition `not a` directly
|
||||
|
|
||||
55 | def f():
|
||||
56 | # SIM103
|
||||
57 | / if a:
|
||||
58 | | return False
|
||||
59 | | else:
|
||||
60 | | return True
|
||||
| |___________________^ SIM103
|
||||
|
|
||||
= help: Replace with `return not a`
|
||||
|
||||
ℹ Unsafe fix
|
||||
54 54 |
|
||||
55 55 | def f():
|
||||
56 56 | # SIM103
|
||||
57 |- if a:
|
||||
58 |- return False
|
||||
59 |- else:
|
||||
60 |- return True
|
||||
57 |+ return not a
|
||||
61 58 |
|
||||
62 59 |
|
||||
63 60 | def f():
|
||||
|
||||
SIM103.py:83:5: SIM103 Return the condition directly
|
||||
|
|
||||
81 | def bool():
|
||||
82 | return False
|
||||
83 | / if a:
|
||||
84 | | return True
|
||||
85 | | else:
|
||||
86 | | return False
|
||||
| |____________________^ SIM103
|
||||
|
|
||||
= help: Inline condition
|
||||
|
||||
SIM103.py:91:5: SIM103 [*] Return the condition `not (keys is not None and notice.key not in keys)` directly
|
||||
|
|
||||
89 | def f():
|
||||
90 | # SIM103
|
||||
91 | / if keys is not None and notice.key not in keys:
|
||||
92 | | return False
|
||||
93 | | else:
|
||||
94 | | return True
|
||||
| |___________________^ SIM103
|
||||
|
|
||||
= help: Replace with `return not (keys is not None and notice.key not in keys)`
|
||||
|
||||
ℹ Unsafe fix
|
||||
88 88 |
|
||||
89 89 | def f():
|
||||
90 90 | # SIM103
|
||||
91 |- if keys is not None and notice.key not in keys:
|
||||
92 |- return False
|
||||
93 |- else:
|
||||
94 |- return True
|
||||
91 |+ return not (keys is not None and notice.key not in keys)
|
||||
95 92 |
|
||||
96 93 |
|
||||
97 94 | ###
|
||||
|
||||
SIM103.py:104:5: SIM103 [*] Return the condition `bool(a)` directly
|
||||
|
|
||||
102 | def f():
|
||||
103 | # SIM103
|
||||
104 | / if a:
|
||||
105 | | return True
|
||||
106 | | return False
|
||||
| |________________^ SIM103
|
||||
|
|
||||
= help: Replace with `return bool(a)`
|
||||
|
||||
ℹ Unsafe fix
|
||||
101 101 |
|
||||
102 102 | def f():
|
||||
103 103 | # SIM103
|
||||
104 |- if a:
|
||||
105 |- return True
|
||||
106 |- return False
|
||||
104 |+ return bool(a)
|
||||
107 105 |
|
||||
108 106 |
|
||||
109 107 | def f():
|
||||
|
||||
SIM103.py:111:5: SIM103 [*] Return the condition `not a` directly
|
||||
|
|
||||
109 | def f():
|
||||
110 | # SIM103
|
||||
111 | / if a:
|
||||
112 | | return False
|
||||
113 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return not a`
|
||||
|
||||
ℹ Unsafe fix
|
||||
108 108 |
|
||||
109 109 | def f():
|
||||
110 110 | # SIM103
|
||||
111 |- if a:
|
||||
112 |- return False
|
||||
113 |- return True
|
||||
111 |+ return not a
|
||||
114 112 |
|
||||
115 113 |
|
||||
116 114 | def f():
|
||||
|
||||
SIM103.py:117:5: SIM103 [*] Return the condition `10 < a` directly
|
||||
|
|
||||
116 | def f():
|
||||
117 | / if not 10 < a:
|
||||
118 | | return False
|
||||
119 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return 10 < a`
|
||||
|
||||
ℹ Unsafe fix
|
||||
114 114 |
|
||||
115 115 |
|
||||
116 116 | def f():
|
||||
117 |- if not 10 < a:
|
||||
118 |- return False
|
||||
119 |- return True
|
||||
117 |+ return 10 < a
|
||||
120 118 |
|
||||
121 119 |
|
||||
122 120 | def f():
|
||||
|
||||
SIM103.py:123:5: SIM103 [*] Return the condition `not 10 < a` directly
|
||||
|
|
||||
122 | def f():
|
||||
123 | / if 10 < a:
|
||||
124 | | return False
|
||||
125 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return not 10 < a`
|
||||
|
||||
ℹ Unsafe fix
|
||||
120 120 |
|
||||
121 121 |
|
||||
122 122 | def f():
|
||||
123 |- if 10 < a:
|
||||
124 |- return False
|
||||
125 |- return True
|
||||
123 |+ return not 10 < a
|
||||
126 124 |
|
||||
127 125 |
|
||||
128 126 | def f():
|
||||
|
||||
SIM103.py:129:5: SIM103 [*] Return the condition `10 not in a` directly
|
||||
|
|
||||
128 | def f():
|
||||
129 | / if 10 in a:
|
||||
130 | | return False
|
||||
131 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return 10 not in a`
|
||||
|
||||
ℹ Unsafe fix
|
||||
126 126 |
|
||||
127 127 |
|
||||
128 128 | def f():
|
||||
129 |- if 10 in a:
|
||||
130 |- return False
|
||||
131 |- return True
|
||||
129 |+ return 10 not in a
|
||||
132 130 |
|
||||
133 131 |
|
||||
134 132 | def f():
|
||||
|
||||
SIM103.py:135:5: SIM103 [*] Return the condition `10 in a` directly
|
||||
|
|
||||
134 | def f():
|
||||
135 | / if 10 not in a:
|
||||
136 | | return False
|
||||
137 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return 10 in a`
|
||||
|
||||
ℹ Unsafe fix
|
||||
132 132 |
|
||||
133 133 |
|
||||
134 134 | def f():
|
||||
135 |- if 10 not in a:
|
||||
136 |- return False
|
||||
137 |- return True
|
||||
135 |+ return 10 in a
|
||||
138 136 |
|
||||
139 137 |
|
||||
140 138 | def f():
|
||||
|
||||
SIM103.py:141:5: SIM103 [*] Return the condition `a is not 10` directly
|
||||
|
|
||||
140 | def f():
|
||||
141 | / if a is 10:
|
||||
142 | | return False
|
||||
143 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return a is not 10`
|
||||
|
||||
ℹ Unsafe fix
|
||||
138 138 |
|
||||
139 139 |
|
||||
140 140 | def f():
|
||||
141 |- if a is 10:
|
||||
142 |- return False
|
||||
143 |- return True
|
||||
141 |+ return a is not 10
|
||||
144 142 |
|
||||
145 143 |
|
||||
146 144 | def f():
|
||||
|
||||
SIM103.py:147:5: SIM103 [*] Return the condition `a is 10` directly
|
||||
|
|
||||
146 | def f():
|
||||
147 | / if a is not 10:
|
||||
148 | | return False
|
||||
149 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return a is 10`
|
||||
|
||||
ℹ Unsafe fix
|
||||
144 144 |
|
||||
145 145 |
|
||||
146 146 | def f():
|
||||
147 |- if a is not 10:
|
||||
148 |- return False
|
||||
149 |- return True
|
||||
147 |+ return a is 10
|
||||
150 148 |
|
||||
151 149 |
|
||||
152 150 | def f():
|
||||
|
||||
SIM103.py:153:5: SIM103 [*] Return the condition `a != 10` directly
|
||||
|
|
||||
152 | def f():
|
||||
153 | / if a == 10:
|
||||
154 | | return False
|
||||
155 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return a != 10`
|
||||
|
||||
ℹ Unsafe fix
|
||||
150 150 |
|
||||
151 151 |
|
||||
152 152 | def f():
|
||||
153 |- if a == 10:
|
||||
154 |- return False
|
||||
155 |- return True
|
||||
153 |+ return a != 10
|
||||
156 154 |
|
||||
157 155 |
|
||||
158 156 | def f():
|
||||
|
||||
SIM103.py:159:5: SIM103 [*] Return the condition `a == 10` directly
|
||||
|
|
||||
158 | def f():
|
||||
159 | / if a != 10:
|
||||
160 | | return False
|
||||
161 | | return True
|
||||
| |_______________^ SIM103
|
||||
|
|
||||
= help: Replace with `return a == 10`
|
||||
|
||||
ℹ Unsafe fix
|
||||
156 156 |
|
||||
157 157 |
|
||||
158 158 | def f():
|
||||
159 |- if a != 10:
|
||||
160 |- return False
|
||||
161 |- return True
|
||||
159 |+ return a == 10
|
||||
@@ -16,102 +16,64 @@ TC005.py:4:5: TC005 [*] Found empty type-checking block
|
||||
4 |- pass # TC005
|
||||
5 3 |
|
||||
6 4 |
|
||||
7 5 | if False:
|
||||
7 5 | def example():
|
||||
|
||||
TC005.py:8:5: TC005 [*] Found empty type-checking block
|
||||
TC005.py:9:9: TC005 [*] Found empty type-checking block
|
||||
|
|
||||
7 | if False:
|
||||
8 | pass # TC005
|
||||
| ^^^^ TC005
|
||||
9 |
|
||||
10 | if 0:
|
||||
7 | def example():
|
||||
8 | if TYPE_CHECKING:
|
||||
9 | pass # TC005
|
||||
| ^^^^ TC005
|
||||
10 | return
|
||||
|
|
||||
= help: Delete empty type-checking block
|
||||
|
||||
ℹ Safe fix
|
||||
4 4 | pass # TC005
|
||||
5 5 |
|
||||
6 6 |
|
||||
7 |-if False:
|
||||
8 |- pass # TC005
|
||||
9 7 |
|
||||
10 8 | if 0:
|
||||
11 9 | pass # TC005
|
||||
|
||||
TC005.py:11:5: TC005 [*] Found empty type-checking block
|
||||
|
|
||||
10 | if 0:
|
||||
11 | pass # TC005
|
||||
| ^^^^ TC005
|
||||
|
|
||||
= help: Delete empty type-checking block
|
||||
|
||||
ℹ Safe fix
|
||||
7 7 | if False:
|
||||
8 8 | pass # TC005
|
||||
9 9 |
|
||||
10 |-if 0:
|
||||
11 |- pass # TC005
|
||||
5 5 |
|
||||
6 6 |
|
||||
7 7 | def example():
|
||||
8 |- if TYPE_CHECKING:
|
||||
9 |- pass # TC005
|
||||
10 8 | return
|
||||
11 9 |
|
||||
12 10 |
|
||||
13 11 |
|
||||
14 12 | def example():
|
||||
|
||||
TC005.py:16:9: TC005 [*] Found empty type-checking block
|
||||
TC005.py:15:9: TC005 [*] Found empty type-checking block
|
||||
|
|
||||
14 | def example():
|
||||
15 | if TYPE_CHECKING:
|
||||
16 | pass # TC005
|
||||
13 | class Test:
|
||||
14 | if TYPE_CHECKING:
|
||||
15 | pass # TC005
|
||||
| ^^^^ TC005
|
||||
17 | return
|
||||
16 | x = 2
|
||||
|
|
||||
= help: Delete empty type-checking block
|
||||
|
||||
ℹ Safe fix
|
||||
11 11 |
|
||||
12 12 |
|
||||
13 13 |
|
||||
14 14 | def example():
|
||||
15 |- if TYPE_CHECKING:
|
||||
16 |- pass # TC005
|
||||
17 15 | return
|
||||
13 13 | class Test:
|
||||
14 |- if TYPE_CHECKING:
|
||||
15 |- pass # TC005
|
||||
16 14 | x = 2
|
||||
17 15 |
|
||||
18 16 |
|
||||
19 17 |
|
||||
|
||||
TC005.py:22:9: TC005 [*] Found empty type-checking block
|
||||
TC005.py:31:5: TC005 [*] Found empty type-checking block
|
||||
|
|
||||
20 | class Test:
|
||||
21 | if TYPE_CHECKING:
|
||||
22 | pass # TC005
|
||||
| ^^^^ TC005
|
||||
23 | x = 2
|
||||
|
|
||||
= help: Delete empty type-checking block
|
||||
|
||||
ℹ Safe fix
|
||||
18 18 |
|
||||
19 19 |
|
||||
20 20 | class Test:
|
||||
21 |- if TYPE_CHECKING:
|
||||
22 |- pass # TC005
|
||||
23 21 | x = 2
|
||||
24 22 |
|
||||
25 23 |
|
||||
|
||||
TC005.py:45:5: TC005 [*] Found empty type-checking block
|
||||
|
|
||||
44 | if TYPE_CHECKING:
|
||||
45 | pass # TC005
|
||||
30 | if TYPE_CHECKING:
|
||||
31 | pass # TC005
|
||||
| ^^^^ TC005
|
||||
46 |
|
||||
47 | # https://github.com/astral-sh/ruff/issues/11368
|
||||
32 |
|
||||
33 | # https://github.com/astral-sh/ruff/issues/11368
|
||||
|
|
||||
= help: Delete empty type-checking block
|
||||
|
||||
ℹ Safe fix
|
||||
41 41 |
|
||||
42 42 | from typing_extensions import TYPE_CHECKING
|
||||
43 43 |
|
||||
44 |-if TYPE_CHECKING:
|
||||
45 |- pass # TC005
|
||||
46 44 |
|
||||
47 45 | # https://github.com/astral-sh/ruff/issues/11368
|
||||
48 46 | if TYPE_CHECKING:
|
||||
27 27 |
|
||||
28 28 | from typing_extensions import TYPE_CHECKING
|
||||
29 29 |
|
||||
30 |-if TYPE_CHECKING:
|
||||
31 |- pass # TC005
|
||||
32 30 |
|
||||
33 31 | # https://github.com/astral-sh/ruff/issues/11368
|
||||
34 32 | if TYPE_CHECKING:
|
||||
|
||||
@@ -14,13 +14,13 @@ mod tests {
|
||||
use crate::registry::Rule;
|
||||
use crate::rules::pep8_naming::settings::IgnoreNames;
|
||||
use crate::rules::{flake8_import_conventions, pep8_naming};
|
||||
use crate::settings::types::PreviewMode;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_messages, settings};
|
||||
|
||||
#[test_case(Rule::InvalidClassName, Path::new("N801.py"))]
|
||||
#[test_case(Rule::InvalidFunctionName, Path::new("N802.py"))]
|
||||
#[test_case(Rule::InvalidArgumentName, Path::new("N803.py"))]
|
||||
#[test_case(Rule::InvalidArgumentName, Path::new("N804.py"))]
|
||||
#[test_case(Rule::InvalidFirstArgumentNameForClassMethod, Path::new("N804.py"))]
|
||||
#[test_case(Rule::InvalidFirstArgumentNameForMethod, Path::new("N805.py"))]
|
||||
#[test_case(Rule::NonLowercaseVariableInFunction, Path::new("N806.py"))]
|
||||
@@ -89,25 +89,6 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::InvalidArgumentName, Path::new("N803.py"))]
|
||||
#[test_case(Rule::InvalidArgumentName, Path::new("N804.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview__{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("pep8_naming").join(path).as_path(),
|
||||
&settings::LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn camelcase_imported_as_incorrect_convention() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
|
||||
@@ -23,7 +23,7 @@ use crate::checkers::ast::Checker;
|
||||
/// > mixedCase is allowed only in contexts where that’s already the
|
||||
/// > prevailing style (e.g. threading.py), to retain backwards compatibility.
|
||||
///
|
||||
/// In [preview], overridden methods are ignored.
|
||||
/// Methods decorated with `@typing.override` are ignored.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
@@ -61,8 +61,7 @@ pub(crate) fn invalid_argument_name_function(checker: &Checker, function_def: &S
|
||||
let semantic = checker.semantic();
|
||||
let scope = semantic.current_scope();
|
||||
|
||||
if checker.settings.preview.is_enabled()
|
||||
&& matches!(scope.kind, ScopeKind::Class(_))
|
||||
if matches!(scope.kind, ScopeKind::Class(_))
|
||||
&& is_override(&function_def.decorator_list, semantic)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -82,8 +82,8 @@ impl Violation for InvalidFirstArgumentNameForMethod {
|
||||
/// Checks for class methods that use a name other than `cls` for their
|
||||
/// first argument.
|
||||
///
|
||||
/// With [`preview`] enabled, the method `__new__` is exempted from this
|
||||
/// check and the corresponding violation is then caught by
|
||||
/// The method `__new__` is exempted from this
|
||||
/// check and the corresponding violation is caught by
|
||||
/// [`bad-staticmethod-argument`][PLW0211].
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
@@ -164,8 +164,6 @@ enum FunctionType {
|
||||
Method,
|
||||
/// The function is a class method.
|
||||
ClassMethod,
|
||||
/// The function is the method `__new__`
|
||||
NewMethod,
|
||||
}
|
||||
|
||||
impl FunctionType {
|
||||
@@ -177,11 +175,6 @@ impl FunctionType {
|
||||
is_new: false,
|
||||
}
|
||||
.into(),
|
||||
Self::NewMethod => InvalidFirstArgumentNameForClassMethod {
|
||||
argument_name,
|
||||
is_new: true,
|
||||
}
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +182,6 @@ impl FunctionType {
|
||||
match self {
|
||||
Self::Method => "self",
|
||||
Self::ClassMethod => "cls",
|
||||
Self::NewMethod => "cls",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +189,6 @@ impl FunctionType {
|
||||
match self {
|
||||
Self::Method => Rule::InvalidFirstArgumentNameForMethod,
|
||||
Self::ClassMethod => Rule::InvalidFirstArgumentNameForClassMethod,
|
||||
Self::NewMethod => Rule::InvalidFirstArgumentNameForClassMethod,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,11 +232,10 @@ pub(crate) fn invalid_first_argument_name(checker: &Checker, scope: &Scope) {
|
||||
IsMetaclass::Maybe => return,
|
||||
},
|
||||
function_type::FunctionType::ClassMethod => FunctionType::ClassMethod,
|
||||
// In preview, this violation is caught by `PLW0211` instead
|
||||
function_type::FunctionType::NewMethod if checker.settings.preview.is_enabled() => {
|
||||
// This violation is caught by `PLW0211` instead
|
||||
function_type::FunctionType::NewMethod => {
|
||||
return;
|
||||
}
|
||||
function_type::FunctionType::NewMethod => FunctionType::NewMethod,
|
||||
};
|
||||
if !checker.enabled(function_type.rule()) {
|
||||
return;
|
||||
|
||||
@@ -16,14 +16,6 @@ N803.py:6:28: N803 Argument name `A` should be lowercase
|
||||
7 | return _, a, A
|
||||
|
|
||||
|
||||
N803.py:18:28: N803 Argument name `A` should be lowercase
|
||||
|
|
||||
16 | class Extended(Class):
|
||||
17 | @override
|
||||
18 | def method(self, _, a, A): ...
|
||||
| ^ N803
|
||||
|
|
||||
|
||||
N803.py:22:16: N803 Argument name `A` should be lowercase
|
||||
|
|
||||
21 | @override # Incorrect usage
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pep8_naming/mod.rs
|
||||
---
|
||||
N803.py:1:16: N803 Argument name `A` should be lowercase
|
||||
|
|
||||
1 | def func(_, a, A):
|
||||
| ^ N803
|
||||
2 | return _, a, A
|
||||
|
|
||||
|
||||
N803.py:6:28: N803 Argument name `A` should be lowercase
|
||||
|
|
||||
5 | class Class:
|
||||
6 | def method(self, _, a, A):
|
||||
| ^ N803
|
||||
7 | return _, a, A
|
||||
|
|
||||
|
||||
N803.py:22:16: N803 Argument name `A` should be lowercase
|
||||
|
|
||||
21 | @override # Incorrect usage
|
||||
22 | def func(_, a, A): ...
|
||||
| ^ N803
|
||||
|
|
||||
|
||||
N803.py:25:21: N803 Argument name `A` should be lowercase
|
||||
|
|
||||
25 | func = lambda _, a, A: ...
|
||||
| ^ N803
|
||||
|
|
||||
|
||||
N803.py:29:42: N803 Argument name `A` should be lowercase
|
||||
|
|
||||
28 | class Extended(Class):
|
||||
29 | method = override(lambda self, _, a, A: ...) # Incorrect usage
|
||||
| ^ N803
|
||||
|
|
||||
@@ -10,7 +10,6 @@ mod tests {
|
||||
|
||||
use crate::registry::Rule;
|
||||
|
||||
use crate::settings::types::PreviewMode;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_messages, settings};
|
||||
|
||||
@@ -30,22 +29,4 @@ mod tests {
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::BlanketNOQA, Path::new("PGH004_2.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview__{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("pygrep_hooks").join(path).as_path(),
|
||||
&settings::LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@ use ruff_macros::{derive_message_formats, ViolationMetadata};
|
||||
use ruff_python_trivia::Cursor;
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use crate::noqa::{Directive, FileNoqaDirectives, NoqaDirectives, ParsedFileExemption};
|
||||
use crate::settings::types::PreviewMode;
|
||||
use crate::noqa::{self, Directive, FileNoqaDirectives, NoqaDirectives};
|
||||
use crate::Locator;
|
||||
|
||||
/// ## What it does
|
||||
@@ -18,9 +17,6 @@ use crate::Locator;
|
||||
/// maintain, as the annotation does not clarify which diagnostics are intended
|
||||
/// to be suppressed.
|
||||
///
|
||||
/// In [preview], this rule also checks for blanket file-level annotations (e.g.,
|
||||
/// `# ruff: noqa`, as opposed to `# ruff: noqa: F401`).
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// from .base import * # noqa
|
||||
@@ -41,12 +37,9 @@ use crate::Locator;
|
||||
///
|
||||
/// ## References
|
||||
/// - [Ruff documentation](https://docs.astral.sh/ruff/configuration/#error-suppression)
|
||||
///
|
||||
/// [preview]: https://docs.astral.sh/ruff/preview/
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct BlanketNOQA {
|
||||
missing_colon: bool,
|
||||
space_before_colon: bool,
|
||||
file_exemption: bool,
|
||||
}
|
||||
|
||||
@@ -57,27 +50,22 @@ impl Violation for BlanketNOQA {
|
||||
fn message(&self) -> String {
|
||||
let BlanketNOQA {
|
||||
missing_colon,
|
||||
space_before_colon,
|
||||
file_exemption,
|
||||
} = self;
|
||||
// This awkward branching is necessary to ensure that the generic message is picked up by
|
||||
// `derive_message_formats`.
|
||||
if !missing_colon && !space_before_colon && !file_exemption {
|
||||
if !missing_colon && !file_exemption {
|
||||
"Use specific rule codes when using `noqa`".to_string()
|
||||
} else if *file_exemption {
|
||||
"Use specific rule codes when using `ruff: noqa`".to_string()
|
||||
} else if *missing_colon {
|
||||
"Use a colon when specifying `noqa` rule codes".to_string()
|
||||
} else {
|
||||
"Do not add spaces between `noqa` and its colon".to_string()
|
||||
"Use a colon when specifying `noqa` rule codes".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> Option<String> {
|
||||
if self.missing_colon {
|
||||
Some("Add missing colon".to_string())
|
||||
} else if self.space_before_colon {
|
||||
Some("Remove space(s) before colon".to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -90,20 +78,16 @@ pub(crate) fn blanket_noqa(
|
||||
noqa_directives: &NoqaDirectives,
|
||||
locator: &Locator,
|
||||
file_noqa_directives: &FileNoqaDirectives,
|
||||
preview: PreviewMode,
|
||||
) {
|
||||
if preview.is_enabled() {
|
||||
for line in file_noqa_directives.lines() {
|
||||
if let ParsedFileExemption::All = line.parsed_file_exemption {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
BlanketNOQA {
|
||||
missing_colon: false,
|
||||
space_before_colon: false,
|
||||
file_exemption: true,
|
||||
},
|
||||
line.range(),
|
||||
));
|
||||
}
|
||||
for line in file_noqa_directives.lines() {
|
||||
if let Directive::All(_) = line.parsed_file_exemption {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
BlanketNOQA {
|
||||
missing_colon: false,
|
||||
file_exemption: true,
|
||||
},
|
||||
line.range(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,22 +100,7 @@ pub(crate) fn blanket_noqa(
|
||||
let mut cursor = Cursor::new(&line[noqa_end.to_usize()..]);
|
||||
cursor.eat_while(char::is_whitespace);
|
||||
|
||||
// Check for extraneous spaces before the colon.
|
||||
// Ex) `# noqa : F401`
|
||||
if cursor.first() == ':' {
|
||||
let start = all.end();
|
||||
let end = start + cursor.token_len();
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
BlanketNOQA {
|
||||
missing_colon: false,
|
||||
space_before_colon: true,
|
||||
file_exemption: false,
|
||||
},
|
||||
TextRange::new(all.start(), end),
|
||||
);
|
||||
diagnostic.set_fix(Fix::unsafe_edit(Edit::deletion(start, end)));
|
||||
diagnostics.push(diagnostic);
|
||||
} else if Directive::lex_code(cursor.chars().as_str()).is_some() {
|
||||
if noqa::lex_codes(cursor.chars().as_str()).is_ok_and(|codes| !codes.is_empty()) {
|
||||
// Check for a missing colon.
|
||||
// Ex) `# noqa F401`
|
||||
let start = all.end();
|
||||
@@ -139,7 +108,6 @@ pub(crate) fn blanket_noqa(
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
BlanketNOQA {
|
||||
missing_colon: true,
|
||||
space_before_colon: false,
|
||||
file_exemption: false,
|
||||
},
|
||||
TextRange::new(all.start(), end),
|
||||
@@ -151,7 +119,6 @@ pub(crate) fn blanket_noqa(
|
||||
diagnostics.push(Diagnostic::new(
|
||||
BlanketNOQA {
|
||||
missing_colon: false,
|
||||
space_before_colon: false,
|
||||
file_exemption: false,
|
||||
},
|
||||
all.range(),
|
||||
|
||||
@@ -68,58 +68,3 @@ PGH004_0.py:21:8: PGH004 [*] Use a colon when specifying `noqa` rule codes
|
||||
22 22 |
|
||||
23 23 | # PGH004
|
||||
24 24 | x = 2 # noqa : X300
|
||||
|
||||
PGH004_0.py:24:8: PGH004 [*] Do not add spaces between `noqa` and its colon
|
||||
|
|
||||
23 | # PGH004
|
||||
24 | x = 2 # noqa : X300
|
||||
| ^^^^^^^ PGH004
|
||||
25 |
|
||||
26 | # PGH004
|
||||
|
|
||||
= help: Remove space(s) before colon
|
||||
|
||||
ℹ Unsafe fix
|
||||
21 21 | x = 2 # noqa X100, X200
|
||||
22 22 |
|
||||
23 23 | # PGH004
|
||||
24 |-x = 2 # noqa : X300
|
||||
24 |+x = 2 # noqa: X300
|
||||
25 25 |
|
||||
26 26 | # PGH004
|
||||
27 27 | x = 2 # noqa : X400
|
||||
|
||||
PGH004_0.py:27:8: PGH004 [*] Do not add spaces between `noqa` and its colon
|
||||
|
|
||||
26 | # PGH004
|
||||
27 | x = 2 # noqa : X400
|
||||
| ^^^^^^^^ PGH004
|
||||
28 |
|
||||
29 | # PGH004
|
||||
|
|
||||
= help: Remove space(s) before colon
|
||||
|
||||
ℹ Unsafe fix
|
||||
24 24 | x = 2 # noqa : X300
|
||||
25 25 |
|
||||
26 26 | # PGH004
|
||||
27 |-x = 2 # noqa : X400
|
||||
27 |+x = 2 # noqa: X400
|
||||
28 28 |
|
||||
29 29 | # PGH004
|
||||
30 30 | x = 2 # noqa :X500
|
||||
|
||||
PGH004_0.py:30:8: PGH004 [*] Do not add spaces between `noqa` and its colon
|
||||
|
|
||||
29 | # PGH004
|
||||
30 | x = 2 # noqa :X500
|
||||
| ^^^^^^^ PGH004
|
||||
|
|
||||
= help: Remove space(s) before colon
|
||||
|
||||
ℹ Unsafe fix
|
||||
27 27 | x = 2 # noqa : X400
|
||||
28 28 |
|
||||
29 29 | # PGH004
|
||||
30 |-x = 2 # noqa :X500
|
||||
30 |+x = 2 # noqa:X500
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pygrep_hooks/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
PGH004_2.py:1:1: PGH004 Use specific rule codes when using `noqa`
|
||||
|
|
||||
@@ -9,3 +8,18 @@ PGH004_2.py:1:1: PGH004 Use specific rule codes when using `noqa`
|
||||
2 | # ruff : noqa
|
||||
3 | # ruff: noqa: F401
|
||||
|
|
||||
|
||||
PGH004_2.py:2:1: PGH004 Use specific rule codes when using `ruff: noqa`
|
||||
|
|
||||
1 | # noqa
|
||||
2 | # ruff : noqa
|
||||
| ^^^^^^^^^^^^^ PGH004
|
||||
3 | # ruff: noqa: F401
|
||||
|
|
||||
|
||||
PGH004_2.py:6:1: PGH004 Use specific rule codes when using `ruff: noqa`
|
||||
|
|
||||
6 | # flake8: noqa
|
||||
| ^^^^^^^^^^^^^^ PGH004
|
||||
7 | import math as m
|
||||
|
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pygrep_hooks/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
PGH004_2.py:1:1: PGH004 Use specific rule codes when using `noqa`
|
||||
|
|
||||
1 | # noqa
|
||||
| ^^^^^^ PGH004
|
||||
2 | # ruff : noqa
|
||||
3 | # ruff: noqa: F401
|
||||
|
|
||||
|
||||
PGH004_2.py:2:1: PGH004 Use specific rule codes when using `ruff: noqa`
|
||||
|
|
||||
1 | # noqa
|
||||
2 | # ruff : noqa
|
||||
| ^^^^^^^^^^^^^ PGH004
|
||||
3 | # ruff: noqa: F401
|
||||
|
|
||||
|
||||
PGH004_2.py:6:1: PGH004 Use specific rule codes when using `ruff: noqa`
|
||||
|
|
||||
6 | # flake8: noqa
|
||||
| ^^^^^^^^^^^^^^ PGH004
|
||||
7 | import math as m
|
||||
|
|
||||
@@ -16,10 +16,10 @@ mod tests {
|
||||
use crate::registry::Rule;
|
||||
use crate::rules::{flake8_tidy_imports, pylint};
|
||||
|
||||
use crate::assert_messages;
|
||||
use crate::settings::types::PreviewMode;
|
||||
use crate::settings::LinterSettings;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_messages, settings};
|
||||
|
||||
#[test_case(Rule::SingledispatchMethod, Path::new("singledispatch_method.py"))]
|
||||
#[test_case(
|
||||
@@ -440,31 +440,4 @@ mod tests {
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(
|
||||
Rule::RepeatedEqualityComparison,
|
||||
Path::new("repeated_equality_comparison.py")
|
||||
)]
|
||||
#[test_case(Rule::InvalidEnvvarDefault, Path::new("invalid_envvar_default.py"))]
|
||||
#[test_case(Rule::BadStrStripCall, Path::new("bad_str_strip_call.py"))]
|
||||
#[test_case(
|
||||
Rule::BadStaticmethodArgument,
|
||||
Path::new("bad_staticmethod_argument.py")
|
||||
)]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview__{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("pylint").join(path).as_path(),
|
||||
&settings::LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ use ruff_macros::{derive_message_formats, ViolationMetadata};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::ParameterWithDefault;
|
||||
use ruff_python_semantic::analyze::function_type;
|
||||
use ruff_python_semantic::analyze::function_type::FunctionType;
|
||||
use ruff_python_semantic::Scope;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
@@ -10,9 +11,7 @@ use crate::checkers::ast::Checker;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for static methods that use `self` or `cls` as their first argument.
|
||||
///
|
||||
/// If [`preview`] mode is enabled, this rule also applies to
|
||||
/// `__new__` methods, which are implicitly static.
|
||||
/// This rule also applies to `__new__` methods, which are implicitly static.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// [PEP 8] recommends the use of `self` and `cls` as the first arguments for
|
||||
@@ -77,9 +76,8 @@ pub(crate) fn bad_staticmethod_argument(checker: &Checker, scope: &Scope) {
|
||||
);
|
||||
|
||||
match type_ {
|
||||
function_type::FunctionType::StaticMethod => {}
|
||||
function_type::FunctionType::NewMethod if checker.settings.preview.is_enabled() => {}
|
||||
_ => {
|
||||
FunctionType::StaticMethod | FunctionType::NewMethod => {}
|
||||
FunctionType::Function | FunctionType::Method | FunctionType::ClassMethod => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -187,12 +187,6 @@ pub(crate) fn bad_str_strip_call(checker: &Checker, call: &ast::ExprCall) {
|
||||
|
||||
let value = &**value;
|
||||
|
||||
if checker.settings.preview.is_disabled()
|
||||
&& !matches!(value, Expr::StringLiteral(_) | Expr::BytesLiteral(_))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(value_kind) = ValueKind::from(value, checker.semantic()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -52,14 +52,10 @@ pub(crate) fn invalid_envvar_default(checker: &Checker, call: &ast::ExprCall) {
|
||||
.semantic()
|
||||
.resolve_qualified_name(&call.func)
|
||||
.is_some_and(|qualified_name| {
|
||||
if checker.settings.preview.is_enabled() {
|
||||
matches!(
|
||||
qualified_name.segments(),
|
||||
["os", "getenv"] | ["os", "environ", "get"]
|
||||
)
|
||||
} else {
|
||||
matches!(qualified_name.segments(), ["os", "getenv"])
|
||||
}
|
||||
matches!(
|
||||
qualified_name.segments(),
|
||||
["os", "getenv"] | ["os", "environ", "get"]
|
||||
)
|
||||
})
|
||||
{
|
||||
// Find the `default` argument, if it exists.
|
||||
|
||||
@@ -9,12 +9,11 @@ use ruff_python_semantic::{BindingId, SemanticModel};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for usage of call of 'len' on sequences
|
||||
/// in boolean test context.
|
||||
/// Checks for `len` calls on sequences in a boolean test context.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Empty sequences are considered false in a boolean context.
|
||||
/// You can either remove the call to 'len'
|
||||
/// You can either remove the call to `len`
|
||||
/// or compare the length against a scalar.
|
||||
///
|
||||
/// ## Example
|
||||
|
||||
@@ -15,9 +15,13 @@ use crate::fix::snippet::SourceCodeSnippet;
|
||||
use crate::Locator;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for repeated equality comparisons that can rewritten as a membership
|
||||
/// Checks for repeated equality comparisons that can be rewritten as a membership
|
||||
/// test.
|
||||
///
|
||||
/// This rule will try to determine if the values are hashable
|
||||
/// and the fix will use a `set` if they are. If unable to determine, the fix
|
||||
/// will use a `tuple` and suggest the use of a `set`.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// To check if a variable is equal to one of many values, it is common to
|
||||
/// write a series of equality comparisons (e.g.,
|
||||
@@ -28,10 +32,6 @@ use crate::Locator;
|
||||
/// If the items are hashable, use a `set` for efficiency; otherwise, use a
|
||||
/// `tuple`.
|
||||
///
|
||||
/// In [preview], this rule will try to determine if the values are hashable
|
||||
/// and the fix will use a `set` if they are. If unable to determine, the fix
|
||||
/// will use a `tuple` and continue to suggest the use of a `set`.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// foo == "bar" or foo == "baz" or foo == "qux"
|
||||
@@ -46,8 +46,6 @@ use crate::Locator;
|
||||
/// - [Python documentation: Comparisons](https://docs.python.org/3/reference/expressions.html#comparisons)
|
||||
/// - [Python documentation: Membership test operations](https://docs.python.org/3/reference/expressions.html#membership-test-operations)
|
||||
/// - [Python documentation: `set`](https://docs.python.org/3/library/stdtypes.html#set)
|
||||
///
|
||||
/// [preview]: https://docs.astral.sh/ruff/preview/
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct RepeatedEqualityComparison {
|
||||
expression: SourceCodeSnippet,
|
||||
@@ -135,10 +133,9 @@ pub(crate) fn repeated_equality_comparison(checker: &Checker, bool_op: &ast::Exp
|
||||
|
||||
// if we can determine that all the values are hashable, we can use a set
|
||||
// TODO: improve with type inference
|
||||
let all_hashable = checker.settings.preview.is_enabled()
|
||||
&& comparators
|
||||
.iter()
|
||||
.all(|comparator| comparator.is_literal_expr());
|
||||
let all_hashable = comparators
|
||||
.iter()
|
||||
.all(|comparator| comparator.is_literal_expr());
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
RepeatedEqualityComparison {
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::checkers::ast::Checker;
|
||||
/// `os.environ` is not a `dict` object, but rather, a proxy object. As such, mutating a shallow
|
||||
/// copy of `os.environ` will also mutate the original object.
|
||||
///
|
||||
/// See: [#15373] for more information.
|
||||
/// See [BPO 15373] for more information.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
@@ -41,7 +41,7 @@ use crate::checkers::ast::Checker;
|
||||
/// - [Python documentation: `copy` — Shallow and deep copy operations](https://docs.python.org/3/library/copy.html)
|
||||
/// - [Python documentation: `os.environ`](https://docs.python.org/3/library/os.html#os.environ)
|
||||
///
|
||||
/// [#15373]: https://bugs.python.org/issue15373
|
||||
/// [BPO 15373]: https://bugs.python.org/issue15373
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct ShallowCopyEnviron;
|
||||
|
||||
|
||||
@@ -181,3 +181,30 @@ bad_str_strip_call.py:81:10: PLE1310 String `strip` call contains duplicate char
|
||||
82 |
|
||||
83 | # Errors: Type inference
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:85:9: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
83 | # Errors: Type inference
|
||||
84 | b = b''
|
||||
85 | b.strip(b'//')
|
||||
| ^^^^^ PLE1310
|
||||
86 |
|
||||
87 | # Errors: Type inference (preview)
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:89:12: PLE1310 String `rstrip` call contains duplicate characters (did you mean `removesuffix`?)
|
||||
|
|
||||
87 | # Errors: Type inference (preview)
|
||||
88 | foo: str = ""; bar: bytes = b""
|
||||
89 | foo.rstrip("//")
|
||||
| ^^^^ PLE1310
|
||||
90 | bar.lstrip(b"//")
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:90:12: PLE1310 String `lstrip` call contains duplicate characters (did you mean `removeprefix`?)
|
||||
|
|
||||
88 | foo: str = ""; bar: bytes = b""
|
||||
89 | foo.rstrip("//")
|
||||
90 | bar.lstrip(b"//")
|
||||
| ^^^^^ PLE1310
|
||||
|
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
||||
---
|
||||
repeated_equality_comparison.py:2:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:2:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b"}`.
|
||||
|
|
||||
1 | # Errors.
|
||||
2 | foo == "a" or foo == "b"
|
||||
@@ -14,12 +14,12 @@ repeated_equality_comparison.py:2:1: PLR1714 [*] Consider merging multiple compa
|
||||
ℹ Unsafe fix
|
||||
1 1 | # Errors.
|
||||
2 |-foo == "a" or foo == "b"
|
||||
2 |+foo in ("a", "b")
|
||||
2 |+foo in {"a", "b"}
|
||||
3 3 |
|
||||
4 4 | foo != "a" and foo != "b"
|
||||
5 5 |
|
||||
|
||||
repeated_equality_comparison.py:4:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in ("a", "b")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:4:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in {"a", "b"}`.
|
||||
|
|
||||
2 | foo == "a" or foo == "b"
|
||||
3 |
|
||||
@@ -35,12 +35,12 @@ repeated_equality_comparison.py:4:1: PLR1714 [*] Consider merging multiple compa
|
||||
2 2 | foo == "a" or foo == "b"
|
||||
3 3 |
|
||||
4 |-foo != "a" and foo != "b"
|
||||
4 |+foo not in ("a", "b")
|
||||
4 |+foo not in {"a", "b"}
|
||||
5 5 |
|
||||
6 6 | foo == "a" or foo == "b" or foo == "c"
|
||||
7 7 |
|
||||
|
||||
repeated_equality_comparison.py:6:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:6:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b", "c"}`.
|
||||
|
|
||||
4 | foo != "a" and foo != "b"
|
||||
5 |
|
||||
@@ -56,12 +56,12 @@ repeated_equality_comparison.py:6:1: PLR1714 [*] Consider merging multiple compa
|
||||
4 4 | foo != "a" and foo != "b"
|
||||
5 5 |
|
||||
6 |-foo == "a" or foo == "b" or foo == "c"
|
||||
6 |+foo in ("a", "b", "c")
|
||||
6 |+foo in {"a", "b", "c"}
|
||||
7 7 |
|
||||
8 8 | foo != "a" and foo != "b" and foo != "c"
|
||||
9 9 |
|
||||
|
||||
repeated_equality_comparison.py:8:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in ("a", "b", "c")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:8:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in {"a", "b", "c"}`.
|
||||
|
|
||||
6 | foo == "a" or foo == "b" or foo == "c"
|
||||
7 |
|
||||
@@ -77,7 +77,7 @@ repeated_equality_comparison.py:8:1: PLR1714 [*] Consider merging multiple compa
|
||||
6 6 | foo == "a" or foo == "b" or foo == "c"
|
||||
7 7 |
|
||||
8 |-foo != "a" and foo != "b" and foo != "c"
|
||||
8 |+foo not in ("a", "b", "c")
|
||||
8 |+foo not in {"a", "b", "c"}
|
||||
9 9 |
|
||||
10 10 | foo == a or foo == "b" or foo == 3 # Mixed types.
|
||||
11 11 |
|
||||
@@ -103,7 +103,7 @@ repeated_equality_comparison.py:10:1: PLR1714 [*] Consider merging multiple comp
|
||||
12 12 | "a" == foo or "b" == foo or "c" == foo
|
||||
13 13 |
|
||||
|
||||
repeated_equality_comparison.py:12:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:12:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b", "c"}`.
|
||||
|
|
||||
10 | foo == a or foo == "b" or foo == 3 # Mixed types.
|
||||
11 |
|
||||
@@ -119,12 +119,12 @@ repeated_equality_comparison.py:12:1: PLR1714 [*] Consider merging multiple comp
|
||||
10 10 | foo == a or foo == "b" or foo == 3 # Mixed types.
|
||||
11 11 |
|
||||
12 |-"a" == foo or "b" == foo or "c" == foo
|
||||
12 |+foo in ("a", "b", "c")
|
||||
12 |+foo in {"a", "b", "c"}
|
||||
13 13 |
|
||||
14 14 | "a" != foo and "b" != foo and "c" != foo
|
||||
15 15 |
|
||||
|
||||
repeated_equality_comparison.py:14:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in ("a", "b", "c")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:14:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in {"a", "b", "c"}`.
|
||||
|
|
||||
12 | "a" == foo or "b" == foo or "c" == foo
|
||||
13 |
|
||||
@@ -140,12 +140,12 @@ repeated_equality_comparison.py:14:1: PLR1714 [*] Consider merging multiple comp
|
||||
12 12 | "a" == foo or "b" == foo or "c" == foo
|
||||
13 13 |
|
||||
14 |-"a" != foo and "b" != foo and "c" != foo
|
||||
14 |+foo not in ("a", "b", "c")
|
||||
14 |+foo not in {"a", "b", "c"}
|
||||
15 15 |
|
||||
16 16 | "a" == foo or foo == "b" or "c" == foo
|
||||
17 17 |
|
||||
|
||||
repeated_equality_comparison.py:16:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:16:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b", "c"}`.
|
||||
|
|
||||
14 | "a" != foo and "b" != foo and "c" != foo
|
||||
15 |
|
||||
@@ -161,7 +161,7 @@ repeated_equality_comparison.py:16:1: PLR1714 [*] Consider merging multiple comp
|
||||
14 14 | "a" != foo and "b" != foo and "c" != foo
|
||||
15 15 |
|
||||
16 |-"a" == foo or foo == "b" or "c" == foo
|
||||
16 |+foo in ("a", "b", "c")
|
||||
16 |+foo in {"a", "b", "c"}
|
||||
17 17 |
|
||||
18 18 | foo == bar or baz == foo or qux == foo
|
||||
19 19 |
|
||||
@@ -187,7 +187,7 @@ repeated_equality_comparison.py:18:1: PLR1714 [*] Consider merging multiple comp
|
||||
20 20 | foo == "a" or "b" == foo or foo == "c"
|
||||
21 21 |
|
||||
|
||||
repeated_equality_comparison.py:20:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:20:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b", "c"}`.
|
||||
|
|
||||
18 | foo == bar or baz == foo or qux == foo
|
||||
19 |
|
||||
@@ -203,12 +203,12 @@ repeated_equality_comparison.py:20:1: PLR1714 [*] Consider merging multiple comp
|
||||
18 18 | foo == bar or baz == foo or qux == foo
|
||||
19 19 |
|
||||
20 |-foo == "a" or "b" == foo or foo == "c"
|
||||
20 |+foo in ("a", "b", "c")
|
||||
20 |+foo in {"a", "b", "c"}
|
||||
21 21 |
|
||||
22 22 | foo != "a" and "b" != foo and foo != "c"
|
||||
23 23 |
|
||||
|
||||
repeated_equality_comparison.py:22:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in ("a", "b", "c")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:22:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in {"a", "b", "c"}`.
|
||||
|
|
||||
20 | foo == "a" or "b" == foo or foo == "c"
|
||||
21 |
|
||||
@@ -224,12 +224,12 @@ repeated_equality_comparison.py:22:1: PLR1714 [*] Consider merging multiple comp
|
||||
20 20 | foo == "a" or "b" == foo or foo == "c"
|
||||
21 21 |
|
||||
22 |-foo != "a" and "b" != foo and foo != "c"
|
||||
22 |+foo not in ("a", "b", "c")
|
||||
22 |+foo not in {"a", "b", "c"}
|
||||
23 23 |
|
||||
24 24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
25 25 |
|
||||
|
||||
repeated_equality_comparison.py:24:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:24:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b"}`.
|
||||
|
|
||||
22 | foo != "a" and "b" != foo and foo != "c"
|
||||
23 |
|
||||
@@ -245,12 +245,12 @@ repeated_equality_comparison.py:24:1: PLR1714 [*] Consider merging multiple comp
|
||||
22 22 | foo != "a" and "b" != foo and foo != "c"
|
||||
23 23 |
|
||||
24 |-foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
24 |+foo in ("a", "b") or "c" == bar or "d" == bar # Multiple targets
|
||||
24 |+foo in {"a", "b"} or "c" == bar or "d" == bar # Multiple targets
|
||||
25 25 |
|
||||
26 26 | foo.bar == "a" or foo.bar == "b" # Attributes.
|
||||
27 27 |
|
||||
|
||||
repeated_equality_comparison.py:24:1: PLR1714 [*] Consider merging multiple comparisons: `bar in ("c", "d")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:24:1: PLR1714 [*] Consider merging multiple comparisons: `bar in {"c", "d"}`.
|
||||
|
|
||||
22 | foo != "a" and "b" != foo and foo != "c"
|
||||
23 |
|
||||
@@ -266,12 +266,12 @@ repeated_equality_comparison.py:24:1: PLR1714 [*] Consider merging multiple comp
|
||||
22 22 | foo != "a" and "b" != foo and foo != "c"
|
||||
23 23 |
|
||||
24 |-foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
24 |+foo == "a" or foo == "b" or bar in ("c", "d") # Multiple targets
|
||||
24 |+foo == "a" or foo == "b" or bar in {"c", "d"} # Multiple targets
|
||||
25 25 |
|
||||
26 26 | foo.bar == "a" or foo.bar == "b" # Attributes.
|
||||
27 27 |
|
||||
|
||||
repeated_equality_comparison.py:26:1: PLR1714 [*] Consider merging multiple comparisons: `foo.bar in ("a", "b")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:26:1: PLR1714 [*] Consider merging multiple comparisons: `foo.bar in {"a", "b"}`.
|
||||
|
|
||||
24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
25 |
|
||||
@@ -287,12 +287,12 @@ repeated_equality_comparison.py:26:1: PLR1714 [*] Consider merging multiple comp
|
||||
24 24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
25 25 |
|
||||
26 |-foo.bar == "a" or foo.bar == "b" # Attributes.
|
||||
26 |+foo.bar in ("a", "b") # Attributes.
|
||||
26 |+foo.bar in {"a", "b"} # Attributes.
|
||||
27 27 |
|
||||
28 28 | # OK
|
||||
29 29 | foo == "a" and foo == "b" and foo == "c" # `and` mixed with `==`.
|
||||
|
||||
repeated_equality_comparison.py:61:16: PLR1714 [*] Consider merging multiple comparisons: `bar in ("c", "d")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:61:16: PLR1714 [*] Consider merging multiple comparisons: `bar in {"c", "d"}`.
|
||||
|
|
||||
59 | foo == "a" or "c" == bar or foo == "b" or "d" == bar # Multiple targets
|
||||
60 |
|
||||
@@ -308,12 +308,12 @@ repeated_equality_comparison.py:61:16: PLR1714 [*] Consider merging multiple com
|
||||
59 59 | foo == "a" or "c" == bar or foo == "b" or "d" == bar # Multiple targets
|
||||
60 60 |
|
||||
61 |-foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
61 |+foo == "a" or (bar in ("c", "d")) or foo == "b" # Multiple targets
|
||||
61 |+foo == "a" or (bar in {"c", "d"}) or foo == "b" # Multiple targets
|
||||
62 62 |
|
||||
63 63 | foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
64 64 |
|
||||
|
||||
repeated_equality_comparison.py:63:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:63:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b"}`.
|
||||
|
|
||||
61 | foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
62 |
|
||||
@@ -329,12 +329,12 @@ repeated_equality_comparison.py:63:1: PLR1714 [*] Consider merging multiple comp
|
||||
61 61 | foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
62 62 |
|
||||
63 |-foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
63 |+foo in ("a", "b") or "c" != bar and "d" != bar # Multiple targets
|
||||
63 |+foo in {"a", "b"} or "c" != bar and "d" != bar # Multiple targets
|
||||
64 64 |
|
||||
65 65 | foo == "a" or ("c" != bar and "d" != bar) or foo == "b" # Multiple targets
|
||||
66 66 |
|
||||
|
||||
repeated_equality_comparison.py:63:29: PLR1714 [*] Consider merging multiple comparisons: `bar not in ("c", "d")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:63:29: PLR1714 [*] Consider merging multiple comparisons: `bar not in {"c", "d"}`.
|
||||
|
|
||||
61 | foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
62 |
|
||||
@@ -350,12 +350,12 @@ repeated_equality_comparison.py:63:29: PLR1714 [*] Consider merging multiple com
|
||||
61 61 | foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
62 62 |
|
||||
63 |-foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
63 |+foo == "a" or foo == "b" or bar not in ("c", "d") # Multiple targets
|
||||
63 |+foo == "a" or foo == "b" or bar not in {"c", "d"} # Multiple targets
|
||||
64 64 |
|
||||
65 65 | foo == "a" or ("c" != bar and "d" != bar) or foo == "b" # Multiple targets
|
||||
66 66 |
|
||||
|
||||
repeated_equality_comparison.py:65:16: PLR1714 [*] Consider merging multiple comparisons: `bar not in ("c", "d")`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:65:16: PLR1714 [*] Consider merging multiple comparisons: `bar not in {"c", "d"}`.
|
||||
|
|
||||
63 | foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
64 |
|
||||
@@ -371,12 +371,12 @@ repeated_equality_comparison.py:65:16: PLR1714 [*] Consider merging multiple com
|
||||
63 63 | foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
64 64 |
|
||||
65 |-foo == "a" or ("c" != bar and "d" != bar) or foo == "b" # Multiple targets
|
||||
65 |+foo == "a" or (bar not in ("c", "d")) or foo == "b" # Multiple targets
|
||||
65 |+foo == "a" or (bar not in {"c", "d"}) or foo == "b" # Multiple targets
|
||||
66 66 |
|
||||
67 67 | foo == "a" and "c" != bar or foo == "b" and "d" != bar # Multiple targets
|
||||
68 68 |
|
||||
|
||||
repeated_equality_comparison.py:69:1: PLR1714 [*] Consider merging multiple comparisons: `foo in (1, True)`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:69:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {1, True}`.
|
||||
|
|
||||
67 | foo == "a" and "c" != bar or foo == "b" and "d" != bar # Multiple targets
|
||||
68 |
|
||||
@@ -392,12 +392,12 @@ repeated_equality_comparison.py:69:1: PLR1714 [*] Consider merging multiple comp
|
||||
67 67 | foo == "a" and "c" != bar or foo == "b" and "d" != bar # Multiple targets
|
||||
68 68 |
|
||||
69 |-foo == 1 or foo == True # Different types, same hashed value
|
||||
69 |+foo in (1, True) # Different types, same hashed value
|
||||
69 |+foo in {1, True} # Different types, same hashed value
|
||||
70 70 |
|
||||
71 71 | foo == 1 or foo == 1.0 # Different types, same hashed value
|
||||
72 72 |
|
||||
|
||||
repeated_equality_comparison.py:71:1: PLR1714 [*] Consider merging multiple comparisons: `foo in (1, 1.0)`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:71:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {1, 1.0}`.
|
||||
|
|
||||
69 | foo == 1 or foo == True # Different types, same hashed value
|
||||
70 |
|
||||
@@ -413,12 +413,12 @@ repeated_equality_comparison.py:71:1: PLR1714 [*] Consider merging multiple comp
|
||||
69 69 | foo == 1 or foo == True # Different types, same hashed value
|
||||
70 70 |
|
||||
71 |-foo == 1 or foo == 1.0 # Different types, same hashed value
|
||||
71 |+foo in (1, 1.0) # Different types, same hashed value
|
||||
71 |+foo in {1, 1.0} # Different types, same hashed value
|
||||
72 72 |
|
||||
73 73 | foo == False or foo == 0 # Different types, same hashed value
|
||||
74 74 |
|
||||
|
||||
repeated_equality_comparison.py:73:1: PLR1714 [*] Consider merging multiple comparisons: `foo in (False, 0)`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:73:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {False, 0}`.
|
||||
|
|
||||
71 | foo == 1 or foo == 1.0 # Different types, same hashed value
|
||||
72 |
|
||||
@@ -434,11 +434,11 @@ repeated_equality_comparison.py:73:1: PLR1714 [*] Consider merging multiple comp
|
||||
71 71 | foo == 1 or foo == 1.0 # Different types, same hashed value
|
||||
72 72 |
|
||||
73 |-foo == False or foo == 0 # Different types, same hashed value
|
||||
73 |+foo in (False, 0) # Different types, same hashed value
|
||||
73 |+foo in {False, 0} # Different types, same hashed value
|
||||
74 74 |
|
||||
75 75 | foo == 0.0 or foo == 0j # Different types, same hashed value
|
||||
|
||||
repeated_equality_comparison.py:75:1: PLR1714 [*] Consider merging multiple comparisons: `foo in (0.0, 0j)`. Use a `set` if the elements are hashable.
|
||||
repeated_equality_comparison.py:75:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {0.0, 0j}`.
|
||||
|
|
||||
73 | foo == False or foo == 0 # Different types, same hashed value
|
||||
74 |
|
||||
@@ -452,4 +452,4 @@ repeated_equality_comparison.py:75:1: PLR1714 [*] Consider merging multiple comp
|
||||
73 73 | foo == False or foo == 0 # Different types, same hashed value
|
||||
74 74 |
|
||||
75 |-foo == 0.0 or foo == 0j # Different types, same hashed value
|
||||
75 |+foo in (0.0, 0j) # Different types, same hashed value
|
||||
75 |+foo in {0.0, 0j} # Different types, same hashed value
|
||||
|
||||
@@ -26,3 +26,12 @@ bad_staticmethod_argument.py:19:15: PLW0211 First argument of a static method sh
|
||||
| ^^^^ PLW0211
|
||||
20 | pass
|
||||
|
|
||||
|
||||
bad_staticmethod_argument.py:55:17: PLW0211 First argument of a static method should not be named `self`
|
||||
|
|
||||
53 | # `self` but not with `cls` as first argument - see above).
|
||||
54 | class Foo:
|
||||
55 | def __new__(self, x, y, z): # [bad-staticmethod-argument]
|
||||
| ^^^^ PLW0211
|
||||
56 | pass
|
||||
|
|
||||
|
||||
@@ -50,3 +50,13 @@ invalid_envvar_default.py:14:17: PLW1508 Invalid type for environment variable d
|
||||
15 | os.environ.get("TEST", 12) # [invalid-envvar-default]
|
||||
16 | os.environ.get("TEST", "AA" * 12)
|
||||
|
|
||||
|
||||
invalid_envvar_default.py:15:24: PLW1508 Invalid type for environment variable default; expected `str` or `None`
|
||||
|
|
||||
13 | os.getenv("AA", "GOOD" if Z else "BAR")
|
||||
14 | os.getenv("AA", 1 if Z else "BAR") # [invalid-envvar-default]
|
||||
15 | os.environ.get("TEST", 12) # [invalid-envvar-default]
|
||||
| ^^ PLW1508
|
||||
16 | os.environ.get("TEST", "AA" * 12)
|
||||
17 | os.environ.get("TEST", 13 * "AA")
|
||||
|
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
||||
---
|
||||
bad_str_strip_call.py:2:21: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
1 | # PLE1310
|
||||
2 | "Hello World".strip("Hello")
|
||||
| ^^^^^^^ PLE1310
|
||||
3 |
|
||||
4 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:5:21: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
4 | # PLE1310
|
||||
5 | "Hello World".strip("Hello")
|
||||
| ^^^^^^^ PLE1310
|
||||
6 |
|
||||
7 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:8:21: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
7 | # PLE1310
|
||||
8 | "Hello World".strip(u"Hello")
|
||||
| ^^^^^^^^ PLE1310
|
||||
9 |
|
||||
10 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:11:21: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
10 | # PLE1310
|
||||
11 | "Hello World".strip(r"Hello")
|
||||
| ^^^^^^^^ PLE1310
|
||||
12 |
|
||||
13 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:14:21: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
13 | # PLE1310
|
||||
14 | "Hello World".strip("Hello\t")
|
||||
| ^^^^^^^^^ PLE1310
|
||||
15 |
|
||||
16 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:17:21: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
16 | # PLE1310
|
||||
17 | "Hello World".strip(r"Hello\t")
|
||||
| ^^^^^^^^^^ PLE1310
|
||||
18 |
|
||||
19 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:20:21: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
19 | # PLE1310
|
||||
20 | "Hello World".strip("Hello\\")
|
||||
| ^^^^^^^^^ PLE1310
|
||||
21 |
|
||||
22 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:23:21: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
22 | # PLE1310
|
||||
23 | "Hello World".strip(r"Hello\\")
|
||||
| ^^^^^^^^^^ PLE1310
|
||||
24 |
|
||||
25 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:26:21: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
25 | # PLE1310
|
||||
26 | "Hello World".strip("🤣🤣🤣🤣🙃👀😀")
|
||||
| ^^^^^^^^^^^^^^^^ PLE1310
|
||||
27 |
|
||||
28 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:30:5: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
28 | # PLE1310
|
||||
29 | "Hello World".strip(
|
||||
30 | / """
|
||||
31 | | there are a lot of characters to strip
|
||||
32 | | """
|
||||
| |___^ PLE1310
|
||||
33 | )
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:36:21: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
35 | # PLE1310
|
||||
36 | "Hello World".strip("can we get a long " \
|
||||
| _____________________^
|
||||
37 | | "string of characters to strip " \
|
||||
38 | | "please?")
|
||||
| |_____________________________^ PLE1310
|
||||
39 |
|
||||
40 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:42:5: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
40 | # PLE1310
|
||||
41 | "Hello World".strip(
|
||||
42 | / "can we get a long "
|
||||
43 | | "string of characters to strip "
|
||||
44 | | "please?"
|
||||
| |_____________^ PLE1310
|
||||
45 | )
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:49:5: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
47 | # PLE1310
|
||||
48 | "Hello World".strip(
|
||||
49 | / "can \t we get a long"
|
||||
50 | | "string \t of characters to strip"
|
||||
51 | | "please?"
|
||||
| |_____________^ PLE1310
|
||||
52 | )
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:61:11: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
60 | # PLE1310
|
||||
61 | u''.strip('http://')
|
||||
| ^^^^^^^^^ PLE1310
|
||||
62 |
|
||||
63 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:64:12: PLE1310 String `lstrip` call contains duplicate characters (did you mean `removeprefix`?)
|
||||
|
|
||||
63 | # PLE1310
|
||||
64 | u''.lstrip('http://')
|
||||
| ^^^^^^^^^ PLE1310
|
||||
65 |
|
||||
66 | # PLE1310
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:67:12: PLE1310 String `rstrip` call contains duplicate characters (did you mean `removesuffix`?)
|
||||
|
|
||||
66 | # PLE1310
|
||||
67 | b''.rstrip(b'http://')
|
||||
| ^^^^^^^^^^ PLE1310
|
||||
68 |
|
||||
69 | # OK
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:79:10: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
78 | # Errors: Multiple backslashes
|
||||
79 | ''.strip('\\b\\x09')
|
||||
| ^^^^^^^^^^ PLE1310
|
||||
80 | ''.strip(r'\b\x09')
|
||||
81 | ''.strip('\\\x5C')
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:80:10: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
78 | # Errors: Multiple backslashes
|
||||
79 | ''.strip('\\b\\x09')
|
||||
80 | ''.strip(r'\b\x09')
|
||||
| ^^^^^^^^^ PLE1310
|
||||
81 | ''.strip('\\\x5C')
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:81:10: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
79 | ''.strip('\\b\\x09')
|
||||
80 | ''.strip(r'\b\x09')
|
||||
81 | ''.strip('\\\x5C')
|
||||
| ^^^^^^^^ PLE1310
|
||||
82 |
|
||||
83 | # Errors: Type inference
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:85:9: PLE1310 String `strip` call contains duplicate characters
|
||||
|
|
||||
83 | # Errors: Type inference
|
||||
84 | b = b''
|
||||
85 | b.strip(b'//')
|
||||
| ^^^^^ PLE1310
|
||||
86 |
|
||||
87 | # Errors: Type inference (preview)
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:89:12: PLE1310 String `rstrip` call contains duplicate characters (did you mean `removesuffix`?)
|
||||
|
|
||||
87 | # Errors: Type inference (preview)
|
||||
88 | foo: str = ""; bar: bytes = b""
|
||||
89 | foo.rstrip("//")
|
||||
| ^^^^ PLE1310
|
||||
90 | bar.lstrip(b"//")
|
||||
|
|
||||
|
||||
bad_str_strip_call.py:90:12: PLE1310 String `lstrip` call contains duplicate characters (did you mean `removeprefix`?)
|
||||
|
|
||||
88 | foo: str = ""; bar: bytes = b""
|
||||
89 | foo.rstrip("//")
|
||||
90 | bar.lstrip(b"//")
|
||||
| ^^^^^ PLE1310
|
||||
|
|
||||
@@ -1,455 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
||||
---
|
||||
repeated_equality_comparison.py:2:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b"}`.
|
||||
|
|
||||
1 | # Errors.
|
||||
2 | foo == "a" or foo == "b"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
3 |
|
||||
4 | foo != "a" and foo != "b"
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
1 1 | # Errors.
|
||||
2 |-foo == "a" or foo == "b"
|
||||
2 |+foo in {"a", "b"}
|
||||
3 3 |
|
||||
4 4 | foo != "a" and foo != "b"
|
||||
5 5 |
|
||||
|
||||
repeated_equality_comparison.py:4:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in {"a", "b"}`.
|
||||
|
|
||||
2 | foo == "a" or foo == "b"
|
||||
3 |
|
||||
4 | foo != "a" and foo != "b"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
5 |
|
||||
6 | foo == "a" or foo == "b" or foo == "c"
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
1 1 | # Errors.
|
||||
2 2 | foo == "a" or foo == "b"
|
||||
3 3 |
|
||||
4 |-foo != "a" and foo != "b"
|
||||
4 |+foo not in {"a", "b"}
|
||||
5 5 |
|
||||
6 6 | foo == "a" or foo == "b" or foo == "c"
|
||||
7 7 |
|
||||
|
||||
repeated_equality_comparison.py:6:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b", "c"}`.
|
||||
|
|
||||
4 | foo != "a" and foo != "b"
|
||||
5 |
|
||||
6 | foo == "a" or foo == "b" or foo == "c"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
7 |
|
||||
8 | foo != "a" and foo != "b" and foo != "c"
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
3 3 |
|
||||
4 4 | foo != "a" and foo != "b"
|
||||
5 5 |
|
||||
6 |-foo == "a" or foo == "b" or foo == "c"
|
||||
6 |+foo in {"a", "b", "c"}
|
||||
7 7 |
|
||||
8 8 | foo != "a" and foo != "b" and foo != "c"
|
||||
9 9 |
|
||||
|
||||
repeated_equality_comparison.py:8:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in {"a", "b", "c"}`.
|
||||
|
|
||||
6 | foo == "a" or foo == "b" or foo == "c"
|
||||
7 |
|
||||
8 | foo != "a" and foo != "b" and foo != "c"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
9 |
|
||||
10 | foo == a or foo == "b" or foo == 3 # Mixed types.
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
5 5 |
|
||||
6 6 | foo == "a" or foo == "b" or foo == "c"
|
||||
7 7 |
|
||||
8 |-foo != "a" and foo != "b" and foo != "c"
|
||||
8 |+foo not in {"a", "b", "c"}
|
||||
9 9 |
|
||||
10 10 | foo == a or foo == "b" or foo == 3 # Mixed types.
|
||||
11 11 |
|
||||
|
||||
repeated_equality_comparison.py:10:1: PLR1714 [*] Consider merging multiple comparisons: `foo in (a, "b", 3)`. Use a `set` if the elements are hashable.
|
||||
|
|
||||
8 | foo != "a" and foo != "b" and foo != "c"
|
||||
9 |
|
||||
10 | foo == a or foo == "b" or foo == 3 # Mixed types.
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
11 |
|
||||
12 | "a" == foo or "b" == foo or "c" == foo
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
7 7 |
|
||||
8 8 | foo != "a" and foo != "b" and foo != "c"
|
||||
9 9 |
|
||||
10 |-foo == a or foo == "b" or foo == 3 # Mixed types.
|
||||
10 |+foo in (a, "b", 3) # Mixed types.
|
||||
11 11 |
|
||||
12 12 | "a" == foo or "b" == foo or "c" == foo
|
||||
13 13 |
|
||||
|
||||
repeated_equality_comparison.py:12:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b", "c"}`.
|
||||
|
|
||||
10 | foo == a or foo == "b" or foo == 3 # Mixed types.
|
||||
11 |
|
||||
12 | "a" == foo or "b" == foo or "c" == foo
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
13 |
|
||||
14 | "a" != foo and "b" != foo and "c" != foo
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
9 9 |
|
||||
10 10 | foo == a or foo == "b" or foo == 3 # Mixed types.
|
||||
11 11 |
|
||||
12 |-"a" == foo or "b" == foo or "c" == foo
|
||||
12 |+foo in {"a", "b", "c"}
|
||||
13 13 |
|
||||
14 14 | "a" != foo and "b" != foo and "c" != foo
|
||||
15 15 |
|
||||
|
||||
repeated_equality_comparison.py:14:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in {"a", "b", "c"}`.
|
||||
|
|
||||
12 | "a" == foo or "b" == foo or "c" == foo
|
||||
13 |
|
||||
14 | "a" != foo and "b" != foo and "c" != foo
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
15 |
|
||||
16 | "a" == foo or foo == "b" or "c" == foo
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
11 11 |
|
||||
12 12 | "a" == foo or "b" == foo or "c" == foo
|
||||
13 13 |
|
||||
14 |-"a" != foo and "b" != foo and "c" != foo
|
||||
14 |+foo not in {"a", "b", "c"}
|
||||
15 15 |
|
||||
16 16 | "a" == foo or foo == "b" or "c" == foo
|
||||
17 17 |
|
||||
|
||||
repeated_equality_comparison.py:16:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b", "c"}`.
|
||||
|
|
||||
14 | "a" != foo and "b" != foo and "c" != foo
|
||||
15 |
|
||||
16 | "a" == foo or foo == "b" or "c" == foo
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
17 |
|
||||
18 | foo == bar or baz == foo or qux == foo
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
13 13 |
|
||||
14 14 | "a" != foo and "b" != foo and "c" != foo
|
||||
15 15 |
|
||||
16 |-"a" == foo or foo == "b" or "c" == foo
|
||||
16 |+foo in {"a", "b", "c"}
|
||||
17 17 |
|
||||
18 18 | foo == bar or baz == foo or qux == foo
|
||||
19 19 |
|
||||
|
||||
repeated_equality_comparison.py:18:1: PLR1714 [*] Consider merging multiple comparisons: `foo in (bar, baz, qux)`. Use a `set` if the elements are hashable.
|
||||
|
|
||||
16 | "a" == foo or foo == "b" or "c" == foo
|
||||
17 |
|
||||
18 | foo == bar or baz == foo or qux == foo
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
19 |
|
||||
20 | foo == "a" or "b" == foo or foo == "c"
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
15 15 |
|
||||
16 16 | "a" == foo or foo == "b" or "c" == foo
|
||||
17 17 |
|
||||
18 |-foo == bar or baz == foo or qux == foo
|
||||
18 |+foo in (bar, baz, qux)
|
||||
19 19 |
|
||||
20 20 | foo == "a" or "b" == foo or foo == "c"
|
||||
21 21 |
|
||||
|
||||
repeated_equality_comparison.py:20:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b", "c"}`.
|
||||
|
|
||||
18 | foo == bar or baz == foo or qux == foo
|
||||
19 |
|
||||
20 | foo == "a" or "b" == foo or foo == "c"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
21 |
|
||||
22 | foo != "a" and "b" != foo and foo != "c"
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
17 17 |
|
||||
18 18 | foo == bar or baz == foo or qux == foo
|
||||
19 19 |
|
||||
20 |-foo == "a" or "b" == foo or foo == "c"
|
||||
20 |+foo in {"a", "b", "c"}
|
||||
21 21 |
|
||||
22 22 | foo != "a" and "b" != foo and foo != "c"
|
||||
23 23 |
|
||||
|
||||
repeated_equality_comparison.py:22:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in {"a", "b", "c"}`.
|
||||
|
|
||||
20 | foo == "a" or "b" == foo or foo == "c"
|
||||
21 |
|
||||
22 | foo != "a" and "b" != foo and foo != "c"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
23 |
|
||||
24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
19 19 |
|
||||
20 20 | foo == "a" or "b" == foo or foo == "c"
|
||||
21 21 |
|
||||
22 |-foo != "a" and "b" != foo and foo != "c"
|
||||
22 |+foo not in {"a", "b", "c"}
|
||||
23 23 |
|
||||
24 24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
25 25 |
|
||||
|
||||
repeated_equality_comparison.py:24:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b"}`.
|
||||
|
|
||||
22 | foo != "a" and "b" != foo and foo != "c"
|
||||
23 |
|
||||
24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
25 |
|
||||
26 | foo.bar == "a" or foo.bar == "b" # Attributes.
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
21 21 |
|
||||
22 22 | foo != "a" and "b" != foo and foo != "c"
|
||||
23 23 |
|
||||
24 |-foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
24 |+foo in {"a", "b"} or "c" == bar or "d" == bar # Multiple targets
|
||||
25 25 |
|
||||
26 26 | foo.bar == "a" or foo.bar == "b" # Attributes.
|
||||
27 27 |
|
||||
|
||||
repeated_equality_comparison.py:24:1: PLR1714 [*] Consider merging multiple comparisons: `bar in {"c", "d"}`.
|
||||
|
|
||||
22 | foo != "a" and "b" != foo and foo != "c"
|
||||
23 |
|
||||
24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
25 |
|
||||
26 | foo.bar == "a" or foo.bar == "b" # Attributes.
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
21 21 |
|
||||
22 22 | foo != "a" and "b" != foo and foo != "c"
|
||||
23 23 |
|
||||
24 |-foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
24 |+foo == "a" or foo == "b" or bar in {"c", "d"} # Multiple targets
|
||||
25 25 |
|
||||
26 26 | foo.bar == "a" or foo.bar == "b" # Attributes.
|
||||
27 27 |
|
||||
|
||||
repeated_equality_comparison.py:26:1: PLR1714 [*] Consider merging multiple comparisons: `foo.bar in {"a", "b"}`.
|
||||
|
|
||||
24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
25 |
|
||||
26 | foo.bar == "a" or foo.bar == "b" # Attributes.
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
27 |
|
||||
28 | # OK
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
23 23 |
|
||||
24 24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets
|
||||
25 25 |
|
||||
26 |-foo.bar == "a" or foo.bar == "b" # Attributes.
|
||||
26 |+foo.bar in {"a", "b"} # Attributes.
|
||||
27 27 |
|
||||
28 28 | # OK
|
||||
29 29 | foo == "a" and foo == "b" and foo == "c" # `and` mixed with `==`.
|
||||
|
||||
repeated_equality_comparison.py:61:16: PLR1714 [*] Consider merging multiple comparisons: `bar in {"c", "d"}`.
|
||||
|
|
||||
59 | foo == "a" or "c" == bar or foo == "b" or "d" == bar # Multiple targets
|
||||
60 |
|
||||
61 | foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
62 |
|
||||
63 | foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
58 58 |
|
||||
59 59 | foo == "a" or "c" == bar or foo == "b" or "d" == bar # Multiple targets
|
||||
60 60 |
|
||||
61 |-foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
61 |+foo == "a" or (bar in {"c", "d"}) or foo == "b" # Multiple targets
|
||||
62 62 |
|
||||
63 63 | foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
64 64 |
|
||||
|
||||
repeated_equality_comparison.py:63:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {"a", "b"}`.
|
||||
|
|
||||
61 | foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
62 |
|
||||
63 | foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
64 |
|
||||
65 | foo == "a" or ("c" != bar and "d" != bar) or foo == "b" # Multiple targets
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
60 60 |
|
||||
61 61 | foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
62 62 |
|
||||
63 |-foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
63 |+foo in {"a", "b"} or "c" != bar and "d" != bar # Multiple targets
|
||||
64 64 |
|
||||
65 65 | foo == "a" or ("c" != bar and "d" != bar) or foo == "b" # Multiple targets
|
||||
66 66 |
|
||||
|
||||
repeated_equality_comparison.py:63:29: PLR1714 [*] Consider merging multiple comparisons: `bar not in {"c", "d"}`.
|
||||
|
|
||||
61 | foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
62 |
|
||||
63 | foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
64 |
|
||||
65 | foo == "a" or ("c" != bar and "d" != bar) or foo == "b" # Multiple targets
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
60 60 |
|
||||
61 61 | foo == "a" or ("c" == bar or "d" == bar) or foo == "b" # Multiple targets
|
||||
62 62 |
|
||||
63 |-foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
63 |+foo == "a" or foo == "b" or bar not in {"c", "d"} # Multiple targets
|
||||
64 64 |
|
||||
65 65 | foo == "a" or ("c" != bar and "d" != bar) or foo == "b" # Multiple targets
|
||||
66 66 |
|
||||
|
||||
repeated_equality_comparison.py:65:16: PLR1714 [*] Consider merging multiple comparisons: `bar not in {"c", "d"}`.
|
||||
|
|
||||
63 | foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
64 |
|
||||
65 | foo == "a" or ("c" != bar and "d" != bar) or foo == "b" # Multiple targets
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
66 |
|
||||
67 | foo == "a" and "c" != bar or foo == "b" and "d" != bar # Multiple targets
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
62 62 |
|
||||
63 63 | foo == "a" or foo == "b" or "c" != bar and "d" != bar # Multiple targets
|
||||
64 64 |
|
||||
65 |-foo == "a" or ("c" != bar and "d" != bar) or foo == "b" # Multiple targets
|
||||
65 |+foo == "a" or (bar not in {"c", "d"}) or foo == "b" # Multiple targets
|
||||
66 66 |
|
||||
67 67 | foo == "a" and "c" != bar or foo == "b" and "d" != bar # Multiple targets
|
||||
68 68 |
|
||||
|
||||
repeated_equality_comparison.py:69:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {1, True}`.
|
||||
|
|
||||
67 | foo == "a" and "c" != bar or foo == "b" and "d" != bar # Multiple targets
|
||||
68 |
|
||||
69 | foo == 1 or foo == True # Different types, same hashed value
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
70 |
|
||||
71 | foo == 1 or foo == 1.0 # Different types, same hashed value
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
66 66 |
|
||||
67 67 | foo == "a" and "c" != bar or foo == "b" and "d" != bar # Multiple targets
|
||||
68 68 |
|
||||
69 |-foo == 1 or foo == True # Different types, same hashed value
|
||||
69 |+foo in {1, True} # Different types, same hashed value
|
||||
70 70 |
|
||||
71 71 | foo == 1 or foo == 1.0 # Different types, same hashed value
|
||||
72 72 |
|
||||
|
||||
repeated_equality_comparison.py:71:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {1, 1.0}`.
|
||||
|
|
||||
69 | foo == 1 or foo == True # Different types, same hashed value
|
||||
70 |
|
||||
71 | foo == 1 or foo == 1.0 # Different types, same hashed value
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
72 |
|
||||
73 | foo == False or foo == 0 # Different types, same hashed value
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
68 68 |
|
||||
69 69 | foo == 1 or foo == True # Different types, same hashed value
|
||||
70 70 |
|
||||
71 |-foo == 1 or foo == 1.0 # Different types, same hashed value
|
||||
71 |+foo in {1, 1.0} # Different types, same hashed value
|
||||
72 72 |
|
||||
73 73 | foo == False or foo == 0 # Different types, same hashed value
|
||||
74 74 |
|
||||
|
||||
repeated_equality_comparison.py:73:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {False, 0}`.
|
||||
|
|
||||
71 | foo == 1 or foo == 1.0 # Different types, same hashed value
|
||||
72 |
|
||||
73 | foo == False or foo == 0 # Different types, same hashed value
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
74 |
|
||||
75 | foo == 0.0 or foo == 0j # Different types, same hashed value
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
70 70 |
|
||||
71 71 | foo == 1 or foo == 1.0 # Different types, same hashed value
|
||||
72 72 |
|
||||
73 |-foo == False or foo == 0 # Different types, same hashed value
|
||||
73 |+foo in {False, 0} # Different types, same hashed value
|
||||
74 74 |
|
||||
75 75 | foo == 0.0 or foo == 0j # Different types, same hashed value
|
||||
|
||||
repeated_equality_comparison.py:75:1: PLR1714 [*] Consider merging multiple comparisons: `foo in {0.0, 0j}`.
|
||||
|
|
||||
73 | foo == False or foo == 0 # Different types, same hashed value
|
||||
74 |
|
||||
75 | foo == 0.0 or foo == 0j # Different types, same hashed value
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ PLR1714
|
||||
|
|
||||
= help: Merge multiple comparisons
|
||||
|
||||
ℹ Unsafe fix
|
||||
72 72 |
|
||||
73 73 | foo == False or foo == 0 # Different types, same hashed value
|
||||
74 74 |
|
||||
75 |-foo == 0.0 or foo == 0j # Different types, same hashed value
|
||||
75 |+foo in {0.0, 0j} # Different types, same hashed value
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
||||
---
|
||||
bad_staticmethod_argument.py:3:13: PLW0211 First argument of a static method should not be named `self`
|
||||
|
|
||||
1 | class Wolf:
|
||||
2 | @staticmethod
|
||||
3 | def eat(self): # [bad-staticmethod-argument]
|
||||
| ^^^^ PLW0211
|
||||
4 | pass
|
||||
|
|
||||
|
||||
bad_staticmethod_argument.py:15:13: PLW0211 First argument of a static method should not be named `cls`
|
||||
|
|
||||
13 | class Sheep:
|
||||
14 | @staticmethod
|
||||
15 | def eat(cls, x, y, z): # [bad-staticmethod-argument]
|
||||
| ^^^ PLW0211
|
||||
16 | pass
|
||||
|
|
||||
|
||||
bad_staticmethod_argument.py:19:15: PLW0211 First argument of a static method should not be named `self`
|
||||
|
|
||||
18 | @staticmethod
|
||||
19 | def sleep(self, x, y, z): # [bad-staticmethod-argument]
|
||||
| ^^^^ PLW0211
|
||||
20 | pass
|
||||
|
|
||||
|
||||
bad_staticmethod_argument.py:55:17: PLW0211 First argument of a static method should not be named `self`
|
||||
|
|
||||
53 | # `self` but not with `cls` as first argument - see above).
|
||||
54 | class Foo:
|
||||
55 | def __new__(self, x, y, z): # [bad-staticmethod-argument]
|
||||
| ^^^^ PLW0211
|
||||
56 | pass
|
||||
|
|
||||
@@ -1,62 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
||||
---
|
||||
invalid_envvar_default.py:3:29: PLW1508 Invalid type for environment variable default; expected `str` or `None`
|
||||
|
|
||||
1 | import os
|
||||
2 |
|
||||
3 | tempVar = os.getenv("TEST", 12) # [invalid-envvar-default]
|
||||
| ^^ PLW1508
|
||||
4 | goodVar = os.getenv("TESTING", None)
|
||||
5 | dictVarBad = os.getenv("AAA", {"a", 7}) # [invalid-envvar-default]
|
||||
|
|
||||
|
||||
invalid_envvar_default.py:5:31: PLW1508 Invalid type for environment variable default; expected `str` or `None`
|
||||
|
|
||||
3 | tempVar = os.getenv("TEST", 12) # [invalid-envvar-default]
|
||||
4 | goodVar = os.getenv("TESTING", None)
|
||||
5 | dictVarBad = os.getenv("AAA", {"a", 7}) # [invalid-envvar-default]
|
||||
| ^^^^^^^^ PLW1508
|
||||
6 | print(os.getenv("TEST", False)) # [invalid-envvar-default]
|
||||
7 | os.getenv("AA", "GOOD")
|
||||
|
|
||||
|
||||
invalid_envvar_default.py:6:25: PLW1508 Invalid type for environment variable default; expected `str` or `None`
|
||||
|
|
||||
4 | goodVar = os.getenv("TESTING", None)
|
||||
5 | dictVarBad = os.getenv("AAA", {"a", 7}) # [invalid-envvar-default]
|
||||
6 | print(os.getenv("TEST", False)) # [invalid-envvar-default]
|
||||
| ^^^^^ PLW1508
|
||||
7 | os.getenv("AA", "GOOD")
|
||||
8 | os.getenv("AA", f"GOOD")
|
||||
|
|
||||
|
||||
invalid_envvar_default.py:10:17: PLW1508 Invalid type for environment variable default; expected `str` or `None`
|
||||
|
|
||||
8 | os.getenv("AA", f"GOOD")
|
||||
9 | os.getenv("AA", "GOOD" + "BAR")
|
||||
10 | os.getenv("AA", "GOOD" + 1)
|
||||
| ^^^^^^^^^^ PLW1508
|
||||
11 | os.getenv("AA", "GOOD %s" % "BAR")
|
||||
12 | os.getenv("B", Z)
|
||||
|
|
||||
|
||||
invalid_envvar_default.py:14:17: PLW1508 Invalid type for environment variable default; expected `str` or `None`
|
||||
|
|
||||
12 | os.getenv("B", Z)
|
||||
13 | os.getenv("AA", "GOOD" if Z else "BAR")
|
||||
14 | os.getenv("AA", 1 if Z else "BAR") # [invalid-envvar-default]
|
||||
| ^^^^^^^^^^^^^^^^^ PLW1508
|
||||
15 | os.environ.get("TEST", 12) # [invalid-envvar-default]
|
||||
16 | os.environ.get("TEST", "AA" * 12)
|
||||
|
|
||||
|
||||
invalid_envvar_default.py:15:24: PLW1508 Invalid type for environment variable default; expected `str` or `None`
|
||||
|
|
||||
13 | os.getenv("AA", "GOOD" if Z else "BAR")
|
||||
14 | os.getenv("AA", 1 if Z else "BAR") # [invalid-envvar-default]
|
||||
15 | os.environ.get("TEST", 12) # [invalid-envvar-default]
|
||||
| ^^ PLW1508
|
||||
16 | os.environ.get("TEST", "AA" * 12)
|
||||
17 | os.environ.get("TEST", 13 * "AA")
|
||||
|
|
||||
@@ -119,25 +119,6 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::RedundantOpenModes, Path::new("UP015.py"))]
|
||||
#[test_case(Rule::RedundantOpenModes, Path::new("UP015_1.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview__{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("pyupgrade").join(path).as_path(),
|
||||
&settings::LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn up007_preview() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
@@ -285,7 +266,6 @@ mod tests {
|
||||
let diagnostics = test_path(
|
||||
Path::new("pyupgrade/UP044.py"),
|
||||
&settings::LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
unresolved_target_version: PythonVersion::PY311,
|
||||
..settings::LinterSettings::for_rule(Rule::NonPEP646Unpack)
|
||||
},
|
||||
|
||||
@@ -11,6 +11,7 @@ pub(crate) use format_literals::*;
|
||||
pub(crate) use lru_cache_with_maxsize_none::*;
|
||||
pub(crate) use lru_cache_without_parameters::*;
|
||||
pub(crate) use native_literals::*;
|
||||
pub(crate) use non_pep646_unpack::*;
|
||||
pub(crate) use open_alias::*;
|
||||
pub(crate) use os_error_alias::*;
|
||||
pub(crate) use outdated_version_block::*;
|
||||
@@ -36,7 +37,6 @@ pub(crate) use unpacked_list_comprehension::*;
|
||||
pub(crate) use use_pep585_annotation::*;
|
||||
pub(crate) use use_pep604_annotation::*;
|
||||
pub(crate) use use_pep604_isinstance::*;
|
||||
pub(crate) use use_pep646_unpack::*;
|
||||
pub(crate) use useless_metaclass_type::*;
|
||||
pub(crate) use useless_object_inheritance::*;
|
||||
pub(crate) use yield_in_for_loop::*;
|
||||
@@ -54,6 +54,7 @@ mod format_literals;
|
||||
mod lru_cache_with_maxsize_none;
|
||||
mod lru_cache_without_parameters;
|
||||
mod native_literals;
|
||||
mod non_pep646_unpack;
|
||||
mod open_alias;
|
||||
mod os_error_alias;
|
||||
mod outdated_version_block;
|
||||
@@ -79,7 +80,6 @@ mod unpacked_list_comprehension;
|
||||
mod use_pep585_annotation;
|
||||
mod use_pep604_annotation;
|
||||
mod use_pep604_isinstance;
|
||||
mod use_pep646_unpack;
|
||||
mod useless_metaclass_type;
|
||||
mod useless_object_inheritance;
|
||||
mod yield_in_for_loop;
|
||||
|
||||
@@ -91,17 +91,11 @@ fn create_diagnostic(
|
||||
mode: OpenMode,
|
||||
checker: &Checker,
|
||||
) -> Diagnostic {
|
||||
let range = if checker.settings.preview.is_enabled() {
|
||||
mode_arg.range()
|
||||
} else {
|
||||
call.range
|
||||
};
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
RedundantOpenModes {
|
||||
replacement: mode.to_string(),
|
||||
},
|
||||
range,
|
||||
mode_arg.range(),
|
||||
);
|
||||
|
||||
if mode.is_empty() {
|
||||
|
||||
@@ -33,6 +33,12 @@ impl CallKind {
|
||||
}
|
||||
}
|
||||
|
||||
/// ## Deprecation
|
||||
/// This rule was deprecated as using [PEP 604] syntax in `isinstance` and `issubclass` calls
|
||||
/// isn't recommended practice, and it incorrectly suggests that other typing syntaxes like [PEP 695]
|
||||
/// would be supported by `isinstance` and `issubclass`. Using the [PEP 604] syntax
|
||||
/// is also slightly slower.
|
||||
///
|
||||
/// ## What it does
|
||||
/// Checks for uses of `isinstance` and `issubclass` that take a tuple
|
||||
/// of types for comparison.
|
||||
@@ -64,6 +70,7 @@ impl CallKind {
|
||||
/// - [Python documentation: `issubclass`](https://docs.python.org/3/library/functions.html#issubclass)
|
||||
///
|
||||
/// [PEP 604]: https://peps.python.org/pep-0604/
|
||||
/// [PEP 695]: https://peps.python.org/pep-0695/
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct NonPEP604Isinstance {
|
||||
kind: CallKind,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pyupgrade/mod.rs
|
||||
---
|
||||
UP015.py:1:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:1:13: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
1 | open("foo", "U")
|
||||
| ^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
2 | open("foo", "Ur")
|
||||
3 | open("foo", "Ub")
|
||||
|
|
||||
@@ -17,11 +17,11 @@ UP015.py:1:1: UP015 [*] Unnecessary mode argument
|
||||
3 3 | open("foo", "Ub")
|
||||
4 4 | open("foo", "rUb")
|
||||
|
||||
UP015.py:2:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:2:13: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
1 | open("foo", "U")
|
||||
2 | open("foo", "Ur")
|
||||
| ^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
3 | open("foo", "Ub")
|
||||
4 | open("foo", "rUb")
|
||||
|
|
||||
@@ -35,12 +35,12 @@ UP015.py:2:1: UP015 [*] Unnecessary mode argument
|
||||
4 4 | open("foo", "rUb")
|
||||
5 5 | open("foo", "r")
|
||||
|
||||
UP015.py:3:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:3:13: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
1 | open("foo", "U")
|
||||
2 | open("foo", "Ur")
|
||||
3 | open("foo", "Ub")
|
||||
| ^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
4 | open("foo", "rUb")
|
||||
5 | open("foo", "r")
|
||||
|
|
||||
@@ -55,12 +55,12 @@ UP015.py:3:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
5 5 | open("foo", "r")
|
||||
6 6 | open("foo", "rt")
|
||||
|
||||
UP015.py:4:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:4:13: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
2 | open("foo", "Ur")
|
||||
3 | open("foo", "Ub")
|
||||
4 | open("foo", "rUb")
|
||||
| ^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^^ UP015
|
||||
5 | open("foo", "r")
|
||||
6 | open("foo", "rt")
|
||||
|
|
||||
@@ -76,12 +76,12 @@ UP015.py:4:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
6 6 | open("foo", "rt")
|
||||
7 7 | open("f", "r", encoding="UTF-8")
|
||||
|
||||
UP015.py:5:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:5:13: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
3 | open("foo", "Ub")
|
||||
4 | open("foo", "rUb")
|
||||
5 | open("foo", "r")
|
||||
| ^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
6 | open("foo", "rt")
|
||||
7 | open("f", "r", encoding="UTF-8")
|
||||
|
|
||||
@@ -97,12 +97,12 @@ UP015.py:5:1: UP015 [*] Unnecessary mode argument
|
||||
7 7 | open("f", "r", encoding="UTF-8")
|
||||
8 8 | open("f", "wt")
|
||||
|
||||
UP015.py:6:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:6:13: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
4 | open("foo", "rUb")
|
||||
5 | open("foo", "r")
|
||||
6 | open("foo", "rt")
|
||||
| ^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
7 | open("f", "r", encoding="UTF-8")
|
||||
8 | open("f", "wt")
|
||||
|
|
||||
@@ -118,12 +118,12 @@ UP015.py:6:1: UP015 [*] Unnecessary mode argument
|
||||
8 8 | open("f", "wt")
|
||||
9 9 | open("f", "tw")
|
||||
|
||||
UP015.py:7:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:7:11: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
5 | open("foo", "r")
|
||||
6 | open("foo", "rt")
|
||||
7 | open("f", "r", encoding="UTF-8")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
8 | open("f", "wt")
|
||||
9 | open("f", "tw")
|
||||
|
|
||||
@@ -139,12 +139,12 @@ UP015.py:7:1: UP015 [*] Unnecessary mode argument
|
||||
9 9 | open("f", "tw")
|
||||
10 10 |
|
||||
|
||||
UP015.py:8:1: UP015 [*] Unnecessary modes, use `w`
|
||||
UP015.py:8:11: UP015 [*] Unnecessary modes, use `w`
|
||||
|
|
||||
6 | open("foo", "rt")
|
||||
7 | open("f", "r", encoding="UTF-8")
|
||||
8 | open("f", "wt")
|
||||
| ^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
9 | open("f", "tw")
|
||||
|
|
||||
= help: Replace with `w`
|
||||
@@ -159,12 +159,12 @@ UP015.py:8:1: UP015 [*] Unnecessary modes, use `w`
|
||||
10 10 |
|
||||
11 11 | with open("foo", "U") as f:
|
||||
|
||||
UP015.py:9:1: UP015 [*] Unnecessary modes, use `w`
|
||||
UP015.py:9:11: UP015 [*] Unnecessary modes, use `w`
|
||||
|
|
||||
7 | open("f", "r", encoding="UTF-8")
|
||||
8 | open("f", "wt")
|
||||
9 | open("f", "tw")
|
||||
| ^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
10 |
|
||||
11 | with open("foo", "U") as f:
|
||||
|
|
||||
@@ -180,12 +180,12 @@ UP015.py:9:1: UP015 [*] Unnecessary modes, use `w`
|
||||
11 11 | with open("foo", "U") as f:
|
||||
12 12 | pass
|
||||
|
||||
UP015.py:11:6: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:11:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
9 | open("f", "tw")
|
||||
10 |
|
||||
11 | with open("foo", "U") as f:
|
||||
| ^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
12 | pass
|
||||
13 | with open("foo", "Ur") as f:
|
||||
|
|
||||
@@ -201,12 +201,12 @@ UP015.py:11:6: UP015 [*] Unnecessary mode argument
|
||||
13 13 | with open("foo", "Ur") as f:
|
||||
14 14 | pass
|
||||
|
||||
UP015.py:13:6: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:13:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
11 | with open("foo", "U") as f:
|
||||
12 | pass
|
||||
13 | with open("foo", "Ur") as f:
|
||||
| ^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
14 | pass
|
||||
15 | with open("foo", "Ub") as f:
|
||||
|
|
||||
@@ -222,12 +222,12 @@ UP015.py:13:6: UP015 [*] Unnecessary mode argument
|
||||
15 15 | with open("foo", "Ub") as f:
|
||||
16 16 | pass
|
||||
|
||||
UP015.py:15:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:15:18: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
13 | with open("foo", "Ur") as f:
|
||||
14 | pass
|
||||
15 | with open("foo", "Ub") as f:
|
||||
| ^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
16 | pass
|
||||
17 | with open("foo", "rUb") as f:
|
||||
|
|
||||
@@ -243,12 +243,12 @@ UP015.py:15:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
17 17 | with open("foo", "rUb") as f:
|
||||
18 18 | pass
|
||||
|
||||
UP015.py:17:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:17:18: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
15 | with open("foo", "Ub") as f:
|
||||
16 | pass
|
||||
17 | with open("foo", "rUb") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^^ UP015
|
||||
18 | pass
|
||||
19 | with open("foo", "r") as f:
|
||||
|
|
||||
@@ -264,12 +264,12 @@ UP015.py:17:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
19 19 | with open("foo", "r") as f:
|
||||
20 20 | pass
|
||||
|
||||
UP015.py:19:6: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:19:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
17 | with open("foo", "rUb") as f:
|
||||
18 | pass
|
||||
19 | with open("foo", "r") as f:
|
||||
| ^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
20 | pass
|
||||
21 | with open("foo", "rt") as f:
|
||||
|
|
||||
@@ -285,12 +285,12 @@ UP015.py:19:6: UP015 [*] Unnecessary mode argument
|
||||
21 21 | with open("foo", "rt") as f:
|
||||
22 22 | pass
|
||||
|
||||
UP015.py:21:6: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:21:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
19 | with open("foo", "r") as f:
|
||||
20 | pass
|
||||
21 | with open("foo", "rt") as f:
|
||||
| ^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
22 | pass
|
||||
23 | with open("foo", "r", encoding="UTF-8") as f:
|
||||
|
|
||||
@@ -306,12 +306,12 @@ UP015.py:21:6: UP015 [*] Unnecessary mode argument
|
||||
23 23 | with open("foo", "r", encoding="UTF-8") as f:
|
||||
24 24 | pass
|
||||
|
||||
UP015.py:23:6: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:23:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
21 | with open("foo", "rt") as f:
|
||||
22 | pass
|
||||
23 | with open("foo", "r", encoding="UTF-8") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
24 | pass
|
||||
25 | with open("foo", "wt") as f:
|
||||
|
|
||||
@@ -327,12 +327,12 @@ UP015.py:23:6: UP015 [*] Unnecessary mode argument
|
||||
25 25 | with open("foo", "wt") as f:
|
||||
26 26 | pass
|
||||
|
||||
UP015.py:25:6: UP015 [*] Unnecessary modes, use `w`
|
||||
UP015.py:25:18: UP015 [*] Unnecessary modes, use `w`
|
||||
|
|
||||
23 | with open("foo", "r", encoding="UTF-8") as f:
|
||||
24 | pass
|
||||
25 | with open("foo", "wt") as f:
|
||||
| ^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
26 | pass
|
||||
|
|
||||
= help: Replace with `w`
|
||||
@@ -347,12 +347,12 @@ UP015.py:25:6: UP015 [*] Unnecessary modes, use `w`
|
||||
27 27 |
|
||||
28 28 | open(f("a", "b", "c"), "U")
|
||||
|
||||
UP015.py:28:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:28:24: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
26 | pass
|
||||
27 |
|
||||
28 | open(f("a", "b", "c"), "U")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
29 | open(f("a", "b", "c"), "Ub")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
@@ -367,11 +367,11 @@ UP015.py:28:1: UP015 [*] Unnecessary mode argument
|
||||
30 30 |
|
||||
31 31 | with open(f("a", "b", "c"), "U") as f:
|
||||
|
||||
UP015.py:29:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:29:24: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
28 | open(f("a", "b", "c"), "U")
|
||||
29 | open(f("a", "b", "c"), "Ub")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
30 |
|
||||
31 | with open(f("a", "b", "c"), "U") as f:
|
||||
|
|
||||
@@ -387,12 +387,12 @@ UP015.py:29:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
31 31 | with open(f("a", "b", "c"), "U") as f:
|
||||
32 32 | pass
|
||||
|
||||
UP015.py:31:6: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:31:29: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
29 | open(f("a", "b", "c"), "Ub")
|
||||
30 |
|
||||
31 | with open(f("a", "b", "c"), "U") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
32 | pass
|
||||
33 | with open(f("a", "b", "c"), "Ub") as f:
|
||||
|
|
||||
@@ -408,12 +408,12 @@ UP015.py:31:6: UP015 [*] Unnecessary mode argument
|
||||
33 33 | with open(f("a", "b", "c"), "Ub") as f:
|
||||
34 34 | pass
|
||||
|
||||
UP015.py:33:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:33:29: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
31 | with open(f("a", "b", "c"), "U") as f:
|
||||
32 | pass
|
||||
33 | with open(f("a", "b", "c"), "Ub") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
34 | pass
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
@@ -428,12 +428,12 @@ UP015.py:33:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
35 35 |
|
||||
36 36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
|
||||
UP015.py:36:6: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:36:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
34 | pass
|
||||
35 |
|
||||
36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
| ^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
37 | pass
|
||||
38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
|
|
||||
@@ -449,12 +449,12 @@ UP015.py:36:6: UP015 [*] Unnecessary mode argument
|
||||
38 38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
39 39 | pass
|
||||
|
||||
UP015.py:36:30: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:36:42: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
34 | pass
|
||||
35 |
|
||||
36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
| ^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
37 | pass
|
||||
38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
|
|
||||
@@ -470,12 +470,12 @@ UP015.py:36:30: UP015 [*] Unnecessary mode argument
|
||||
38 38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
39 39 | pass
|
||||
|
||||
UP015.py:38:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:38:18: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
37 | pass
|
||||
38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
| ^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
39 | pass
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
@@ -490,12 +490,12 @@ UP015.py:38:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
40 40 |
|
||||
41 41 | open("foo", mode="U")
|
||||
|
||||
UP015.py:38:31: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:38:43: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
37 | pass
|
||||
38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
| ^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
39 | pass
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
@@ -510,12 +510,12 @@ UP015.py:38:31: UP015 [*] Unnecessary modes, use `rb`
|
||||
40 40 |
|
||||
41 41 | open("foo", mode="U")
|
||||
|
||||
UP015.py:41:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:41:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
39 | pass
|
||||
40 |
|
||||
41 | open("foo", mode="U")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
42 | open(name="foo", mode="U")
|
||||
43 | open(mode="U", name="foo")
|
||||
|
|
||||
@@ -531,11 +531,11 @@ UP015.py:41:1: UP015 [*] Unnecessary mode argument
|
||||
43 43 | open(mode="U", name="foo")
|
||||
44 44 |
|
||||
|
||||
UP015.py:42:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:42:23: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
41 | open("foo", mode="U")
|
||||
42 | open(name="foo", mode="U")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
43 | open(mode="U", name="foo")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
@@ -550,12 +550,12 @@ UP015.py:42:1: UP015 [*] Unnecessary mode argument
|
||||
44 44 |
|
||||
45 45 | with open("foo", mode="U") as f:
|
||||
|
||||
UP015.py:43:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:43:11: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
41 | open("foo", mode="U")
|
||||
42 | open(name="foo", mode="U")
|
||||
43 | open(mode="U", name="foo")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
44 |
|
||||
45 | with open("foo", mode="U") as f:
|
||||
|
|
||||
@@ -571,12 +571,12 @@ UP015.py:43:1: UP015 [*] Unnecessary mode argument
|
||||
45 45 | with open("foo", mode="U") as f:
|
||||
46 46 | pass
|
||||
|
||||
UP015.py:45:6: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:45:23: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
43 | open(mode="U", name="foo")
|
||||
44 |
|
||||
45 | with open("foo", mode="U") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
46 | pass
|
||||
47 | with open(name="foo", mode="U") as f:
|
||||
|
|
||||
@@ -592,12 +592,12 @@ UP015.py:45:6: UP015 [*] Unnecessary mode argument
|
||||
47 47 | with open(name="foo", mode="U") as f:
|
||||
48 48 | pass
|
||||
|
||||
UP015.py:47:6: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:47:28: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
45 | with open("foo", mode="U") as f:
|
||||
46 | pass
|
||||
47 | with open(name="foo", mode="U") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
48 | pass
|
||||
49 | with open(mode="U", name="foo") as f:
|
||||
|
|
||||
@@ -613,12 +613,12 @@ UP015.py:47:6: UP015 [*] Unnecessary mode argument
|
||||
49 49 | with open(mode="U", name="foo") as f:
|
||||
50 50 | pass
|
||||
|
||||
UP015.py:49:6: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:49:16: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
47 | with open(name="foo", mode="U") as f:
|
||||
48 | pass
|
||||
49 | with open(mode="U", name="foo") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
50 | pass
|
||||
|
|
||||
= help: Remove mode argument
|
||||
@@ -633,12 +633,12 @@ UP015.py:49:6: UP015 [*] Unnecessary mode argument
|
||||
51 51 |
|
||||
52 52 | open("foo", mode="Ub")
|
||||
|
||||
UP015.py:52:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:52:18: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
50 | pass
|
||||
51 |
|
||||
52 | open("foo", mode="Ub")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
53 | open(name="foo", mode="Ub")
|
||||
54 | open(mode="Ub", name="foo")
|
||||
|
|
||||
@@ -654,11 +654,11 @@ UP015.py:52:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
54 54 | open(mode="Ub", name="foo")
|
||||
55 55 |
|
||||
|
||||
UP015.py:53:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:53:23: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
52 | open("foo", mode="Ub")
|
||||
53 | open(name="foo", mode="Ub")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
54 | open(mode="Ub", name="foo")
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
@@ -673,12 +673,12 @@ UP015.py:53:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
55 55 |
|
||||
56 56 | with open("foo", mode="Ub") as f:
|
||||
|
||||
UP015.py:54:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:54:11: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
52 | open("foo", mode="Ub")
|
||||
53 | open(name="foo", mode="Ub")
|
||||
54 | open(mode="Ub", name="foo")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
55 |
|
||||
56 | with open("foo", mode="Ub") as f:
|
||||
|
|
||||
@@ -694,12 +694,12 @@ UP015.py:54:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
56 56 | with open("foo", mode="Ub") as f:
|
||||
57 57 | pass
|
||||
|
||||
UP015.py:56:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:56:23: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
54 | open(mode="Ub", name="foo")
|
||||
55 |
|
||||
56 | with open("foo", mode="Ub") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
57 | pass
|
||||
58 | with open(name="foo", mode="Ub") as f:
|
||||
|
|
||||
@@ -715,12 +715,12 @@ UP015.py:56:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
58 58 | with open(name="foo", mode="Ub") as f:
|
||||
59 59 | pass
|
||||
|
||||
UP015.py:58:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:58:28: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
56 | with open("foo", mode="Ub") as f:
|
||||
57 | pass
|
||||
58 | with open(name="foo", mode="Ub") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
59 | pass
|
||||
60 | with open(mode="Ub", name="foo") as f:
|
||||
|
|
||||
@@ -736,12 +736,12 @@ UP015.py:58:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
60 60 | with open(mode="Ub", name="foo") as f:
|
||||
61 61 | pass
|
||||
|
||||
UP015.py:60:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:60:16: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
58 | with open(name="foo", mode="Ub") as f:
|
||||
59 | pass
|
||||
60 | with open(mode="Ub", name="foo") as f:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
61 | pass
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
@@ -756,12 +756,12 @@ UP015.py:60:6: UP015 [*] Unnecessary modes, use `rb`
|
||||
62 62 |
|
||||
63 63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
||||
UP015.py:63:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:63:23: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
61 | pass
|
||||
62 |
|
||||
63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
|
|
||||
@@ -777,11 +777,11 @@ UP015.py:63:1: UP015 [*] Unnecessary mode argument
|
||||
65 65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
66 66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
||||
UP015.py:64:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:64:106: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
|
||||
@@ -797,12 +797,12 @@ UP015.py:64:1: UP015 [*] Unnecessary mode argument
|
||||
66 66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
67 67 |
|
||||
|
||||
UP015.py:65:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:65:65: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
|
||||
= help: Remove mode argument
|
||||
@@ -817,12 +817,12 @@ UP015.py:65:1: UP015 [*] Unnecessary mode argument
|
||||
67 67 |
|
||||
68 68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
||||
UP015.py:66:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:66:11: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
67 |
|
||||
68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
|
||||
@@ -838,12 +838,12 @@ UP015.py:66:1: UP015 [*] Unnecessary mode argument
|
||||
68 68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
|
||||
UP015.py:68:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:68:23: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
67 |
|
||||
68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
|
|
||||
@@ -859,11 +859,11 @@ UP015.py:68:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
70 70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
71 71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
||||
UP015.py:69:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:69:106: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
|
||||
@@ -879,12 +879,12 @@ UP015.py:69:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
71 71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
72 72 |
|
||||
|
||||
UP015.py:70:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:70:65: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
@@ -899,12 +899,12 @@ UP015.py:70:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
72 72 |
|
||||
73 73 | import aiofiles
|
||||
|
||||
UP015.py:71:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
UP015.py:71:11: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^^ UP015
|
||||
72 |
|
||||
73 | import aiofiles
|
||||
|
|
||||
@@ -920,12 +920,12 @@ UP015.py:71:1: UP015 [*] Unnecessary modes, use `rb`
|
||||
73 73 | import aiofiles
|
||||
74 74 |
|
||||
|
||||
UP015.py:75:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:75:22: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
73 | import aiofiles
|
||||
74 |
|
||||
75 | aiofiles.open("foo", "U")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
76 | aiofiles.open("foo", "r")
|
||||
77 | aiofiles.open("foo", mode="r")
|
||||
|
|
||||
@@ -941,11 +941,11 @@ UP015.py:75:1: UP015 [*] Unnecessary mode argument
|
||||
77 77 | aiofiles.open("foo", mode="r")
|
||||
78 78 |
|
||||
|
||||
UP015.py:76:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:76:22: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
75 | aiofiles.open("foo", "U")
|
||||
76 | aiofiles.open("foo", "r")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
77 | aiofiles.open("foo", mode="r")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
@@ -960,12 +960,12 @@ UP015.py:76:1: UP015 [*] Unnecessary mode argument
|
||||
78 78 |
|
||||
79 79 | open("foo", "r+")
|
||||
|
||||
UP015.py:77:1: UP015 [*] Unnecessary mode argument
|
||||
UP015.py:77:27: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
75 | aiofiles.open("foo", "U")
|
||||
76 | aiofiles.open("foo", "r")
|
||||
77 | aiofiles.open("foo", mode="r")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
78 |
|
||||
79 | open("foo", "r+")
|
||||
|
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pyupgrade/mod.rs
|
||||
---
|
||||
UP015_1.py:3:5: UP015 [*] Unnecessary mode argument
|
||||
UP015_1.py:3:17: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
1 | # Not a valid type annotation but this test shouldn't result in a panic.
|
||||
2 | # Refer: https://github.com/astral-sh/ruff/issues/11736
|
||||
3 | x: 'open("foo", "r")'
|
||||
| ^^^^^^^^^^^^^^^^ UP015
|
||||
| ^^^ UP015
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
|
||||
@@ -1,982 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pyupgrade/mod.rs
|
||||
---
|
||||
UP015.py:1:13: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
1 | open("foo", "U")
|
||||
| ^^^ UP015
|
||||
2 | open("foo", "Ur")
|
||||
3 | open("foo", "Ub")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
1 |-open("foo", "U")
|
||||
1 |+open("foo")
|
||||
2 2 | open("foo", "Ur")
|
||||
3 3 | open("foo", "Ub")
|
||||
4 4 | open("foo", "rUb")
|
||||
|
||||
UP015.py:2:13: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
1 | open("foo", "U")
|
||||
2 | open("foo", "Ur")
|
||||
| ^^^^ UP015
|
||||
3 | open("foo", "Ub")
|
||||
4 | open("foo", "rUb")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
1 1 | open("foo", "U")
|
||||
2 |-open("foo", "Ur")
|
||||
2 |+open("foo")
|
||||
3 3 | open("foo", "Ub")
|
||||
4 4 | open("foo", "rUb")
|
||||
5 5 | open("foo", "r")
|
||||
|
||||
UP015.py:3:13: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
1 | open("foo", "U")
|
||||
2 | open("foo", "Ur")
|
||||
3 | open("foo", "Ub")
|
||||
| ^^^^ UP015
|
||||
4 | open("foo", "rUb")
|
||||
5 | open("foo", "r")
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
1 1 | open("foo", "U")
|
||||
2 2 | open("foo", "Ur")
|
||||
3 |-open("foo", "Ub")
|
||||
3 |+open("foo", "rb")
|
||||
4 4 | open("foo", "rUb")
|
||||
5 5 | open("foo", "r")
|
||||
6 6 | open("foo", "rt")
|
||||
|
||||
UP015.py:4:13: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
2 | open("foo", "Ur")
|
||||
3 | open("foo", "Ub")
|
||||
4 | open("foo", "rUb")
|
||||
| ^^^^^ UP015
|
||||
5 | open("foo", "r")
|
||||
6 | open("foo", "rt")
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
1 1 | open("foo", "U")
|
||||
2 2 | open("foo", "Ur")
|
||||
3 3 | open("foo", "Ub")
|
||||
4 |-open("foo", "rUb")
|
||||
4 |+open("foo", "rb")
|
||||
5 5 | open("foo", "r")
|
||||
6 6 | open("foo", "rt")
|
||||
7 7 | open("f", "r", encoding="UTF-8")
|
||||
|
||||
UP015.py:5:13: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
3 | open("foo", "Ub")
|
||||
4 | open("foo", "rUb")
|
||||
5 | open("foo", "r")
|
||||
| ^^^ UP015
|
||||
6 | open("foo", "rt")
|
||||
7 | open("f", "r", encoding="UTF-8")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
2 2 | open("foo", "Ur")
|
||||
3 3 | open("foo", "Ub")
|
||||
4 4 | open("foo", "rUb")
|
||||
5 |-open("foo", "r")
|
||||
5 |+open("foo")
|
||||
6 6 | open("foo", "rt")
|
||||
7 7 | open("f", "r", encoding="UTF-8")
|
||||
8 8 | open("f", "wt")
|
||||
|
||||
UP015.py:6:13: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
4 | open("foo", "rUb")
|
||||
5 | open("foo", "r")
|
||||
6 | open("foo", "rt")
|
||||
| ^^^^ UP015
|
||||
7 | open("f", "r", encoding="UTF-8")
|
||||
8 | open("f", "wt")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
3 3 | open("foo", "Ub")
|
||||
4 4 | open("foo", "rUb")
|
||||
5 5 | open("foo", "r")
|
||||
6 |-open("foo", "rt")
|
||||
6 |+open("foo")
|
||||
7 7 | open("f", "r", encoding="UTF-8")
|
||||
8 8 | open("f", "wt")
|
||||
9 9 | open("f", "tw")
|
||||
|
||||
UP015.py:7:11: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
5 | open("foo", "r")
|
||||
6 | open("foo", "rt")
|
||||
7 | open("f", "r", encoding="UTF-8")
|
||||
| ^^^ UP015
|
||||
8 | open("f", "wt")
|
||||
9 | open("f", "tw")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
4 4 | open("foo", "rUb")
|
||||
5 5 | open("foo", "r")
|
||||
6 6 | open("foo", "rt")
|
||||
7 |-open("f", "r", encoding="UTF-8")
|
||||
7 |+open("f", encoding="UTF-8")
|
||||
8 8 | open("f", "wt")
|
||||
9 9 | open("f", "tw")
|
||||
10 10 |
|
||||
|
||||
UP015.py:8:11: UP015 [*] Unnecessary modes, use `w`
|
||||
|
|
||||
6 | open("foo", "rt")
|
||||
7 | open("f", "r", encoding="UTF-8")
|
||||
8 | open("f", "wt")
|
||||
| ^^^^ UP015
|
||||
9 | open("f", "tw")
|
||||
|
|
||||
= help: Replace with `w`
|
||||
|
||||
ℹ Safe fix
|
||||
5 5 | open("foo", "r")
|
||||
6 6 | open("foo", "rt")
|
||||
7 7 | open("f", "r", encoding="UTF-8")
|
||||
8 |-open("f", "wt")
|
||||
8 |+open("f", "w")
|
||||
9 9 | open("f", "tw")
|
||||
10 10 |
|
||||
11 11 | with open("foo", "U") as f:
|
||||
|
||||
UP015.py:9:11: UP015 [*] Unnecessary modes, use `w`
|
||||
|
|
||||
7 | open("f", "r", encoding="UTF-8")
|
||||
8 | open("f", "wt")
|
||||
9 | open("f", "tw")
|
||||
| ^^^^ UP015
|
||||
10 |
|
||||
11 | with open("foo", "U") as f:
|
||||
|
|
||||
= help: Replace with `w`
|
||||
|
||||
ℹ Safe fix
|
||||
6 6 | open("foo", "rt")
|
||||
7 7 | open("f", "r", encoding="UTF-8")
|
||||
8 8 | open("f", "wt")
|
||||
9 |-open("f", "tw")
|
||||
9 |+open("f", "w")
|
||||
10 10 |
|
||||
11 11 | with open("foo", "U") as f:
|
||||
12 12 | pass
|
||||
|
||||
UP015.py:11:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
9 | open("f", "tw")
|
||||
10 |
|
||||
11 | with open("foo", "U") as f:
|
||||
| ^^^ UP015
|
||||
12 | pass
|
||||
13 | with open("foo", "Ur") as f:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
8 8 | open("f", "wt")
|
||||
9 9 | open("f", "tw")
|
||||
10 10 |
|
||||
11 |-with open("foo", "U") as f:
|
||||
11 |+with open("foo") as f:
|
||||
12 12 | pass
|
||||
13 13 | with open("foo", "Ur") as f:
|
||||
14 14 | pass
|
||||
|
||||
UP015.py:13:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
11 | with open("foo", "U") as f:
|
||||
12 | pass
|
||||
13 | with open("foo", "Ur") as f:
|
||||
| ^^^^ UP015
|
||||
14 | pass
|
||||
15 | with open("foo", "Ub") as f:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
10 10 |
|
||||
11 11 | with open("foo", "U") as f:
|
||||
12 12 | pass
|
||||
13 |-with open("foo", "Ur") as f:
|
||||
13 |+with open("foo") as f:
|
||||
14 14 | pass
|
||||
15 15 | with open("foo", "Ub") as f:
|
||||
16 16 | pass
|
||||
|
||||
UP015.py:15:18: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
13 | with open("foo", "Ur") as f:
|
||||
14 | pass
|
||||
15 | with open("foo", "Ub") as f:
|
||||
| ^^^^ UP015
|
||||
16 | pass
|
||||
17 | with open("foo", "rUb") as f:
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
12 12 | pass
|
||||
13 13 | with open("foo", "Ur") as f:
|
||||
14 14 | pass
|
||||
15 |-with open("foo", "Ub") as f:
|
||||
15 |+with open("foo", "rb") as f:
|
||||
16 16 | pass
|
||||
17 17 | with open("foo", "rUb") as f:
|
||||
18 18 | pass
|
||||
|
||||
UP015.py:17:18: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
15 | with open("foo", "Ub") as f:
|
||||
16 | pass
|
||||
17 | with open("foo", "rUb") as f:
|
||||
| ^^^^^ UP015
|
||||
18 | pass
|
||||
19 | with open("foo", "r") as f:
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
14 14 | pass
|
||||
15 15 | with open("foo", "Ub") as f:
|
||||
16 16 | pass
|
||||
17 |-with open("foo", "rUb") as f:
|
||||
17 |+with open("foo", "rb") as f:
|
||||
18 18 | pass
|
||||
19 19 | with open("foo", "r") as f:
|
||||
20 20 | pass
|
||||
|
||||
UP015.py:19:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
17 | with open("foo", "rUb") as f:
|
||||
18 | pass
|
||||
19 | with open("foo", "r") as f:
|
||||
| ^^^ UP015
|
||||
20 | pass
|
||||
21 | with open("foo", "rt") as f:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
16 16 | pass
|
||||
17 17 | with open("foo", "rUb") as f:
|
||||
18 18 | pass
|
||||
19 |-with open("foo", "r") as f:
|
||||
19 |+with open("foo") as f:
|
||||
20 20 | pass
|
||||
21 21 | with open("foo", "rt") as f:
|
||||
22 22 | pass
|
||||
|
||||
UP015.py:21:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
19 | with open("foo", "r") as f:
|
||||
20 | pass
|
||||
21 | with open("foo", "rt") as f:
|
||||
| ^^^^ UP015
|
||||
22 | pass
|
||||
23 | with open("foo", "r", encoding="UTF-8") as f:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
18 18 | pass
|
||||
19 19 | with open("foo", "r") as f:
|
||||
20 20 | pass
|
||||
21 |-with open("foo", "rt") as f:
|
||||
21 |+with open("foo") as f:
|
||||
22 22 | pass
|
||||
23 23 | with open("foo", "r", encoding="UTF-8") as f:
|
||||
24 24 | pass
|
||||
|
||||
UP015.py:23:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
21 | with open("foo", "rt") as f:
|
||||
22 | pass
|
||||
23 | with open("foo", "r", encoding="UTF-8") as f:
|
||||
| ^^^ UP015
|
||||
24 | pass
|
||||
25 | with open("foo", "wt") as f:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
20 20 | pass
|
||||
21 21 | with open("foo", "rt") as f:
|
||||
22 22 | pass
|
||||
23 |-with open("foo", "r", encoding="UTF-8") as f:
|
||||
23 |+with open("foo", encoding="UTF-8") as f:
|
||||
24 24 | pass
|
||||
25 25 | with open("foo", "wt") as f:
|
||||
26 26 | pass
|
||||
|
||||
UP015.py:25:18: UP015 [*] Unnecessary modes, use `w`
|
||||
|
|
||||
23 | with open("foo", "r", encoding="UTF-8") as f:
|
||||
24 | pass
|
||||
25 | with open("foo", "wt") as f:
|
||||
| ^^^^ UP015
|
||||
26 | pass
|
||||
|
|
||||
= help: Replace with `w`
|
||||
|
||||
ℹ Safe fix
|
||||
22 22 | pass
|
||||
23 23 | with open("foo", "r", encoding="UTF-8") as f:
|
||||
24 24 | pass
|
||||
25 |-with open("foo", "wt") as f:
|
||||
25 |+with open("foo", "w") as f:
|
||||
26 26 | pass
|
||||
27 27 |
|
||||
28 28 | open(f("a", "b", "c"), "U")
|
||||
|
||||
UP015.py:28:24: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
26 | pass
|
||||
27 |
|
||||
28 | open(f("a", "b", "c"), "U")
|
||||
| ^^^ UP015
|
||||
29 | open(f("a", "b", "c"), "Ub")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
25 25 | with open("foo", "wt") as f:
|
||||
26 26 | pass
|
||||
27 27 |
|
||||
28 |-open(f("a", "b", "c"), "U")
|
||||
28 |+open(f("a", "b", "c"))
|
||||
29 29 | open(f("a", "b", "c"), "Ub")
|
||||
30 30 |
|
||||
31 31 | with open(f("a", "b", "c"), "U") as f:
|
||||
|
||||
UP015.py:29:24: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
28 | open(f("a", "b", "c"), "U")
|
||||
29 | open(f("a", "b", "c"), "Ub")
|
||||
| ^^^^ UP015
|
||||
30 |
|
||||
31 | with open(f("a", "b", "c"), "U") as f:
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
26 26 | pass
|
||||
27 27 |
|
||||
28 28 | open(f("a", "b", "c"), "U")
|
||||
29 |-open(f("a", "b", "c"), "Ub")
|
||||
29 |+open(f("a", "b", "c"), "rb")
|
||||
30 30 |
|
||||
31 31 | with open(f("a", "b", "c"), "U") as f:
|
||||
32 32 | pass
|
||||
|
||||
UP015.py:31:29: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
29 | open(f("a", "b", "c"), "Ub")
|
||||
30 |
|
||||
31 | with open(f("a", "b", "c"), "U") as f:
|
||||
| ^^^ UP015
|
||||
32 | pass
|
||||
33 | with open(f("a", "b", "c"), "Ub") as f:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
28 28 | open(f("a", "b", "c"), "U")
|
||||
29 29 | open(f("a", "b", "c"), "Ub")
|
||||
30 30 |
|
||||
31 |-with open(f("a", "b", "c"), "U") as f:
|
||||
31 |+with open(f("a", "b", "c")) as f:
|
||||
32 32 | pass
|
||||
33 33 | with open(f("a", "b", "c"), "Ub") as f:
|
||||
34 34 | pass
|
||||
|
||||
UP015.py:33:29: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
31 | with open(f("a", "b", "c"), "U") as f:
|
||||
32 | pass
|
||||
33 | with open(f("a", "b", "c"), "Ub") as f:
|
||||
| ^^^^ UP015
|
||||
34 | pass
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
30 30 |
|
||||
31 31 | with open(f("a", "b", "c"), "U") as f:
|
||||
32 32 | pass
|
||||
33 |-with open(f("a", "b", "c"), "Ub") as f:
|
||||
33 |+with open(f("a", "b", "c"), "rb") as f:
|
||||
34 34 | pass
|
||||
35 35 |
|
||||
36 36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
|
||||
UP015.py:36:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
34 | pass
|
||||
35 |
|
||||
36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
| ^^^ UP015
|
||||
37 | pass
|
||||
38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
33 33 | with open(f("a", "b", "c"), "Ub") as f:
|
||||
34 34 | pass
|
||||
35 35 |
|
||||
36 |-with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
36 |+with open("foo") as fa, open("bar", "U") as fb:
|
||||
37 37 | pass
|
||||
38 38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
39 39 | pass
|
||||
|
||||
UP015.py:36:42: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
34 | pass
|
||||
35 |
|
||||
36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
| ^^^ UP015
|
||||
37 | pass
|
||||
38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
33 33 | with open(f("a", "b", "c"), "Ub") as f:
|
||||
34 34 | pass
|
||||
35 35 |
|
||||
36 |-with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
36 |+with open("foo", "U") as fa, open("bar") as fb:
|
||||
37 37 | pass
|
||||
38 38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
39 39 | pass
|
||||
|
||||
UP015.py:38:18: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
37 | pass
|
||||
38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
| ^^^^ UP015
|
||||
39 | pass
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
35 35 |
|
||||
36 36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
37 37 | pass
|
||||
38 |-with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
38 |+with open("foo", "rb") as fa, open("bar", "Ub") as fb:
|
||||
39 39 | pass
|
||||
40 40 |
|
||||
41 41 | open("foo", mode="U")
|
||||
|
||||
UP015.py:38:43: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
37 | pass
|
||||
38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
| ^^^^ UP015
|
||||
39 | pass
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
35 35 |
|
||||
36 36 | with open("foo", "U") as fa, open("bar", "U") as fb:
|
||||
37 37 | pass
|
||||
38 |-with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
38 |+with open("foo", "Ub") as fa, open("bar", "rb") as fb:
|
||||
39 39 | pass
|
||||
40 40 |
|
||||
41 41 | open("foo", mode="U")
|
||||
|
||||
UP015.py:41:18: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
39 | pass
|
||||
40 |
|
||||
41 | open("foo", mode="U")
|
||||
| ^^^ UP015
|
||||
42 | open(name="foo", mode="U")
|
||||
43 | open(mode="U", name="foo")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
38 38 | with open("foo", "Ub") as fa, open("bar", "Ub") as fb:
|
||||
39 39 | pass
|
||||
40 40 |
|
||||
41 |-open("foo", mode="U")
|
||||
41 |+open("foo")
|
||||
42 42 | open(name="foo", mode="U")
|
||||
43 43 | open(mode="U", name="foo")
|
||||
44 44 |
|
||||
|
||||
UP015.py:42:23: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
41 | open("foo", mode="U")
|
||||
42 | open(name="foo", mode="U")
|
||||
| ^^^ UP015
|
||||
43 | open(mode="U", name="foo")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
39 39 | pass
|
||||
40 40 |
|
||||
41 41 | open("foo", mode="U")
|
||||
42 |-open(name="foo", mode="U")
|
||||
42 |+open(name="foo")
|
||||
43 43 | open(mode="U", name="foo")
|
||||
44 44 |
|
||||
45 45 | with open("foo", mode="U") as f:
|
||||
|
||||
UP015.py:43:11: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
41 | open("foo", mode="U")
|
||||
42 | open(name="foo", mode="U")
|
||||
43 | open(mode="U", name="foo")
|
||||
| ^^^ UP015
|
||||
44 |
|
||||
45 | with open("foo", mode="U") as f:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
40 40 |
|
||||
41 41 | open("foo", mode="U")
|
||||
42 42 | open(name="foo", mode="U")
|
||||
43 |-open(mode="U", name="foo")
|
||||
43 |+open(name="foo")
|
||||
44 44 |
|
||||
45 45 | with open("foo", mode="U") as f:
|
||||
46 46 | pass
|
||||
|
||||
UP015.py:45:23: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
43 | open(mode="U", name="foo")
|
||||
44 |
|
||||
45 | with open("foo", mode="U") as f:
|
||||
| ^^^ UP015
|
||||
46 | pass
|
||||
47 | with open(name="foo", mode="U") as f:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
42 42 | open(name="foo", mode="U")
|
||||
43 43 | open(mode="U", name="foo")
|
||||
44 44 |
|
||||
45 |-with open("foo", mode="U") as f:
|
||||
45 |+with open("foo") as f:
|
||||
46 46 | pass
|
||||
47 47 | with open(name="foo", mode="U") as f:
|
||||
48 48 | pass
|
||||
|
||||
UP015.py:47:28: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
45 | with open("foo", mode="U") as f:
|
||||
46 | pass
|
||||
47 | with open(name="foo", mode="U") as f:
|
||||
| ^^^ UP015
|
||||
48 | pass
|
||||
49 | with open(mode="U", name="foo") as f:
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
44 44 |
|
||||
45 45 | with open("foo", mode="U") as f:
|
||||
46 46 | pass
|
||||
47 |-with open(name="foo", mode="U") as f:
|
||||
47 |+with open(name="foo") as f:
|
||||
48 48 | pass
|
||||
49 49 | with open(mode="U", name="foo") as f:
|
||||
50 50 | pass
|
||||
|
||||
UP015.py:49:16: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
47 | with open(name="foo", mode="U") as f:
|
||||
48 | pass
|
||||
49 | with open(mode="U", name="foo") as f:
|
||||
| ^^^ UP015
|
||||
50 | pass
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
46 46 | pass
|
||||
47 47 | with open(name="foo", mode="U") as f:
|
||||
48 48 | pass
|
||||
49 |-with open(mode="U", name="foo") as f:
|
||||
49 |+with open(name="foo") as f:
|
||||
50 50 | pass
|
||||
51 51 |
|
||||
52 52 | open("foo", mode="Ub")
|
||||
|
||||
UP015.py:52:18: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
50 | pass
|
||||
51 |
|
||||
52 | open("foo", mode="Ub")
|
||||
| ^^^^ UP015
|
||||
53 | open(name="foo", mode="Ub")
|
||||
54 | open(mode="Ub", name="foo")
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
49 49 | with open(mode="U", name="foo") as f:
|
||||
50 50 | pass
|
||||
51 51 |
|
||||
52 |-open("foo", mode="Ub")
|
||||
52 |+open("foo", mode="rb")
|
||||
53 53 | open(name="foo", mode="Ub")
|
||||
54 54 | open(mode="Ub", name="foo")
|
||||
55 55 |
|
||||
|
||||
UP015.py:53:23: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
52 | open("foo", mode="Ub")
|
||||
53 | open(name="foo", mode="Ub")
|
||||
| ^^^^ UP015
|
||||
54 | open(mode="Ub", name="foo")
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
50 50 | pass
|
||||
51 51 |
|
||||
52 52 | open("foo", mode="Ub")
|
||||
53 |-open(name="foo", mode="Ub")
|
||||
53 |+open(name="foo", mode="rb")
|
||||
54 54 | open(mode="Ub", name="foo")
|
||||
55 55 |
|
||||
56 56 | with open("foo", mode="Ub") as f:
|
||||
|
||||
UP015.py:54:11: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
52 | open("foo", mode="Ub")
|
||||
53 | open(name="foo", mode="Ub")
|
||||
54 | open(mode="Ub", name="foo")
|
||||
| ^^^^ UP015
|
||||
55 |
|
||||
56 | with open("foo", mode="Ub") as f:
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
51 51 |
|
||||
52 52 | open("foo", mode="Ub")
|
||||
53 53 | open(name="foo", mode="Ub")
|
||||
54 |-open(mode="Ub", name="foo")
|
||||
54 |+open(mode="rb", name="foo")
|
||||
55 55 |
|
||||
56 56 | with open("foo", mode="Ub") as f:
|
||||
57 57 | pass
|
||||
|
||||
UP015.py:56:23: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
54 | open(mode="Ub", name="foo")
|
||||
55 |
|
||||
56 | with open("foo", mode="Ub") as f:
|
||||
| ^^^^ UP015
|
||||
57 | pass
|
||||
58 | with open(name="foo", mode="Ub") as f:
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
53 53 | open(name="foo", mode="Ub")
|
||||
54 54 | open(mode="Ub", name="foo")
|
||||
55 55 |
|
||||
56 |-with open("foo", mode="Ub") as f:
|
||||
56 |+with open("foo", mode="rb") as f:
|
||||
57 57 | pass
|
||||
58 58 | with open(name="foo", mode="Ub") as f:
|
||||
59 59 | pass
|
||||
|
||||
UP015.py:58:28: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
56 | with open("foo", mode="Ub") as f:
|
||||
57 | pass
|
||||
58 | with open(name="foo", mode="Ub") as f:
|
||||
| ^^^^ UP015
|
||||
59 | pass
|
||||
60 | with open(mode="Ub", name="foo") as f:
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
55 55 |
|
||||
56 56 | with open("foo", mode="Ub") as f:
|
||||
57 57 | pass
|
||||
58 |-with open(name="foo", mode="Ub") as f:
|
||||
58 |+with open(name="foo", mode="rb") as f:
|
||||
59 59 | pass
|
||||
60 60 | with open(mode="Ub", name="foo") as f:
|
||||
61 61 | pass
|
||||
|
||||
UP015.py:60:16: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
58 | with open(name="foo", mode="Ub") as f:
|
||||
59 | pass
|
||||
60 | with open(mode="Ub", name="foo") as f:
|
||||
| ^^^^ UP015
|
||||
61 | pass
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
57 57 | pass
|
||||
58 58 | with open(name="foo", mode="Ub") as f:
|
||||
59 59 | pass
|
||||
60 |-with open(mode="Ub", name="foo") as f:
|
||||
60 |+with open(mode="rb", name="foo") as f:
|
||||
61 61 | pass
|
||||
62 62 |
|
||||
63 63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
||||
UP015.py:63:23: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
61 | pass
|
||||
62 |
|
||||
63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
| ^^^ UP015
|
||||
64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
60 60 | with open(mode="Ub", name="foo") as f:
|
||||
61 61 | pass
|
||||
62 62 |
|
||||
63 |-open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
63 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
65 65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
66 66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
||||
UP015.py:64:106: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
| ^^^ UP015
|
||||
65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
61 61 | pass
|
||||
62 62 |
|
||||
63 63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
64 |-open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
64 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
65 65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
66 66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
67 67 |
|
||||
|
||||
UP015.py:65:65: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
| ^^^ UP015
|
||||
66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
62 62 |
|
||||
63 63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
65 |-open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
65 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
66 66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
67 67 |
|
||||
68 68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
||||
UP015.py:66:11: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
| ^^^ UP015
|
||||
67 |
|
||||
68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
63 63 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U')
|
||||
65 65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
66 |-open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
66 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
67 67 |
|
||||
68 68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
|
||||
UP015.py:68:23: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
67 |
|
||||
68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
| ^^^^ UP015
|
||||
69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
65 65 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None)
|
||||
66 66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
67 67 |
|
||||
68 |-open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
68 |+open(file="foo", mode="rb", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
70 70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
71 71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
||||
UP015.py:69:106: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
| ^^^^ UP015
|
||||
70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
66 66 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
67 67 |
|
||||
68 68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
69 |-open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
69 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode="rb")
|
||||
70 70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
71 71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
72 72 |
|
||||
|
||||
UP015.py:70:65: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
| ^^^^ UP015
|
||||
71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
67 67 |
|
||||
68 68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
70 |-open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
70 |+open(file="foo", buffering=-1, encoding=None, errors=None, mode="rb", newline=None, closefd=True, opener=None)
|
||||
71 71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
72 72 |
|
||||
73 73 | import aiofiles
|
||||
|
||||
UP015.py:71:11: UP015 [*] Unnecessary modes, use `rb`
|
||||
|
|
||||
69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
71 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
| ^^^^ UP015
|
||||
72 |
|
||||
73 | import aiofiles
|
||||
|
|
||||
= help: Replace with `rb`
|
||||
|
||||
ℹ Safe fix
|
||||
68 68 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub')
|
||||
70 70 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None)
|
||||
71 |-open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
71 |+open(mode="rb", file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
72 72 |
|
||||
73 73 | import aiofiles
|
||||
74 74 |
|
||||
|
||||
UP015.py:75:22: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
73 | import aiofiles
|
||||
74 |
|
||||
75 | aiofiles.open("foo", "U")
|
||||
| ^^^ UP015
|
||||
76 | aiofiles.open("foo", "r")
|
||||
77 | aiofiles.open("foo", mode="r")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
72 72 |
|
||||
73 73 | import aiofiles
|
||||
74 74 |
|
||||
75 |-aiofiles.open("foo", "U")
|
||||
75 |+aiofiles.open("foo")
|
||||
76 76 | aiofiles.open("foo", "r")
|
||||
77 77 | aiofiles.open("foo", mode="r")
|
||||
78 78 |
|
||||
|
||||
UP015.py:76:22: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
75 | aiofiles.open("foo", "U")
|
||||
76 | aiofiles.open("foo", "r")
|
||||
| ^^^ UP015
|
||||
77 | aiofiles.open("foo", mode="r")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
73 73 | import aiofiles
|
||||
74 74 |
|
||||
75 75 | aiofiles.open("foo", "U")
|
||||
76 |-aiofiles.open("foo", "r")
|
||||
76 |+aiofiles.open("foo")
|
||||
77 77 | aiofiles.open("foo", mode="r")
|
||||
78 78 |
|
||||
79 79 | open("foo", "r+")
|
||||
|
||||
UP015.py:77:27: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
75 | aiofiles.open("foo", "U")
|
||||
76 | aiofiles.open("foo", "r")
|
||||
77 | aiofiles.open("foo", mode="r")
|
||||
| ^^^ UP015
|
||||
78 |
|
||||
79 | open("foo", "r+")
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
74 74 |
|
||||
75 75 | aiofiles.open("foo", "U")
|
||||
76 76 | aiofiles.open("foo", "r")
|
||||
77 |-aiofiles.open("foo", mode="r")
|
||||
77 |+aiofiles.open("foo")
|
||||
78 78 |
|
||||
79 79 | open("foo", "r+")
|
||||
80 80 | open("foo", "rb")
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pyupgrade/mod.rs
|
||||
---
|
||||
UP015_1.py:3:17: UP015 [*] Unnecessary mode argument
|
||||
|
|
||||
1 | # Not a valid type annotation but this test shouldn't result in a panic.
|
||||
2 | # Refer: https://github.com/astral-sh/ruff/issues/11736
|
||||
3 | x: 'open("foo", "r")'
|
||||
| ^^^ UP015
|
||||
|
|
||||
= help: Remove mode argument
|
||||
|
||||
ℹ Safe fix
|
||||
1 1 | # Not a valid type annotation but this test shouldn't result in a panic.
|
||||
2 2 | # Refer: https://github.com/astral-sh/ruff/issues/11736
|
||||
3 |-x: 'open("foo", "r")'
|
||||
3 |+x: 'open("foo")'
|
||||
4 4 |
|
||||
@@ -12,7 +12,6 @@ mod tests {
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::types::PreviewMode;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_messages, settings};
|
||||
|
||||
@@ -62,24 +61,6 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::TypeNoneComparison, Path::new("FURB169.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview__{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("refurb").join(path).as_path(),
|
||||
&settings::LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_whole_file_python_39() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
|
||||
@@ -13,9 +13,6 @@ use crate::rules::refurb::helpers::replace_with_identity_check;
|
||||
/// There is only ever one instance of `None`, so it is more efficient and
|
||||
/// readable to use the `is` operator to check if an object is `None`.
|
||||
///
|
||||
/// Only name expressions (e.g., `type(foo) == type(None)`) are reported.
|
||||
/// In [preview], the rule will also report other kinds of expressions.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// type(obj) is type(None)
|
||||
@@ -34,8 +31,6 @@ use crate::rules::refurb::helpers::replace_with_identity_check;
|
||||
/// - [Python documentation: `None`](https://docs.python.org/3/library/constants.html#None)
|
||||
/// - [Python documentation: `type`](https://docs.python.org/3/library/functions.html#type)
|
||||
/// - [Python documentation: Identity comparisons](https://docs.python.org/3/reference/expressions.html#is-not)
|
||||
///
|
||||
/// [preview]: https://docs.astral.sh/ruff/preview/
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct TypeNoneComparison {
|
||||
replacement: IdentityCheck,
|
||||
@@ -80,12 +75,6 @@ pub(crate) fn type_none_comparison(checker: &Checker, compare: &ast::ExprCompare
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if checker.settings.preview.is_disabled()
|
||||
&& !matches!(other_arg, Expr::Name(_) | Expr::NoneLiteral(_))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let diagnostic = Diagnostic::new(TypeNoneComparison { replacement }, compare.range);
|
||||
|
||||
let negate = replacement == IdentityCheck::IsNot;
|
||||
|
||||
@@ -251,4 +251,102 @@ FURB169.py:27:1: FURB169 [*] When checking against `None`, use `is not` instead
|
||||
27 |+None is not None
|
||||
28 28 |
|
||||
29 29 | type(a.b) is type(None)
|
||||
30 30 |
|
||||
30 30 |
|
||||
|
||||
FURB169.py:29:1: FURB169 [*] When checking against `None`, use `is` instead of comparison with `type(None)`
|
||||
|
|
||||
27 | type(None) != type(None)
|
||||
28 |
|
||||
29 | type(a.b) is type(None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
30 |
|
||||
31 | type(
|
||||
|
|
||||
= help: Replace with `is None`
|
||||
|
||||
ℹ Safe fix
|
||||
26 26 |
|
||||
27 27 | type(None) != type(None)
|
||||
28 28 |
|
||||
29 |-type(a.b) is type(None)
|
||||
29 |+a.b is None
|
||||
30 30 |
|
||||
31 31 | type(
|
||||
32 32 | a(
|
||||
|
||||
FURB169.py:31:1: FURB169 [*] When checking against `None`, use `is not` instead of comparison with `type(None)`
|
||||
|
|
||||
29 | type(a.b) is type(None)
|
||||
30 |
|
||||
31 | / type(
|
||||
32 | | a(
|
||||
33 | | # Comment
|
||||
34 | | )
|
||||
35 | | ) != type(None)
|
||||
| |_______________^ FURB169
|
||||
36 |
|
||||
37 | type(
|
||||
|
|
||||
= help: Replace with `is not None`
|
||||
|
||||
ℹ Unsafe fix
|
||||
28 28 |
|
||||
29 29 | type(a.b) is type(None)
|
||||
30 30 |
|
||||
31 |-type(
|
||||
32 |- a(
|
||||
33 |- # Comment
|
||||
34 |- )
|
||||
35 |-) != type(None)
|
||||
31 |+a() is not None
|
||||
36 32 |
|
||||
37 33 | type(
|
||||
38 34 | a := 1
|
||||
|
||||
FURB169.py:37:1: FURB169 [*] When checking against `None`, use `is` instead of comparison with `type(None)`
|
||||
|
|
||||
35 | ) != type(None)
|
||||
36 |
|
||||
37 | / type(
|
||||
38 | | a := 1
|
||||
39 | | ) == type(None)
|
||||
| |_______________^ FURB169
|
||||
40 |
|
||||
41 | type(
|
||||
|
|
||||
= help: Replace with `is None`
|
||||
|
||||
ℹ Safe fix
|
||||
34 34 | )
|
||||
35 35 | ) != type(None)
|
||||
36 36 |
|
||||
37 |-type(
|
||||
38 |- a := 1
|
||||
39 |-) == type(None)
|
||||
37 |+(a := 1) is None
|
||||
40 38 |
|
||||
41 39 | type(
|
||||
42 40 | a for a in range(0)
|
||||
|
||||
FURB169.py:41:1: FURB169 [*] When checking against `None`, use `is not` instead of comparison with `type(None)`
|
||||
|
|
||||
39 | ) == type(None)
|
||||
40 |
|
||||
41 | / type(
|
||||
42 | | a for a in range(0)
|
||||
43 | | ) is not type(None)
|
||||
| |___________________^ FURB169
|
||||
|
|
||||
= help: Replace with `is not None`
|
||||
|
||||
ℹ Safe fix
|
||||
38 38 | a := 1
|
||||
39 39 | ) == type(None)
|
||||
40 40 |
|
||||
41 |-type(
|
||||
42 |- a for a in range(0)
|
||||
43 |-) is not type(None)
|
||||
41 |+(a for a in range(0)) is not None
|
||||
44 42 |
|
||||
45 43 |
|
||||
46 44 | # Ok.
|
||||
|
||||
@@ -1,352 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/refurb/mod.rs
|
||||
---
|
||||
FURB169.py:5:1: FURB169 [*] When checking against `None`, use `is` instead of comparison with `type(None)`
|
||||
|
|
||||
3 | # Error.
|
||||
4 |
|
||||
5 | type(foo) is type(None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
6 |
|
||||
7 | type(None) is type(foo)
|
||||
|
|
||||
= help: Replace with `is None`
|
||||
|
||||
ℹ Safe fix
|
||||
2 2 |
|
||||
3 3 | # Error.
|
||||
4 4 |
|
||||
5 |-type(foo) is type(None)
|
||||
5 |+foo is None
|
||||
6 6 |
|
||||
7 7 | type(None) is type(foo)
|
||||
8 8 |
|
||||
|
||||
FURB169.py:7:1: FURB169 [*] When checking against `None`, use `is` instead of comparison with `type(None)`
|
||||
|
|
||||
5 | type(foo) is type(None)
|
||||
6 |
|
||||
7 | type(None) is type(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
8 |
|
||||
9 | type(None) is type(None)
|
||||
|
|
||||
= help: Replace with `is None`
|
||||
|
||||
ℹ Safe fix
|
||||
4 4 |
|
||||
5 5 | type(foo) is type(None)
|
||||
6 6 |
|
||||
7 |-type(None) is type(foo)
|
||||
7 |+foo is None
|
||||
8 8 |
|
||||
9 9 | type(None) is type(None)
|
||||
10 10 |
|
||||
|
||||
FURB169.py:9:1: FURB169 [*] When checking against `None`, use `is` instead of comparison with `type(None)`
|
||||
|
|
||||
7 | type(None) is type(foo)
|
||||
8 |
|
||||
9 | type(None) is type(None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
10 |
|
||||
11 | type(foo) is not type(None)
|
||||
|
|
||||
= help: Replace with `is None`
|
||||
|
||||
ℹ Safe fix
|
||||
6 6 |
|
||||
7 7 | type(None) is type(foo)
|
||||
8 8 |
|
||||
9 |-type(None) is type(None)
|
||||
9 |+None is None
|
||||
10 10 |
|
||||
11 11 | type(foo) is not type(None)
|
||||
12 12 |
|
||||
|
||||
FURB169.py:11:1: FURB169 [*] When checking against `None`, use `is not` instead of comparison with `type(None)`
|
||||
|
|
||||
9 | type(None) is type(None)
|
||||
10 |
|
||||
11 | type(foo) is not type(None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
12 |
|
||||
13 | type(None) is not type(foo)
|
||||
|
|
||||
= help: Replace with `is not None`
|
||||
|
||||
ℹ Safe fix
|
||||
8 8 |
|
||||
9 9 | type(None) is type(None)
|
||||
10 10 |
|
||||
11 |-type(foo) is not type(None)
|
||||
11 |+foo is not None
|
||||
12 12 |
|
||||
13 13 | type(None) is not type(foo)
|
||||
14 14 |
|
||||
|
||||
FURB169.py:13:1: FURB169 [*] When checking against `None`, use `is not` instead of comparison with `type(None)`
|
||||
|
|
||||
11 | type(foo) is not type(None)
|
||||
12 |
|
||||
13 | type(None) is not type(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
14 |
|
||||
15 | type(None) is not type(None)
|
||||
|
|
||||
= help: Replace with `is not None`
|
||||
|
||||
ℹ Safe fix
|
||||
10 10 |
|
||||
11 11 | type(foo) is not type(None)
|
||||
12 12 |
|
||||
13 |-type(None) is not type(foo)
|
||||
13 |+foo is not None
|
||||
14 14 |
|
||||
15 15 | type(None) is not type(None)
|
||||
16 16 |
|
||||
|
||||
FURB169.py:15:1: FURB169 [*] When checking against `None`, use `is not` instead of comparison with `type(None)`
|
||||
|
|
||||
13 | type(None) is not type(foo)
|
||||
14 |
|
||||
15 | type(None) is not type(None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
16 |
|
||||
17 | type(foo) == type(None)
|
||||
|
|
||||
= help: Replace with `is not None`
|
||||
|
||||
ℹ Safe fix
|
||||
12 12 |
|
||||
13 13 | type(None) is not type(foo)
|
||||
14 14 |
|
||||
15 |-type(None) is not type(None)
|
||||
15 |+None is not None
|
||||
16 16 |
|
||||
17 17 | type(foo) == type(None)
|
||||
18 18 |
|
||||
|
||||
FURB169.py:17:1: FURB169 [*] When checking against `None`, use `is` instead of comparison with `type(None)`
|
||||
|
|
||||
15 | type(None) is not type(None)
|
||||
16 |
|
||||
17 | type(foo) == type(None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
18 |
|
||||
19 | type(None) == type(foo)
|
||||
|
|
||||
= help: Replace with `is None`
|
||||
|
||||
ℹ Safe fix
|
||||
14 14 |
|
||||
15 15 | type(None) is not type(None)
|
||||
16 16 |
|
||||
17 |-type(foo) == type(None)
|
||||
17 |+foo is None
|
||||
18 18 |
|
||||
19 19 | type(None) == type(foo)
|
||||
20 20 |
|
||||
|
||||
FURB169.py:19:1: FURB169 [*] When checking against `None`, use `is` instead of comparison with `type(None)`
|
||||
|
|
||||
17 | type(foo) == type(None)
|
||||
18 |
|
||||
19 | type(None) == type(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
20 |
|
||||
21 | type(None) == type(None)
|
||||
|
|
||||
= help: Replace with `is None`
|
||||
|
||||
ℹ Safe fix
|
||||
16 16 |
|
||||
17 17 | type(foo) == type(None)
|
||||
18 18 |
|
||||
19 |-type(None) == type(foo)
|
||||
19 |+foo is None
|
||||
20 20 |
|
||||
21 21 | type(None) == type(None)
|
||||
22 22 |
|
||||
|
||||
FURB169.py:21:1: FURB169 [*] When checking against `None`, use `is` instead of comparison with `type(None)`
|
||||
|
|
||||
19 | type(None) == type(foo)
|
||||
20 |
|
||||
21 | type(None) == type(None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
22 |
|
||||
23 | type(foo) != type(None)
|
||||
|
|
||||
= help: Replace with `is None`
|
||||
|
||||
ℹ Safe fix
|
||||
18 18 |
|
||||
19 19 | type(None) == type(foo)
|
||||
20 20 |
|
||||
21 |-type(None) == type(None)
|
||||
21 |+None is None
|
||||
22 22 |
|
||||
23 23 | type(foo) != type(None)
|
||||
24 24 |
|
||||
|
||||
FURB169.py:23:1: FURB169 [*] When checking against `None`, use `is not` instead of comparison with `type(None)`
|
||||
|
|
||||
21 | type(None) == type(None)
|
||||
22 |
|
||||
23 | type(foo) != type(None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
24 |
|
||||
25 | type(None) != type(foo)
|
||||
|
|
||||
= help: Replace with `is not None`
|
||||
|
||||
ℹ Safe fix
|
||||
20 20 |
|
||||
21 21 | type(None) == type(None)
|
||||
22 22 |
|
||||
23 |-type(foo) != type(None)
|
||||
23 |+foo is not None
|
||||
24 24 |
|
||||
25 25 | type(None) != type(foo)
|
||||
26 26 |
|
||||
|
||||
FURB169.py:25:1: FURB169 [*] When checking against `None`, use `is not` instead of comparison with `type(None)`
|
||||
|
|
||||
23 | type(foo) != type(None)
|
||||
24 |
|
||||
25 | type(None) != type(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
26 |
|
||||
27 | type(None) != type(None)
|
||||
|
|
||||
= help: Replace with `is not None`
|
||||
|
||||
ℹ Safe fix
|
||||
22 22 |
|
||||
23 23 | type(foo) != type(None)
|
||||
24 24 |
|
||||
25 |-type(None) != type(foo)
|
||||
25 |+foo is not None
|
||||
26 26 |
|
||||
27 27 | type(None) != type(None)
|
||||
28 28 |
|
||||
|
||||
FURB169.py:27:1: FURB169 [*] When checking against `None`, use `is not` instead of comparison with `type(None)`
|
||||
|
|
||||
25 | type(None) != type(foo)
|
||||
26 |
|
||||
27 | type(None) != type(None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
28 |
|
||||
29 | type(a.b) is type(None)
|
||||
|
|
||||
= help: Replace with `is not None`
|
||||
|
||||
ℹ Safe fix
|
||||
24 24 |
|
||||
25 25 | type(None) != type(foo)
|
||||
26 26 |
|
||||
27 |-type(None) != type(None)
|
||||
27 |+None is not None
|
||||
28 28 |
|
||||
29 29 | type(a.b) is type(None)
|
||||
30 30 |
|
||||
|
||||
FURB169.py:29:1: FURB169 [*] When checking against `None`, use `is` instead of comparison with `type(None)`
|
||||
|
|
||||
27 | type(None) != type(None)
|
||||
28 |
|
||||
29 | type(a.b) is type(None)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB169
|
||||
30 |
|
||||
31 | type(
|
||||
|
|
||||
= help: Replace with `is None`
|
||||
|
||||
ℹ Safe fix
|
||||
26 26 |
|
||||
27 27 | type(None) != type(None)
|
||||
28 28 |
|
||||
29 |-type(a.b) is type(None)
|
||||
29 |+a.b is None
|
||||
30 30 |
|
||||
31 31 | type(
|
||||
32 32 | a(
|
||||
|
||||
FURB169.py:31:1: FURB169 [*] When checking against `None`, use `is not` instead of comparison with `type(None)`
|
||||
|
|
||||
29 | type(a.b) is type(None)
|
||||
30 |
|
||||
31 | / type(
|
||||
32 | | a(
|
||||
33 | | # Comment
|
||||
34 | | )
|
||||
35 | | ) != type(None)
|
||||
| |_______________^ FURB169
|
||||
36 |
|
||||
37 | type(
|
||||
|
|
||||
= help: Replace with `is not None`
|
||||
|
||||
ℹ Unsafe fix
|
||||
28 28 |
|
||||
29 29 | type(a.b) is type(None)
|
||||
30 30 |
|
||||
31 |-type(
|
||||
32 |- a(
|
||||
33 |- # Comment
|
||||
34 |- )
|
||||
35 |-) != type(None)
|
||||
31 |+a() is not None
|
||||
36 32 |
|
||||
37 33 | type(
|
||||
38 34 | a := 1
|
||||
|
||||
FURB169.py:37:1: FURB169 [*] When checking against `None`, use `is` instead of comparison with `type(None)`
|
||||
|
|
||||
35 | ) != type(None)
|
||||
36 |
|
||||
37 | / type(
|
||||
38 | | a := 1
|
||||
39 | | ) == type(None)
|
||||
| |_______________^ FURB169
|
||||
40 |
|
||||
41 | type(
|
||||
|
|
||||
= help: Replace with `is None`
|
||||
|
||||
ℹ Safe fix
|
||||
34 34 | )
|
||||
35 35 | ) != type(None)
|
||||
36 36 |
|
||||
37 |-type(
|
||||
38 |- a := 1
|
||||
39 |-) == type(None)
|
||||
37 |+(a := 1) is None
|
||||
40 38 |
|
||||
41 39 | type(
|
||||
42 40 | a for a in range(0)
|
||||
|
||||
FURB169.py:41:1: FURB169 [*] When checking against `None`, use `is not` instead of comparison with `type(None)`
|
||||
|
|
||||
39 | ) == type(None)
|
||||
40 |
|
||||
41 | / type(
|
||||
42 | | a for a in range(0)
|
||||
43 | | ) is not type(None)
|
||||
| |___________________^ FURB169
|
||||
|
|
||||
= help: Replace with `is not None`
|
||||
|
||||
ℹ Safe fix
|
||||
38 38 | a := 1
|
||||
39 39 | ) == type(None)
|
||||
40 40 |
|
||||
41 |-type(
|
||||
42 |- a for a in range(0)
|
||||
43 |-) is not type(None)
|
||||
41 |+(a for a in range(0)) is not None
|
||||
44 42 |
|
||||
45 43 |
|
||||
46 44 | # Ok.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user