File: test_decimal.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (141 lines) | stat: -rw-r--r-- 4,051 bytes parent folder | download | duplicates (2)
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)