Repository: astral-sh/ruff
File: crates/ty_ide/src/rename.rs (Rust)

Code before:
                        pass
                "#,
            )
            .build();

        assert_snapshot!(test.rename("gamma"), @"
        info[rename]: Rename symbol (found 3 locations)
         --> lib.py:4:9
          |
        2 | class Foo:
        3 |     @property
        4 |     def alpha(self) -> int:
          |         ^^^^^
        5 |         return 1
        6 |
        7 |     @alpha.setter
          |      -----
        8 |     def alpha(self, value: int) -> None:
          |         -----
        9 |         pass
          |
        ");
    }

    /// A non-property decorator that happens to have a `.setter` attribute
    /// should not trigger property rename behavior.
    #[test]
    fn rename_non_property_setter_decorator() {
        let test = CursorTest::builder()
            .source(
                "lib.py",
                r#"
                class Registry:
                    def setter(self, func):
                        return func

                registry = Registry()

                def my_func<CURSOR>():
                    pass

                @my_func.setter
                def other_func():
                    pass
                "#,
            )
            .build();

        assert_snapshot!(test.rename("better_name"), @r#"
        info[rename]: Rename symbol (found 2 locations)
          --> lib.py:8:5

Review comment (bug):
I don't think this test is testing what it claims to. If I change the name of `other_func` to `my_func` below, then run the test, it wrongly renames the decorated `my_func`, which it shouldn't according to this comment.

In other words, what is really being tested here is that we don't rename a setter/deleter if it has a different name from the getter.

That's an unusual thing to do with a property, but it's certainly possible:

```py
class C:
    @property
    def my_getter(self): ...

    @getter.setter
    def my_setter(self): ...
```

I think if our intention is that in this case we would not rename the getter if the setter is renamed, or vice versa, it would be good to have a test explicitly demonstrating that with an actual property.

And if this test is really supposed to demonstrate that we don't ever do this with non-properties, then this test should be updated to use the same name for both functions... and then we should make it pass.

Code after:
                        pass
                "#,
            )
            .build();

        assert_snapshot!(test.rename("gamma"), @"
        info[rename]: Rename symbol (found 3 locations)
         --> lib.py:4:9
          |
        2 | class Foo:
        3 |     @property
        4 |     def alpha(self) -> int:
          |         ^^^^^
        5 |         return 1
        6 |
        7 |     @alpha.setter
          |      -----
        8 |     def alpha(self, value: int) -> None:
          |         -----
        9 |         pass
          |
        ");
    }

    /// A non-property decorator that happens to have a `.setter` attribute
    /// should not trigger property rename behavior.
    #[test]
    fn rename_non_property_setter_decorator() {
        let test = CursorTest::builder()
            .source(
                "lib.py",
                r#"
                class Registry:
                    def setter(self, func):
                        return func

                registry = Registry()

                def my_func<CURSOR>():
                    pass

                @my_func.setter
                def my_func():
                    pass
                "#,
            )
            .build();

        // Only 2 locations should be found (the definition and the decorator reference),
        // not the second `my_func` function definition, because `my_func` is not a property.
        assert_snapshot!(test.rename("better_name"), @r#"