Skip to content

Infer type from "assert isinstance()" even if types aren't overlapping #1542

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 May 17, 2016 · 7 comments
Closed

Infer type from "assert isinstance()" even if types aren't overlapping #1542

JukkaL opened this issue May 17, 2016 · 7 comments

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented May 17, 2016

I think that we should infer x to be str in this example (this is based on a user issue):

def f(x: int):
    assert isinstance(x, str)
    x + ''  # should be fine
    x + 2  # should be an error

Here the rationale is that if the isinstance checks passes, x will be a string, not an integer.

Currently this doesn't work since mypy considers int and str to be non-overlapping. This is perhaps okay for if isinstance() (though perhaps only if variable has a type variable type with values such as AnyStr), but for assert isinstance() it doesn't make sense.

@refi64
Copy link
Contributor

refi64 commented May 17, 2016

I would argue that this should be an error; if a function expects its int argument to be a string, then there's probably a bug in either the type declarations or the function itself.

@JukkaL
Copy link
Collaborator Author

JukkaL commented May 17, 2016

Yeah, the simple example I gave doesn't make sense. Here is another example:

class Thingye: ...
class SomeMixin(...): ...
class ThingyeWithSome(Thingye, SomeMixin): ...

def f(t: Thingye) -> None:
    ...
    if isinstance(t, SomeMixin):
        # do some SomeMixin specific stuff
        ...

@rwbarton
Copy link
Contributor

You might want to do some Thingye stuff in that if branch too though. A case for intersection types? Related to #1539 too.

@rwbarton
Copy link
Contributor

@JukkaL, according to my experiments, in the case above, mypy currently does not check the body of the if branch at all. (Even reveal_type is silently ignored.) Is that intentional?

@JukkaL
Copy link
Collaborator Author

JukkaL commented May 18, 2016

Yes, that is used for type checking functions that use AnyStr, etc. We type check those functions multiple times, and often we ignore some parts of the function on some passes, as otherwise we would get false positives.

However, if there are no type variables with values in the current scope, it's not the right thing to do.

@ddfisher ddfisher added this to the 0.5 milestone May 19, 2016
@rwbarton
Copy link
Contributor

Ah, I see. I wonder if type checking the branch with the string having an intersection type would work, but I bet there would be some cases where type inference wouldn't do the right thing...

@gvanrossum gvanrossum removed this from the 0.5 milestone Mar 29, 2017
@ilevkivskyi
Copy link
Member

This is essentially a duplicate of #3603 that has some ideas how to fix this.

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