PY-78828 No Protocol[] must include all type variables error is reported

GitOrigin-RevId: 5b8ed27b66cf78fa49009b39f9e70a14eae65d9d
This commit is contained in:
Petr
2025-05-20 18:48:27 +00:00
committed by intellij-monorepo-bot
parent 47b67bdbb4
commit f30dc5d254
3 changed files with 16 additions and 13 deletions
@@ -1162,7 +1162,7 @@ INSP.type.hints.typed.dict.is.not.allowed.as.a.bound.for.a.type.var=TypedDict is
INSP.type.hints.generics.should.be.specified.through.square.brackets=Generics should be specified through square brackets
INSP.type.hints.cannot.inherit.from.plain.generic=Cannot inherit from plain 'Generic'
INSP.type.hints.cannot.inherit.from.generic.multiple.times=Cannot inherit from 'Generic[...]' multiple times
INSP.type.hints.some.type.variables.are.not.listed.in.generic=Some type variables ({0}) are not listed in ''Generic[{1}]''
INSP.type.hints.generic.or.protocol.should.list.all.type.variables=''Generic[...]'' or ''Protocol[...]'' should list all type variables ({0})
INSP.type.hints.illegal.literal.parameter='Literal' may be parameterized with literal ints, byte and unicode strings, bools, Enum values, None, other literal types, or type aliases to other literal types
INSP.type.hints.parameters.to.generic.must.all.be.type.variables=Parameters to 'Generic[...]' must all be type variables
INSP.type.hints.parameters.to.generic.must.all.be.unique=Parameters to 'Generic[...]' must all be unique
@@ -57,6 +57,8 @@ class PyTypeHintsInspection : PyInspection() {
private class Visitor(holder: ProblemsHolder, context: TypeEvalContext) : PyInspectionVisitor(holder, context) {
private val genericQName = QualifiedName.fromDottedString(PyTypingTypeProvider.GENERIC)
private val protocolQName = QualifiedName.fromDottedString(PyTypingTypeProvider.PROTOCOL)
private val protocolExtQName = QualifiedName.fromDottedString(PyTypingTypeProvider.PROTOCOL_EXT)
override fun visitPyCallExpression(node: PyCallExpression) {
super.visitPyCallExpression(node)
@@ -830,14 +832,9 @@ class PyTypeHintsInspection : PyInspection() {
.mapNotNull { it.name }
.joinToString(", ")
val genericTypeVarsNames = genericTypeVars
.asSequence()
.mapNotNull { it.name }
.joinToString(", ")
registerProblem(cls.superClassExpressionList,
PyPsiBundle.message("INSP.type.hints.some.type.variables.are.not.listed.in.generic",
nonGenericTypeVarsNames, genericTypeVarsNames),
PyPsiBundle.message("INSP.type.hints.generic.or.protocol.should.list.all.type.variables",
nonGenericTypeVarsNames),
ProblemHighlightType.GENERIC_ERROR)
}
}
@@ -859,7 +856,9 @@ class PyTypeHintsInspection : PyInspection() {
val operand = superSubscription.operand
val generic =
operand is PyReferenceExpression &&
genericQName in PyResolveUtil.resolveImportedElementQNameLocally(operand)
PyResolveUtil.resolveImportedElementQNameLocally(operand).any {
it in listOf(genericQName, protocolQName, protocolExtQName)
}
val index = superSubscription.indexExpression
val parameters = (index as? PyTupleExpression)?.elements ?: arrayOf(index)
@@ -209,17 +209,20 @@ public class PyTypeHintsInspectionTest extends PyInspectionTestCase {
// PY-28227
public void testGenericCompleteness() {
doTestByText("""
from typing import Generic, TypeVar, Iterable
from typing import Generic, TypeVar, Iterable, Protocol
T = TypeVar('T')
S = TypeVar('S')
class C<error descr="Some type variables (S) are not listed in 'Generic[T]'">(Generic[T], Iterable[S])</error>:
class C<error descr="'Generic[...]' or 'Protocol[...]' should list all type variables (S)">(Generic[T], Iterable[S])</error>:
pass
class P<error descr="'Generic[...]' or 'Protocol[...]' should list all type variables (S)">(Iterable[S], Protocol[T])</error>:
pass
B = Generic
D = T
class A<error descr="Some type variables (S) are not listed in 'Generic[T]'">(B[<error descr="Parameters to 'Generic[...]' must all be type variables">D</error>], Iterable[S])</error>:
class A<error descr="'Generic[...]' or 'Protocol[...]' should list all type variables (S)">(B[<error descr="Parameters to 'Generic[...]' must all be type variables">D</error>], Iterable[S])</error>:
pass
class E(Generic[T], Iterable[T]):
@@ -229,7 +232,8 @@ public class PyTypeHintsInspectionTest extends PyInspectionTestCase {
pass
class G(Iterable[T]):
pass""");
pass
""");
}
// PY-31147