mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:48:32 +00:00
[flake8-bugbear
] Do not raise error if keyword argument is present and target-python version is less or equals than 3.9 (B903
) (#15549)
This commit is contained in:
parent
4328df7226
commit
4fdf8af747
5 changed files with 118 additions and 2 deletions
|
@ -95,4 +95,10 @@ class WarningsWithDocstring:
|
|||
self.foo = foo
|
||||
self.bar = bar
|
||||
|
||||
|
||||
class KeywordOnly: # OK with python3.9 or less, not OK starting python3.10
|
||||
def __init__(self, *, foo: int, bar: int):
|
||||
self.foo = foo
|
||||
self.bar = bar
|
||||
|
||||
# <-- end flake8-bugbear tests
|
||||
|
|
|
@ -16,6 +16,8 @@ mod tests {
|
|||
use crate::settings::LinterSettings;
|
||||
use crate::test::test_path;
|
||||
|
||||
use crate::settings::types::PythonVersion;
|
||||
|
||||
#[test_case(Rule::AbstractBaseClassWithoutAbstractMethod, Path::new("B024.py"))]
|
||||
#[test_case(Rule::AssertFalse, Path::new("B011.py"))]
|
||||
#[test_case(Rule::AssertRaisesException, Path::new("B017.py"))]
|
||||
|
@ -78,6 +80,34 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(
|
||||
Rule::ClassAsDataStructure,
|
||||
Path::new("class_as_data_structure.py"),
|
||||
PythonVersion::Py39
|
||||
)]
|
||||
fn rules_with_target_version(
|
||||
rule_code: Rule,
|
||||
path: &Path,
|
||||
target_version: PythonVersion,
|
||||
) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"{}_py{}{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
target_version.major(),
|
||||
target_version.minor(),
|
||||
path.to_string_lossy(),
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_bugbear").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
target_version,
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zip_without_explicit_strict() -> Result<()> {
|
||||
let snapshot = "B905.py";
|
||||
|
|
|
@ -5,6 +5,7 @@ use ruff_python_semantic::analyze::visibility::{self, Visibility::Public};
|
|||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::settings::types::PythonVersion;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for classes that only have a public `__init__` method,
|
||||
|
@ -77,6 +78,7 @@ pub(crate) fn class_as_data_structure(checker: &mut Checker, class_def: &ast::St
|
|||
// skip `self`
|
||||
.skip(1)
|
||||
.all(|param| param.annotation().is_some() && !param.is_variadic())
|
||||
&& (func_def.parameters.kwonlyargs.is_empty() || checker.settings.target_version >= PythonVersion::Py310)
|
||||
// `__init__` should not have complicated logic in it
|
||||
// only assignments
|
||||
&& func_def
|
||||
|
|
|
@ -66,6 +66,15 @@ class_as_data_structure.py:91:1: B903 Class could be dataclass or namedtuple
|
|||
95 | | self.foo = foo
|
||||
96 | | self.bar = bar
|
||||
| |______________________^ B903
|
||||
97 |
|
||||
98 | # <-- end flake8-bugbear tests
|
||||
|
|
||||
|
||||
class_as_data_structure.py:99:1: B903 Class could be dataclass or namedtuple
|
||||
|
|
||||
99 | / class KeywordOnly: # OK with python3.9 or less, not OK starting python3.10
|
||||
100 | | def __init__(self, *, foo: int, bar: int):
|
||||
101 | | self.foo = foo
|
||||
102 | | self.bar = bar
|
||||
| |______________________^ B903
|
||||
103 |
|
||||
104 | # <-- end flake8-bugbear tests
|
||||
|
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
|
||||
---
|
||||
class_as_data_structure.py:6:1: B903 Class could be dataclass or namedtuple
|
||||
|
|
||||
6 | / class Point: # B903
|
||||
7 | | def __init__(self, x: float, y: float) -> None:
|
||||
8 | | self.x = x
|
||||
9 | | self.y = y
|
||||
| |__________________^ B903
|
||||
|
|
||||
|
||||
class_as_data_structure.py:40:1: B903 Class could be dataclass or namedtuple
|
||||
|
|
||||
38 | ...
|
||||
39 |
|
||||
40 | / class C: # B903
|
||||
41 | | c: int
|
||||
42 | | def __init__(self,d:list):
|
||||
43 | | self.d = d
|
||||
| |__________________^ B903
|
||||
44 |
|
||||
45 | class D: # B903
|
||||
|
|
||||
|
||||
class_as_data_structure.py:45:1: B903 Class could be dataclass or namedtuple
|
||||
|
|
||||
43 | self.d = d
|
||||
44 |
|
||||
45 | / class D: # B903
|
||||
46 | | """This class has a docstring."""
|
||||
47 | | # this next method is an init
|
||||
48 | | def __init__(self,e:dict):
|
||||
49 | | self.e = e
|
||||
| |__________________^ B903
|
||||
50 |
|
||||
51 | # <--- begin flake8-bugbear tests below
|
||||
|
|
||||
|
||||
class_as_data_structure.py:63:1: B903 Class could be dataclass or namedtuple
|
||||
|
|
||||
63 | / class NoWarningsClassAttributes:
|
||||
64 | | spam = "ham"
|
||||
65 | |
|
||||
66 | | def __init__(self, foo:int, bar:list):
|
||||
67 | | self.foo = foo
|
||||
68 | | self.bar = bar
|
||||
| |______________________^ B903
|
||||
|
|
||||
|
||||
class_as_data_structure.py:85:1: B903 Class could be dataclass or namedtuple
|
||||
|
|
||||
85 | / class Warnings:
|
||||
86 | | def __init__(self, foo:int, bar:list):
|
||||
87 | | self.foo = foo
|
||||
88 | | self.bar = bar
|
||||
| |______________________^ B903
|
||||
|
|
||||
|
||||
class_as_data_structure.py:91:1: B903 Class could be dataclass or namedtuple
|
||||
|
|
||||
91 | / class WarningsWithDocstring:
|
||||
92 | | """A docstring should not be an impediment to a warning"""
|
||||
93 | |
|
||||
94 | | def __init__(self, foo:int, bar:list):
|
||||
95 | | self.foo = foo
|
||||
96 | | self.bar = bar
|
||||
| |______________________^ B903
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue