Skip to content

mypy does not infer that a string Literal is a str in the context of a dict or Mapping #18494

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
msto opened this issue Jan 20, 2025 · 1 comment
Labels
bug mypy got something wrong

Comments

@msto
Copy link

msto commented Jan 20, 2025

Bug Report

Mypy reports an arg-type error when passing a dictionary with Literal keys to a function typed to receive a dictionary with str keys, even when all such literals are strings.

To Reproduce

from collections.abc import Mapping
from typing import Literal


def foo(mapping: dict[str, str]) -> None:
    pass


def bar(mapping: Mapping[str, str]) -> None:
    pass


mapping: dict[Literal["key"], str] = {"key": "value"}

foo(mapping)  # E: Argument 1 to "foo" has incompatible type "dict[Literal['key'], str]"; expected "dict[str, str]"  [arg-type]
bar(mapping)  # E: Argument 1 to "bar" has incompatible type "dict[Literal['key'], str]"; expected "Mapping[str, str]"  [arg-type]

Expected Behavior

Since the literal "key" is a string, I expected mypy to report no error here.

Actual Behavior

Mypy reported the arg-type errors described in the above reprex.

Your Environment

  • Mypy version used: 1.14.1
  • Mypy command-line flags:
  • Mypy configuration options from mypy.ini (and other config files):
     strict_optional             = true
     strict_equality             = true
     check_untyped_defs          = true
     disallow_incomplete_defs    = true
     disallow_untyped_calls      = true
     disallow_untyped_decorators = true
     disallow_untyped_defs       = true
     no_implicit_optional        = true
     warn_no_return              = true
     warn_redundant_casts        = true
     warn_return_any             = true
     warn_unreachable            = true
     warn_unused_configs         = true
     warn_unused_ignores         = true
     enable_error_code           = "ignore-without-code"
    
  • Python version used: 3.12.8
@msto msto added the bug mypy got something wrong label Jan 20, 2025
@sterliakov
Copy link
Collaborator

Mapping is invariant in key type, so Mapping[Literal['a'], str] can't be assigned to Mapping[str, str].

See, for example, an old python/typing#273 for discussion of this limitation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

2 participants