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

TypeVars should be allowed to be the same #7864

Open
twoertwein opened this issue Nov 4, 2019 · 11 comments · May be fixed by #8572
Open

TypeVars should be allowed to be the same #7864

twoertwein opened this issue Nov 4, 2019 · 11 comments · May be fixed by #8572

Comments

@twoertwein
Copy link

Two unbound TypeVars A and B can potentially be the same:

from typing import Callable, Iterable, TypeVar

A = TypeVar("A")
B = TypeVar("B")

def identity(x: A) -> A:
    return x

# ok
def _map(queue: Iterable[B], function: Callable[[B], A]) -> Iterable[A]:
    return map(function, queue)

# fails
def _map2(queue: Iterable[B], function: Callable[[B], A] = identity) -> Iterable[A]:
    return map(function, queue)

The introduced default keyword argument leads to the following unexpected error:
error: Incompatible default for argument "function" (default has type "Callable[[A], A]", argument has type "Callable[[B], A]")

I'm using mypy 0.740.

@ilevkivskyi
Copy link
Member

TypeVars should be allowed to be the same

No, they shouldn't. The default value isn't part of the function API, so calls with omitted second argument will be either unsafe or underspecified. For example, imagine you have an entry in a stub:

def _map2(queue: Iterable[B], function: Callable[[B], A] = ...) -> Iterable[A]: ...

assuming this type, what should be the inferred type of _map2([1, 2, 3])? Instead you should just use a correct signature for your function:

@overload
def _map2(queue: Iterable[A]) -> Iterable[A]: ...
@overload
def _map2(queue: Iterable[B], function: Callable[[B], A]) -> Iterable[A]: ...
def _map2(queue, function=identity):
    # implementation goes here
    ...

Surprisingly, this often comes as a source of confusion (I have seen half a dozen issues about this), so I think we should document this (probably in the section "Common issues").

@twoertwein
Copy link
Author

thank you for the clarifications!

It might be helpful if mypy/the typing module provide examples of some more 'complex' functions (map, zip, function decorators, callables which have a few typed arguments and arbitrarily many Any arguments).

@tz-earl
Copy link

tz-earl commented Mar 18, 2020

First time contributor here. If no one else is expanding the docs, I'd like to take a stab at it.

@ethanhs
Copy link
Collaborator

ethanhs commented Mar 18, 2020

@tz-earl Welcome, please feel free to get started on it! Let me know if you have any questions.

@tz-earl
Copy link

tz-earl commented Mar 19, 2020

@ethanhs Thanks a lot for the go-ahead.

Just to be sure, it seems that there is an older package overload that has been superceded by the package overloading. Is that right?

@JelleZijlstra
Copy link
Member

I don't think any packages named overload or overloading are relevant here. The relevant overload is the one defined in the typing module in the standard library.

@tz-earl
Copy link

tz-earl commented Mar 19, 2020

@JelleZijlstra Thank you!

I'm not at all familiar with the @overload decorator, and I missed the reference to the typing package in other comments.

@tz-earl
Copy link

tz-earl commented Mar 20, 2020

With respect to TypeVar, there is a difference between unconstrained and unbound.

For this particular issue, is it more accurate to talk about unconstrained TypeVars rather than unbound? Or is it both?

@JukkaL
Copy link
Collaborator

JukkaL commented Mar 20, 2020

I don't think type variable constraints or bounds make a difference here. The explanation would work for all type variables.

@tz-earl
Copy link

tz-earl commented Mar 20, 2020

@JukkaL Thanks so much for pointing out that the issue applies to all type variables, regardless of how they are defined.

tz-earl pushed a commit to tz-earl/mypy that referenced this issue Mar 22, 2020
@mixed-source
Copy link
Contributor

Hi, I would like to ask what's the process I should follow to contribute to this issue since the last pull request has some issues that have not been resolved for a long time.

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

Successfully merging a pull request may close this issue.

7 participants