mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[flake8-bugbear
] Mark autofix for B004
as unsafe if the hasattr
call expr contains comments (#18755)
This commit is contained in:
parent
4c8d612120
commit
f7a741a99e
3 changed files with 64 additions and 2 deletions
|
@ -29,3 +29,13 @@ def this_is_fine():
|
|||
o = object()
|
||||
if callable(o):
|
||||
print("Ooh, this is actually callable.")
|
||||
|
||||
# https://github.com/astral-sh/ruff/issues/18741
|
||||
# The autofix for this is unsafe due to the comments.
|
||||
hasattr(
|
||||
# comment 1
|
||||
obj, # comment 2
|
||||
# comment 3
|
||||
"__call__", # comment 4
|
||||
# comment 5
|
||||
)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use ruff_diagnostics::Applicability;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -26,6 +27,21 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
|||
/// callable(obj)
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// This rule's fix is marked as unsafe if there's comments in the `hasattr` call
|
||||
/// expression, as comments may be removed.
|
||||
///
|
||||
/// For example, the fix would be marked as unsafe in the following case:
|
||||
/// ```python
|
||||
/// hasattr(
|
||||
/// # comment 1
|
||||
/// obj, # comment 2
|
||||
/// # comment 3
|
||||
/// "__call__", # comment 4
|
||||
/// # comment 5
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `callable`](https://docs.python.org/3/library/functions.html#callable)
|
||||
/// - [Python documentation: `hasattr`](https://docs.python.org/3/library/functions.html#hasattr)
|
||||
|
@ -84,7 +100,15 @@ pub(crate) fn unreliable_callable_check(
|
|||
format!("{binding}({})", checker.locator().slice(obj)),
|
||||
expr.range(),
|
||||
);
|
||||
Ok(Fix::safe_edits(binding_edit, import_edit))
|
||||
Ok(Fix::applicable_edits(
|
||||
binding_edit,
|
||||
import_edit,
|
||||
if checker.comment_ranges().intersects(expr.range()) {
|
||||
Applicability::Unsafe
|
||||
} else {
|
||||
Applicability::Safe
|
||||
},
|
||||
))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,4 +85,32 @@ B004.py:24:8: B004 [*] Using `hasattr(x, "__call__")` to test if x is callable i
|
|||
25 |+ if builtins.callable(o):
|
||||
25 26 | print("STILL a bug!")
|
||||
26 27 |
|
||||
27 28 |
|
||||
27 28 |
|
||||
|
||||
B004.py:35:1: B004 [*] Using `hasattr(x, "__call__")` to test if x is callable is unreliable. Use `callable(x)` for consistent results.
|
||||
|
|
||||
33 | # https://github.com/astral-sh/ruff/issues/18741
|
||||
34 | # The autofix for this is unsafe due to the comments.
|
||||
35 | / hasattr(
|
||||
36 | | # comment 1
|
||||
37 | | obj, # comment 2
|
||||
38 | | # comment 3
|
||||
39 | | "__call__", # comment 4
|
||||
40 | | # comment 5
|
||||
41 | | )
|
||||
| |_^ B004
|
||||
|
|
||||
= help: Replace with `callable()`
|
||||
|
||||
ℹ Unsafe fix
|
||||
32 32 |
|
||||
33 33 | # https://github.com/astral-sh/ruff/issues/18741
|
||||
34 34 | # The autofix for this is unsafe due to the comments.
|
||||
35 |-hasattr(
|
||||
36 |- # comment 1
|
||||
37 |- obj, # comment 2
|
||||
38 |- # comment 3
|
||||
39 |- "__call__", # comment 4
|
||||
40 |- # comment 5
|
||||
41 |-)
|
||||
35 |+callable(obj)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue