python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.46k stars 2.83k forks source link

error in argument when using chained function-call #5311

Open z33ky opened 6 years ago

z33ky commented 6 years ago

Example:

dct = {"": ""}

# ok
trans = str.maketrans(dct)
"".translate(trans)

# err
"".translate(str.maketrans(dct))

maketrans.py:8: error: Argument 1 to "maketrans" of "str" has incompatible type "Dict[str, str]"; expected "Union[Dict[int, Union[int, str, None]], Dict[str, Union[int, str, None]], Dict[Union[str, int], Union[int, str, None]]]"

No error.

I tested both mypy 0.610 and mypy 0.620+dev-0ca6bf9ce63439a1e8bcc4dec80ef12f8414cb87 with Python 3.6.5; behavior is identical.

gvanrossum commented 6 years ago

Yeah, there are two overloads in typeshed:

# in class str:
    @staticmethod
    @overload
    def maketrans(x: Union[Dict[int, _T], Dict[str, _T], Dict[Union[str, int], _T]]) -> Dict[int, _T]: ...
    @staticmethod
    @overload
    def maketrans(x: str, y: str, z: str = ...) -> Dict[int, Union[int, None]]: ...

It should use the first overload, and pick Dict[str, _T] as the union member, setting _T to str. But somehow the definition of translate makes this difficult for the type solver:

# also in class str:
    def translate(self, table: Union[Mapping[int, Union[int, str, None]], Sequence[Union[int, str, None]]]) -> str: ...

Here it should pick Mapping[int, Union[int, str, None]] as the applicable union member. But apparently that's too much for the type solver.

You've already found the work-around, but this is definitely a bug.

ilevkivskyi commented 6 years ago

This is yet another duplicate of https://github.com/python/mypy/issues/4872 mypy uses translate context first to bind _T to a wider union and then complains about its own decision. @JukkaL maybe we should fix this (with a simple backtracking), note this also happened few times to our internal users.

JukkaL commented 6 years ago

Yeah, this is probably one of the more annoying bugs at the moment. #4872 is already a high-priority issue so maybe we only need somebody with a bit of extra bandwidth to implement a fix (who understands the type solver). Any takers?

ilevkivskyi commented 6 years ago

This issue will not be fixed by the upcoming fix for #4872, therefore I am re-opening. The general fix for this problem may be tricky.