facebook / facebook/pyrefly

`Literal[False, True]` is not assignable to `bool`, sometimes

Open
#4,556 2 comments 0 reactions 0 assignees View on GitHub
narrowing typechecking
Dominant language
Rust
Stars
7k
Forks
516
PR merge metrics
No merged PRs in 30d

Description

### Describe the Bug

`pyright` and `ty` accept both versions, but `pyrefly` complains if there was an assignment before passing the argument to the function:

```py
from typing import Literal

def func(_mapping: dict[str, str | bool]) -> None:
return

def example(a: Literal[True], b: Literal[False], c: str) -> None:
ok = func({"a": a, "b": b, "c": c})
infer = {"a": a, "b": b, "c": c}
nope = func(infer) # Argument `dict[str, Literal[False, True] | str]` is not assignable to parameter `_mapping` with type `dict[str, bool | str]` in function `func` [bad-argument-type]
```

I took a look at the typing spec, and I didn't find anything specifying my expectation.
The closest was here:
- https://typing.python.org/en/latest/spec/literal.html#interactions-with-enums-and-exhaustiveness-checks
- https://typing.python.org/en/latest/spec/literal.html#interactions-with-narrowing

Essentially I'd expect `Literal[False, True]` to be assignable to `bool` - in the same way that `Literal[, ...]` is assignable to ``

### Sandbox Link

https://pyrefly.org/sandbox/?project=v2.pZTBDoIwDIZfZZEDmBB35wE8excOY0wkmo3A8GJ8d_92EAUTovHWNO2frf36_2CZo-u9Y5pgSewZmajgXnRojBFgLXHcxXL_AalJwYRDTFQ2aR9pX0UqyldmrwAdUppveynoLpgKv-SebxRYESrFlEqKSoo0RfoBIPhI7Ml06FgvDrXWtbQYFue-7efGI3EICTEOD14HVOoBjgoEdrmNYKZGnL1v-0zKqd11tTRWVk73ctYhBcGtbqphn57LCceE9pD9B7U4kBavgRYTZ6jAlwfrG3811RcwPQE

### Additional Info
The repro is based on (https://github.com/dangotbanned/mosaic/blob/f24c14ed921794cb5db3712ab626d694c5501c00/packages/vgplot/spec-python/tools/codegen/typed_dict.py#L51-L80).
Where I tried out `pyrefly` on a new codebase and this error was reported twice

Contributor guide

Open the contributing guide

Research direction

Start with the Python example in the issue and reproduce it in the linked pyrefly sandbox, comparing the direct dictionary argument with the assigned `infer` variable. Review the referenced `packages/vgplot/spec-python/tools/codegen/typed_dict.py` context and the typing-spec links; done means the assigned dictionary containing `Literal[False, True]` is accepted as `dict[str, str | bool]` without regressing related checks.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
compilers, devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.