PY-78822 Type argument for "Protocol" must be a type parameter is not reported by PyCharm

GitOrigin-RevId: 8e02ca094674c75bed86e1feffeac5909828f38c
This commit is contained in:
Petr
2025-05-20 18:48:27 +00:00
committed by intellij-monorepo-bot
parent f30dc5d254
commit 2f533480a1
4 changed files with 14 additions and 7 deletions
@@ -1164,7 +1164,7 @@ INSP.type.hints.cannot.inherit.from.plain.generic=Cannot inherit from plain 'Gen
INSP.type.hints.cannot.inherit.from.generic.multiple.times=Cannot inherit from 'Generic[...]' multiple times
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.type.variables=Parameters to ''{0,choice,0#Generic|1#Protocol}[...]'' must all be type variables
INSP.type.hints.parameters.to.generic.must.all.be.unique=Parameters to 'Generic[...]' must all be unique
INSP.type.hints.non.default.type.vars.cannot.follow.defaults=Non-default TypeVars cannot follow ones with defaults
INSP.type.hints.default.type.var.cannot.follow.type.var.tuple=TypeVar with a default value cannot follow TypeVarTuple
@@ -935,7 +935,8 @@ class PyTypeHintsInspection : PyInspection() {
qNames.forEach {
when (it) {
genericQName -> checkTypingGenericParameters(node)
genericQName -> checkTypingGenericParameters(node, false)
protocolQName, protocolExtQName -> checkTypingGenericParameters(node, true)
literalQName, literalExtQName -> checkLiteralParameter(index)
annotatedQName, annotatedExtQName -> checkAnnotatedParameter(index)
typeAliasQName, typeAliasExtQName -> reportParameterizedTypeAlias(index)
@@ -1105,7 +1106,7 @@ class PyTypeHintsInspection : PyInspection() {
return typeArgumentTypes
}
private fun checkTypingGenericParameters(node: PySubscriptionExpression) {
private fun checkTypingGenericParameters(node: PySubscriptionExpression, isProtocol: Boolean) {
val indexExpression = node.indexExpression ?: return
val typeExpressions = (indexExpression as? PyTupleExpression)?.elements ?: arrayOf(indexExpression)
val typeParams = mutableSetOf<PyTypeParameterType>()
@@ -1115,13 +1116,17 @@ class PyTypeHintsInspection : PyInspection() {
for (typeExpr in typeExpressions) {
if (typeExpr !is PyReferenceExpression && typeExpr !is PyStarExpression && typeExpr !is PySubscriptionExpression) {
registerProblem(typeExpr, PyPsiBundle.message("INSP.type.hints.parameters.to.generic.must.all.be.type.variables"),
registerProblem(typeExpr,
PyPsiBundle.message("INSP.type.hints.parameters.to.generic.must.all.be.type.variables",
if (isProtocol) 1 else 0),
ProblemHighlightType.GENERIC_ERROR)
continue
}
val typeParameterType = Ref.deref(PyTypingTypeProvider.getType(typeExpr, myTypeEvalContext))
if (typeParameterType !is PyTypeParameterType) {
registerProblem(typeExpr, PyPsiBundle.message("INSP.type.hints.parameters.to.generic.must.all.be.type.variables"),
registerProblem(typeExpr,
PyPsiBundle.message("INSP.type.hints.parameters.to.generic.must.all.be.type.variables",
if (isProtocol) 1 else 0),
ProblemHighlightType.GENERIC_ERROR)
continue
}
-1
View File
@@ -27,7 +27,6 @@ directives_deprecated.py
directives_type_checking.py
directives_version_platform.py
generics_base_class.py
generics_basic.py
generics_defaults.py
generics_defaults_referential.py
generics_paramspec_components.py
@@ -115,13 +115,16 @@ public class PyTypeHintsInspectionTest extends PyInspectionTestCase {
// PY-28227
public void testGenericParametersTypes() {
doTestByText("""
from typing import Generic, TypeVar
from typing import Generic, Protocol, TypeVar
class A1(Generic[<error descr="Parameters to 'Generic[...]' must all be type variables">0</error>]):
pass
class B1(Generic[<error descr="Parameters to 'Generic[...]' must all be type variables">int</error>]):
pass
class B11(Protocol[<error descr="Parameters to 'Protocol[...]' must all be type variables">int</error>]):
pass
class A2(Generic[<error descr="Parameters to 'Generic[...]' must all be type variables">0</error>, <error descr="Parameters to 'Generic[...]' must all be type variables">0</error>]):
pass