Type narrowing not working with dict with literal keys
Describe the Bug
In the following example, I expected reveal_type(x) to output int, but the actual output was dict[Literal['value'], int] | int.
As a result, the type checker gives a [bad-return] error.
from typing import Literal, reveal_type
def get_value(x: dict[Literal['value'], int] | int) -> int | None:
if isinstance(x, dict):
return x.get('value')
reveal_type(x) # Revealed type is `dict[Literal['value'], int] | int`, but it should be `int`
return x
(This example works as expected in Pyright.)
Sandbox Link
https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeSIAxAAQDqMUAxrgLYzUAuunAFuwAqkATjDBRS1AMoYcBADS8IcakuqpqxVAHMYAHXQ0A7nxHVSuAK7VGGaoaEQOMBXB6pTM6rHfo1eCxycpMQQ6FoqvoIcPLjohPqUCdQAEjAeHtaWxLDUYDCoHBYiyrhgispoWHj4iEkAtNQA4jCBIqhQdRwQbEHE7Ix8jADWoeF5MDiow-XUAKpw7CIAbvlQAPocwTAAFACUnNyhcH2MgaF5QiKYvfAzMPh9DmzogYaOPLzsAJIAIgCiuXyhWKvAKdnYcAsxGIuCEgW2MEIWkIagCuGYLGyLWc1C0uE6%2BMwolCjggsQUMRWQgULUYuxmtAcTjUWGoQgskVI0VimSJ1EwEBEp3EETMliE1GwQlwhgWQn0%2BjA0pYvVGKkxsMCABlHGl2gplqsNlsFQZqAAVHiqQywoZwfREso6DhrJbtCwwNY2oQjMLbGr8iCnADacA41IiHAAutQAD6R-Z1AB8kbj1AAcrEYLVfNQ8xAykojhwMIwdvgFALTrsc3m63WRMDfERndsAORuqAetv03N5w3tY19f37GjJ1OoZT3E5OTD6euNorN000ZIymBUhTRVSYXDwajoXCvW0O0S4lqu92ew8u72%2BrT%2BxCBkM6pxCdrBjtXttRhShaNpv%2BiYpv%2BaaZug2bznWBYqHAxaluWlZBhwNZQfW-YtEu1Ati07adt2vYLhuRqbMO%2BCjtQABKxHtBMNywdQAAGVYcMGr56lAn74TAP5-i8Mbxv%2BjEKNgAQqIEriWFA1zYOwjFCWhbKYUIy7oKaIByCAATQHAJDkIgVBzF0UCOBIYAcqcZLoPaalYGeYCwiwBRrOgFgsLJQiPgm1DjmGQi1g2ym%2BGAuggOmbkeU%2BwD4AAvqF%2BgaSAZAiGIpCEFwLBQBQNCCClIqVLI%2BCZOgkBaEUBRWfEZqSDA7A8BwHDEHAiAAPQtclojiIQsJaC1MDoC1u6MHALXMCVEBle%2BXSxC1uSwmobrQKg2A5GNpXldNvi4MQm26foZDcugdRUnBPIALzUKFADMhAAIwAEzxegIAxZpUxdCsABi0AwBQBXVHpL1AA
(Only applicable for extension issues) IDE Information
No response
Thanks for the bug report!
For whoever picks this up: my initial thought was that maybe negations for generics are generally wrong, but that doesn't seem to be the case (sandbox) so it's something specific to literal, dict, or both.