Skip to content

ty literal narrowing: invalid-assignment after Literal branch test #2140

@dsfaccini

Description

@dsfaccini

Summary

Ty does not narrow a Literal/tuple union when assigning to a wider Literal union.

Playground link: https://play.ty.dev/f8ecb06d-124e-4921-a082-9038c1302ed2

Repro (self-contained)

ty_repro_literal.py:

from typing import Literal

def demo(x: Literal['none', 'auto', 'required'] | tuple[list[str], Literal['auto', 'required']]):
    y: Literal['none', 'required', 'auto'] | int | None
    if x in ('auto', 'required'):
        y = x
    elif x == 'none':
        y = 'none'
    elif isinstance(x, tuple):
        y = 'auto'
    else:
        y = None
    return y

Run:

uvx ty check ty_repro_literal.py

Actual result

error[invalid-assignment]: Object of type `Literal["auto", "required"] | tuple[list[str], Literal["auto", "required"]]` is not assignable to `Literal["none", "required", "auto"] | int | None`
 --> ty_repro_literal.py:6:9

Expected result

No diagnostic: in the x in ('auto', 'required') branch, x is narrowed to Literal['auto', 'required'], which is assignable to Literal['none', 'required', 'auto'] | int | None.

Notes

Occurs on ty 0.0.4 via uvx ty check.

Metadata

Metadata

Assignees

Labels

narrowingrelated to flow-sensitive type narrowing

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions