diff --git a/mypy/checker.py b/mypy/checker.py index 5d97a0dec713..a21780defe0c 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -5305,9 +5305,7 @@ def conditional_types_for_iterable( for key in item_str_literals: if key in possible_iterable_type.required_keys: if_types.append(possible_iterable_type) - elif ( - key in possible_iterable_type.items or not possible_iterable_type.is_final - ): + elif key in possible_iterable_type.items: if_types.append(possible_iterable_type) else_types.append(possible_iterable_type) else: diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index 7de8e6416f35..c57f34ce2f7e 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -2017,9 +2017,7 @@ v = {bad2: 2} # E: Missing key "num" for TypedDict "Value" \ [case testOperatorContainsNarrowsTypedDicts_unionWithList] from __future__ import annotations from typing import assert_type, TypedDict, Union -from typing_extensions import final -@final class D(TypedDict): foo: int @@ -2037,20 +2035,16 @@ else: [typing fixtures/typing-typeddict.pyi] [case testOperatorContainsNarrowsTypedDicts_total] +# flags: --warn-unreachable from __future__ import annotations from typing import assert_type, Literal, TypedDict, TypeVar, Union -from typing_extensions import final -@final class D1(TypedDict): foo: int - -@final class D2(TypedDict): bar: int - d: D1 | D2 if 'foo' in d: @@ -2058,6 +2052,11 @@ if 'foo' in d: else: assert_type(d, D2) +if 'unknown_key' in d: + object() # E: Statement is unreachable +else: + assert_type(d, Union[D1, D2]) + foo_or_bar: Literal['foo', 'bar'] if foo_or_bar in d: assert_type(d, Union[D1, D2]) @@ -2083,69 +2082,20 @@ def f(arg: TD) -> None: else: assert_type(arg['bar'], int) - [builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] -[case testOperatorContainsNarrowsTypedDicts_final] +[case testOperatorContainsNarrowsTypedDicts_totalFalse] # flags: --warn-unreachable from __future__ import annotations -from typing import assert_type, TypedDict, Union -from typing_extensions import final - -@final -class DFinal(TypedDict): - foo: int - - -class DNotFinal(TypedDict): - bar: int - - -d_not_final: DNotFinal - -if 'bar' in d_not_final: - assert_type(d_not_final, DNotFinal) -else: - spam = 'ham' # E: Statement is unreachable - -if 'spam' in d_not_final: - assert_type(d_not_final, DNotFinal) -else: - assert_type(d_not_final, DNotFinal) - -d_final: DFinal - -if 'spam' in d_final: - spam = 'ham' # E: Statement is unreachable -else: - assert_type(d_final, DFinal) - -d_union: DFinal | DNotFinal - -if 'foo' in d_union: - assert_type(d_union, Union[DFinal, DNotFinal]) -else: - assert_type(d_union, DNotFinal) - -[builtins fixtures/dict.pyi] -[typing fixtures/typing-typeddict.pyi] - -[case testOperatorContainsNarrowsTypedDicts_partialThroughTotalFalse] -from __future__ import annotations from typing import assert_type, Literal, TypedDict, Union -from typing_extensions import final -@final class DTotal(TypedDict): required_key: int - -@final class DNotTotal(TypedDict, total=False): optional_key: int - d: DTotal | DNotTotal if 'required_key' in d: @@ -2158,6 +2108,11 @@ if 'optional_key' in d: else: assert_type(d, Union[DTotal, DNotTotal]) +if 'unknown_key' in d: + object() # E: Statement is unreachable +else: + assert_type(d, Union[DTotal, DNotTotal]) + key: Literal['optional_key', 'required_key'] if key in d: assert_type(d, Union[DTotal, DNotTotal]) @@ -2167,23 +2122,19 @@ else: [builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] -[case testOperatorContainsNarrowsTypedDicts_partialThroughNotRequired] +[case testOperatorContainsNarrowsTypedDicts_NotRequired] +# flags: --warn-unreachable from __future__ import annotations from typing import assert_type, Required, NotRequired, TypedDict, Union -from typing_extensions import final -@final class D1(TypedDict): required_key: Required[int] optional_key: NotRequired[int] - -@final class D2(TypedDict): abc: int xyz: int - d: D1 | D2 if 'required_key' in d: @@ -2196,6 +2147,11 @@ if 'optional_key' in d: else: assert_type(d, Union[D1, D2]) +if 'unknown_key' in d: + object() # E: Statement is unreachable +else: + assert_type(d, Union[D1, D2]) + [builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi]