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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
import pytest
from hypothesis import example, settings, given, strategies as st
import pickle
import sys
from .support import import_fresh_module
C = import_fresh_module('decimal', fresh=['_decimal'])
P = import_fresh_module('decimal', blocked=['_decimal'])
# import _decimal as C
# import _pydecimal as P
if not C:
C = P
@pytest.fixture(params=[C, P], ids=['_decimal', '_pydecimal'])
def module(request):
yield request.param
# Translate symbols.
CondMap = {
C.Clamped: P.Clamped,
C.ConversionSyntax: P.ConversionSyntax,
C.DivisionByZero: P.DivisionByZero,
C.DivisionImpossible: P.InvalidOperation,
C.DivisionUndefined: P.DivisionUndefined,
C.Inexact: P.Inexact,
C.InvalidContext: P.InvalidContext,
C.InvalidOperation: P.InvalidOperation,
C.Overflow: P.Overflow,
C.Rounded: P.Rounded,
C.Subnormal: P.Subnormal,
C.Underflow: P.Underflow,
C.FloatOperation: P.FloatOperation,
}
def check_same_flags(flags_C, flags_P):
for signal in flags_C:
assert flags_C[signal] == flags_P[CondMap[signal]]
def test_C():
sys.modules["decimal"] = C
import decimal
d = decimal.Decimal('1')
assert isinstance(d, C.Decimal)
assert isinstance(d, decimal.Decimal)
assert isinstance(d.as_tuple(), C.DecimalTuple)
assert d == C.Decimal('1')
def check_round_trip(val, proto):
d = C.Decimal(val)
p = pickle.dumps(d, proto)
assert d == pickle.loads(p)
def test_pickle():
v = '-3.123e81723'
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
sys.modules["decimal"] = C
check_round_trip('-3.141590000', proto)
check_round_trip(v, proto)
cd = C.Decimal(v)
pd = P.Decimal(v)
cdt = cd.as_tuple()
pdt = pd.as_tuple()
assert cdt.__module__ == pdt.__module__
p = pickle.dumps(cdt, proto)
r = pickle.loads(p)
assert isinstance(r, C.DecimalTuple)
assert cdt == r
sys.modules["decimal"] = C
p = pickle.dumps(cd, proto)
sys.modules["decimal"] = P
r = pickle.loads(p)
assert isinstance(r, P.Decimal)
assert r == pd
sys.modules["decimal"] = C
p = pickle.dumps(cdt, proto)
sys.modules["decimal"] = P
r = pickle.loads(p)
assert isinstance(r, P.DecimalTuple)
assert r == pdt
def test_compare_total(module):
assert module.Decimal('12').compare_total(module.Decimal('12.0')) == 1
assert module.Decimal('4367').compare_total(module.Decimal('NaN')) == -1
def test_compare_total_mag(module):
assert module.Decimal(1).compare_total_mag(-2) == -1
def convert_arg(module, arg):
if isinstance(arg, module.Decimal):
return arg
elif type(arg).__name__ == 'Decimal':
return module.Decimal(str(arg))
else:
return arg
def test_subclass_fromfloat_oddity_fixed(module):
# older versions of CPython's _decimal did weird stuff here
class A(module.Decimal):
def __init__(self, a):
self.a_type = type(a)
a = A.from_float(42.5)
assert a.a_type is module.Decimal
def test_subclass_float_constructor(module):
class A(module.Decimal):
pass
a = A(0.25)
assert type(a) is A
from fractions import Fraction
from decimal import Decimal
@given(st.decimals(), st.decimals() | st.fractions())
def test_lt(d1, d2):
with C.localcontext(C.ExtendedContext) as ctx_C:
d1_C = convert_arg(C, d1)
d2_C = convert_arg(C, d2)
try:
res_C = d1_C < d2_C
except Exception as e:
res_C = str(type(e))
with P.localcontext(P.ExtendedContext) as ctx_P:
d1_P = convert_arg(P, d1)
d2_P = convert_arg(P, d2)
try:
res_P = d1_P < d2_P
except Exception as e:
res_P = str(type(e))
assert res_C == res_P
check_same_flags(ctx_C.flags, ctx_P.flags)
|