PY-79834 Fixed pattern matching logic for untyped namedtuples

GitOrigin-RevId: a376074a7869e8278d3c60a0389064616b536472
This commit is contained in:
Aleksandr.Govenko
2025-12-22 22:36:14 +00:00
committed by intellij-monorepo-bot
parent b51231f76a
commit aa58078ab8
3 changed files with 9 additions and 12 deletions
@@ -9,4 +9,8 @@ public interface PyKeywordPattern extends PyAstKeywordPattern, PyPattern {
default @Nullable PyPattern getValuePattern() {
return (PyPattern)PyAstKeywordPattern.super.getValuePattern();
}
default @Nullable PyClassPattern getContainingClassPattern() {
return getParent().getParent() instanceof PyClassPattern classPattern ? classPattern : null;
}
}
@@ -252,10 +252,9 @@ class PyNamedTupleTypeProvider : PyTypeProviderBase() {
qualifierType: PyClassLikeType,
context: TypeEvalContext,
): PyCallableType? {
val call = anchor as? PyCallExpression ?: return null
val parameters = mutableListOf<PyCallableParameter>()
val resultType = qualifierType.toInstance()
val elementGenerator = PyElementGenerator.getInstance(call.project)
val elementGenerator = PyElementGenerator.getInstance(anchor.project)
if (qualifierType.isDefinition) {
parameters.add(PyCallableParameterImpl.nonPsi(PyNames.CANONICAL_SELF, resultType))
@@ -266,8 +265,9 @@ class PyNamedTupleTypeProvider : PyTypeProviderBase() {
fields.keys.mapTo(parameters) { PyCallableParameterImpl.nonPsi(it, null, ellipsis) }
return if (resultType is PyNamedTupleType) {
return if (resultType is PyNamedTupleType && anchor is PyCallExpression) {
val newFields = mutableMapOf<String?, PyType?>()
val call = anchor
for (argument in call.arguments) {
if (argument is PyKeywordArgument) {
@@ -19,14 +19,11 @@ import com.jetbrains.python.psi.types.PyInstantiableType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import static com.jetbrains.python.psi.PyUtil.as;
public final class PyKeywordPatternReference extends PsiReferenceBase.Poly<PyKeywordPattern> {
public PyKeywordPatternReference(@NotNull PyKeywordPattern keywordPattern) {
super(keywordPattern, keywordPattern.getKeywordElement().getTextRangeInParent(), false);
@@ -34,7 +31,7 @@ public final class PyKeywordPatternReference extends PsiReferenceBase.Poly<PyKey
@Override
public ResolveResult @NotNull [] multiResolve(boolean incompleteCode) {
PyClassPattern classPattern = getContainingClassPattern();
PyClassPattern classPattern = getElement().getContainingClassPattern();
if (classPattern == null) {
return ResolveResult.EMPTY_ARRAY;
}
@@ -52,7 +49,7 @@ public final class PyKeywordPatternReference extends PsiReferenceBase.Poly<PyKey
@Override
public Object @NotNull [] getVariants() {
PyClassPattern classPattern = getContainingClassPattern();
PyClassPattern classPattern = getElement().getContainingClassPattern();
if (classPattern == null) {
return LookupElement.EMPTY_ARRAY;
}
@@ -61,10 +58,6 @@ public final class PyKeywordPatternReference extends PsiReferenceBase.Poly<PyKey
return collectClassAttributeVariants(getElement(), classPattern, typeContext);
}
private @Nullable PyClassPattern getContainingClassPattern() {
return as(getElement().getParent().getParent(), PyClassPattern.class);
}
static LookupElement @NotNull [] collectClassAttributeVariants(@NotNull PsiElement location,
@NotNull PyClassPattern classPattern,
@NotNull TypeEvalContext typeContext) {