Skip to content

Inference for Literal arguments not handled  #11003

Open

Description

@Dr-Irv

Bug Report

If you have a function with Literal arguments, and a variable that is set to one of the options, an error is reported.

To Reproduce

from typing import Literal


def myfun(a: Literal["a", "b", "c"]) -> str:
    return a


s = "a"

myfun(s)


def myfun2(a: Literal[1, 2]) -> int:
    return a


b = 2
myfun2(b)

c = 1 if s == "a" else 2
myfun2(c)

reports

literalinf.py:10: error: Argument 1 to "myfun" has incompatible type "str"; expected "Union[Literal['a'], Literal['b'], Literal['c']]"
literalinf.py:18: error: Argument 1 to "myfun2" has incompatible type "int"; expected "Union[Literal[1], Literal[2]]"
literalinf.py:21: error: Argument 1 to "myfun2" has incompatible type "int"; expected "Union[Literal[1], Literal[2]]"

Expected Behavior

No error. The values can be inferred to be of the Literal value

Actual Behavior

See above.

Your Environment

  • Mypy version used: 0.910
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.8.5
  • Operating system and version: Windows 10 21H1

Activity

  1. emmatyping commented on Aug 20, 2021

    @emmatyping
    Member

    The problem is if the variable is re-assigned to, then it could be incorrect to pass it to these functions. The solution for your scenario is to type these assignments with Final, like a: Final = "a".

  2. erictraut commented on Aug 20, 2021

    @erictraut

    It shouldn't be necessary to mark them as Final. If a variable is reassigned, the type checker knows it's reassigned and can flag it as an error.

    There is no type violation, so these errors are false positives.

    The above code type checks without errors in pyright. I don't see why it shouldn't work with mypy.

  3. Dr-Irv commented on Aug 21, 2021

    @Dr-Irv
    Author

    It shouldn't be necessary to mark them as Final. If a variable is reassigned, the type checker knows it's reassigned and can flag it as an error.

    There is no type violation, so these errors are false positives.

    The above code type checks without errors in pyright. I don't see why it shouldn't work with mypy.

    I agree. @ethanhs based on @erictraut 's comment, can you reopen this?

  4. Zac-HD commented on Dec 10, 2021

    @Zac-HD
    Contributor

    I get a related error when setting the default argument to a function:

    from typing import Literal, Sequence
    
    def f(arg: Sequence[Literal["a"]] = ("a",)) -> None:
        pass
    example.py:3:37: error: Incompatible default for argument "arg"
        (default has type "Tuple[str]", argument has type "Sequence[Literal['a']]")
    
  5. hauntsaninja commented on Dec 10, 2021

    @hauntsaninja
    Collaborator

    Hello @Zac-HD ! I enjoyed your recent paper :-) The default arguments issue is fixed on master, in #11236

  6. Zac-HD commented on Dec 10, 2021

    @Zac-HD
    Contributor

    Thanks, and thanks! I'm really looking forward to 0.920 and the release after 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions