Skip to content
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

Type inference does not work for inherited Literal properties #6824

Closed
antonagestam opened this issue May 12, 2019 · 5 comments
Closed

Type inference does not work for inherited Literal properties #6824

antonagestam opened this issue May 12, 2019 · 5 comments

Comments

@antonagestam
Copy link
Contributor

I expected mypy to be able to infer that the literal in the subtype is a subtype of the property in its ancestor. Should this be allowed? I didn't find anything in the PEP defining the behavior here, but it seems like a really useful thing to be able to do.

from typing_extensions import Literal
from typing import Union


HTTPMethodName = Union[
    Literal['GET'],
    Literal['POST'],
]


class A:
    method: HTTPMethodName


class B(A):
    # works if the subclass also annotates the property
    method: HTTPMethodName = 'POST' 


class C(A):
    # error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "Union[Literal['GET'], Literal['POST']]")
    method = 'POST'

setup.cfg:

[mypy]
ignore_missing_imports = True
strict_optional = True
no_implicit_optional = True
check_untyped_defs = True
disallow_incomplete_defs = True
$ mypy --version
mypy 0.710+dev.b53dae73eebf72e3fe1f868dfa9ad008204c5701
@Michael0x2a
Copy link
Collaborator

Yeah, this does seem like a bug -- I suspect we're not taking the parent type/existing type into account when determining if we're in a literal context while performing type inference.

I'll dig a little deeper into this later today.

@Michael0x2a Michael0x2a self-assigned this May 12, 2019
@ilevkivskyi
Copy link
Member

@Michael0x2a I first wanted to close this as a duplicate of #4547, but it is up to you whether to track the effect on literal types separately.

@antonagestam You can use Literal['GET', 'POST'] instead of the union.

@hiaselhans
Copy link

mypy also fails to infer the type as literal for this simple example:

from typing import Literal


def test(a: Literal["a", "b"]) -> None:
    return a + "-test"


def test2() -> None:
    x="a"
    test(x) # error: Argument 1 to "test" has incompatible type "str"; expected "Literal['a', 'b']"

@antonagestam
Copy link
Contributor Author

antonagestam commented Oct 13, 2022

@hiaselhans That's a quite different issue, and I think it's to be expected. FWIW, it works if you make x final.

@erictraut
Copy link

This bug appears to have been fixed. The error is no longer emitted by the latest version of mypy.

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

No branches or pull requests

6 participants