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
TypeError from sorting incompatible types isn't flagged #9122
I was surprised that some code like this wasn't flagged by mypy:
[1, None].sort()
What is the actual behavior/output?
No error.
What is the behavior/output you expect?
I would expect a similar warning as I get if I do 1 > None
test.py:12: error: Unsupported operand types for > ("int" and "None")
What are the versions of mypy and Python you are using?
mypy 0.782, python 3.8.2
What are the mypy flags you are using? (For example --strict-optional)
follow_imports=normal
warn_redundant_casts=True
warn_unused_ignores=True
strict_optional=True
strict_equality=True
no_implicit_optional=True
disallow_untyped_defs=True
disallow_any_generics=True
Hmm, there have been some typeshed changes aimed at fixing this, eg: python/typeshed#4192 (that haven't made it to the latest mypy release). Note that they've definitely helped when passing key, but clearly haven't fixed your case:
~/tmp λ cat test19.py
z = [1, None]
reveal_type(z)
z.sort()
~/tmp λ mypy test19.py
test19.py:2: note: Revealed type is 'builtins.list[Union[builtins.int, None]]'
~/tmp λ mypy test19.py --custom-typeshed-dir ~/dev/typeshed
test19.py:2: note: Revealed type is 'builtins.list[Union[builtins.int, None]]'
~/tmp λ vim test19.py
~/tmp λ cat test19.py
z = [1, None]
reveal_type(z)
z.sort(key=lambda x: x)
~/tmp λ mypy test19.py
test19.py:2: note: Revealed type is 'builtins.list[Union[builtins.int, None]]'
~/tmp λ mypy test19.py --custom-typeshed-dir ~/dev/typeshed
test19.py:2: note: Revealed type is 'builtins.list[Union[builtins.int, None]]'
test19.py:3: error: Argument "key" to "sort" of "list" has incompatible type "Callable[[Optional[int]], Optional[int]]"; expected "Callable[[Optional[int]], _SupportsLessThan]"
test19.py:3: error: Incompatible return value type (got "Optional[int]", expected "_SupportsLessThan")
Found 2 errors in 1 file (checked 1 source file)
Oh, interesting - the key version of this is actually more similar to my original code. For example, neither of these sorts produces a warning:
fromtypingimportOptionalclassA:
def__init__(self, thing: Optional[int]) ->None:
self.thing=thingsorted([A(1), A(None)], key=lambdaa: a.thing)
# or without the lambdadefsort_func(a: A) ->Optional[int]:
returna.thingsorted([A(1), A(None)], key=sort_func)
The next release of mypy will complain about both of those sorts :-) If you point mypy at a copy of typeshed master using --custom-typeshed-dir you can get those errors today.
It's unfortunate that in the key-less case, mypy doesn't seem to be able to use the newly more accurate typeshed stubs, so we should still keep this issue open. Seems mypy has some issue with typevars upper bounded by protocols in self types, but that sentence covers a lot of surface area, so would need to do some digging to actually see where things go wrong 🤷♂️
@mortoray That probably won't be caught, since both float and str are comparable (they just can't be compared with each other). We could support this via a plugin for sorted (and sort) that does some special casing.
Activity
hauntsaninja commentedon Jul 10, 2020
Hmm, there have been some typeshed changes aimed at fixing this, eg: python/typeshed#4192 (that haven't made it to the latest mypy release). Note that they've definitely helped when passing
key, but clearly haven't fixed your case:The typeshed change looks correct to me now and looked correct to me at the time. Maybe mypy doesn't deal with typevar upper bounded by protocols in self types correctly?
https://github.com/python/typeshed/blob/028f0d52931fe1f96bb25d066186961159c1f801/stdlib/2and3/builtins.pyi#L961
https://github.com/python/typeshed/blob/028f0d52931fe1f96bb25d066186961159c1f801/stdlib/2and3/builtins.pyi#L84
akaptur commentedon Jul 11, 2020
Oh, interesting - the
keyversion of this is actually more similar to my original code. For example, neither of these sorts produces a warning:hauntsaninja commentedon Jul 11, 2020
The next release of mypy will complain about both of those sorts :-) If you point mypy at a copy of typeshed master using
--custom-typeshed-diryou can get those errors today.It's unfortunate that in the
key-less case, mypy doesn't seem to be able to use the newly more accurate typeshed stubs, so we should still keep this issue open. Seems mypy has some issue with typevars upper bounded by protocols in self types, but that sentence covers a lot of surface area, so would need to do some digging to actually see where things go wrong 🤷♂️mortoray commentedon Jul 27, 2020
Here's another simple example that came up in our code:
Will the next release catch this one?
JukkaL commentedon Sep 11, 2020
@mortoray That probably won't be caught, since both
floatandstrare comparable (they just can't be compared with each other). We could support this via a plugin forsorted(andsort) that does some special casing.hauntsaninja commentedon Sep 11, 2020
The next version of mypy will actually catch:
But not other ways of sorting. I believe this is due to a mypy bug. #9122 (comment)