PY-83287 Fix an infinite recursion during name resolution of property accessor decorators

During resolving decorators like `@x.setter`, `x` was checked for overloads.
For that, every function, including the one originally decorated by `@x.setter` was checked for having an `@overload` decorator.
For that, `@x.setter` was resolved again, leading to an infinite recursion.

To fix that, a direct check is added to return early if `setter`, `getter` or `deleter` are converted to known decorators.


(cherry picked from commit 2e9eaccd3146b17734902b6be69ebe7d9e9a8b95)

IJ-MR-172702

GitOrigin-RevId: 77d71e6a19f8b9005395e5c69480580b519fc73b
This commit is contained in:
evgeny.bovykin
2025-11-19 13:10:40 +00:00
committed by intellij-monorepo-bot
parent ccacedc456
commit b1005df634
@@ -6,6 +6,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.util.QualifiedName;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.FunctionParameter;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.PyResolveUtil;
@@ -56,6 +57,11 @@ public final class PyKnownDecoratorUtil {
if (qualifiedName == null) {
return Collections.emptyList();
}
// Avoid resolving property accessor decorators to prevent an infinite recursion
String lastComponent = qualifiedName.getLastComponent();
if (PyNames.GETTER.equals(lastComponent) || PyNames.SETTER.equals(lastComponent) || PyNames.DELETER.equals(lastComponent)) {
return Collections.emptyList();
}
if (context.maySwitchToAST(decorator)) {
PsiFile containingFile = decorator.getContainingFile();
List<PsiElement> resolved;