Commits

Amaury Forgeot d'Arc  committed 189b465

Add Context.__init__, and create_from_float

  • Participants
  • Parent commits 81ca8a3
  • Branches decimal-libmpdec

Comments (0)

Files changed (3)

File pypy/module/_decimal/interp_context.py

         if self.ctx:
             lltype.free(self.ctx, flavor='raw', track_allocation=False)
 
+    def descr_init(self, space,
+                   w_prec=None, w_rounding=None, w_Emin=None, w_Emax=None,
+                   w_capitals=None, w_clamp=None, w_flags=None, w_traps=None):
+        if not space.is_none(w_prec):
+            self.set_prec(space, w_prec)
+        if not space.is_none(w_rounding):
+            self.set_rounding(space, w_rounding)
+        if not space.is_none(w_Emin):
+            self.set_emin(space, w_Emin)
+        if not space.is_none(w_Emax):
+            self.set_emax(space, w_Emax)
+        if not space.is_none(w_capitals):
+            self.set_capitals(space, w_capitals)
+        if not space.is_none(w_clamp):
+            self.set_clamp(space, w_clamp)
+        if not space.is_none(w_flags):
+            flags = interp_signals.list_as_flags(space, w_flags)
+            rffi.setintfield(self.ctx, 'c_status', flags)
+        if not space.is_none(w_traps):
+            flags = interp_signals.list_as_flags(space, w_traps)
+            rffi.setintfield(self.ctx, 'c_traps', flags)
+
     def addstatus(self, space, status):
         "Add resulting status to context, and eventually raise an exception."
         new_status = (rffi.cast(lltype.Signed, status) |
         return interp_decimal.decimal_from_object(
             space, None, w_value, self, exact=False)
 
+    def create_decimal_from_float_w(self, space, w_value=None):
+        from pypy.module._decimal import interp_decimal
+        return interp_decimal.decimal_from_float(
+            space, None, w_value, self, exact=False)
+
     def descr_repr(self, space):
         # Rounding string.
         rounding = rffi.cast(lltype.Signed, self.ctx.c_round)
 W_Context.typedef = TypeDef(
     'Context',
     __new__ = interp2app(descr_new_context),
+    __init__ = interp2app(W_Context.descr_init),
     # Attributes
     flags=interp_attrproperty_w('w_flags', W_Context),
     traps=interp_attrproperty_w('w_traps', W_Context),
     clear_flags=interp2app(W_Context.clear_flags_w),
     clear_traps=interp2app(W_Context.clear_traps_w),
     create_decimal=interp2app(W_Context.create_decimal_w),
+    create_decimal_from_float=interp2app(W_Context.create_decimal_from_float_w),
     # Unary Operations
     abs=make_unary_method('mpd_qabs'),
     exp=make_unary_method('mpd_qexp'),

File pypy/module/_decimal/interp_signals.py

                     "invalid error flag")
     return OperationError(w_exc, space.w_None)
 
+def list_as_flags(space, w_list):
+    flags = 0
+    for w_item in space.unpackiterable(w_list):
+        flags |= exception_as_flag(space, w_item)
+    return flags
+
 def exception_as_flag(space, w_exc):
     for name, flag in SIGNAL_MAP:
         if space.is_w(w_exc, getattr(get(space), 'w_' + name)):

File pypy/module/_decimal/test/test_context.py

             x = self.random_float()
             self.assertEqual(x, float(nc.create_decimal(x))) # roundtrip
 
+    def test_create_decimal_from_float(self):
+        import math
+        Decimal = self.decimal.Decimal
+        Context = self.decimal.Context
+        Inexact = self.decimal.Inexact
+
+        context = Context(prec=5, rounding=self.decimal.ROUND_DOWN)
+        self.assertEqual(
+            context.create_decimal_from_float(math.pi),
+            Decimal('3.1415')
+        )
+        context = Context(prec=5, rounding=self.decimal.ROUND_UP)
+        self.assertEqual(
+            context.create_decimal_from_float(math.pi),
+            Decimal('3.1416')
+        )
+        context = Context(prec=5, traps=[Inexact])
+        self.assertRaises(
+            Inexact,
+            context.create_decimal_from_float,
+            math.pi
+        )
+        self.assertEqual(repr(context.create_decimal_from_float(-0.0)),
+                         "Decimal('-0')")
+        self.assertEqual(repr(context.create_decimal_from_float(1.0)),
+                         "Decimal('1')")
+        self.assertEqual(repr(context.create_decimal_from_float(10)),
+                         "Decimal('10')")
+
     def test_add(self):
         Decimal = self.decimal.Decimal
         Context = self.decimal.Context