Skip to content

Warn about "type(x) is C" or support it? #7260

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
JukkaL opened this issue Jul 24, 2019 · 2 comments
Closed

Warn about "type(x) is C" or support it? #7260

JukkaL opened this issue Jul 24, 2019 · 2 comments

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Jul 24, 2019

Mypy doesn't allow things like type(x) is int to be used to narrow down types, since this doesn't cover any subtypes of int. Maybe we should generate an error and suggest using isinstance(...) instead. Since this could be noisy, perhaps we should only do this if x is a union type.

Alternatively, we could support this as a valid type check, but treat it as an incomplete type check. This code would therefore still generate an error (but only one error):

def f(x: Union[int, str]) -> None:
    if type(x) is int:
        return x + 1  # Should be okay? (currently generates an error)
    else:
        return x + 'foo'  # Still an error, since 'x' could be a subtype of 'int'

Also, if the target type X is final, using type(x) is X instead of isinstance() would be technically fine, though it's still stylistically suspect.

See #7258 for an example where this caused confusion.

@ilevkivskyi
Copy link
Member

I think I am fine with supporting this. This is a bad style but we probably should not be too opinionated about style in cases where we can do safe reasoning about the code. I think we can indeed show only error in the second branch, and not show any errors at all in case of a final class.

@AlexWaygood
Copy link
Member

Using type(C) is int for type narrowing is now documented as being supported, and the example now works as expected on mypy 0.942, so I'm closing this. (Feel free to reopen if I'm mistaken!)

def f(x: int | str) -> None:
    if type(x) is int:
        x + 1  # No error on mypy 0.942
    else:
        x + 'foo'  # error: Unsupported operand types for + ("int" and "str")  # note: Left operand is of type "Union[int, str]"

@AlexWaygood AlexWaygood added topic-type-narrowing Conditional type narrowing / binder and removed needs discussion labels Apr 19, 2022
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

3 participants