PY-76895 Allow forward references from new-style type parameter's bound and default expressions

GitOrigin-RevId: ca85a33ecfcb8db5e6cf92c0e864ab8783954fb2
This commit is contained in:
Daniil Kalinin
2025-05-20 15:35:38 +00:00
committed by intellij-monorepo-bot
parent 077f780a2b
commit 2f648c2121
2 changed files with 23 additions and 3 deletions
@@ -424,9 +424,14 @@ public final class PyResolveUtil {
// Forward references are allowed in annotations according to PEP 563
PsiFile file = element.getContainingFile();
if (file instanceof PyFile pyFile) {
return pyFile.getLanguageLevel().isAtLeast(LanguageLevel.PYTHON37) &&
pyFile.hasImportFromFuture(FutureFeature.ANNOTATIONS) &&
PsiTreeUtil.getParentOfType(element, PyAnnotation.class) != null;
boolean isAnnotation = pyFile.getLanguageLevel().isAtLeast(LanguageLevel.PYTHON37) &&
pyFile.hasImportFromFuture(FutureFeature.ANNOTATIONS) &&
PsiTreeUtil.getParentOfType(element, PyAnnotation.class) != null;
if (isAnnotation) return true;
boolean isReferenceFromTypeParameterList = pyFile.getLanguageLevel().isAtLeast(LanguageLevel.PYTHON312) &&
PsiTreeUtil.getParentOfType(element, PyTypeParameter.class, true) != null;
if (isReferenceFromTypeParameterList) return true;
}
return false;
}
@@ -881,6 +881,21 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
});
}
// PY-76895
public void testForwardReferenceInTypeParameterBound() {
runWithLanguageLevel(LanguageLevel.PYTHON312, () -> {
doTestByText("""
class ClassA[S: ForwardReference[int], T: "ForwardReference[str]"]: # OK
...
class ClassB[T: (ForwardReference[int], "ForwardReference[str]", bytes)]: # OK
...
class ClassC[T = ForwardReference[int], T1 = "ForwardReference[str]"]: # OK
...
class ForwardReference[T]: ...
""");
});
}
@NotNull
@Override
protected Class<? extends PyInspection> getInspectionClass() {