File: numeric.py

package info (click to toggle)
python-eth-utils 5.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 1,140 kB
  • sloc: python: 5,985; makefile: 238
file content (43 lines) | stat: -rw-r--r-- 1,190 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from abc import (
    ABC,
    abstractmethod,
)
import decimal
import numbers
from typing import (
    Any,
    TypeVar,
    Union,
)


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

    @abstractmethod
    def __gt__(self, other: Any) -> bool:
        ...


TComparable = Union[Comparable, numbers.Real, int, float, decimal.Decimal]


TValue = TypeVar("TValue", bound=TComparable)


def clamp(lower_bound: TValue, upper_bound: TValue, value: TValue) -> TValue:
    # The `mypy` ignore statements here are due to doing a comparison of
    # `Union` types which isn't allowed. (per cburgdorf). This approach was
    # chosen over using `typing.overload` to define multiple signatures for
    # each comparison type here since the added value of "proper" typing
    # doesn't seem to justify the complexity of having a bunch of different
    # signatures defined. The external library perspective on this function
    # should still be adequate under this approach
    if value < lower_bound:  # type: ignore
        return lower_bound
    elif value > upper_bound:  # type: ignore
        return upper_bound
    else:
        return value