PY-61137 Accept LiteralString if expected is a TypeVar with LiteralString as a bound

(cherry picked from commit 5de62a9e91dbfa74b5077671858f96e446e9d121)

IJ-MR-112631

GitOrigin-RevId: 829184b6a204609d67cf4c668eb1125c46fa2d84
This commit is contained in:
lada.gagina
2023-09-29 13:56:33 +02:00
committed by intellij-monorepo-bot
parent 4f681032ed
commit be82cf6646
2 changed files with 15 additions and 3 deletions

View File

@@ -234,9 +234,6 @@ public final class PyTypeChecker {
return false;
}
// Remove value-specific components from the actual type to make it safe to propagate
PyType safeActual = replaceLiteralStringWithStr(actual);
final PyType substitution = context.mySubstitutions.typeVars.get(expected);
PyType bound = expected.getBound();
// Promote int in Type[TypeVar('T', int)] to Type[int] before checking that bounds match
@@ -245,6 +242,9 @@ public final class PyTypeChecker {
bound = PyUnionType.union(PyTypeUtil.toStream(bound).map(toDefinition).toList());
}
// Remove value-specific components from the actual type to make it safe to propagate
PyType safeActual = bound instanceof PyLiteralStringType ? actual : replaceLiteralStringWithStr(actual);
Optional<Boolean> match = match(bound, safeActual, context);
if (match.isPresent() && !match.get()) {
return false;

View File

@@ -1943,6 +1943,18 @@ public class Py3TypeCheckerInspectionTest extends PyInspectionTestCase {
""");
}
// PY-61137
public void testTypeVarBoundToLiteralString() {
doTestByText("""
from typing import TypeVar, LiteralString
TLiteral = TypeVar("TLiteral", bound=LiteralString)
def literal_identity(s: TLiteral) -> TLiteral:
return s
s: LiteralString
y2 = literal_identity(s)
""");
}
// PY-62476
public void testTypeGuardReturnTypeTreatedAsBool() {
runWithLanguageLevel(