Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I hint that a type is comparable with typing

Say I want to write a comparison sorting function, I can hint that the input must be a sequence with Sequence[T] (or MutableSequence[T] in this case).

from typing import MutableSequence, T

def comparison_sort(s: MutableSequence[T]) -> None:
    pass

However there does not seems to be an out-of-the box way to hint that T must be comparable. (There is no Comparable or Ordered or anything it seems in typing.) How can I achieve this? I would like to avoid specifying a specific set of types, like int, float, 'str` so that a user could also hint that their own type is comparable.

like image 564
tahsmith Avatar asked Jun 07 '16 01:06

tahsmith


People also ask

What are type hints?

Introduction to Python type hints It means that you need to declare types of variables, parameters, and return values of a function upfront. The predefined types allow the compilers to check the code before compiling and running the program.

What is type hint in programming?

Type hinting is the process of annotating your code so that other developers reading your code will understand the type of an object declared. Type hinting was officially added with the release of Python 3.5.

Are type hints enforced?

Not enforced at runtime They can be used by third party tools such as type checkers, IDEs, linters, etc.

Should you use type hints Python?

Type hints work best in modern Pythons. Annotations were introduced in Python 3.0, and it's possible to use type comments in Python 2.7. Still, improvements like variable annotations and postponed evaluation of type hints mean that you'll have a better experience doing type checks using Python 3.6 or even Python 3.7.


1 Answers

As noted in the comments, Comparable isn't a state of being, it's only meaningful as a descriptor for a pair of types. Usually, a sorting function is working with homogeneous types though, so as long as you don't mind the type checker only handling the concept of "supports < with some types" rather than "supports < with arbitrary types", you can define your own Comparable and bound a typing TypeVar with it. Conveniently, PEP484 (which defines typing hints) already provides an example of how you'd do this:

from abc import ABCMeta
from typing import Any, TypeVar

class Comparable(metaclass=ABCMeta):
    @abstractmethod
    def __lt__(self, other: Any) -> bool: ...

CT = TypeVar('CT', bound=Comparable)

You can then use this for your comparable_sort definition with:

def comparable_sort(s: MutableSequence[CT]) -> None:

Note that I only required __lt__ to be defined; as a rule, Python 3 implements its own sorting functions entirely in terms of __lt__ (it doesn't use any of the other rich comparator operators, not even __eq__), so it's a good idea to design your own algorithm the same way, so anything sorted can handle, you can handle the same way.

: Python 2 originally used __le__ in at least one place (heapq), but it's been intentionally, consistently, __lt__ for the builtins and standard library in the Python 3 timeframe, and your style of typing is Python 3-only anyway.

like image 160
ShadowRanger Avatar answered Sep 18 '22 12:09

ShadowRanger