From e28d9d9e9eb35162bc971549abdb808ddca287a6 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 9 Sep 2024 15:45:17 -0400 Subject: [PATCH] Add tests for invalid syntax --- .../src/types/infer.rs | 60 ++++++++++++++++--- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/crates/red_knot_python_semantic/src/types/infer.rs b/crates/red_knot_python_semantic/src/types/infer.rs index 225ad37d09d8ac..da804e26875bc3 100644 --- a/crates/red_knot_python_semantic/src/types/infer.rs +++ b/crates/red_knot_python_semantic/src/types/infer.rs @@ -4414,15 +4414,10 @@ mod tests { } #[test] - fn comprehension_with_not_iterable_iter() -> anyhow::Result<()> { + fn comprehension_with_unbound_iter() -> anyhow::Result<()> { let mut db = setup_db(); - db.write_dedented( - "src/a.py", - " - [z for z in x] - ", - )?; + db.write_dedented("src/a.py", "[z for z in x]")?; assert_scope_ty(&db, "src/a.py", &[""], "x", "Unbound"); @@ -4518,6 +4513,57 @@ mod tests { Ok(()) } + #[test] + fn comprehension_with_missing_in_keyword() -> anyhow::Result<()> { + let mut db = setup_db(); + + db.write_dedented( + "src/a.py", + " + def foo(): + [z for z IntIterable()] + + class IntIterator: + def __next__(self) -> int: + return 42 + + class IntIterable: + def __iter__(self) -> IntIterator: + return IntIterator() + ", + )?; + + // We'll emit a diagnostic separately for invalid syntax, + // but it's reasonably clear here what they *meant* to write, + // so we'll still infer the correct type: + assert_scope_ty(&db, "src/a.py", &["foo", ""], "z", "int"); + Ok(()) + } + + #[test] + fn comprehension_with_missing_in_keyword_and_missing_iter() -> anyhow::Result<()> { + let mut db = setup_db(); + + db.write_dedented( + "src/a.py", + " + def foo(): + [z for z] + + class IntIterator: + def __next__(self) -> int: + return 42 + + class IntIterable: + def __iter__(self) -> IntIterator: + return IntIterator() + ", + )?; + + assert_scope_ty(&db, "src/a.py", &["foo", ""], "z", "Unknown"); + Ok(()) + } + /// This tests that we understand that `async` comprehensions /// do not work according to the synchronous iteration protocol #[test]