]> granicus.if.org Git - python/commitdiff
Issue #9136: Profiling Decimal gave 'dictionary changed size during iteration'.
authorMark Dickinson <dickinsm@gmail.com>
Thu, 8 Jul 2010 21:15:36 +0000 (21:15 +0000)
committerMark Dickinson <dickinsm@gmail.com>
Thu, 8 Jul 2010 21:15:36 +0000 (21:15 +0000)
Remove the use of locals() that caused this error.

Lib/decimal.py
Misc/NEWS

index 5cb5ea9ba0dacb8abcf13ed444a78cc92599991c..c3dffa3ed7b353f4b36a29ad1bc71a3400bb07ac 100644 (file)
@@ -3813,20 +3813,38 @@ class Context(object):
                  Emin=None, Emax=None,
                  capitals=None, clamp=None,
                  _ignored_flags=None):
-        if flags is None:
-            flags = []
+        # Set defaults; for everything except flags and _ignored_flags,
+        # inherit from DefaultContext.
+        try:
+            dc = DefaultContext
+        except NameError:
+            pass
+
+        self.prec = prec if prec is not None else dc.prec
+        self.rounding = rounding if rounding is not None else dc.rounding
+        self.Emin = Emin if Emin is not None else dc.Emin
+        self.Emax = Emax if Emax is not None else dc.Emax
+        self.capitals = capitals if capitals is not None else dc.capitals
+        self.clamp = clamp if clamp is not None else dc.clamp
+
         if _ignored_flags is None:
-            _ignored_flags = []
-        if not isinstance(flags, dict):
-            flags = dict([(s, int(s in flags)) for s in _signals])
-        if traps is not None and not isinstance(traps, dict):
-            traps = dict([(s, int(s in traps)) for s in _signals])
-        for name, val in locals().items():
-            if val is None:
-                setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
-            else:
-                setattr(self, name, val)
-        del self.self
+            self._ignored_flags = []
+        else:
+            self._ignored_flags = _ignored_flags
+
+        if traps is None:
+            self.traps = dc.traps.copy()
+        elif not isinstance(traps, dict):
+            self.traps = dict((s, int(s in traps)) for s in _signals)
+        else:
+            self.traps = traps
+
+        if flags is None:
+            self.flags = dict.fromkeys(_signals, 0)
+        elif not isinstance(flags, dict):
+            self.flags = dict((s, int(s in flags)) for s in _signals)
+        else:
+            self.flags = flags
 
     def __repr__(self):
         """Show the current context."""
index 369eaff885c751ae441d1afc63c274e8bacbdd81..d1edda23ac8fc140fa2119a407e39fbaf9cc2236 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -470,6 +470,10 @@ C-API
 Library
 -------
 
+- Issue #9136: Fix 'dictionary changed size during iteration'
+  RuntimeError produced when profiling the decimal module.  This was
+  due to a dangerous iteration over 'locals()' in Context.__init__.
+
 - Fix extreme speed issue in Decimal.pow when the base is an exact
   power of 10 and the exponent is tiny (for example,
   Decimal(10) ** Decimal('1e-999999999')).