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

Regression: isinstance(x, AliasOfTuple) is not supported #3068

Closed
elazarg opened this issue Mar 27, 2017 · 7 comments
Closed

Regression: isinstance(x, AliasOfTuple) is not supported #3068

elazarg opened this issue Mar 27, 2017 · 7 comments
Assignees

Comments

@elazarg
Copy link
Contributor

elazarg commented Mar 27, 2017

Example:

T = (int, int)
x : object
if isinstance(x, T):
    reveal_type(x)  # Revealed type is 'builtins.object'
    x + x  # E: Unsupported left operand type for + ("object")

This was introduced in #2995

@gvanrossum
Copy link
Member

Also @pkch please have a look.

@pkch
Copy link
Contributor

pkch commented Mar 27, 2017

Yes, I will fix it. It's not really a type alias though, since (int, int) is not a type, it's a regular python object. A type alias would be

T = Tuple[int, int]
x : object
if isinstance(x, T):
    reveal_type(x)  # Revealed type is 'builtins.object'
    x + x  # E: Unsupported left operand type for + ("object")

and I don't think we intend to support that correct?

@elazarg
Copy link
Contributor Author

elazarg commented Mar 27, 2017

I have used T = (types ...) in the PR precisely in order to avoid testing against union, but also avoid repeating long, possibly changing, list of types. Maybe isinstance(x, Union[simple types]) should be OK?

This way or another the decision needs to be conscious.

@pkch
Copy link
Contributor

pkch commented Mar 28, 2017

I think it's good to keep typing-related stuff separated from regular python code; otherwise the logic becomes very complicated - both for Python developers and for mypy.

Originally, this separation was very clean: names defined in typing could only be used in annotations. Later, type aliases were introduced, and so typing domain leaked through to the regular python code in the form of assignments. But it was worth it because type aliases are very useful.

Now, unless I'm missing something, "type concepts" (i.e., names imported from typing and type aliases) can only be used in annotations or on the RHS of assignment expressions where LHS is a simple identifier.

I think adding more contexts where "type concepts" can be used should be done rarely and with a very strong use case. In particular, I don't think isinstance(x, Union[A,B]) is worth allowing because it's easy to rewrite it as an or statement.

@pkch
Copy link
Contributor

pkch commented Mar 28, 2017

Actually, I just realized that there is one more context where "type concepts" can currently be used: in the second argument of isinstance (and issubclass); this is both valid and useful:

x: Union[List[str], List[int]]
if isinstance(x, List[str]): ...

Given that, I don't see any problem with supporting more complicated type expressions, if it seems useful (including isinstance(x, Union[A, B]) which isn't currently allowed).

@JelleZijlstra
Copy link
Member

That code fails at runtime though (TypeError: Parameterized generics cannot be used with class or instance checks), so what's the point of supporting it in mypy?

@pkch
Copy link
Contributor

pkch commented Mar 28, 2017

@JelleZijlstra Oh lol riiiiight, my own PR #3040 is supposed to catch this statically :) I forgot.

So, then I am going back to my earlier suggestion: perhaps it's better not to expand the contexts where "type concepts" are allowed beyond the current (type annotations and RHS of simple assignments).

JukkaL pushed a commit that referenced this issue Apr 3, 2017
Fixes #3068

This would allow the use of variables inside the second argument to 
isinstance/issubclass, as long as those variables are assigned a tuple of 
types in a "visible range".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants