Skip to content

Commit 9dbb53e

Browse files
committed
test: cover generator ternary narrowing regression
1 parent 5679a89 commit 9dbb53e

2 files changed

Lines changed: 20 additions & 7 deletions

File tree

mypy/checker.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4767,8 +4767,12 @@ def infer_rvalue_with_fallback_context(
47674767
# binder.accumulate_type_assignments() and assign the types inferred for type
47684768
# context that is ultimately used. This is however tricky with redefinitions.
47694769
# For now we simply disable second accept in cases known to cause problems,
4770-
# see e.g. testAssignToOptionalTupleWalrus.
4771-
has_walrus = self._has_assignment_expr(rvalue)
4770+
# see e.g. testAssignToOptionalTupleWalrus. We only need to scan for walrus
4771+
# when union fallback is otherwise applicable.
4772+
union_fallback_possible = (
4773+
preferred_context is not None and isinstance(get_proper_type(lvalue_type), UnionType)
4774+
)
4775+
has_walrus = union_fallback_possible and self._has_assignment_expr(rvalue)
47724776

47734777
fallback_context_used = False
47744778
with (
@@ -4795,11 +4799,7 @@ def infer_rvalue_with_fallback_context(
47954799
# Try re-inferring r.h.s. in empty context for union with explicit annotation,
47964800
# and use it results in a narrower type. This helps with various practical
47974801
# examples, see e.g. testOptionalTypeNarrowedByGenericCall.
4798-
union_fallback = (
4799-
preferred_context is not None
4800-
and isinstance(get_proper_type(lvalue_type), UnionType)
4801-
and not has_walrus
4802-
)
4802+
union_fallback = union_fallback_possible and not has_walrus
48034803

48044804
# Skip literal types, as they have special logic (for better errors).
48054805
try_fallback = redefinition_fallback or union_fallback or argument_redefinition_fallback

test-data/unit/check-inference-context.test

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,19 @@ i = i if isinstance(i, int) else b
15141514
reveal_type(i) # N: Revealed type is "Any | builtins.int"
15151515
[builtins fixtures/isinstance.pyi]
15161516

1517+
[case testTypeNarrowingByReassignmentGeneratorTernary]
1518+
from typing import Iterable, Union
1519+
1520+
def foo(args: Union[Iterable[Union[str, int]], str, int]) -> Iterable[str]:
1521+
if isinstance(args, (str, int)):
1522+
args = (args,)
1523+
args = (
1524+
arg if isinstance(arg, str) else str(arg)
1525+
for arg in args
1526+
)
1527+
return args
1528+
[builtins fixtures/isinstance.pyi]
1529+
15171530
[case testLambdaInferenceUsesNarrowedTypes]
15181531
from typing import Optional, Callable
15191532

0 commit comments

Comments
 (0)