What are all the syntactic elements of a Python function tooltip?

Solution 1:

That is a bit of a train wreck. It boils down to this:

  • If you only pass an iterable to sorted (so that the keyword argument key gets its default value None), then there has to be a way to compare the elements to determine an ordering.

  • If you do provide a key argument, then you can have an arbitrary iterable, because the value of key will be used to "map" the values to things that can be compared.

Regular parameters can be specified via positional arguments or keyword arguments.

Parameters that precede / are positional-only: you cannot specify values for them using keywords arguments. (sorted(__iterable=[1,2,3]) would be illegal.)

Parameters that follow * are keyword-only: you can only specify values for them using keyword arguments. (sorted([1,2,3], f) would be illegal.)

_T is a type variable: it represents a specific but unknown type, basically used to tie the type hint for __iterable to the type hints for key.

SupportsRichComparison looks to be a typing.Protocol, which means it is basically an abstract base class that asserts its subclasses provide definitions for __lt__ et al. Note that either the elements of __iterable are instance of SupportsRichComparison, or they are instances of some class _T that key knows how to convert to instances of SupportsRichComparison.

I am at a loss for how to explain @. It doesn't conform to any actual Python syntax that I am aware of; it might simply be some sort of conventional separator used to construct a type variable from some other pieces of information.


As a concrete example, consider complex numbers. Two complex numbers are not directly comparable:

>>> sorted([3+4j, 6-7j])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'complex' and 'complex'

But integers are comparable:

>>> sorted([4, -7])
[-7, 4]

So if you had some function that could map 3 + 4j to 4 and 6-7j to -7, you could sort the original list of complex numbers.

>>> sorted([3+4j, 6-7j], key=lambda x: x.imag)
[(6-7j), (3+4j)]