mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-86310 Code Insight: Fix false-positive "Type alias is not generic or already specialized"
Correctly resolve type aliases to their declarations GitOrigin-RevId: 1bf29bf68e8c79dc3e403b7addf9e62ead8cd7d3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
761b7a99d7
commit
34eafbc5cf
+14
-9
@@ -2291,18 +2291,23 @@ public final class PyTypingTypeProvider extends PyTypeProviderWithCustomContext<
|
||||
* It can be done either with a variable annotation or a type comment.
|
||||
*/
|
||||
public static boolean isExplicitTypeAlias(@NotNull PyAssignmentStatement assignment, @NotNull TypeEvalContext context) {
|
||||
PyExpression annotationValue = getAnnotationValue(assignment, context);
|
||||
PyTargetExpression target = as(ArrayUtil.getFirstElement(assignment.getTargets()), PyTargetExpression.class);
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
return isExplicitTypeAlias(target, context);
|
||||
}
|
||||
|
||||
public static boolean isExplicitTypeAlias(@NotNull PyTargetExpression targetExpression, @NotNull TypeEvalContext context) {
|
||||
PyExpression annotationValue = getAnnotationValue(targetExpression, context);
|
||||
if (annotationValue instanceof PyReferenceExpression) {
|
||||
return resolvesToQualifiedNames(annotationValue, context, TYPE_ALIAS, TYPE_ALIAS_EXT);
|
||||
}
|
||||
PyTargetExpression target = as(ArrayUtil.getFirstElement(assignment.getTargets()), PyTargetExpression.class);
|
||||
if (target != null) {
|
||||
String typeCommentAnnotation = target.getTypeCommentAnnotation();
|
||||
if (typeCommentAnnotation != null) {
|
||||
PyExpression commentValue = toExpression(typeCommentAnnotation, assignment);
|
||||
if (commentValue instanceof PyReferenceExpression) {
|
||||
return resolvesToQualifiedNames(commentValue, context, TYPE_ALIAS, TYPE_ALIAS_EXT);
|
||||
}
|
||||
String typeCommentAnnotation = targetExpression.getTypeCommentAnnotation();
|
||||
if (typeCommentAnnotation != null) {
|
||||
PyExpression commentValue = toExpression(typeCommentAnnotation, targetExpression);
|
||||
if (commentValue instanceof PyReferenceExpression) {
|
||||
return resolvesToQualifiedNames(commentValue, context, TYPE_ALIAS, TYPE_ALIAS_EXT);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
+9
-5
@@ -1096,8 +1096,14 @@ class PyTypeHintsInspection : PyInspection() {
|
||||
}
|
||||
|
||||
private fun checkGenericTypeParameterization(node: PySubscriptionExpression) {
|
||||
val declaration = node.operand.reference
|
||||
?.let { PyResolveUtil.resolveDeclaration(it, resolveContext) }
|
||||
val operandRefExpression = node.operand as? PyReferenceExpression ?: return
|
||||
val declaration = multiFollowAssignmentsChain(operandRefExpression) {
|
||||
return@multiFollowAssignmentsChain when {
|
||||
PyTypingTypeProvider.isExplicitTypeAlias(it, myTypeEvalContext) -> false
|
||||
PyTypingAliasStubType.getAssignedValueStubLike(it) is PyReferenceExpression -> followNotTypingOpaque(it)
|
||||
else -> false
|
||||
}
|
||||
}.firstOrNull()
|
||||
|
||||
when (declaration) {
|
||||
is PyTargetExpression -> checkTypeAliasParameterization(node, declaration)
|
||||
@@ -1134,11 +1140,9 @@ class PyTypeHintsInspection : PyInspection() {
|
||||
|
||||
private fun checkTypeAliasParameterization(node: PySubscriptionExpression, declaration: PyTargetExpression) {
|
||||
val assignedValue = PyTypingAliasStubType.getAssignedValueStubLike(declaration) ?: return
|
||||
if (PyTypingTypeProvider.resolveToQualifiedNames(assignedValue, myTypeEvalContext)
|
||||
.any { PyTypingTypeProvider.OPAQUE_NAMES.contains(it) }) return
|
||||
val assignedValueType = Ref.deref(PyTypingTypeProvider.getType(assignedValue, myTypeEvalContext)) ?: return
|
||||
|
||||
val isExplicitTypeAlias = declaration.annotationValue != null
|
||||
val isExplicitTypeAlias = PyTypingTypeProvider.isExplicitTypeAlias(declaration, myTypeEvalContext)
|
||||
val generics = collectTypeParametersFromTypeAlias(assignedValue, assignedValueType, isExplicitTypeAlias)
|
||||
if (generics.isEmpty) {
|
||||
registerProblem(node.indexExpression, PyPsiBundle.message("INSP.type.hints.generic.type.alias.is.not.generic.or.already.parameterized"), ProblemHighlightType.WARNING)
|
||||
|
||||
@@ -3243,6 +3243,15 @@ public class PyTypeHintsInspectionTest extends PyInspectionTestCase {
|
||||
""");
|
||||
}
|
||||
|
||||
// PY-86310
|
||||
public void testTargetExpressionWithReassignmentNotProcessedAsImplicitTypeAlias() {
|
||||
doTestByText("""
|
||||
b = []
|
||||
a = b
|
||||
_ = a[0] # No error expected
|
||||
""");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Class<? extends PyInspection> getInspectionClass() {
|
||||
|
||||
Reference in New Issue
Block a user