mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
Move compare-to-empty-string
to nursery (#5264)
## Summary This rule has too many false positives. It has parity with the Pylint version, but the Pylint version is part of an [extension](https://pylint.readthedocs.io/en/stable/user_guide/messages/convention/compare-to-empty-string.html), and so requires explicit opt-in. I'm moving this rule to the nursery to require explicit opt-in, as with Pylint. Closes #4282.
This commit is contained in:
parent
9419d3f9c8
commit
62e2c46f98
3 changed files with 56 additions and 55 deletions
|
@ -157,7 +157,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
|||
|
||||
// pylint
|
||||
(Pylint, "C0414") => (RuleGroup::Unspecified, rules::pylint::rules::UselessImportAlias),
|
||||
(Pylint, "C1901") => (RuleGroup::Unspecified, rules::pylint::rules::CompareToEmptyString),
|
||||
(Pylint, "C1901") => (RuleGroup::Nursery, rules::pylint::rules::CompareToEmptyString),
|
||||
(Pylint, "C3002") => (RuleGroup::Unspecified, rules::pylint::rules::UnnecessaryDirectLambdaCall),
|
||||
(Pylint, "C0208") => (RuleGroup::Unspecified, rules::pylint::rules::IterationOverSet),
|
||||
(Pylint, "E0100") => (RuleGroup::Unspecified, rules::pylint::rules::YieldInInit),
|
||||
|
|
|
@ -7,49 +7,6 @@ use ruff_macros::{derive_message_formats, violation};
|
|||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub(crate) enum EmptyStringCmpOp {
|
||||
Is,
|
||||
IsNot,
|
||||
Eq,
|
||||
NotEq,
|
||||
}
|
||||
|
||||
impl TryFrom<&CmpOp> for EmptyStringCmpOp {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: &CmpOp) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
CmpOp::Is => Ok(Self::Is),
|
||||
CmpOp::IsNot => Ok(Self::IsNot),
|
||||
CmpOp::Eq => Ok(Self::Eq),
|
||||
CmpOp::NotEq => Ok(Self::NotEq),
|
||||
_ => bail!("{value:?} cannot be converted to EmptyStringCmpOp"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EmptyStringCmpOp {
|
||||
pub(crate) fn into_unary(self) -> &'static str {
|
||||
match self {
|
||||
Self::Is | Self::Eq => "not ",
|
||||
Self::IsNot | Self::NotEq => "",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for EmptyStringCmpOp {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let repr = match self {
|
||||
Self::Is => "is",
|
||||
Self::IsNot => "is not",
|
||||
Self::Eq => "==",
|
||||
Self::NotEq => "!=",
|
||||
};
|
||||
write!(f, "{repr}")
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for comparisons to empty strings.
|
||||
///
|
||||
|
@ -83,13 +40,15 @@ pub struct CompareToEmptyString {
|
|||
impl Violation for CompareToEmptyString {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!(
|
||||
"`{}` can be simplified to `{}` as an empty string is falsey",
|
||||
self.existing, self.replacement,
|
||||
)
|
||||
let CompareToEmptyString {
|
||||
existing,
|
||||
replacement,
|
||||
} = self;
|
||||
format!("`{existing}` can be simplified to `{replacement}` as an empty string is falsey",)
|
||||
}
|
||||
}
|
||||
|
||||
/// PLC1901
|
||||
pub(crate) fn compare_to_empty_string(
|
||||
checker: &mut Checker,
|
||||
left: &Expr,
|
||||
|
@ -98,10 +57,12 @@ pub(crate) fn compare_to_empty_string(
|
|||
) {
|
||||
// Omit string comparison rules within subscripts. This is mostly commonly used within
|
||||
// DataFrame and np.ndarray indexing.
|
||||
for parent in checker.semantic().expr_ancestors() {
|
||||
if matches!(parent, Expr::Subscript(_)) {
|
||||
return;
|
||||
}
|
||||
if checker
|
||||
.semantic()
|
||||
.expr_ancestors()
|
||||
.any(|parent| parent.is_subscript_expr())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let mut first = true;
|
||||
|
@ -153,3 +114,46 @@ pub(crate) fn compare_to_empty_string(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
enum EmptyStringCmpOp {
|
||||
Is,
|
||||
IsNot,
|
||||
Eq,
|
||||
NotEq,
|
||||
}
|
||||
|
||||
impl TryFrom<&CmpOp> for EmptyStringCmpOp {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: &CmpOp) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
CmpOp::Is => Ok(Self::Is),
|
||||
CmpOp::IsNot => Ok(Self::IsNot),
|
||||
CmpOp::Eq => Ok(Self::Eq),
|
||||
CmpOp::NotEq => Ok(Self::NotEq),
|
||||
_ => bail!("{value:?} cannot be converted to EmptyStringCmpOp"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EmptyStringCmpOp {
|
||||
fn into_unary(self) -> &'static str {
|
||||
match self {
|
||||
Self::Is | Self::Eq => "not ",
|
||||
Self::IsNot | Self::NotEq => "",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for EmptyStringCmpOp {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let repr = match self {
|
||||
Self::Is => "is",
|
||||
Self::IsNot => "is not",
|
||||
Self::Eq => "==",
|
||||
Self::NotEq => "!=",
|
||||
};
|
||||
write!(f, "{repr}")
|
||||
}
|
||||
}
|
||||
|
|
3
ruff.schema.json
generated
3
ruff.schema.json
generated
|
@ -2093,9 +2093,6 @@
|
|||
"PLC04",
|
||||
"PLC041",
|
||||
"PLC0414",
|
||||
"PLC1",
|
||||
"PLC19",
|
||||
"PLC190",
|
||||
"PLC1901",
|
||||
"PLC3",
|
||||
"PLC30",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue