[pypy-commit] pypy decimal-libmpdec: Progress: Decimal.__repr__

amauryfa noreply at buildbot.pypy.org
Sun May 11 00:27:55 CEST 2014


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: decimal-libmpdec
Changeset: r71463:423fc178afd4
Date: 2014-05-10 20:54 +0200
http://bitbucket.org/pypy/pypy/changeset/423fc178afd4/

Log:	Progress: Decimal.__repr__

diff --git a/pypy/module/_decimal/interp_decimal.py b/pypy/module/_decimal/interp_decimal.py
--- a/pypy/module/_decimal/interp_decimal.py
+++ b/pypy/module/_decimal/interp_decimal.py
@@ -67,6 +67,17 @@
                 rmpdec.mpd_free(cp)
         return space.wrap(result)  # Convert bytes to unicode
 
+    def descr_repr(self, space):
+        context = interp_context.getcontext(space)
+        cp = rmpdec.mpd_to_sci(self.mpd, context.capitals)
+        if not cp:
+            raise OperationError(space.w_MemoryError, space.w_None)
+        try:
+            result = rffi.charp2str(cp)
+        finally:
+            rmpdec.mpd_free(cp)
+        return space.wrap("Decimal('%s')" % result)
+
     def descr_bool(self, space):
         return space.wrap(not rmpdec.mpd_iszero(self.mpd))
 
@@ -374,6 +385,7 @@
     'Decimal',
     __new__ = interp2app(descr_new_decimal),
     __str__ = interp2app(W_Decimal.descr_str),
+    __repr__ = interp2app(W_Decimal.descr_repr),
     __bool__ = interp2app(W_Decimal.descr_bool),
     __float__ = interp2app(W_Decimal.descr_float),
     __eq__ = interp2app(W_Decimal.descr_eq),
diff --git a/pypy/module/_decimal/test/test_decimal.py b/pypy/module/_decimal/test/test_decimal.py
--- a/pypy/module/_decimal/test/test_decimal.py
+++ b/pypy/module/_decimal/test/test_decimal.py
@@ -323,3 +323,113 @@
         assert Decimal(4) - Decimal(3) == Decimal(1)
         assert Decimal(4) * Decimal(3) == Decimal(12)
         assert Decimal(6) / Decimal(3) == Decimal(2)
+
+    def test_tostring_methods(self):
+        Decimal = self.decimal.Decimal
+        d = Decimal('15.32')
+        assert str(d) == '15.32'
+        assert repr(d) == "Decimal('15.32')"
+
+    def test_tonum_methods(self):
+        #Test float and int methods.
+        Decimal = self.decimal.Decimal
+
+        d1 = Decimal('66')
+        d2 = Decimal('15.32')
+
+        #int
+        int(d1) == 66
+        int(d2) == 15
+
+        #float
+        float(d1) == 66
+        float(d2) == 15.32
+
+        #floor
+        test_pairs = [
+            ('123.00', 123),
+            ('3.2', 3),
+            ('3.54', 3),
+            ('3.899', 3),
+            ('-2.3', -3),
+            ('-11.0', -11),
+            ('0.0', 0),
+            ('-0E3', 0),
+            ('89891211712379812736.1', 89891211712379812736),
+            ]
+        for d, i in test_pairs:
+            assert math.floor(Decimal(d)) == i
+        raises(ValueError, math.floor, Decimal('-NaN'))
+        raises(ValueError, math.floor, Decimal('sNaN'))
+        raises(ValueError, math.floor, Decimal('NaN123'))
+        raises(OverflowError, math.floor, Decimal('Inf'))
+        raises(OverflowError, math.floor, Decimal('-Inf'))
+
+        #ceiling
+        test_pairs = [
+            ('123.00', 123),
+            ('3.2', 4),
+            ('3.54', 4),
+            ('3.899', 4),
+            ('-2.3', -2),
+            ('-11.0', -11),
+            ('0.0', 0),
+            ('-0E3', 0),
+            ('89891211712379812736.1', 89891211712379812737),
+            ]
+        for d, i in test_pairs:
+            assert math.ceil(Decimal(d)) == i
+        raises(ValueError, math.ceil, Decimal('-NaN'))
+        raises(ValueError, math.ceil, Decimal('sNaN'))
+        raises(ValueError, math.ceil, Decimal('NaN123'))
+        raises(OverflowError, math.ceil, Decimal('Inf'))
+        raises(OverflowError, math.ceil, Decimal('-Inf'))
+
+        #round, single argument
+        test_pairs = [
+            ('123.00', 123),
+            ('3.2', 3),
+            ('3.54', 4),
+            ('3.899', 4),
+            ('-2.3', -2),
+            ('-11.0', -11),
+            ('0.0', 0),
+            ('-0E3', 0),
+            ('-3.5', -4),
+            ('-2.5', -2),
+            ('-1.5', -2),
+            ('-0.5', 0),
+            ('0.5', 0),
+            ('1.5', 2),
+            ('2.5', 2),
+            ('3.5', 4),
+            ]
+        for d, i in test_pairs:
+            assert round(Decimal(d)) == i
+        raises(ValueError, round, Decimal('-NaN'))
+        raises(ValueError, round, Decimal('sNaN'))
+        raises(ValueError, round, Decimal('NaN123'))
+        raises(OverflowError, round, Decimal('Inf'))
+        raises(OverflowError, round, Decimal('-Inf'))
+
+        #round, two arguments;  this is essentially equivalent
+        #to quantize, which is already extensively tested
+        test_triples = [
+            ('123.456', -4, '0E+4'),
+            ('123.456', -3, '0E+3'),
+            ('123.456', -2, '1E+2'),
+            ('123.456', -1, '1.2E+2'),
+            ('123.456', 0, '123'),
+            ('123.456', 1, '123.5'),
+            ('123.456', 2, '123.46'),
+            ('123.456', 3, '123.456'),
+            ('123.456', 4, '123.4560'),
+            ('123.455', 2, '123.46'),
+            ('123.445', 2, '123.44'),
+            ('Inf', 4, 'NaN'),
+            ('-Inf', -23, 'NaN'),
+            ('sNaN314', 3, 'NaN314'),
+            ]
+        for d, n, r in test_triples:
+            assert str(round(Decimal(d), n)) == r
+
diff --git a/rpython/rlib/rmpdec.py b/rpython/rlib/rmpdec.py
--- a/rpython/rlib/rmpdec.py
+++ b/rpython/rlib/rmpdec.py
@@ -42,7 +42,7 @@
         "mpd_qsetprec", "mpd_qsetemin",  "mpd_qsetemax", "mpd_qsetround", "mpd_qsetclamp",
         "mpd_maxcontext",
         "mpd_qnew",
-        "mpd_to_sci_size",
+        "mpd_to_sci", "mpd_to_sci_size",
         "mpd_iszero", "mpd_isnegative", "mpd_isinfinite", "mpd_isspecial",
         "mpd_isnan", "mpd_issnan", "mpd_isqnan",
         "mpd_qcmp",
@@ -182,6 +182,8 @@
     'mpd_seterror', [MPD_PTR, rffi.UINT, rffi.UINTP], lltype.Void)
 
 # Conversion
+mpd_to_sci = external(
+    'mpd_to_sci', [MPD_PTR, rffi.INT], rffi.CCHARP)
 mpd_to_sci_size = external(
     'mpd_to_sci_size', [rffi.CCHARPP, MPD_PTR, rffi.INT], rffi.SSIZE_T)
 


More information about the pypy-commit mailing list