mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 05:45:24 +00:00
Use __class_getitem__
for more specific non-subscript errors (#13596)
This commit is contained in:
parent
0a6dc8e1b8
commit
961fc98344
1 changed files with 34 additions and 3 deletions
|
@ -1327,12 +1327,13 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||||
&mut self,
|
&mut self,
|
||||||
node: AnyNodeRef,
|
node: AnyNodeRef,
|
||||||
non_subscriptable_ty: Type<'db>,
|
non_subscriptable_ty: Type<'db>,
|
||||||
|
method: &str,
|
||||||
) {
|
) {
|
||||||
self.add_diagnostic(
|
self.add_diagnostic(
|
||||||
node,
|
node,
|
||||||
"non-subscriptable",
|
"non-subscriptable",
|
||||||
format_args!(
|
format_args!(
|
||||||
"Cannot subscript object of type '{}' with no `__getitem__` method.",
|
"Cannot subscript object of type '{}' with no `{method}` method.",
|
||||||
non_subscriptable_ty.display(self.db)
|
non_subscriptable_ty.display(self.db)
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -2627,10 +2628,16 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||||
.call(self.db, &[slice_ty])
|
.call(self.db, &[slice_ty])
|
||||||
.unwrap_with_diagnostic(self.db, value.as_ref().into(), self);
|
.unwrap_with_diagnostic(self.db, value.as_ref().into(), self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.non_subscriptable_diagnostic(
|
||||||
|
(&**value).into(),
|
||||||
|
value_ty,
|
||||||
|
"__class_getitem__",
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.non_subscriptable_diagnostic((&**value).into(), value_ty, "__getitem__");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, emit a diagnostic.
|
|
||||||
self.non_subscriptable_diagnostic((&**value).into(), value_ty);
|
|
||||||
Type::Unknown
|
Type::Unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6791,6 +6798,30 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn subscript_class_getitem_unbound() -> anyhow::Result<()> {
|
||||||
|
let mut db = setup_db();
|
||||||
|
|
||||||
|
db.write_dedented(
|
||||||
|
"/src/a.py",
|
||||||
|
"
|
||||||
|
class NotSubscriptable:
|
||||||
|
pass
|
||||||
|
|
||||||
|
a = NotSubscriptable[0]
|
||||||
|
",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
assert_public_ty(&db, "/src/a.py", "a", "Unknown");
|
||||||
|
assert_file_diagnostics(
|
||||||
|
&db,
|
||||||
|
"/src/a.py",
|
||||||
|
&["Cannot subscript object of type 'Literal[NotSubscriptable]' with no `__class_getitem__` method."],
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn subscript_not_callable_getitem() -> anyhow::Result<()> {
|
fn subscript_not_callable_getitem() -> anyhow::Result<()> {
|
||||||
let mut db = setup_db();
|
let mut db = setup_db();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue