Skip to content

"Incompatible return value type" error with TypeVar #4590

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
elias6 opened this issue Feb 19, 2018 · 6 comments
Closed

"Incompatible return value type" error with TypeVar #4590

elias6 opened this issue Feb 19, 2018 · 6 comments

Comments

@elias6
Copy link
Contributor

elias6 commented Feb 19, 2018

I am using Python 3.6.4 and the latest version of Mypy from master (mypy 0.570-dev-3545a71ba11576b08007f70d8407bf7924738886).

I have a file with the following code:

from typing import TypeVar

T = TypeVar('T', int, str)

def foo() -> T:
    return 1

If I run it through Mypy, I get this error: typevar_test.py:6: error: Incompatible return value type (got "int", expected "str").

If I make the function return a string, I get a similar error: typevar_test.py:6: error: Incompatible return value type (got "str", expected "int").

If I make the function return something not specified by the TypeVar (such as a list, for example), I get two errors:

typevar_test.py:6: error: Incompatible return value type (got "List[int]", expected "int")
typevar_test.py:6: error: Incompatible return value type (got "List[int]", expected "str")
@gvanrossum
Copy link
Member

That's not how type variables work. You seem to be looking for a type alias for a union, e.g.

U = Union[int, str]
def foo() -> U:
    return 1

A type variable is used to create a generic function or class -- please read the docs:
http://mypy.readthedocs.io/en/latest/generics.html

@elias6
Copy link
Contributor Author

elias6 commented Feb 19, 2018

I read the documentation about generic functions, both for Mypy and for the typing module.

That was a toy example. I tried to come up with the simplest thing that would trigger the error. I know that in this case, I use a union to do the same thing.

Regardless of that, does a type variable, used in the return hint of a function, absolutely need to also be used in the hint of one of its parameters? If so, then I am doing something invalid. But I don't see anything in the Mypy docs, in the typing module docs, or in PEP 484 that mentions this.

And even if I am doing something invalid, I think the error messages could be made clearer. I think it is strange that if I use an int, I'm told that a string is expected, but if I use a string, I'm told that an int is expected. That is what made me suspect that this might be a bug in Mypy, and not (only) incorrect usage.

I wish I could work on this and try to improve it, but I feel that I am still not familiar enough with Mypy to feel that I could realistically do it myself.

@gvanrossum
Copy link
Member

Even if you are using the type variable legitimately, you still cannot do what you have in your example.

There are indeed cases where the return type can contain a type variable without the arguments containing one, but the only use cases I'm familiar with are when returning a generic function, such as is done for certain decorators.

The problem with your example is that the type system doesn't have a way to describe the type of a value assigned from a call to foo():

x = foo()  # What is the type of x?

(Note that a variable cannot have a type variable in its type unless the type variable is bound in the containing generic class or function.)

I agree that the error is confusing though.

If you still don't understand what's illegal, please show a more complete example (it has to make sense at runtime too).

@elias6
Copy link
Contributor Author

elias6 commented Feb 19, 2018

Now I understand what is invalid about my example. Thanks for the explanation.

@gvanrossum
Copy link
Member

Hm, we should probably improve the docs. Can you make a suggestion (e.g. by submitting a PR)?

@elias6
Copy link
Contributor Author

elias6 commented Feb 19, 2018

I will consider submitting a PR. Keep in mind that I am still somewhat unfamiliar with some of the details of this project (like how the docs are implemented), and I'm unsure how to explain the problem with my example in a simple way, so I can't make any promise that I'll get it done in any given amount of time.

elias6 added a commit to elias6/mypy that referenced this issue Feb 21, 2018
This explains that a variable of a generic type must be able to be resolved to a non-generic type, hopefully preventing the confusion that made me (and possibly others) think python#4590 is a bug.
gvanrossum pushed a commit that referenced this issue Aug 1, 2018
This explains that a variable of a generic type must be able to be resolved to a non-generic type, hopefully preventing the confusion that made me (and possibly others) think #4590 is a bug.
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

2 participants