Skip to content

Commit 961fc98

Browse files
Use __class_getitem__ for more specific non-subscript errors (#13596)
1 parent 0a6dc8e commit 961fc98

File tree

1 file changed

+34
-3
lines changed
  • crates/red_knot_python_semantic/src/types

1 file changed

+34
-3
lines changed

crates/red_knot_python_semantic/src/types/infer.rs

+34-3
Original file line numberDiff line numberDiff line change
@@ -1327,12 +1327,13 @@ impl<'db> TypeInferenceBuilder<'db> {
13271327
&mut self,
13281328
node: AnyNodeRef,
13291329
non_subscriptable_ty: Type<'db>,
1330+
method: &str,
13301331
) {
13311332
self.add_diagnostic(
13321333
node,
13331334
"non-subscriptable",
13341335
format_args!(
1335-
"Cannot subscript object of type '{}' with no `__getitem__` method.",
1336+
"Cannot subscript object of type '{}' with no `{method}` method.",
13361337
non_subscriptable_ty.display(self.db)
13371338
),
13381339
);
@@ -2627,10 +2628,16 @@ impl<'db> TypeInferenceBuilder<'db> {
26272628
.call(self.db, &[slice_ty])
26282629
.unwrap_with_diagnostic(self.db, value.as_ref().into(), self);
26292630
}
2631+
2632+
self.non_subscriptable_diagnostic(
2633+
(&**value).into(),
2634+
value_ty,
2635+
"__class_getitem__",
2636+
);
2637+
} else {
2638+
self.non_subscriptable_diagnostic((&**value).into(), value_ty, "__getitem__");
26302639
}
26312640

2632-
// Otherwise, emit a diagnostic.
2633-
self.non_subscriptable_diagnostic((&**value).into(), value_ty);
26342641
Type::Unknown
26352642
}
26362643
}
@@ -6791,6 +6798,30 @@ mod tests {
67916798
Ok(())
67926799
}
67936800

6801+
#[test]
6802+
fn subscript_class_getitem_unbound() -> anyhow::Result<()> {
6803+
let mut db = setup_db();
6804+
6805+
db.write_dedented(
6806+
"/src/a.py",
6807+
"
6808+
class NotSubscriptable:
6809+
pass
6810+
6811+
a = NotSubscriptable[0]
6812+
",
6813+
)?;
6814+
6815+
assert_public_ty(&db, "/src/a.py", "a", "Unknown");
6816+
assert_file_diagnostics(
6817+
&db,
6818+
"/src/a.py",
6819+
&["Cannot subscript object of type 'Literal[NotSubscriptable]' with no `__class_getitem__` method."],
6820+
);
6821+
6822+
Ok(())
6823+
}
6824+
67946825
#[test]
67956826
fn subscript_not_callable_getitem() -> anyhow::Result<()> {
67966827
let mut db = setup_db();

0 commit comments

Comments
 (0)