[pypy-commit] pypy decimal-libmpdec: Fix Context traps when passed as a dictionary.

amauryfa noreply at buildbot.pypy.org
Sun Oct 5 20:23:02 CEST 2014


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: decimal-libmpdec
Changeset: r73798:8ca6f0d4f9a2
Date: 2014-09-19 20:39 +0200
http://bitbucket.org/pypy/pypy/changeset/8ca6f0d4f9a2/

Log:	Fix Context traps when passed as a dictionary.

diff --git a/pypy/module/_decimal/interp_context.py b/pypy/module/_decimal/interp_context.py
--- a/pypy/module/_decimal/interp_context.py
+++ b/pypy/module/_decimal/interp_context.py
@@ -129,10 +129,16 @@
         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)
+            if space.isinstance_w(w_flags, space.w_list):
+                flags = interp_signals.list_as_flags(space, w_flags)
+            else:
+                flags = interp_signals.dict_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)
+            if space.isinstance_w(w_traps, space.w_list):
+                flags = interp_signals.list_as_flags(space, w_traps)
+            else:
+                flags = interp_signals.dict_as_flags(space, w_traps)
             rffi.setintfield(self.ctx, 'c_traps', flags)
 
     def addstatus(self, space, status):
diff --git a/pypy/module/_decimal/interp_signals.py b/pypy/module/_decimal/interp_signals.py
--- a/pypy/module/_decimal/interp_signals.py
+++ b/pypy/module/_decimal/interp_signals.py
@@ -4,7 +4,7 @@
 from rpython.rlib.unroll import unrolling_iterable
 from pypy.interpreter.error import oefmt, OperationError
 
-SIGNAL_MAP = unrolling_iterable([
+SIGNAL_LIST = [
     ('InvalidOperation', rmpdec.MPD_IEEE_Invalid_operation),
     ('FloatOperation', rmpdec.MPD_Float_operation),
     ('DivisionByZero', rmpdec.MPD_Division_by_zero),
@@ -14,7 +14,9 @@
     ('Inexact', rmpdec.MPD_Inexact),
     ('Rounded', rmpdec.MPD_Rounded),
     ('Clamped', rmpdec.MPD_Clamped),
-    ])
+    ]
+SIGNAL_MAP = unrolling_iterable(SIGNAL_LIST)
+
 # Exceptions that inherit from InvalidOperation
 COND_MAP = unrolling_iterable([
     ('InvalidOperation', rmpdec.MPD_Invalid_operation),
@@ -53,6 +55,23 @@
         flags |= exception_as_flag(space, w_item)
     return flags
 
+def dict_as_flags(space, w_dict):
+    if space.len_w(w_dict) != len(SIGNAL_LIST):
+        raise oefmt(space.w_KeyError,
+                    "invalid signal dict")
+    flags = 0
+    for name, flag in SIGNAL_MAP:
+        try:
+            w_value = space.getitem(w_dict, getattr(get(space), 'w_' + name))
+        except OperationError as e:
+            if e.match(space, space.w_KeyError):
+                raise oefmt(space.w_KeyError,
+                            "invalid signal dict")
+            raise
+        if space.bool_w(w_value):
+            flags |= flag
+    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)):
@@ -78,7 +97,7 @@
         if flag & flags:
             if not first:
                 builder.append(', ')
-                first = False
+            first = False
             builder.append(value)
     builder.append(']')
     return builder.build()
diff --git a/pypy/module/_decimal/test/test_context.py b/pypy/module/_decimal/test/test_context.py
--- a/pypy/module/_decimal/test/test_context.py
+++ b/pypy/module/_decimal/test/test_context.py
@@ -31,6 +31,11 @@
 
         cls.w_assertRaises = space.appexec([], """(): return raises""")
 
+    def test_dict_flags(self):
+        c = self.decimal.Context(traps=dict.fromkeys(
+                self.decimal.DefaultContext.traps.keys(), 0))
+        assert c.traps[self.decimal.Rounded] == False
+
     def test_deepcopy(self):
         import copy
         c = self.decimal.DefaultContext.copy()


More information about the pypy-commit mailing list