From 402b3c7f0455485d3088f80e73630626a2f3ba8a Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Fri, 14 Jul 2023 16:13:45 -0400 Subject: [PATCH] Expand scope of quoted-annotation rule --- .../pyupgrade/{UP037.py => UP037_0.py} | 2 + .../test/fixtures/pyupgrade/UP037_1.py | 108 ++++ crates/ruff/src/checkers/ast/mod.rs | 2 +- crates/ruff/src/rules/pyupgrade/mod.rs | 3 +- .../pyupgrade/rules/quoted_annotation.rs | 5 + ...__rules__pyupgrade__tests__UP037_0.py.snap | 559 ++++++++++++++++++ ...__rules__pyupgrade__tests__UP037_1.py.snap | 22 + 7 files changed, 699 insertions(+), 2 deletions(-) rename crates/ruff/resources/test/fixtures/pyupgrade/{UP037.py => UP037_0.py} (95%) create mode 100644 crates/ruff/resources/test/fixtures/pyupgrade/UP037_1.py create mode 100644 crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP037_0.py.snap create mode 100644 crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP037_1.py.snap diff --git a/crates/ruff/resources/test/fixtures/pyupgrade/UP037.py b/crates/ruff/resources/test/fixtures/pyupgrade/UP037_0.py similarity index 95% rename from crates/ruff/resources/test/fixtures/pyupgrade/UP037.py rename to crates/ruff/resources/test/fixtures/pyupgrade/UP037_0.py index f970c605a8..2536dbc043 100644 --- a/crates/ruff/resources/test/fixtures/pyupgrade/UP037.py +++ b/crates/ruff/resources/test/fixtures/pyupgrade/UP037_0.py @@ -1,3 +1,5 @@ +"""A mirror of UP037_1.py, with `from __future__ import annotations`.""" + from __future__ import annotations from typing import ( diff --git a/crates/ruff/resources/test/fixtures/pyupgrade/UP037_1.py b/crates/ruff/resources/test/fixtures/pyupgrade/UP037_1.py new file mode 100644 index 0000000000..f40257f85a --- /dev/null +++ b/crates/ruff/resources/test/fixtures/pyupgrade/UP037_1.py @@ -0,0 +1,108 @@ +"""A mirror of UP037_0.py, without `from __future__ import annotations`.""" + +from typing import ( + Annotated, + Callable, + List, + Literal, + NamedTuple, + Tuple, + TypeVar, + TypedDict, + cast, +) + +from mypy_extensions import Arg, DefaultArg, DefaultNamedArg, NamedArg, VarArg + + +def foo(var: "MyClass") -> "MyClass": + x: "MyClass" + + +def foo(*, inplace: "bool"): + pass + + +def foo(*args: "str", **kwargs: "int"): + pass + + +x: Tuple["MyClass"] + +x: Callable[["MyClass"], None] + + +class Foo(NamedTuple): + x: "MyClass" + + +class D(TypedDict): + E: TypedDict("E", foo="int", total=False) + + +class D(TypedDict): + E: TypedDict("E", {"foo": "int"}) + + +x: Annotated["str", "metadata"] + +x: Arg("str", "name") + +x: DefaultArg("str", "name") + +x: NamedArg("str", "name") + +x: DefaultNamedArg("str", "name") + +x: DefaultNamedArg("str", name="name") + +x: VarArg("str") + +x: List[List[List["MyClass"]]] + +x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) + +x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + +x: NamedTuple(typename="X", fields=[("foo", "int")]) + +X: MyCallable("X") + + +# OK +class D(TypedDict): + E: TypedDict("E") + + +x: Annotated[()] + +x: DefaultNamedArg(name="name", quox="str") + +x: DefaultNamedArg(name="name") + +x: NamedTuple("X", [("foo",), ("bar",)]) + +x: NamedTuple("X", ["foo", "bar"]) + +x: NamedTuple() + +x: Literal["foo", "bar"] + +x = cast(x, "str") + + +def foo(x, *args, **kwargs): + ... + + +def foo(*, inplace): + ... + + +x: Annotated[1:2] = ... + +x = TypeVar("x", "str", "int") + +x = cast("str", x) + +X = List["MyClass"] diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index 2c2188caa7..5af47439ee 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -4586,7 +4586,7 @@ impl<'a> Checker<'a> { self.semantic.restore(snapshot); - if self.semantic.in_annotation() && self.semantic.future_annotations() { + if self.semantic.in_typing_only_annotation() { if self.enabled(Rule::QuotedAnnotation) { pyupgrade::rules::quoted_annotation(self, value, range); } diff --git a/crates/ruff/src/rules/pyupgrade/mod.rs b/crates/ruff/src/rules/pyupgrade/mod.rs index f65042ebc9..db02317a37 100644 --- a/crates/ruff/src/rules/pyupgrade/mod.rs +++ b/crates/ruff/src/rules/pyupgrade/mod.rs @@ -55,7 +55,8 @@ mod tests { #[test_case(Rule::OutdatedVersionBlock, Path::new("UP036_5.py"))] #[test_case(Rule::PrintfStringFormatting, Path::new("UP031_0.py"))] #[test_case(Rule::PrintfStringFormatting, Path::new("UP031_1.py"))] - #[test_case(Rule::QuotedAnnotation, Path::new("UP037.py"))] + #[test_case(Rule::QuotedAnnotation, Path::new("UP037_0.py"))] + #[test_case(Rule::QuotedAnnotation, Path::new("UP037_1.py"))] #[test_case(Rule::RedundantOpenModes, Path::new("UP015.py"))] #[test_case(Rule::ReplaceStdoutStderr, Path::new("UP022.py"))] #[test_case(Rule::ReplaceUniversalNewlines, Path::new("UP021.py"))] diff --git a/crates/ruff/src/rules/pyupgrade/rules/quoted_annotation.rs b/crates/ruff/src/rules/pyupgrade/rules/quoted_annotation.rs index 749e3011f5..ac137b97e2 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/quoted_annotation.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/quoted_annotation.rs @@ -15,6 +15,11 @@ use crate::registry::Rule; /// will always evaluate type annotations in a deferred manner, making /// the quotes unnecessary. /// +/// Type annotations can also be unquoted in some other contexts, even +/// without `from __future__ import annotations`. For example, annotated +/// assignments within function bodies are not evaluated at runtime, and so can +/// be unquoted. +/// /// ## Example /// ```python /// from __future__ import annotations diff --git a/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP037_0.py.snap b/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP037_0.py.snap new file mode 100644 index 0000000000..f9b3084db5 --- /dev/null +++ b/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP037_0.py.snap @@ -0,0 +1,559 @@ +--- +source: crates/ruff/src/rules/pyupgrade/mod.rs +--- +UP037_0.py:20:14: UP037 [*] Remove quotes from type annotation + | +20 | def foo(var: "MyClass") -> "MyClass": + | ^^^^^^^^^ UP037 +21 | x: "MyClass" + | + = help: Remove quotes + +ℹ Fix +17 17 | from mypy_extensions import Arg, DefaultArg, DefaultNamedArg, NamedArg, VarArg +18 18 | +19 19 | +20 |-def foo(var: "MyClass") -> "MyClass": + 20 |+def foo(var: MyClass) -> "MyClass": +21 21 | x: "MyClass" +22 22 | +23 23 | + +UP037_0.py:20:28: UP037 [*] Remove quotes from type annotation + | +20 | def foo(var: "MyClass") -> "MyClass": + | ^^^^^^^^^ UP037 +21 | x: "MyClass" + | + = help: Remove quotes + +ℹ Fix +17 17 | from mypy_extensions import Arg, DefaultArg, DefaultNamedArg, NamedArg, VarArg +18 18 | +19 19 | +20 |-def foo(var: "MyClass") -> "MyClass": + 20 |+def foo(var: "MyClass") -> MyClass: +21 21 | x: "MyClass" +22 22 | +23 23 | + +UP037_0.py:21:8: UP037 [*] Remove quotes from type annotation + | +20 | def foo(var: "MyClass") -> "MyClass": +21 | x: "MyClass" + | ^^^^^^^^^ UP037 + | + = help: Remove quotes + +ℹ Fix +18 18 | +19 19 | +20 20 | def foo(var: "MyClass") -> "MyClass": +21 |- x: "MyClass" + 21 |+ x: MyClass +22 22 | +23 23 | +24 24 | def foo(*, inplace: "bool"): + +UP037_0.py:24:21: UP037 [*] Remove quotes from type annotation + | +24 | def foo(*, inplace: "bool"): + | ^^^^^^ UP037 +25 | pass + | + = help: Remove quotes + +ℹ Fix +21 21 | x: "MyClass" +22 22 | +23 23 | +24 |-def foo(*, inplace: "bool"): + 24 |+def foo(*, inplace: bool): +25 25 | pass +26 26 | +27 27 | + +UP037_0.py:28:16: UP037 [*] Remove quotes from type annotation + | +28 | def foo(*args: "str", **kwargs: "int"): + | ^^^^^ UP037 +29 | pass + | + = help: Remove quotes + +ℹ Fix +25 25 | pass +26 26 | +27 27 | +28 |-def foo(*args: "str", **kwargs: "int"): + 28 |+def foo(*args: str, **kwargs: "int"): +29 29 | pass +30 30 | +31 31 | + +UP037_0.py:28:33: UP037 [*] Remove quotes from type annotation + | +28 | def foo(*args: "str", **kwargs: "int"): + | ^^^^^ UP037 +29 | pass + | + = help: Remove quotes + +ℹ Fix +25 25 | pass +26 26 | +27 27 | +28 |-def foo(*args: "str", **kwargs: "int"): + 28 |+def foo(*args: "str", **kwargs: int): +29 29 | pass +30 30 | +31 31 | + +UP037_0.py:32:10: UP037 [*] Remove quotes from type annotation + | +32 | x: Tuple["MyClass"] + | ^^^^^^^^^ UP037 +33 | +34 | x: Callable[["MyClass"], None] + | + = help: Remove quotes + +ℹ Fix +29 29 | pass +30 30 | +31 31 | +32 |-x: Tuple["MyClass"] + 32 |+x: Tuple[MyClass] +33 33 | +34 34 | x: Callable[["MyClass"], None] +35 35 | + +UP037_0.py:34:14: UP037 [*] Remove quotes from type annotation + | +32 | x: Tuple["MyClass"] +33 | +34 | x: Callable[["MyClass"], None] + | ^^^^^^^^^ UP037 + | + = help: Remove quotes + +ℹ Fix +31 31 | +32 32 | x: Tuple["MyClass"] +33 33 | +34 |-x: Callable[["MyClass"], None] + 34 |+x: Callable[[MyClass], None] +35 35 | +36 36 | +37 37 | class Foo(NamedTuple): + +UP037_0.py:38:8: UP037 [*] Remove quotes from type annotation + | +37 | class Foo(NamedTuple): +38 | x: "MyClass" + | ^^^^^^^^^ UP037 + | + = help: Remove quotes + +ℹ Fix +35 35 | +36 36 | +37 37 | class Foo(NamedTuple): +38 |- x: "MyClass" + 38 |+ x: MyClass +39 39 | +40 40 | +41 41 | class D(TypedDict): + +UP037_0.py:42:27: UP037 [*] Remove quotes from type annotation + | +41 | class D(TypedDict): +42 | E: TypedDict("E", foo="int", total=False) + | ^^^^^ UP037 + | + = help: Remove quotes + +ℹ Fix +39 39 | +40 40 | +41 41 | class D(TypedDict): +42 |- E: TypedDict("E", foo="int", total=False) + 42 |+ E: TypedDict("E", foo=int, total=False) +43 43 | +44 44 | +45 45 | class D(TypedDict): + +UP037_0.py:46:31: UP037 [*] Remove quotes from type annotation + | +45 | class D(TypedDict): +46 | E: TypedDict("E", {"foo": "int"}) + | ^^^^^ UP037 + | + = help: Remove quotes + +ℹ Fix +43 43 | +44 44 | +45 45 | class D(TypedDict): +46 |- E: TypedDict("E", {"foo": "int"}) + 46 |+ E: TypedDict("E", {"foo": int}) +47 47 | +48 48 | +49 49 | x: Annotated["str", "metadata"] + +UP037_0.py:49:14: UP037 [*] Remove quotes from type annotation + | +49 | x: Annotated["str", "metadata"] + | ^^^^^ UP037 +50 | +51 | x: Arg("str", "name") + | + = help: Remove quotes + +ℹ Fix +46 46 | E: TypedDict("E", {"foo": "int"}) +47 47 | +48 48 | +49 |-x: Annotated["str", "metadata"] + 49 |+x: Annotated[str, "metadata"] +50 50 | +51 51 | x: Arg("str", "name") +52 52 | + +UP037_0.py:51:8: UP037 [*] Remove quotes from type annotation + | +49 | x: Annotated["str", "metadata"] +50 | +51 | x: Arg("str", "name") + | ^^^^^ UP037 +52 | +53 | x: DefaultArg("str", "name") + | + = help: Remove quotes + +ℹ Fix +48 48 | +49 49 | x: Annotated["str", "metadata"] +50 50 | +51 |-x: Arg("str", "name") + 51 |+x: Arg(str, "name") +52 52 | +53 53 | x: DefaultArg("str", "name") +54 54 | + +UP037_0.py:53:15: UP037 [*] Remove quotes from type annotation + | +51 | x: Arg("str", "name") +52 | +53 | x: DefaultArg("str", "name") + | ^^^^^ UP037 +54 | +55 | x: NamedArg("str", "name") + | + = help: Remove quotes + +ℹ Fix +50 50 | +51 51 | x: Arg("str", "name") +52 52 | +53 |-x: DefaultArg("str", "name") + 53 |+x: DefaultArg(str, "name") +54 54 | +55 55 | x: NamedArg("str", "name") +56 56 | + +UP037_0.py:55:13: UP037 [*] Remove quotes from type annotation + | +53 | x: DefaultArg("str", "name") +54 | +55 | x: NamedArg("str", "name") + | ^^^^^ UP037 +56 | +57 | x: DefaultNamedArg("str", "name") + | + = help: Remove quotes + +ℹ Fix +52 52 | +53 53 | x: DefaultArg("str", "name") +54 54 | +55 |-x: NamedArg("str", "name") + 55 |+x: NamedArg(str, "name") +56 56 | +57 57 | x: DefaultNamedArg("str", "name") +58 58 | + +UP037_0.py:57:20: UP037 [*] Remove quotes from type annotation + | +55 | x: NamedArg("str", "name") +56 | +57 | x: DefaultNamedArg("str", "name") + | ^^^^^ UP037 +58 | +59 | x: DefaultNamedArg("str", name="name") + | + = help: Remove quotes + +ℹ Fix +54 54 | +55 55 | x: NamedArg("str", "name") +56 56 | +57 |-x: DefaultNamedArg("str", "name") + 57 |+x: DefaultNamedArg(str, "name") +58 58 | +59 59 | x: DefaultNamedArg("str", name="name") +60 60 | + +UP037_0.py:59:20: UP037 [*] Remove quotes from type annotation + | +57 | x: DefaultNamedArg("str", "name") +58 | +59 | x: DefaultNamedArg("str", name="name") + | ^^^^^ UP037 +60 | +61 | x: VarArg("str") + | + = help: Remove quotes + +ℹ Fix +56 56 | +57 57 | x: DefaultNamedArg("str", "name") +58 58 | +59 |-x: DefaultNamedArg("str", name="name") + 59 |+x: DefaultNamedArg(str, name="name") +60 60 | +61 61 | x: VarArg("str") +62 62 | + +UP037_0.py:61:11: UP037 [*] Remove quotes from type annotation + | +59 | x: DefaultNamedArg("str", name="name") +60 | +61 | x: VarArg("str") + | ^^^^^ UP037 +62 | +63 | x: List[List[List["MyClass"]]] + | + = help: Remove quotes + +ℹ Fix +58 58 | +59 59 | x: DefaultNamedArg("str", name="name") +60 60 | +61 |-x: VarArg("str") + 61 |+x: VarArg(str) +62 62 | +63 63 | x: List[List[List["MyClass"]]] +64 64 | + +UP037_0.py:63:19: UP037 [*] Remove quotes from type annotation + | +61 | x: VarArg("str") +62 | +63 | x: List[List[List["MyClass"]]] + | ^^^^^^^^^ UP037 +64 | +65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) + | + = help: Remove quotes + +ℹ Fix +60 60 | +61 61 | x: VarArg("str") +62 62 | +63 |-x: List[List[List["MyClass"]]] + 63 |+x: List[List[List[MyClass]]] +64 64 | +65 65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) +66 66 | + +UP037_0.py:65:29: UP037 [*] Remove quotes from type annotation + | +63 | x: List[List[List["MyClass"]]] +64 | +65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) + | ^^^^^ UP037 +66 | +67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + | + = help: Remove quotes + +ℹ Fix +62 62 | +63 63 | x: List[List[List["MyClass"]]] +64 64 | +65 |-x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) + 65 |+x: NamedTuple("X", [("foo", int), ("bar", "str")]) +66 66 | +67 67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) +68 68 | + +UP037_0.py:65:45: UP037 [*] Remove quotes from type annotation + | +63 | x: List[List[List["MyClass"]]] +64 | +65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) + | ^^^^^ UP037 +66 | +67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + | + = help: Remove quotes + +ℹ Fix +62 62 | +63 63 | x: List[List[List["MyClass"]]] +64 64 | +65 |-x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) + 65 |+x: NamedTuple("X", [("foo", "int"), ("bar", str)]) +66 66 | +67 67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) +68 68 | + +UP037_0.py:67:29: UP037 [*] Remove quotes from type annotation + | +65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) +66 | +67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + | ^^^^^ UP037 +68 | +69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) + | + = help: Remove quotes + +ℹ Fix +64 64 | +65 65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) +66 66 | +67 |-x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + 67 |+x: NamedTuple("X", fields=[(foo, "int"), ("bar", "str")]) +68 68 | +69 69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) +70 70 | + +UP037_0.py:67:36: UP037 [*] Remove quotes from type annotation + | +65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) +66 | +67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + | ^^^^^ UP037 +68 | +69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) + | + = help: Remove quotes + +ℹ Fix +64 64 | +65 65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) +66 66 | +67 |-x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + 67 |+x: NamedTuple("X", fields=[("foo", int), ("bar", "str")]) +68 68 | +69 69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) +70 70 | + +UP037_0.py:67:45: UP037 [*] Remove quotes from type annotation + | +65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) +66 | +67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + | ^^^^^ UP037 +68 | +69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) + | + = help: Remove quotes + +ℹ Fix +64 64 | +65 65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) +66 66 | +67 |-x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + 67 |+x: NamedTuple("X", fields=[("foo", "int"), (bar, "str")]) +68 68 | +69 69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) +70 70 | + +UP037_0.py:67:52: UP037 [*] Remove quotes from type annotation + | +65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) +66 | +67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + | ^^^^^ UP037 +68 | +69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) + | + = help: Remove quotes + +ℹ Fix +64 64 | +65 65 | x: NamedTuple("X", [("foo", "int"), ("bar", "str")]) +66 66 | +67 |-x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) + 67 |+x: NamedTuple("X", fields=[("foo", "int"), ("bar", str)]) +68 68 | +69 69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) +70 70 | + +UP037_0.py:69:24: UP037 [*] Remove quotes from type annotation + | +67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) +68 | +69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) + | ^^^ UP037 +70 | +71 | X: MyCallable("X") + | + = help: Remove quotes + +ℹ Fix +66 66 | +67 67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) +68 68 | +69 |-x: NamedTuple(typename="X", fields=[("foo", "int")]) + 69 |+x: NamedTuple(typename=X, fields=[("foo", "int")]) +70 70 | +71 71 | X: MyCallable("X") +72 72 | + +UP037_0.py:69:38: UP037 [*] Remove quotes from type annotation + | +67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) +68 | +69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) + | ^^^^^ UP037 +70 | +71 | X: MyCallable("X") + | + = help: Remove quotes + +ℹ Fix +66 66 | +67 67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) +68 68 | +69 |-x: NamedTuple(typename="X", fields=[("foo", "int")]) + 69 |+x: NamedTuple(typename="X", fields=[(foo, "int")]) +70 70 | +71 71 | X: MyCallable("X") +72 72 | + +UP037_0.py:69:45: UP037 [*] Remove quotes from type annotation + | +67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) +68 | +69 | x: NamedTuple(typename="X", fields=[("foo", "int")]) + | ^^^^^ UP037 +70 | +71 | X: MyCallable("X") + | + = help: Remove quotes + +ℹ Fix +66 66 | +67 67 | x: NamedTuple("X", fields=[("foo", "int"), ("bar", "str")]) +68 68 | +69 |-x: NamedTuple(typename="X", fields=[("foo", "int")]) + 69 |+x: NamedTuple(typename="X", fields=[("foo", int)]) +70 70 | +71 71 | X: MyCallable("X") +72 72 | + + diff --git a/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP037_1.py.snap b/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP037_1.py.snap new file mode 100644 index 0000000000..22d8da416d --- /dev/null +++ b/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP037_1.py.snap @@ -0,0 +1,22 @@ +--- +source: crates/ruff/src/rules/pyupgrade/mod.rs +--- +UP037_1.py:19:8: UP037 [*] Remove quotes from type annotation + | +18 | def foo(var: "MyClass") -> "MyClass": +19 | x: "MyClass" + | ^^^^^^^^^ UP037 + | + = help: Remove quotes + +ℹ Fix +16 16 | +17 17 | +18 18 | def foo(var: "MyClass") -> "MyClass": +19 |- x: "MyClass" + 19 |+ x: MyClass +20 20 | +21 21 | +22 22 | def foo(*, inplace: "bool"): + +