Skip to content

Commit

Permalink
Added support for bool expansion to `Literal[True] | Literal[False]…
Browse files Browse the repository at this point in the history
…` during pattern matching when using value patterns. (#8677)
  • Loading branch information
erictraut authored Aug 6, 2024
1 parent c1df659 commit 08e02e4
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 22 deletions.
45 changes: 24 additions & 21 deletions packages/pyright-internal/src/analyzer/patternMatching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1145,29 +1145,32 @@ function narrowTypeBasedOnValuePattern(
(subjectSubtypeExpanded) => {
// If this is a negative test, see if it's an enum value.
if (!isPositiveTest) {
if (
isClassInstance(subjectSubtypeExpanded) &&
ClassType.isEnumClass(subjectSubtypeExpanded) &&
!isLiteralType(subjectSubtypeExpanded) &&
isClassInstance(valueSubtypeExpanded) &&
isSameWithoutLiteralValue(subjectSubtypeExpanded, valueSubtypeExpanded) &&
isLiteralType(valueSubtypeExpanded)
) {
const allEnumTypes = enumerateLiteralsForType(evaluator, subjectSubtypeExpanded);
if (allEnumTypes) {
return combineTypes(
allEnumTypes.filter(
(enumType) => !ClassType.isLiteralValueSame(valueSubtypeExpanded, enumType)
)
if (isClassInstance(subjectSubtypeExpanded) && isClassInstance(valueSubtypeExpanded)) {
if (
!isLiteralType(subjectSubtypeExpanded) &&
isSameWithoutLiteralValue(subjectSubtypeExpanded, valueSubtypeExpanded) &&
isLiteralType(valueSubtypeExpanded)
) {
const expandedLiterals = enumerateLiteralsForType(
evaluator,
subjectSubtypeExpanded
);
if (expandedLiterals) {
return combineTypes(
expandedLiterals.filter(
(enumType) =>
!ClassType.isLiteralValueSame(valueSubtypeExpanded, enumType)
)
);
}
}

if (
isLiteralType(subjectSubtypeExpanded) &&
ClassType.isLiteralValueSame(valueSubtypeExpanded, subjectSubtypeExpanded)
) {
return undefined;
}
} else if (
isClassInstance(subjectSubtypeExpanded) &&
isClassInstance(valueSubtypeExpanded) &&
isLiteralType(subjectSubtypeExpanded) &&
ClassType.isLiteralValueSame(valueSubtypeExpanded, subjectSubtypeExpanded)
) {
return undefined;
}

return subjectSubtypeExpanded;
Expand Down
16 changes: 15 additions & 1 deletion packages/pyright-internal/src/tests/samples/matchValue1.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

from dataclasses import dataclass
from enum import Enum, auto
from typing import Annotated, TypeVar
from http import HTTPStatus
from typing import Annotated, Literal, TypeVar

# pyright: reportIncompatibleMethodOverride=false

Expand Down Expand Up @@ -141,3 +141,17 @@ def test_enum_narrowing_with_inf(subj: float):
reveal_type(subj, expected_text="float")
case f:
reveal_type(subj, expected_text="float")


@dataclass
class DC2:
a: Literal[False]


def test_bool_expansion(subj: bool):
match subj:
case DC2.a:
reveal_type(subj, expected_text="Literal[False]")

case x:
reveal_type(subj, expected_text="Literal[True]")

0 comments on commit 08e02e4

Please sign in to comment.