[Python-checkins] r82657 - in python/branches/release26-maint: Lib/decimal.py Misc/NEWS

mark.dickinson python-checkins at python.org
Thu Jul 8 23:27:06 CEST 2010


Author: mark.dickinson
Date: Thu Jul  8 23:27:05 2010
New Revision: 82657

Log:
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__.
(Backport of r82656 from release27-maint.)



Modified:
   python/branches/release26-maint/Lib/decimal.py
   python/branches/release26-maint/Misc/NEWS

Modified: python/branches/release26-maint/Lib/decimal.py
==============================================================================
--- python/branches/release26-maint/Lib/decimal.py	(original)
+++ python/branches/release26-maint/Lib/decimal.py	Thu Jul  8 23:27:05 2010
@@ -3690,22 +3690,38 @@
                  Emin=None, Emax=None,
                  capitals=None, _clamp=0,
                  _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])
-            del s
-        if traps is not None and not isinstance(traps, dict):
-            traps = dict([(s, int(s in traps)) for s in _signals])
-            del s
-        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."""

Modified: python/branches/release26-maint/Misc/NEWS
==============================================================================
--- python/branches/release26-maint/Misc/NEWS	(original)
+++ python/branches/release26-maint/Misc/NEWS	Thu Jul  8 23:27:05 2010
@@ -81,6 +81,10 @@
 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')).


More information about the Python-checkins mailing list