mirror of https://github.com/astral-sh/ruff
[ty] Preserve quoting style when autofixing `TypedDict` keys (#21682)
This commit is contained in:
parent
b5b4917d7f
commit
594b7b04d3
|
|
@ -52,6 +52,9 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/typed_dict.md
|
|||
38 |
|
||||
39 | def write_to_readonly_key(employee: Employee):
|
||||
40 | employee["id"] = 42 # error: [invalid-assignment]
|
||||
41 | def write_to_non_existing_key_single_quotes(person: Person):
|
||||
42 | # error: [invalid-key]
|
||||
43 | person['naem'] = "Alice" # fmt: skip
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
|
@ -217,6 +220,8 @@ error[invalid-assignment]: Cannot assign to key "id" on TypedDict `Employee`
|
|||
| -------- ^^^^ key is marked read-only
|
||||
| |
|
||||
| TypedDict `Employee`
|
||||
41 | def write_to_non_existing_key_single_quotes(person: Person):
|
||||
42 | # error: [invalid-key]
|
||||
|
|
||||
info: Item declaration
|
||||
--> src/mdtest_snippet.py:36:5
|
||||
|
|
@ -229,3 +234,24 @@ info: Item declaration
|
|||
info: rule `invalid-assignment` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-key]: Unknown key "naem" for TypedDict `Person`
|
||||
--> src/mdtest_snippet.py:43:5
|
||||
|
|
||||
41 | def write_to_non_existing_key_single_quotes(person: Person):
|
||||
42 | # error: [invalid-key]
|
||||
43 | person['naem'] = "Alice" # fmt: skip
|
||||
| ------ ^^^^^^ Did you mean 'name'?
|
||||
| |
|
||||
| TypedDict `Person`
|
||||
|
|
||||
info: rule `invalid-key` is enabled by default
|
||||
40 | employee["id"] = 42 # error: [invalid-assignment]
|
||||
41 | def write_to_non_existing_key_single_quotes(person: Person):
|
||||
42 | # error: [invalid-key]
|
||||
- person['naem'] = "Alice" # fmt: skip
|
||||
43 + person['name'] = "Alice" # fmt: skip
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1502,6 +1502,14 @@ def write_to_readonly_key(employee: Employee):
|
|||
employee["id"] = 42 # error: [invalid-assignment]
|
||||
```
|
||||
|
||||
If the key uses single quotes, the autofix preserves that quoting style:
|
||||
|
||||
```py
|
||||
def write_to_non_existing_key_single_quotes(person: Person):
|
||||
# error: [invalid-key]
|
||||
person['naem'] = "Alice" # fmt: skip
|
||||
```
|
||||
|
||||
## Import aliases
|
||||
|
||||
`TypedDict` can be imported with aliases and should work correctly:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ use ruff_db::{
|
|||
use ruff_diagnostics::{Edit, Fix};
|
||||
use ruff_python_ast::name::Name;
|
||||
use ruff_python_ast::parenthesize::parentheses_iterator;
|
||||
use ruff_python_ast::{self as ast, AnyNodeRef};
|
||||
use ruff_python_ast::{self as ast, AnyNodeRef, StringFlags};
|
||||
use ruff_python_trivia::CommentRanges;
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
use rustc_hash::FxHashSet;
|
||||
|
|
@ -3456,11 +3456,15 @@ pub(crate) fn report_invalid_key_on_typed_dict<'db>(
|
|||
|
||||
let existing_keys = items.keys();
|
||||
if let Some(suggestion) = did_you_mean(existing_keys, key) {
|
||||
if key_node.is_expr_string_literal() {
|
||||
if let AnyNodeRef::ExprStringLiteral(literal) = key_node {
|
||||
let quoted_suggestion = format!(
|
||||
"{quote}{suggestion}{quote}",
|
||||
quote = literal.value.first_literal_flags().quote_str()
|
||||
);
|
||||
diagnostic
|
||||
.set_primary_message(format_args!("Did you mean \"{suggestion}\"?"));
|
||||
.set_primary_message(format_args!("Did you mean {quoted_suggestion}?"));
|
||||
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
|
||||
format!("\"{suggestion}\""),
|
||||
quoted_suggestion,
|
||||
key_node.range(),
|
||||
)));
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue