diff --git a/resources/test/fixtures/flake8_bugbear/B024.py b/resources/test/fixtures/flake8_bugbear/B024.py index 86e5eb4c2a..854e9b08ad 100644 --- a/resources/test/fixtures/flake8_bugbear/B024.py +++ b/resources/test/fixtures/flake8_bugbear/B024.py @@ -1,15 +1,16 @@ """ Should emit: -B024 - on lines 17, 34, 52, 58, 69, 74, 79, 84, 89 +B024 - on lines 18, 71, 82, 87, 92, 141 """ import abc import abc as notabc from abc import ABC, ABCMeta -from abc import abstractmethod +from abc import abstractmethod, abstractproperty from abc import abstractmethod as abstract from abc import abstractmethod as abstractaoeuaoeuaoeu from abc import abstractmethod as notabstract +from abc import abstractproperty as notabstract_property import foo @@ -49,12 +50,24 @@ class Base_6(ABC): foo() -class Base_7(ABC): # error +class Base_7(ABC): @notabstract def method(self): foo() +class Base_8(ABC): + @notabstract_property + def method(self): + foo() + + +class Base_9(ABC): + @abstractproperty + def method(self): + foo() + + class MetaBase_1(metaclass=ABCMeta): # error def method(self): foo() diff --git a/resources/test/fixtures/flake8_bugbear/B027.py b/resources/test/fixtures/flake8_bugbear/B027.py index 6a5472a616..d7d563c365 100644 --- a/resources/test/fixtures/flake8_bugbear/B027.py +++ b/resources/test/fixtures/flake8_bugbear/B027.py @@ -1,11 +1,12 @@ """ Should emit: -B027 - on lines 12, 15, 18, 22, 30 +B027 - on lines 13, 16, 19, 23 """ import abc from abc import ABC -from abc import abstractmethod +from abc import abstractmethod, abstractproperty from abc import abstractmethod as notabstract +from abc import abstractproperty as notabstract_property class AbstractClass(ABC): @@ -42,6 +43,18 @@ class AbstractClass(ABC): def abstract_3(self): ... + @abc.abstractproperty + def abstract_4(self): + ... + + @abstractproperty + def abstract_5(self): + ... + + @notabstract_property + def abstract_6(self): + ... + def body_1(self): print("foo") ... diff --git a/src/flake8_bugbear/rules/abstract_base_class.rs b/src/flake8_bugbear/rules/abstract_base_class.rs index ed660c3d30..b1023fd079 100644 --- a/src/flake8_bugbear/rules/abstract_base_class.rs +++ b/src/flake8_bugbear/rules/abstract_base_class.rs @@ -52,6 +52,20 @@ fn is_abstractmethod( match_module_member(expr, "abc", "abstractmethod", from_imports, import_aliases) } +fn is_abstractproperty( + expr: &Expr, + from_imports: &FxHashMap<&str, FxHashSet<&str>>, + import_aliases: &FxHashMap<&str, &str>, +) -> bool { + match_module_member( + expr, + "abc", + "abstractproperty", + from_imports, + import_aliases, + ) +} + fn is_overload( expr: &Expr, from_imports: &FxHashMap<&str, FxHashSet<&str>>, @@ -102,9 +116,10 @@ pub fn abstract_base_class( continue; }; - let has_abstract_decorator = decorator_list - .iter() - .any(|d| is_abstractmethod(d, &checker.from_imports, &checker.import_aliases)); + let has_abstract_decorator = decorator_list.iter().any(|d| { + is_abstractmethod(d, &checker.from_imports, &checker.import_aliases) + || is_abstractproperty(d, &checker.from_imports, &checker.import_aliases) + }); has_abstract_method |= has_abstract_decorator; diff --git a/src/flake8_bugbear/snapshots/ruff__flake8_bugbear__tests__B024_B024.py.snap b/src/flake8_bugbear/snapshots/ruff__flake8_bugbear__tests__B024_B024.py.snap index 6d67534c70..d2345d5438 100644 --- a/src/flake8_bugbear/snapshots/ruff__flake8_bugbear__tests__B024_B024.py.snap +++ b/src/flake8_bugbear/snapshots/ruff__flake8_bugbear__tests__B024_B024.py.snap @@ -1,64 +1,64 @@ --- source: src/flake8_bugbear/mod.rs -expression: checks +expression: diagnostics --- - kind: AbstractBaseClassWithoutAbstractMethod: Base_1 location: - row: 17 + row: 18 column: 0 end_location: - row: 19 + row: 20 column: 13 fix: ~ parent: ~ - kind: AbstractBaseClassWithoutAbstractMethod: MetaBase_1 location: - row: 58 + row: 71 column: 0 end_location: - row: 60 + row: 73 column: 13 fix: ~ parent: ~ - kind: AbstractBaseClassWithoutAbstractMethod: abc_Base_1 location: - row: 69 + row: 82 column: 0 end_location: - row: 71 + row: 84 column: 13 fix: ~ parent: ~ - kind: AbstractBaseClassWithoutAbstractMethod: abc_Base_2 location: - row: 74 + row: 87 column: 0 end_location: - row: 76 + row: 89 column: 13 fix: ~ parent: ~ - kind: AbstractBaseClassWithoutAbstractMethod: notabc_Base_1 location: - row: 79 + row: 92 column: 0 end_location: - row: 81 + row: 94 column: 13 fix: ~ parent: ~ - kind: AbstractBaseClassWithoutAbstractMethod: abc_set_class_variable_4 location: - row: 128 + row: 141 column: 0 end_location: - row: 129 + row: 142 column: 7 fix: ~ parent: ~ diff --git a/src/flake8_bugbear/snapshots/ruff__flake8_bugbear__tests__B027_B027.py.snap b/src/flake8_bugbear/snapshots/ruff__flake8_bugbear__tests__B027_B027.py.snap index 0a2d120421..0ede6284de 100644 --- a/src/flake8_bugbear/snapshots/ruff__flake8_bugbear__tests__B027_B027.py.snap +++ b/src/flake8_bugbear/snapshots/ruff__flake8_bugbear__tests__B027_B027.py.snap @@ -1,44 +1,44 @@ --- source: src/flake8_bugbear/mod.rs -expression: checks +expression: diagnostics --- - kind: EmptyMethodWithoutAbstractDecorator: AbstractClass location: - row: 12 + row: 13 column: 4 end_location: - row: 13 + row: 14 column: 11 fix: ~ parent: ~ - kind: EmptyMethodWithoutAbstractDecorator: AbstractClass location: - row: 15 + row: 16 column: 4 end_location: - row: 16 + row: 17 column: 12 fix: ~ parent: ~ - kind: EmptyMethodWithoutAbstractDecorator: AbstractClass location: - row: 18 + row: 19 column: 4 end_location: - row: 20 + row: 21 column: 11 fix: ~ parent: ~ - kind: EmptyMethodWithoutAbstractDecorator: AbstractClass location: - row: 22 + row: 23 column: 4 end_location: - row: 27 + row: 28 column: 12 fix: ~ parent: ~