From 492275db1c5b58a803bd3ce79cae79f27e5e0587 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 19 Oct 2024 16:36:16 -0700 Subject: [PATCH] Enhanced the `type(y) == x` type guard logic to support the case where `y` is declared as a type variable with an upper bound that overlaps with the type of `x`. This addresses #9227. --- .../pyright-internal/src/analyzer/typeGuards.ts | 2 +- .../src/tests/samples/typeNarrowingTypeIs1.py | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/pyright-internal/src/analyzer/typeGuards.ts b/packages/pyright-internal/src/analyzer/typeGuards.ts index 90105274816a..c728e461983a 100644 --- a/packages/pyright-internal/src/analyzer/typeGuards.ts +++ b/packages/pyright-internal/src/analyzer/typeGuards.ts @@ -2328,7 +2328,7 @@ function narrowTypeForTypeIs(evaluator: TypeEvaluator, type: Type, classType: Cl if (isPositiveTest) { if (matches) { if (ClassType.isSameGenericClass(subtype, classType)) { - return subtype; + return addConditionToType(subtype, classType.props?.condition); } return addConditionToType(ClassType.cloneAsInstance(classType), subtype.props?.condition); diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingTypeIs1.py b/packages/pyright-internal/src/tests/samples/typeNarrowingTypeIs1.py index e4bd834cbc6c..f2972e6516e6 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingTypeIs1.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingTypeIs1.py @@ -93,12 +93,10 @@ def func7(val: Any): reveal_type(val, expected_text="int | Any") -class CParent: - ... +class CParent: ... -class CChild(CParent): - ... +class CChild(CParent): ... _TC = TypeVar("_TC", bound=CParent) @@ -127,3 +125,14 @@ def method1(cls, v: str): reveal_type(v, expected_text="G*") else: reveal_type(v, expected_text="str") + + +class H: + def __init__(self, x): ... + + +def func9[T: H](x: type[T], y: H) -> T: + if type(y) == x: + reveal_type(y, expected_text="H*") + return y + return x(y)