How to correctly use typing for a sort key function

Question:

For this sort key method:

def srt(self,r:Optional[Colour])->Optional[int]:
  if not isinstance(r,Colour):
    return None
  return r.index

used in a later method in the same class (NOT Colour):

items=sorted(self.__dict__.values(),key=self.srt)

results in this error from mypy:

error: Argument "key" to "sorted" has incompatible type "Callable[[Optional[Colour]], Optional[int]]"; expected "Callable[[Any], SupportsLessThan]"  [arg-type]

I can make it shut up by either forcing srt() to the signature it wants, or by doing a type: ignore on the call to sorted. But I’d rather do it right.

I’m clearly doing something wrong, but what? Even if there is no good way to do this, I want to know why mypy is complaining.

Asked By: ivanlan

||

Answers:

You are passing a function that returns Optional[int] but a function is required that returns SupportsLessThan. Optional[int] does not support "less than", because None cannot be compared to any int.

What does support "less than" is just int. So you could change the return type of your function to int and make it return some integer in the special case that r is not a Colour, instead of None.

Which integer it should return in this case depends on what you are trying to achieve. Possibly you could return -1 in case you want any non-Colour values to be sorted before any Colour values, since that would be smaller than any value of r.index (at least that’s what I expect from something called "index").

Answered By: mkrieger1
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.