mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 05:14:52 +00:00
[ruff
] Recognize t-strings, generators, and lambdas in invalid-index-type
(RUF016
) (#20213)
## Summary Fixes #20204 Recognize t-strings, generators, and lambdas in RUF016 - Accept boolean literals as valid index and slice bounds. - Add TString, Generator, and Lambda to `CheckableExprType`. - Expand RUF016.py fixture and update snapshots accordingly.
This commit is contained in:
parent
b6bd32d9dc
commit
ff677a96e4
3 changed files with 58 additions and 2 deletions
|
@ -113,3 +113,18 @@ var = bytearray(b"abc")["x"]
|
||||||
x = "x"
|
x = "x"
|
||||||
var = [1, 2, 3][0:x]
|
var = [1, 2, 3][0:x]
|
||||||
var = [1, 2, 3][x:1]
|
var = [1, 2, 3][x:1]
|
||||||
|
|
||||||
|
# https://github.com/astral-sh/ruff/issues/20204
|
||||||
|
|
||||||
|
# Should not emit for boolean index and slice bounds
|
||||||
|
var = [1, 2, 3][False]
|
||||||
|
var = [1, 2, 3][False:True:True]
|
||||||
|
|
||||||
|
# Should emit for invalid access using t-string
|
||||||
|
var = [1, 2][t"x"]
|
||||||
|
|
||||||
|
# Should emit for invalid access using lambda
|
||||||
|
var = [1, 2, 3][lambda: 0]
|
||||||
|
|
||||||
|
# Should emit for invalid access using generator
|
||||||
|
var = [1, 2, 3][(x for x in ())]
|
||||||
|
|
|
@ -89,7 +89,9 @@ pub(crate) fn invalid_index_type(checker: &Checker, expr: &ExprSubscript) {
|
||||||
|
|
||||||
if index_type.is_literal() {
|
if index_type.is_literal() {
|
||||||
// If the index is a literal, require an integer
|
// If the index is a literal, require an integer
|
||||||
if index_type != CheckableExprType::IntLiteral {
|
if index_type != CheckableExprType::IntLiteral
|
||||||
|
&& index_type != CheckableExprType::BooleanLiteral
|
||||||
|
{
|
||||||
checker.report_diagnostic(
|
checker.report_diagnostic(
|
||||||
InvalidIndexType {
|
InvalidIndexType {
|
||||||
value_type: value_type.to_string(),
|
value_type: value_type.to_string(),
|
||||||
|
@ -111,7 +113,9 @@ pub(crate) fn invalid_index_type(checker: &Checker, expr: &ExprSubscript) {
|
||||||
// If the index is a slice, require integer or null bounds
|
// If the index is a slice, require integer or null bounds
|
||||||
if !matches!(
|
if !matches!(
|
||||||
is_slice_type,
|
is_slice_type,
|
||||||
CheckableExprType::IntLiteral | CheckableExprType::NoneLiteral
|
CheckableExprType::IntLiteral
|
||||||
|
| CheckableExprType::NoneLiteral
|
||||||
|
| CheckableExprType::BooleanLiteral
|
||||||
) {
|
) {
|
||||||
checker.report_diagnostic(
|
checker.report_diagnostic(
|
||||||
InvalidIndexType {
|
InvalidIndexType {
|
||||||
|
@ -154,6 +158,7 @@ pub(crate) fn invalid_index_type(checker: &Checker, expr: &ExprSubscript) {
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
enum CheckableExprType {
|
enum CheckableExprType {
|
||||||
FString,
|
FString,
|
||||||
|
TString,
|
||||||
StringLiteral,
|
StringLiteral,
|
||||||
BytesLiteral,
|
BytesLiteral,
|
||||||
IntLiteral,
|
IntLiteral,
|
||||||
|
@ -170,12 +175,15 @@ enum CheckableExprType {
|
||||||
Dict,
|
Dict,
|
||||||
Tuple,
|
Tuple,
|
||||||
Slice,
|
Slice,
|
||||||
|
Generator,
|
||||||
|
Lambda,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CheckableExprType {
|
impl fmt::Display for CheckableExprType {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::FString => f.write_str("str"),
|
Self::FString => f.write_str("str"),
|
||||||
|
Self::TString => f.write_str("Template"),
|
||||||
Self::StringLiteral => f.write_str("str"),
|
Self::StringLiteral => f.write_str("str"),
|
||||||
Self::BytesLiteral => f.write_str("bytes"),
|
Self::BytesLiteral => f.write_str("bytes"),
|
||||||
Self::IntLiteral => f.write_str("int"),
|
Self::IntLiteral => f.write_str("int"),
|
||||||
|
@ -192,6 +200,8 @@ impl fmt::Display for CheckableExprType {
|
||||||
Self::Slice => f.write_str("slice"),
|
Self::Slice => f.write_str("slice"),
|
||||||
Self::Dict => f.write_str("dict"),
|
Self::Dict => f.write_str("dict"),
|
||||||
Self::Tuple => f.write_str("tuple"),
|
Self::Tuple => f.write_str("tuple"),
|
||||||
|
Self::Generator => f.write_str("generator"),
|
||||||
|
Self::Lambda => f.write_str("lambda"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,6 +219,7 @@ impl CheckableExprType {
|
||||||
Expr::BooleanLiteral(_) => Some(Self::BooleanLiteral),
|
Expr::BooleanLiteral(_) => Some(Self::BooleanLiteral),
|
||||||
Expr::NoneLiteral(_) => Some(Self::NoneLiteral),
|
Expr::NoneLiteral(_) => Some(Self::NoneLiteral),
|
||||||
Expr::EllipsisLiteral(_) => Some(Self::EllipsisLiteral),
|
Expr::EllipsisLiteral(_) => Some(Self::EllipsisLiteral),
|
||||||
|
Expr::TString(_) => Some(Self::TString),
|
||||||
Expr::FString(_) => Some(Self::FString),
|
Expr::FString(_) => Some(Self::FString),
|
||||||
Expr::List(_) => Some(Self::List),
|
Expr::List(_) => Some(Self::List),
|
||||||
Expr::ListComp(_) => Some(Self::ListComp),
|
Expr::ListComp(_) => Some(Self::ListComp),
|
||||||
|
@ -218,6 +229,8 @@ impl CheckableExprType {
|
||||||
Expr::Dict(_) => Some(Self::Dict),
|
Expr::Dict(_) => Some(Self::Dict),
|
||||||
Expr::Tuple(_) => Some(Self::Tuple),
|
Expr::Tuple(_) => Some(Self::Tuple),
|
||||||
Expr::Slice(_) => Some(Self::Slice),
|
Expr::Slice(_) => Some(Self::Slice),
|
||||||
|
Expr::Generator(_) => Some(Self::Generator),
|
||||||
|
Expr::Lambda(_) => Some(Self::Lambda),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -415,3 +415,31 @@ RUF016 Indexed access to type `list` uses type `str` instead of an integer or sl
|
||||||
95 |
|
95 |
|
||||||
96 | # Cannot emit on invalid access using variable in index
|
96 | # Cannot emit on invalid access using variable in index
|
||||||
|
|
|
|
||||||
|
|
||||||
|
RUF016 Indexed access to type `list` uses type `Template` instead of an integer or slice
|
||||||
|
--> RUF016.py:124:14
|
||||||
|
|
|
||||||
|
123 | # Should emit for invalid access using t-string
|
||||||
|
124 | var = [1, 2][t"x"]
|
||||||
|
| ^^^^
|
||||||
|
125 |
|
||||||
|
126 | # Should emit for invalid access using lambda
|
||||||
|
|
|
||||||
|
|
||||||
|
RUF016 Indexed access to type `list` uses type `lambda` instead of an integer or slice
|
||||||
|
--> RUF016.py:127:17
|
||||||
|
|
|
||||||
|
126 | # Should emit for invalid access using lambda
|
||||||
|
127 | var = [1, 2, 3][lambda: 0]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
128 |
|
||||||
|
129 | # Should emit for invalid access using generator
|
||||||
|
|
|
||||||
|
|
||||||
|
RUF016 Indexed access to type `list` uses type `generator` instead of an integer or slice
|
||||||
|
--> RUF016.py:130:17
|
||||||
|
|
|
||||||
|
129 | # Should emit for invalid access using generator
|
||||||
|
130 | var = [1, 2, 3][(x for x in ())]
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue