From f8c20258aec5148029da904fe1ea91c1c8f1be50 Mon Sep 17 00:00:00 2001 From: David Peter Date: Tue, 19 Nov 2024 10:04:51 +0100 Subject: [PATCH] [red-knot] Do not panic on f-string format spec expressions (#14436) ## Summary Previously, we panicked on expressions like `f"{v:{f'0.2f'}}"` because we did not infer types for expressions nested inside format spec elements. ## Test Plan ``` cargo nextest run -p red_knot_workspace -- --ignored linter_af linter_gz ``` --- crates/red_knot_python_semantic/src/types/infer.rs | 6 ++++++ .../resources/test/corpus/94_strformat_conversion.py | 3 +++ crates/red_knot_workspace/tests/check.rs | 2 -- 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 crates/red_knot_workspace/resources/test/corpus/94_strformat_conversion.py diff --git a/crates/red_knot_python_semantic/src/types/infer.rs b/crates/red_knot_python_semantic/src/types/infer.rs index 1b33798a96..b6e8a76a07 100644 --- a/crates/red_knot_python_semantic/src/types/infer.rs +++ b/crates/red_knot_python_semantic/src/types/infer.rs @@ -2285,6 +2285,12 @@ impl<'db> TypeInferenceBuilder<'db> { } = expression; let ty = self.infer_expression(expression); + if let Some(ref format_spec) = format_spec { + for element in format_spec.elements.expressions() { + self.infer_expression(&element.expression); + } + } + // TODO: handle format specifiers by calling a method // (`Type::format`?) that handles the `__format__` method. // Conversion flags should be handled before calling `__format__`. diff --git a/crates/red_knot_workspace/resources/test/corpus/94_strformat_conversion.py b/crates/red_knot_workspace/resources/test/corpus/94_strformat_conversion.py new file mode 100644 index 0000000000..adf563cf77 --- /dev/null +++ b/crates/red_knot_workspace/resources/test/corpus/94_strformat_conversion.py @@ -0,0 +1,3 @@ +msg = "hello" + +f"{msg!r:>{10+10}}" diff --git a/crates/red_knot_workspace/tests/check.rs b/crates/red_knot_workspace/tests/check.rs index 8aae30b261..0a2ad2f426 100644 --- a/crates/red_knot_workspace/tests/check.rs +++ b/crates/red_knot_workspace/tests/check.rs @@ -283,9 +283,7 @@ const KNOWN_FAILURES: &[(&str, bool, bool)] = &[ ("crates/ruff_linter/resources/test/fixtures/pyflakes/F821_20.py", true, true), ("crates/ruff_linter/resources/test/fixtures/pyflakes/F821_26.py", true, false), // Fails for unknown reasons: - ("crates/ruff_linter/resources/test/fixtures/pyflakes/F541.py", true, true), ("crates/ruff_linter/resources/test/fixtures/pyflakes/F632.py", true, true), ("crates/ruff_linter/resources/test/fixtures/pyflakes/F811_19.py", true, false), ("crates/ruff_linter/resources/test/fixtures/pyupgrade/UP039.py", true, false), - ("crates/ruff_python_parser/resources/valid/expressions/f_string.py", true, true), ];