You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Type inference problem with overloaded mkdtemp #1541
tempfile.mkdtemp returns str (in Python 2) if given no arguments. However, if any of the optional arguments is unicode, the return type should be unicode. We can use an overloaded function to represent this:
However, mypy infers type Any for call mkdtemp(), because it thinks that both signatures could match equally well. Instead, mypy should give preference to the first signature.
What if the optional arguments were of type Union[AnyStr, str] and the return type AnyStr? The extra Union would ensure that unicode and str can be mixed, but if unicode values are passed in, then the return type will end up as unicode.
Mypy doesn't just pick all matching signatures, though it's more complex than just picking the first signature. The way the example handled is a bug in mypy.
Originally overloads used runtime dispatch (when used outside stubs) and mypy tried to predict precisely which overload variants could be triggered by the dispatcher. There is longer runtime dispatch, but some of the old logic still persists. One of these days I (or somebody) should clean up the implementation of overloads.
Picking just the first matching signature is not correct if one of the arguments has an Any type, as it can match anything. Also, consider this example (mypy doesn't like the overloaded function definition, actually):
@overload
def f(x: int) -> int: ...
@overload
def f(x: object) -> str: ...
def g(o: object) -> None:
a = f(o) # can be int or str?
There may be other tricky cases, but it's been while since I thought about overloads carefully.
Activity
refi64 commentedon May 17, 2016
As a workaround:
What if the optional arguments were of type
Union[AnyStr, str]and the return typeAnyStr? The extraUnionwould ensure that unicode and str can be mixed, but if unicode values are passed in, then the return type will end up as unicode.Note that this is completely untested...
gvanrossum commentedon May 17, 2016
JukkaL commentedon May 17, 2016
Yeah, using the type of the defaults would likely be a better approach. For example:
Just one default would be sufficient here.
dict.getalso has a related issue once we introduce strict optional checking.matthiaskramm commentedon May 17, 2016
This highlights an interesting difference in how mypy and pytype interpret @overload in
pyi.pytype will pick the first matching signature, mypy (it seems?) all matching signatures.
JukkaL commentedon May 18, 2016
Mypy doesn't just pick all matching signatures, though it's more complex than just picking the first signature. The way the example handled is a bug in mypy.
Originally overloads used runtime dispatch (when used outside stubs) and mypy tried to predict precisely which overload variants could be triggered by the dispatcher. There is longer runtime dispatch, but some of the old logic still persists. One of these days I (or somebody) should clean up the implementation of overloads.
Picking just the first matching signature is not correct if one of the arguments has an
Anytype, as it can match anything. Also, consider this example (mypy doesn't like the overloaded function definition, actually):There may be other tricky cases, but it's been while since I thought about overloads carefully.
Michael0x2a commentedon Jun 15, 2018
The original example appears to typecheck as expected now, most likely due to f61c2ba. I think we can close this; feel free to reopen if necessary.