diff --git a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java index 5beab50275d6..01def84d3cc9 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java +++ b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java @@ -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; diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyTypeHintsInspection.kt b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyTypeHintsInspection.kt index d14e7271f190..1f2134d70a42 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyTypeHintsInspection.kt +++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyTypeHintsInspection.kt @@ -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) diff --git a/python/testSrc/com/jetbrains/python/inspections/PyTypeHintsInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyTypeHintsInspectionTest.java index 85ae12b85927..f8256a860128 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyTypeHintsInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyTypeHintsInspectionTest.java @@ -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 getInspectionClass() {