diff --git a/Cargo.lock b/Cargo.lock
index fb4289b220..c95acc34a3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4561,6 +4561,7 @@ dependencies = [
"path-slash",
"regex",
"ruff_db",
+ "ruff_diagnostics",
"ruff_index",
"ruff_notebook",
"ruff_python_ast",
diff --git a/crates/ty/docs/rules.md b/crates/ty/docs/rules.md
index 3a77ed7946..16c4c225dc 100644
--- a/crates/ty/docs/rules.md
+++ b/crates/ty/docs/rules.md
@@ -39,7 +39,7 @@ def test(): -> "int":
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -63,7 +63,7 @@ Calling a non-callable object will raise a `TypeError` at runtime.
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -95,7 +95,7 @@ f(int) # error
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -126,7 +126,7 @@ a = 1
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -158,7 +158,7 @@ class C(A, B): ...
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -190,7 +190,7 @@ class B(A): ...
Default level: error ·
Preview (since 1.0.0) ·
Related issues ·
-View source
+View source
@@ -218,7 +218,7 @@ type B = A
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -245,7 +245,7 @@ class B(A, A): ...
Default level: error ·
Added in 0.0.1-alpha.12 ·
Related issues ·
-View source
+View source
@@ -357,7 +357,7 @@ def test(): -> "Literal[5]":
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -387,7 +387,7 @@ class C(A, B): ...
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -413,7 +413,7 @@ t[3] # IndexError: tuple index out of range
Default level: error ·
Added in 0.0.1-alpha.12 ·
Related issues ·
-View source
+View source
@@ -502,7 +502,7 @@ an atypical memory layout.
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -529,7 +529,7 @@ func("foo") # error: [invalid-argument-type]
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -557,7 +557,7 @@ a: int = ''
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -591,7 +591,7 @@ C.instance_var = 3 # error: Cannot assign to instance variable
Default level: error ·
Added in 0.0.1-alpha.19 ·
Related issues ·
-View source
+View source
@@ -627,7 +627,7 @@ asyncio.run(main())
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -651,7 +651,7 @@ class A(42): ... # error: [invalid-base]
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -678,7 +678,7 @@ with 1:
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -707,7 +707,7 @@ a: str
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -751,7 +751,7 @@ except ZeroDivisionError:
Default level: error ·
Added in 0.0.1-alpha.28 ·
Related issues ·
-View source
+View source
@@ -793,7 +793,7 @@ class D(A):
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -826,7 +826,7 @@ class C[U](Generic[T]): ...
Default level: error ·
Added in 0.0.1-alpha.17 ·
Related issues ·
-View source
+View source
@@ -865,7 +865,7 @@ carol = Person(name="Carol", age=25) # typo!
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -900,7 +900,7 @@ def f(t: TypeVar("U")): ...
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -934,7 +934,7 @@ class B(metaclass=f): ...
Default level: error ·
Added in 0.0.1-alpha.20 ·
Related issues ·
-View source
+View source
@@ -1041,7 +1041,7 @@ Correct use of `@override` is enforced by ty's `invalid-explicit-override` rule.
Default level: error ·
Added in 0.0.1-alpha.19 ·
Related issues ·
-View source
+View source
@@ -1073,7 +1073,7 @@ TypeError: can only inherit from a NamedTuple type and Generic
Default level: error ·
Preview (since 1.0.0) ·
Related issues ·
-View source
+View source
@@ -1103,7 +1103,7 @@ Baz = NewType("Baz", int | str) # error: invalid base for `typing.NewType`
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1153,7 +1153,7 @@ def foo(x: int) -> int: ...
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1179,7 +1179,7 @@ def f(a: int = ''): ...
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1210,7 +1210,7 @@ P2 = ParamSpec("S2") # error: ParamSpec name must match the variable it's assig
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1244,7 +1244,7 @@ TypeError: Protocols can only inherit from other protocols, got
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1293,7 +1293,7 @@ def g():
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1318,7 +1318,7 @@ def func() -> int:
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1376,7 +1376,7 @@ TODO #14889
Default level: error ·
Added in 0.0.1-alpha.6 ·
Related issues ·
-View source
+View source
@@ -1403,7 +1403,7 @@ NewAlias = TypeAliasType(get_name(), int) # error: TypeAliasType name mus
Default level: error ·
Added in 0.0.1-alpha.29 ·
Related issues ·
-View source
+View source
@@ -1450,7 +1450,7 @@ Bar[int] # error: too few arguments
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1480,7 +1480,7 @@ TYPE_CHECKING = ''
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1510,7 +1510,7 @@ b: Annotated[int] # `Annotated` expects at least two arguments
Default level: error ·
Added in 0.0.1-alpha.11 ·
Related issues ·
-View source
+View source
@@ -1544,7 +1544,7 @@ f(10) # Error
Default level: error ·
Added in 0.0.1-alpha.11 ·
Related issues ·
-View source
+View source
@@ -1578,7 +1578,7 @@ class C:
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1613,7 +1613,7 @@ T = TypeVar('T', bound=str) # valid bound TypeVar
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1638,7 +1638,7 @@ func() # TypeError: func() missing 1 required positional argument: 'x'
Default level: error ·
Added in 0.0.1-alpha.20 ·
Related issues ·
-View source
+View source
@@ -1671,7 +1671,7 @@ alice["age"] # KeyError
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1700,7 +1700,7 @@ func("string") # error: [no-matching-overload]
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1724,7 +1724,7 @@ Subscripting an object that does not support it will raise a `TypeError` at runt
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1750,7 +1750,7 @@ for i in 34: # TypeError: 'int' object is not iterable
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1777,7 +1777,7 @@ f(1, x=2) # Error raised here
Default level: error ·
Added in 0.0.1-alpha.22 ·
Related issues ·
-View source
+View source
@@ -1835,7 +1835,7 @@ def test(): -> "int":
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1865,7 +1865,7 @@ static_assert(int(2.0 * 3.0) == 6) # error: does not have a statically known tr
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1894,7 +1894,7 @@ class B(A): ... # Error raised here
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1921,7 +1921,7 @@ f("foo") # Error raised here
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1949,7 +1949,7 @@ def _(x: int):
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -1995,7 +1995,7 @@ class A:
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -2022,7 +2022,7 @@ f(x=1, y=2) # Error raised here
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -2050,7 +2050,7 @@ A().foo # AttributeError: 'A' object has no attribute 'foo'
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -2075,7 +2075,7 @@ import foo # ModuleNotFoundError: No module named 'foo'
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -2100,7 +2100,7 @@ print(x) # NameError: name 'x' is not defined
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -2137,7 +2137,7 @@ b1 < b2 < b1 # exception raised here
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -2165,7 +2165,7 @@ A() + A() # TypeError: unsupported operand type(s) for +: 'A' and 'A'
Default level: error ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -2190,7 +2190,7 @@ l[1:10:0] # ValueError: slice step cannot be zero
Default level: warn ·
Added in 0.0.1-alpha.20 ·
Related issues ·
-View source
+View source
@@ -2231,7 +2231,7 @@ class SubProto(BaseProto, Protocol):
Default level: warn ·
Added in 0.0.1-alpha.16 ·
Related issues ·
-View source
+View source
@@ -2319,7 +2319,7 @@ a = 20 / 0 # type: ignore
Default level: warn ·
Added in 0.0.1-alpha.22 ·
Related issues ·
-View source
+View source
@@ -2347,7 +2347,7 @@ A.c # AttributeError: type object 'A' has no attribute 'c'
Default level: warn ·
Added in 0.0.1-alpha.22 ·
Related issues ·
-View source
+View source
@@ -2379,7 +2379,7 @@ A()[0] # TypeError: 'A' object is not subscriptable
Default level: warn ·
Added in 0.0.1-alpha.22 ·
Related issues ·
-View source
+View source
@@ -2411,7 +2411,7 @@ from module import a # ImportError: cannot import name 'a' from 'module'
Default level: warn ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -2438,7 +2438,7 @@ cast(int, f()) # Redundant
Default level: warn ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
@@ -2462,7 +2462,7 @@ reveal_type(1) # NameError: name 'reveal_type' is not defined
Default level: warn ·
Added in 0.0.1-alpha.15 ·
Related issues ·
-View source
+View source
@@ -2520,7 +2520,7 @@ def g():
Default level: warn ·
Added in 0.0.1-alpha.7 ·
Related issues ·
-View source
+View source
@@ -2559,7 +2559,7 @@ class D(C): ... # error: [unsupported-base]
Default level: warn ·
Added in 0.0.1-alpha.22 ·
Related issues ·
-View source
+View source
@@ -2622,7 +2622,7 @@ def foo(x: int | str) -> int | str:
Default level: ignore ·
Preview (since 0.0.1-alpha.1) ·
Related issues ·
-View source
+View source
@@ -2646,7 +2646,7 @@ Dividing by zero raises a `ZeroDivisionError` at runtime.
Default level: ignore ·
Added in 0.0.1-alpha.1 ·
Related issues ·
-View source
+View source
diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/assignment_diagnosti…_-_Subscript_assignment…_-_Misspelled_key_for_`…_(7cf0fa634e2a2d59).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/assignment_diagnosti…_-_Subscript_assignment…_-_Misspelled_key_for_`…_(7cf0fa634e2a2d59).snap
index ca95ce1675..029b325cc1 100644
--- a/crates/ty_python_semantic/resources/mdtest/snapshots/assignment_diagnosti…_-_Subscript_assignment…_-_Misspelled_key_for_`…_(7cf0fa634e2a2d59).snap
+++ b/crates/ty_python_semantic/resources/mdtest/snapshots/assignment_diagnosti…_-_Subscript_assignment…_-_Misspelled_key_for_`…_(7cf0fa634e2a2d59).snap
@@ -34,5 +34,11 @@ error[invalid-key]: Unknown key "Retries" for TypedDict `Config`
| TypedDict `Config`
|
info: rule `invalid-key` is enabled by default
+4 | retries: int
+5 |
+6 | def _(config: Config) -> None:
+ - config["Retries"] = 30.0 # error: [invalid-key]
+7 + config["retries"] = 30.0 # error: [invalid-key]
+note: This is an unsafe fix and may change runtime behavior
```
diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/assignment_diagnosti…_-_Subscript_assignment…_-_Unknown_key_for_all_…_(8a0f0e8ceccc51b2).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/assignment_diagnosti…_-_Subscript_assignment…_-_Unknown_key_for_all_…_(8a0f0e8ceccc51b2).snap
index 17a005b9c2..d3e9c7a656 100644
--- a/crates/ty_python_semantic/resources/mdtest/snapshots/assignment_diagnosti…_-_Subscript_assignment…_-_Unknown_key_for_all_…_(8a0f0e8ceccc51b2).snap
+++ b/crates/ty_python_semantic/resources/mdtest/snapshots/assignment_diagnosti…_-_Subscript_assignment…_-_Unknown_key_for_all_…_(8a0f0e8ceccc51b2).snap
@@ -42,6 +42,12 @@ error[invalid-key]: Unknown key "surname" for TypedDict `Person`
| TypedDict `Person` in union type `Person | Animal`
|
info: rule `invalid-key` is enabled by default
+11 | def _(being: Person | Animal) -> None:
+12 | # error: [invalid-key]
+13 | # error: [invalid-key]
+ - being["surname"] = "unknown"
+14 + being["name"] = "unknown"
+note: This is an unsafe fix and may change runtime behavior
```
@@ -57,5 +63,11 @@ error[invalid-key]: Unknown key "surname" for TypedDict `Animal`
| TypedDict `Animal` in union type `Person | Animal`
|
info: rule `invalid-key` is enabled by default
+11 | def _(being: Person | Animal) -> None:
+12 | # error: [invalid-key]
+13 | # error: [invalid-key]
+ - being["surname"] = "unknown"
+14 + being["name"] = "unknown"
+note: This is an unsafe fix and may change runtime behavior
```
diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/invalid.md_-_Tests_for_invalid_ty…_-_Diagnostics_for_comm…_-_Module-literal_used_…_(652fec4fd4a6c63a).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/invalid.md_-_Tests_for_invalid_ty…_-_Diagnostics_for_comm…_-_Module-literal_used_…_(652fec4fd4a6c63a).snap
index 957a2d13f8..8d13cb887f 100644
--- a/crates/ty_python_semantic/resources/mdtest/snapshots/invalid.md_-_Tests_for_invalid_ty…_-_Diagnostics_for_comm…_-_Module-literal_used_…_(652fec4fd4a6c63a).snap
+++ b/crates/ty_python_semantic/resources/mdtest/snapshots/invalid.md_-_Tests_for_invalid_ty…_-_Diagnostics_for_comm…_-_Module-literal_used_…_(652fec4fd4a6c63a).snap
@@ -43,6 +43,11 @@ error[invalid-type-form]: Module `datetime` is not valid in a type expression
| ^^^^^^^^ Did you mean to use the module's member `datetime.datetime`?
|
info: rule `invalid-type-form` is enabled by default
+1 | import datetime
+2 |
+ - def f(x: datetime): ... # error: [invalid-type-form]
+3 + def f(x: datetime.datetime): ... # error: [invalid-type-form]
+note: This is an unsafe fix and may change runtime behavior
```
@@ -56,5 +61,10 @@ error[invalid-type-form]: Module `PIL.Image` is not valid in a type expression
| ^^^^^ Did you mean to use the module's member `Image.Image`?
|
info: rule `invalid-type-form` is enabled by default
+1 | from PIL import Image
+2 |
+ - def g(x: Image): ... # error: [invalid-type-form]
+3 + def g(x: Image.Image): ... # error: [invalid-type-form]
+note: This is an unsafe fix and may change runtime behavior
```
diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/typed_dict.md_-_`TypedDict`_-_Diagnostics_(e5289abf5c570c29).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/typed_dict.md_-_`TypedDict`_-_Diagnostics_(e5289abf5c570c29).snap
index 697188d2be..0fc0bbd2a6 100644
--- a/crates/ty_python_semantic/resources/mdtest/snapshots/typed_dict.md_-_`TypedDict`_-_Diagnostics_(e5289abf5c570c29).snap
+++ b/crates/ty_python_semantic/resources/mdtest/snapshots/typed_dict.md_-_`TypedDict`_-_Diagnostics_(e5289abf5c570c29).snap
@@ -69,6 +69,15 @@ error[invalid-key]: Unknown key "naem" for TypedDict `Person`
10 | NAME_KEY: Final = "naem"
|
info: rule `invalid-key` is enabled by default
+5 | age: int | None
+6 |
+7 | def access_invalid_literal_string_key(person: Person):
+ - person["naem"] # error: [invalid-key]
+8 + person["name"] # error: [invalid-key]
+9 |
+10 | NAME_KEY: Final = "naem"
+11 |
+note: This is an unsafe fix and may change runtime behavior
```
@@ -142,6 +151,15 @@ error[invalid-key]: Unknown key "naem" for TypedDict `Person`
24 | def write_to_non_literal_string_key(person: Person, str_key: str):
|
info: rule `invalid-key` is enabled by default
+19 | person["age"] = "42" # error: [invalid-assignment]
+20 |
+21 | def write_to_non_existing_key(person: Person):
+ - person["naem"] = "Alice" # error: [invalid-key]
+22 + person["name"] = "Alice" # error: [invalid-key]
+23 |
+24 | def write_to_non_literal_string_key(person: Person, str_key: str):
+25 | person[str_key] = "Alice" # error: [invalid-key]
+note: This is an unsafe fix and may change runtime behavior
```
diff --git a/crates/ty_python_semantic/src/types.rs b/crates/ty_python_semantic/src/types.rs
index 998a8dd134..56b794e96b 100644
--- a/crates/ty_python_semantic/src/types.rs
+++ b/crates/ty_python_semantic/src/types.rs
@@ -1,6 +1,7 @@
use compact_str::{CompactString, ToCompactString};
use infer::nearest_enclosing_class;
use itertools::{Either, Itertools};
+use ruff_diagnostics::{Edit, Fix};
use std::borrow::Cow;
use std::time::Duration;
@@ -8752,7 +8753,7 @@ impl<'db> InvalidTypeExpressionError<'db> {
continue;
};
let diagnostic = builder.into_diagnostic(error.reason(context.db()));
- error.add_subdiagnostics(context.db(), diagnostic);
+ error.add_subdiagnostics(context.db(), diagnostic, node);
}
}
fallback_type
@@ -8878,7 +8879,12 @@ impl<'db> InvalidTypeExpression<'db> {
Display { error: self, db }
}
- fn add_subdiagnostics(self, db: &'db dyn Db, mut diagnostic: LintDiagnosticGuard) {
+ fn add_subdiagnostics(
+ self,
+ db: &'db dyn Db,
+ mut diagnostic: LintDiagnosticGuard,
+ node: &impl Ranged,
+ ) {
if let InvalidTypeExpression::InvalidType(Type::Never, _) = self {
diagnostic.help(
"The variable may have been inferred as `Never` because \
@@ -8904,12 +8910,14 @@ impl<'db> InvalidTypeExpression<'db> {
{
return;
}
-
- // TODO: showing a diff (and even having an autofix) would be even better
diagnostic.set_primary_message(format_args!(
"Did you mean to use the module's member \
`{module_name_final_part}.{module_name_final_part}`?"
));
+ diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion(
+ format!(".{module_name_final_part}"),
+ node.end(),
+ )));
} else if let InvalidTypeExpression::TypedDict = self {
diagnostic.help(
"You might have meant to use a concrete TypedDict \
diff --git a/crates/ty_python_semantic/src/types/diagnostic.rs b/crates/ty_python_semantic/src/types/diagnostic.rs
index 4e9c5b96df..368c04601f 100644
--- a/crates/ty_python_semantic/src/types/diagnostic.rs
+++ b/crates/ty_python_semantic/src/types/diagnostic.rs
@@ -37,6 +37,7 @@ use ruff_db::{
parsed::parsed_module,
source::source_text,
};
+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};
@@ -3430,6 +3431,10 @@ pub(crate) fn report_invalid_key_on_typed_dict<'db>(
if key_node.is_expr_string_literal() {
diagnostic
.set_primary_message(format_args!("Did you mean \"{suggestion}\"?"));
+ diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
+ format!("\"{suggestion}\""),
+ key_node.range(),
+ )));
} else {
diagnostic.set_primary_message(format_args!(
"Unknown key \"{key}\" - did you mean \"{suggestion}\"?",
diff --git a/crates/ty_test/Cargo.toml b/crates/ty_test/Cargo.toml
index 271ca8f084..f300b614a0 100644
--- a/crates/ty_test/Cargo.toml
+++ b/crates/ty_test/Cargo.toml
@@ -12,6 +12,7 @@ license.workspace = true
[dependencies]
ruff_db = { workspace = true, features = ["os", "testing"] }
+ruff_diagnostics = { workspace = true }
ruff_index = { workspace = true }
ruff_notebook = { workspace = true }
ruff_python_trivia = { workspace = true }
diff --git a/crates/ty_test/src/lib.rs b/crates/ty_test/src/lib.rs
index 182d4b206e..800d4e4c4d 100644
--- a/crates/ty_test/src/lib.rs
+++ b/crates/ty_test/src/lib.rs
@@ -12,6 +12,7 @@ use ruff_db::panic::{PanicError, catch_unwind};
use ruff_db::parsed::parsed_module;
use ruff_db::system::{DbWithWritableSystem as _, SystemPath, SystemPathBuf};
use ruff_db::testing::{setup_logging, setup_logging_with_filter};
+use ruff_diagnostics::Applicability;
use ruff_source_file::{LineIndex, OneIndexed};
use std::backtrace::BacktraceStatus;
use std::fmt::{Display, Write};
@@ -643,7 +644,8 @@ fn create_diagnostic_snapshot(
) -> String {
let display_config = DisplayDiagnosticConfig::default()
.color(false)
- .show_fix_diff(true);
+ .show_fix_diff(true)
+ .with_fix_applicability(Applicability::DisplayOnly);
let mut snapshot = String::new();
writeln!(snapshot).unwrap();