Fix decimal (#2323)

* Use Tuple field in DecimalTuple

* Remove unnecessary base classes from Decimal

* Decimal.__init__ -> __new__

* Decimal.__ne__ is not defined in Python 3

* Add Decimal.as_integer_ratio()

* Annotate DecimalException.handle()

* Correct types of Decimal method arguments

* Add missing arguments and optional markers to Decimal

* Add missing arguments to Context

* Remove spurious int from Unions with float

* Remove Context.__setattr__()

* Fix return types of Context methods
This commit is contained in:
Sebastian Rittau
2018-07-19 06:59:08 +02:00
committed by Jelle Zijlstra
parent 0f8e0ad661
commit 4b8c37462e

View File

@@ -1,15 +1,20 @@
import numbers
import sys
from types import TracebackType
from typing import (
Any, Dict, NamedTuple, Optional, Sequence, Tuple, Union, Text,
SupportsAbs, SupportsFloat, SupportsInt, SupportsRound,
Any, Dict, NamedTuple, Optional, Sequence, Tuple, Union, Text, Type, Container, List,
)
_Decimal = Union[Decimal, int]
_ComparableNum = Union[Decimal, int, float]
_DecimalNew = Union[Decimal, float, Text, Tuple[int, Sequence[int], int]]
if sys.version_info >= (3,):
_ComparableNum = Union[Decimal, float, numbers.Rational]
else:
_ComparableNum = Union[Decimal, float]
DecimalTuple = NamedTuple('DecimalTuple',
[('sign', int),
('digits', Sequence[int]), # TODO: Use Tuple[int, ...]
('digits', Tuple[int, ...]),
('exponent', int)])
ROUND_DOWN: str
@@ -29,7 +34,7 @@ if sys.version_info >= (3,):
MIN_ETINY: int
class DecimalException(ArithmeticError):
def handle(self, context, *args): ...
def handle(self, context: Context, *args: Any) -> Optional[Decimal]: ...
class Clamped(DecimalException): ...
@@ -62,144 +67,143 @@ def setcontext(context: Context) -> None: ...
def getcontext() -> Context: ...
def localcontext(ctx: Optional[Context] = ...) -> _ContextManager: ...
if sys.version_info >= (3,):
_SupportsRound = SupportsRound[int]
else:
_SupportsRound = object
class Decimal(SupportsAbs[Decimal], SupportsFloat, SupportsInt, _SupportsRound):
# TODO: SupportsCeil, SupportsFloor, SupportsTrunc?
def __init__(cls, value: Union[_Decimal, float, Text,
Tuple[int, Sequence[int], int]] = ...,
context: Context = ...) -> None: ...
class Decimal(object):
def __new__(cls, value: _DecimalNew = ..., context: Optional[Context] = ...) -> None: ...
@classmethod
def from_float(cls, f: float) -> Decimal: ...
if sys.version_info >= (3,):
def __bool__(self) -> bool: ...
else:
def __nonzero__(self) -> bool: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: _ComparableNum) -> bool: ...
def __le__(self, other: _ComparableNum) -> bool: ...
def __gt__(self, other: _ComparableNum) -> bool: ...
def __ge__(self, other: _ComparableNum) -> bool: ...
def __eq__(self, other: object, context: Optional[Context] = ...) -> bool: ...
if sys.version_info < (3,):
def __ne__(self, other: object, context: Optional[Context] = ...) -> bool: ...
def __lt__(self, other: _ComparableNum, context: Optional[Context] = ...) -> bool: ...
def __le__(self, other: _ComparableNum, context: Optional[Context] = ...) -> bool: ...
def __gt__(self, other: _ComparableNum, context: Optional[Context] = ...) -> bool: ...
def __ge__(self, other: _ComparableNum, context: Optional[Context] = ...) -> bool: ...
def compare(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __hash__(self) -> int: ...
def as_tuple(self) -> DecimalTuple: ...
def to_eng_string(self, context: Context = ...) -> str: ...
def __neg__(self) -> Decimal: ...
def __pos__(self) -> Decimal: ...
def __abs__(self, round: bool = ...) -> Decimal: ...
def __add__(self, other: _Decimal) -> Decimal: ...
def __radd__(self, other: int) -> Decimal: ...
def __sub__(self, other: _Decimal) -> Decimal: ...
def __rsub__(self, other: int) -> Decimal: ...
def __mul__(self, other: _Decimal) -> Decimal: ...
def __rmul__(self, other: int) -> Decimal: ...
def __truediv__(self, other: _Decimal) -> Decimal: ...
def __rtruediv__(self, other: int) -> Decimal: ...
if sys.version_info >= (3,):
def as_integer_ratio(self) -> Tuple[int, int]: ...
def __str__(self, eng: bool = ..., context: Optional[Context] = ...) -> str: ...
def to_eng_string(self, context: Optional[Context] = ...) -> str: ...
def __neg__(self, context: Optional[Context] = ...) -> Decimal: ...
def __pos__(self, context: Optional[Context] = ...) -> Decimal: ...
def __abs__(self, round: bool = ..., context: Optional[Context] = ...) -> Decimal: ...
def __add__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __radd__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __sub__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __rsub__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __mul__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __rmul__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __truediv__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __rtruediv__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
if sys.version_info < (3,):
def __div__(self, other: _Decimal) -> Decimal: ...
def __rdiv__(self, other: int) -> Decimal: ...
def __divmod__(self, other: _Decimal) -> Tuple[Decimal, Decimal]: ...
def __rdivmod__(self, other: int) -> Tuple[Decimal, Decimal]: ...
def __mod__(self, other: _Decimal) -> Decimal: ...
def __rmod__(self, other: int) -> Decimal: ...
def remainder_near(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def __floordiv__(self, other: _Decimal) -> Decimal: ...
def __rfloordiv__(self, other: int) -> Decimal: ...
def __div__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __rdiv__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __divmod__(self, other: _Decimal, context: Optional[Context] = ...) -> Tuple[Decimal, Decimal]: ...
def __rdivmod__(self, other: _Decimal, context: Optional[Context] = ...) -> Tuple[Decimal, Decimal]: ...
def __mod__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __rmod__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def remainder_near(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __floordiv__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __rfloordiv__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __float__(self) -> float: ...
def __int__(self) -> int: ...
def __trunc__(self) -> int: ...
@property
def imag(self) -> Decimal: ...
@property
def real(self) -> Decimal: ...
@property
def imag(self) -> Decimal: ...
def conjugate(self) -> Decimal: ...
def __complex__(self) -> complex: ...
if sys.version_info >= (3,):
def __round__(self, n=...) -> int: ...
def __round__(self, n: Optional[int] = ...) -> int: ...
def __floor__(self) -> int: ...
def __ceil__(self) -> int: ...
else:
def __long__(self) -> long: ...
def fma(self, other: _Decimal, third: _Decimal, context: Context = ...) -> Decimal: ...
def __pow__(self, other: _Decimal) -> Decimal: ...
def __rpow__(self, other: int) -> Decimal: ...
def normalize(self, context: Context = ...) -> Decimal: ...
def quantize(self, exp: _Decimal, rounding: str = ...,
context: Context = ...) -> Decimal: ...
def fma(self, other: _Decimal, third: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __pow__(self, other: _Decimal, modulo: Optional[_Decimal] = ..., context: Optional[Context] = ...) -> Decimal: ...
def __rpow__(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def normalize(self, context: Optional[Context] = ...) -> Decimal: ...
if sys.version_info >= (3,):
def same_quantum(self, other: _Decimal, context: Context = ...) -> bool: ...
def quantize(self, exp: _Decimal, rounding: Optional[str] = ...,
context: Optional[Context] = ...) -> Decimal: ...
def same_quantum(self, other: _Decimal, context: Optional[Context] = ...) -> bool: ...
else:
def quantize(self, exp: _Decimal, rounding: Optional[str] = ...,
context: Optional[Context] = ..., watchexp: bool = ...) -> Decimal: ...
def same_quantum(self, other: _Decimal) -> bool: ...
def to_integral(self, rounding: str = ..., context: Context = ...) -> Decimal: ...
def to_integral_exact(self, rounding: str = ..., context: Context = ...) -> Decimal: ...
def to_integral_value(self, rounding: str = ..., context: Context = ...) -> Decimal: ...
def sqrt(self, context: Context = ...) -> Decimal: ...
def max(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def min(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def to_integral_exact(self, rounding: Optional[str] = ..., context: Optional[Context] = ...) -> Decimal: ...
def to_integral_value(self, rounding: Optional[str] = ..., context: Optional[Context] = ...) -> Decimal: ...
def to_integral(self, rounding: Optional[str] = ..., context: Optional[Context] = ...) -> Decimal: ...
def sqrt(self, context: Optional[Context] = ...) -> Decimal: ...
def max(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def min(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def adjusted(self) -> int: ...
if sys.version_info >= (3,):
def canonical(self) -> Decimal: ...
else:
def canonical(self, context: Context = ...) -> Decimal: ...
def compare_signal(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def canonical(self, context: Optional[Context] = ...) -> Decimal: ...
def compare_signal(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
if sys.version_info >= (3,):
def compare_total(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def compare_total_mag(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def compare_total(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def compare_total_mag(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
else:
def compare_total(self, other: _Decimal) -> Decimal: ...
def compare_total_mag(self, other: _Decimal) -> Decimal: ...
def copy_abs(self) -> Decimal: ...
def copy_negate(self) -> Decimal: ...
if sys.version_info >= (3,):
def copy_sign(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def copy_sign(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
else:
def copy_sign(self, other: _Decimal) -> Decimal: ...
def exp(self, context: Context = ...) -> Decimal: ...
def exp(self, context: Optional[Context] = ...) -> Decimal: ...
def is_canonical(self) -> bool: ...
def is_finite(self) -> bool: ...
def is_infinite(self) -> bool: ...
def is_nan(self) -> bool: ...
def is_normal(self, context: Context = ...) -> bool: ...
def is_normal(self, context: Optional[Context] = ...) -> bool: ...
def is_qnan(self) -> bool: ...
def is_signed(self) -> bool: ...
def is_snan(self) -> bool: ...
def is_subnormal(self, context: Context = ...) -> bool: ...
def is_subnormal(self, context: Optional[Context] = ...) -> bool: ...
def is_zero(self) -> bool: ...
def ln(self, context: Context = ...) -> Decimal: ...
def log10(self, context: Context = ...) -> Decimal: ...
def logb(self, context: Context = ...) -> Decimal: ...
def logical_and(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def logical_invert(self, context: Context = ...) -> Decimal: ...
def logical_or(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def logical_xor(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def max_mag(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def min_mag(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def next_minus(self, context: Context = ...) -> Decimal: ...
def next_plus(self, context: Context = ...) -> Decimal: ...
def next_toward(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def number_class(self, context: Context = ...) -> str: ...
def ln(self, context: Optional[Context] = ...) -> Decimal: ...
def log10(self, context: Optional[Context] = ...) -> Decimal: ...
def logb(self, context: Optional[Context] = ...) -> Decimal: ...
def logical_and(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def logical_invert(self, context: Optional[Context] = ...) -> Decimal: ...
def logical_or(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def logical_xor(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def max_mag(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def min_mag(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def next_minus(self, context: Optional[Context] = ...) -> Decimal: ...
def next_plus(self, context: Optional[Context] = ...) -> Decimal: ...
def next_toward(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def number_class(self, context: Optional[Context] = ...) -> str: ...
def radix(self) -> Decimal: ...
def rotate(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def scaleb(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def shift(self, other: _Decimal, context: Context = ...) -> Decimal: ...
def __reduce__(self): ...
def rotate(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def scaleb(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def shift(self, other: _Decimal, context: Optional[Context] = ...) -> Decimal: ...
def __reduce__(self) -> Tuple[Type[Decimal], Tuple[str]]: ...
def __copy__(self) -> Decimal: ...
def __deepcopy__(self, memo) -> Decimal: ...
def __format__(self, specifier, context=..., _localeconv=...) -> str: ...
def __deepcopy__(self, memo: Any) -> Decimal: ...
def __format__(self, specifier: str, context: Optional[Context] = ...) -> str: ...
class _ContextManager:
class _ContextManager(object):
new_context: Context
saved_context: Context
def __init__(self, new_context: Context) -> None: ...
def __enter__(self) -> Context: ...
def __exit__(self, t, v, tb) -> None: ...
def __exit__(self, t: Optional[Type[BaseException]], v: Optional[BaseException], tb: Optional[TracebackType]) -> None: ...
class Context:
_TrapType = Type[DecimalException]
class Context(object):
prec: int
rounding: str
Emin: int
@@ -209,94 +213,98 @@ class Context:
clamp: int
else:
_clamp: int
traps: Dict[type, bool]
flags: Any
traps: Dict[_TrapType, bool]
flags: Dict[_TrapType, bool]
if sys.version_info >= (3,):
def __init__(self, prec: Optional[int] = ..., rounding: Optional[str] = ...,
Emin: Optional[int] = ..., Emax: Optional[int] = ...,
capitals: Optional[int] = ..., clamp: Optional[int] = ...,
flags=..., traps=...,
_ignored_flags=...) -> None: ...
flags: Union[None, Dict[_TrapType, bool], Container[_TrapType]] = ...,
traps: Union[None, Dict[_TrapType, bool], Container[_TrapType]] = ...,
_ignored_flags: Optional[List[_TrapType]] = ...) -> None: ...
else:
def __init__(self, prec: Optional[int] = ..., rounding: Optional[str] = ...,
traps=..., flags=...,
traps: Union[None, Dict[_TrapType, bool], Container[_TrapType]] = ...,
flags: Union[None, Dict[_TrapType, bool], Container[_TrapType]] = ...,
Emin: Optional[int] = ..., Emax: Optional[int] = ...,
capitals: Optional[int] = ..., _clamp: Optional[int] = ...,
_ignored_flags=...) -> None: ...
_ignored_flags: Optional[List[_TrapType]] = ...) -> None: ...
if sys.version_info >= (3,):
def __delattr__(self, name): ...
def __reduce__(self): ...
def clear_flags(self): ...
# __setattr__() only allows to set a specific set of attributes,
# already defined above.
def __delattr__(self, name: str) -> None: ...
def __reduce__(self) -> Tuple[Type[Context], Tuple[Any, ...]]: ...
def clear_flags(self) -> None: ...
if sys.version_info >= (3,):
def clear_traps(self): ...
def clear_traps(self) -> None: ...
def copy(self) -> Context: ...
def __copy__(self) -> Context: ...
__hash__: Any = ...
def Etiny(self): ...
def Etop(self): ...
def create_decimal(self, num=...): ...
def create_decimal_from_float(self, f): ...
def Etiny(self) -> int: ...
def Etop(self) -> int: ...
def create_decimal(self, num: _DecimalNew = ...) -> Decimal: ...
def create_decimal_from_float(self, f: float) -> Decimal: ...
def abs(self, a: _Decimal) -> Decimal: ...
def add(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def canonical(self, a): ...
def compare(self, a, b): ...
def compare_signal(self, a, b): ...
def compare_total(self, a, b): ...
def compare_total_mag(self, a, b): ...
def copy_abs(self, a): ...
def copy_decimal(self, a): ...
def copy_negate(self, a): ...
def copy_sign(self, a, b): ...
def divide(self, a, b): ...
def divide_int(self, a, b): ...
def divmod(self, a, b): ...
def exp(self, a): ...
def fma(self, a, b, c): ...
def is_canonical(self, a): ...
def is_finite(self, a): ...
def is_infinite(self, a): ...
def is_nan(self, a): ...
def is_normal(self, a): ...
def is_qnan(self, a): ...
def is_signed(self, a): ...
def is_snan(self, a): ...
def is_subnormal(self, a): ...
def is_zero(self, a): ...
def ln(self, a): ...
def log10(self, a): ...
def logb(self, a): ...
def logical_and(self, a, b): ...
def logical_invert(self, a): ...
def logical_or(self, a, b): ...
def logical_xor(self, a, b): ...
def max(self, a, b): ...
def max_mag(self, a, b): ...
def min(self, a, b): ...
def min_mag(self, a, b): ...
def minus(self, a): ...
def multiply(self, a, b): ...
def next_minus(self, a): ...
def next_plus(self, a): ...
def next_toward(self, a, b): ...
def normalize(self, a): ...
def number_class(self, a): ...
def plus(self, a): ...
def canonical(self, a: Decimal) -> Decimal: ...
def compare(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def compare_signal(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def compare_total(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def compare_total_mag(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def copy_abs(self, a: _Decimal) -> Decimal: ...
def copy_decimal(self, a: _Decimal) -> Decimal: ...
def copy_negate(self, a: _Decimal) -> Decimal: ...
def copy_sign(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def divide(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def divide_int(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def divmod(self, a: _Decimal, b: _Decimal) -> Tuple[Decimal, Decimal]: ...
def exp(self, a: _Decimal) -> Decimal: ...
def fma(self, a: _Decimal, b: _Decimal, c: _Decimal) -> Decimal: ...
def is_canonical(self, a: _Decimal) -> bool: ...
def is_finite(self, a: _Decimal) -> bool: ...
def is_infinite(self, a: _Decimal) -> bool: ...
def is_nan(self, a: _Decimal) -> bool: ...
def is_normal(self, a: _Decimal) -> bool: ...
def is_qnan(self, a: _Decimal) -> bool: ...
def is_signed(self, a: _Decimal) -> bool: ...
def is_snan(self, a: _Decimal) -> bool: ...
def is_subnormal(self, a: _Decimal) -> bool: ...
def is_zero(self, a: _Decimal) -> bool: ...
def ln(self, a: _Decimal) -> Decimal: ...
def log10(self, a: _Decimal) -> Decimal: ...
def logb(self, a: _Decimal) -> Decimal: ...
def logical_and(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def logical_invert(self, a: _Decimal) -> Decimal: ...
def logical_or(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def logical_xor(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def max(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def max_mag(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def min(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def min_mag(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def minus(self, a: _Decimal) -> Decimal: ...
def multiply(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def next_minus(self, a: _Decimal) -> Decimal: ...
def next_plus(self, a: _Decimal) -> Decimal: ...
def next_toward(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def normalize(self, a: _Decimal) -> Decimal: ...
def number_class(self, a: _Decimal) -> str: ...
def plus(self, a: _Decimal) -> Decimal: ...
def power(self, a: _Decimal, b: _Decimal, modulo: Optional[_Decimal] = ...) -> Decimal: ...
def quantize(self, a, b): ...
def radix(self): ...
def remainder(self, a, b): ...
def remainder_near(self, a, b): ...
def rotate(self, a, b): ...
def same_quantum(self, a, b): ...
def scaleb(self, a, b): ...
def shift(self, a, b): ...
def sqrt(self, a): ...
def subtract(self, a, b): ...
def to_eng_string(self, a): ...
def to_sci_string(self, a): ...
def to_integral_exact(self, a): ...
def to_integral_value(self, a): ...
def to_integral(self, a): ...
def quantize(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def radix(self) -> Decimal: ...
def remainder(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def remainder_near(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def rotate(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def same_quantum(self, a: _Decimal, b: _Decimal) -> bool: ...
def scaleb(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def shift(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def sqrt(self, a: _Decimal) -> Decimal: ...
def subtract(self, a: _Decimal, b: _Decimal) -> Decimal: ...
def to_eng_string(self, a: _Decimal) -> str: ...
def to_sci_string(self, a: _Decimal) -> str: ...
def to_integral_exact(self, a: _Decimal) -> Decimal: ...
def to_integral_value(self, a: _Decimal) -> Decimal: ...
def to_integral(self, a: _Decimal) -> Decimal: ...
DefaultContext: Context
BasicContext: Context