From 8a3a269eef85c4a44cbea749686b279e57e62a0f Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 5 Jun 2023 14:31:47 -0400 Subject: [PATCH] Avoid index-out-of-bands panic for positional placeholders (#4872) --- .../resources/test/fixtures/pyflakes/F523.py | 1 + .../resources/test/fixtures/pyflakes/F524.py | 1 + crates/ruff/src/rules/pyflakes/fixes.rs | 2 +- ..._rules__pyflakes__tests__F523_F523.py.snap | 43 ++++++++++++++----- ..._rules__pyflakes__tests__F524_F524.py.snap | 10 +++++ 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/pyflakes/F523.py b/crates/ruff/resources/test/fixtures/pyflakes/F523.py index 6b2985924b..d3dd1b68db 100644 --- a/crates/ruff/resources/test/fixtures/pyflakes/F523.py +++ b/crates/ruff/resources/test/fixtures/pyflakes/F523.py @@ -26,6 +26,7 @@ # With modified indexes "{1}{2}".format(1, 2, 3) # F523, # F524 "{1}{3}".format(1, 2, 3, 4) # F523, # F524 +"{1} {8}".format(0, 1) # F523, # F524 # Not fixable ('' diff --git a/crates/ruff/resources/test/fixtures/pyflakes/F524.py b/crates/ruff/resources/test/fixtures/pyflakes/F524.py index 30cc80ea0e..feffa38af3 100644 --- a/crates/ruff/resources/test/fixtures/pyflakes/F524.py +++ b/crates/ruff/resources/test/fixtures/pyflakes/F524.py @@ -4,3 +4,4 @@ "{0} {bar}".format(1) # F524 "{0} {bar}".format() # F524 "{bar} {0}".format() # F524 +"{1} {8}".format(0, 1) diff --git a/crates/ruff/src/rules/pyflakes/fixes.rs b/crates/ruff/src/rules/pyflakes/fixes.rs index 83cdc6130b..a83d1c8068 100644 --- a/crates/ruff/src/rules/pyflakes/fixes.rs +++ b/crates/ruff/src/rules/pyflakes/fixes.rs @@ -95,7 +95,7 @@ fn update_field_types(format_string: &FormatString, index_map: &[usize]) -> Stri let new_field_name = FieldName::parse(field_name).unwrap(); let mut new_field_name_string = match new_field_name.field_type { FieldType::Auto => String::new(), - FieldType::Index(i) => index_map[i].to_string(), + FieldType::Index(i) => index_map.get(i).unwrap_or(&i).to_string(), FieldType::Keyword(keyword) => keyword, }; for field_name_part in &new_field_name.parts { diff --git a/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F523_F523.py.snap b/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F523_F523.py.snap index 2b71c0be4e..17a1adab1e 100644 --- a/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F523_F523.py.snap +++ b/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F523_F523.py.snap @@ -251,6 +251,7 @@ F523.py:27:1: F523 [*] `.format` call has unused arguments at position(s): 0 28 | "{1}{2}".format(1, 2, 3) # F523, # F524 | ^^^^^^^^^^^^^^^^^^^^^^^^ F523 29 | "{1}{3}".format(1, 2, 3, 4) # F523, # F524 +30 | "{1} {8}".format(0, 1) # F523, # F524 | = help: Remove extra positional arguments at position(s): 0 @@ -261,8 +262,8 @@ F523.py:27:1: F523 [*] `.format` call has unused arguments at position(s): 0 27 |-"{1}{2}".format(1, 2, 3) # F523, # F524 27 |+"{0}{1}".format(2, 3) # F523, # F524 28 28 | "{1}{3}".format(1, 2, 3, 4) # F523, # F524 -29 29 | -30 30 | # Not fixable +29 29 | "{1} {8}".format(0, 1) # F523, # F524 +30 30 | F523.py:28:1: F523 [*] `.format` call has unused arguments at position(s): 0, 2 | @@ -270,8 +271,7 @@ F523.py:28:1: F523 [*] `.format` call has unused arguments at position(s): 0, 2 29 | "{1}{2}".format(1, 2, 3) # F523, # F524 30 | "{1}{3}".format(1, 2, 3, 4) # F523, # F524 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ F523 -31 | -32 | # Not fixable +31 | "{1} {8}".format(0, 1) # F523, # F524 | = help: Remove extra positional arguments at position(s): 0, 2 @@ -281,16 +281,37 @@ F523.py:28:1: F523 [*] `.format` call has unused arguments at position(s): 0, 2 27 27 | "{1}{2}".format(1, 2, 3) # F523, # F524 28 |-"{1}{3}".format(1, 2, 3, 4) # F523, # F524 28 |+"{0}{1}".format(2, 4) # F523, # F524 -29 29 | -30 30 | # Not fixable -31 31 | ('' +29 29 | "{1} {8}".format(0, 1) # F523, # F524 +30 30 | +31 31 | # Not fixable -F523.py:31:2: F523 `.format` call has unused arguments at position(s): 0 +F523.py:29:1: F523 [*] `.format` call has unused arguments at position(s): 0 | -31 | # Not fixable -32 | ('' +29 | "{1}{2}".format(1, 2, 3) # F523, # F524 +30 | "{1}{3}".format(1, 2, 3, 4) # F523, # F524 +31 | "{1} {8}".format(0, 1) # F523, # F524 + | ^^^^^^^^^^^^^^^^^^^^^^ F523 +32 | +33 | # Not fixable + | + = help: Remove extra positional arguments at position(s): 0 + +ℹ Suggested fix +26 26 | # With modified indexes +27 27 | "{1}{2}".format(1, 2, 3) # F523, # F524 +28 28 | "{1}{3}".format(1, 2, 3, 4) # F523, # F524 +29 |-"{1} {8}".format(0, 1) # F523, # F524 + 29 |+"{0} {8}".format(1) # F523, # F524 +30 30 | +31 31 | # Not fixable +32 32 | ('' + +F523.py:32:2: F523 `.format` call has unused arguments at position(s): 0 + | +32 | # Not fixable +33 | ('' | __^ -33 | | .format(2)) +34 | | .format(2)) | |__________^ F523 | = help: Remove extra positional arguments at position(s): 0 diff --git a/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F524_F524.py.snap b/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F524_F524.py.snap index d4abbf0a61..5d37ffa6ed 100644 --- a/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F524_F524.py.snap +++ b/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F524_F524.py.snap @@ -45,6 +45,7 @@ F524.py:5:1: F524 `.format` call is missing argument(s) for placeholder(s): 0, b 7 | "{0} {bar}".format() # F524 | ^^^^^^^^^^^^^^^^^^^^ F524 8 | "{bar} {0}".format() # F524 +9 | "{1} {8}".format(0, 1) | F524.py:6:1: F524 `.format` call is missing argument(s) for placeholder(s): 0, bar @@ -53,6 +54,15 @@ F524.py:6:1: F524 `.format` call is missing argument(s) for placeholder(s): 0, b 7 | "{0} {bar}".format() # F524 8 | "{bar} {0}".format() # F524 | ^^^^^^^^^^^^^^^^^^^^ F524 +9 | "{1} {8}".format(0, 1) + | + +F524.py:7:1: F524 `.format` call is missing argument(s) for placeholder(s): 8 + | +7 | "{0} {bar}".format() # F524 +8 | "{bar} {0}".format() # F524 +9 | "{1} {8}".format(0, 1) + | ^^^^^^^^^^^^^^^^^^^^^^ F524 |