[pypy-commit] pypy stdlib-2.7.8: merged upstream

alex_gaynor noreply at buildbot.pypy.org
Sun Aug 24 19:23:20 CEST 2014


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: stdlib-2.7.8
Changeset: r73026:0daa85d1846a
Date: 2014-08-24 10:22 -0700
http://bitbucket.org/pypy/pypy/changeset/0daa85d1846a/

Log:	merged upstream

diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -391,16 +391,31 @@
                                 # has no effect any more
                 if stop > 0:
                     self._ignore_items(stop)
+                self.iterable = None
                 raise OperationError(self.space.w_StopIteration,
                                      self.space.w_None)
             self.stop = stop - (ignore + 1)
         if ignore > 0:
             self._ignore_items(ignore)
-        return self.space.next(self.iterable)
+        if self.iterable is None:
+            raise OperationError(self.space.w_StopIteration, self.space.w_None)
+        try:
+            return self.space.next(self.iterable)
+        except OperationError as e:
+            if e.match(self.space, self.space.w_StopIteration):
+                self.iterable = None
+            raise
 
     def _ignore_items(self, num):
+        if self.iterable is None:
+            raise OperationError(self.space.w_StopIteration, self.space.w_None)
         while True:
-            self.space.next(self.iterable)
+            try:
+                self.space.next(self.iterable)
+            except OperationError as e:
+                if e.match(self.space, self.space.w_StopIteration):
+                    self.iterable = None
+                raise
             num -= 1
             if num <= 0:
                 break
diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -237,6 +237,18 @@
         assert list(itertools.islice(xrange(10), None,None)) == range(10)
         assert list(itertools.islice(xrange(10), None,None,None)) == range(10)
 
+        # check source iterator is not referenced from islice()
+        # after the latter has been exhausted
+        import weakref
+        for args in [(1,), (None,), (0, None, 2)]:
+            it = (x for x in (1, 2, 3))
+            wr = weakref.ref(it)
+            it = itertools.islice(it, *args)
+            assert wr() is not None
+            list(it)  # exhaust the iterator
+            assert wr() is None
+            raises(StopIteration, next, it)
+
     def test_islice_dropitems_exact(self):
         import itertools
 
diff --git a/pypy/module/operator/app_operator.py b/pypy/module/operator/app_operator.py
--- a/pypy/module/operator/app_operator.py
+++ b/pypy/module/operator/app_operator.py
@@ -5,8 +5,10 @@
 equivalent to x+y.
 '''
 from __pypy__ import builtinify
+import types
 
-def countOf(a,b): 
+
+def countOf(a,b):
     'countOf(a, b) -- Return the number of times b occurs in a.'
     count = 0
     for x in a:
@@ -37,11 +39,11 @@
         index += 1
     raise ValueError, 'sequence.index(x): x not in sequence'
 
-# XXX the following is approximative
 def isMappingType(obj,):
     'isMappingType(a) -- Return True if a has a mapping type, False otherwise.'
-    # XXX this is fragile and approximative anyway
-    return hasattr(obj, '__getitem__') and hasattr(obj, 'keys')
+    if isinstance(obj, types.InstanceType):
+        return hasattr(obj, '__getitem__')
+    return hasattr(obj, '__getitem__') and not hasattr(obj, '__getslice__')
 
 def isNumberType(obj,):
     'isNumberType(a) -- Return True if a has a numeric type, False otherwise.'
@@ -49,7 +51,9 @@
 
 def isSequenceType(obj,):
     'isSequenceType(a) -- Return True if a has a sequence type, False otherwise.'
-    return hasattr(obj, '__getitem__') and not hasattr(obj, 'keys')
+    if isinstance(obj, dict):
+        return False
+    return hasattr(obj, '__getitem__')
 
 def repeat(obj, num):
     'repeat(a, b) -- Return a * b, where a is a sequence, and b is an integer.'
diff --git a/pypy/module/operator/test/test_operator.py b/pypy/module/operator/test/test_operator.py
--- a/pypy/module/operator/test/test_operator.py
+++ b/pypy/module/operator/test/test_operator.py
@@ -140,6 +140,35 @@
         assert operator.repeat(a, 0) == []
         raises(TypeError, operator.repeat, 6, 7)
 
+    def test_isMappingType(self):
+        import operator
+        assert not operator.isMappingType([])
+        assert operator.isMappingType(dict())
+        class M:
+            def __getitem__(self, key):
+                return 42
+        assert operator.isMappingType(M())
+        del M.__getitem__
+        assert not operator.isMappingType(M())
+        class M(object):
+            def __getitem__(self, key):
+                return 42
+        assert operator.isMappingType(M())
+        del M.__getitem__
+        assert not operator.isMappingType(M())
+        class M:
+            def __getitem__(self, key):
+                return 42
+            def __getslice__(self, key):
+                return 42
+        assert operator.isMappingType(M())
+        class M(object):
+            def __getitem__(self, key):
+                return 42
+            def __getslice__(self, key):
+                return 42
+        assert not operator.isMappingType(M())
+
     def test_isSequenceType(self):
         import operator
 
diff --git a/rpython/translator/c/src/dtoa.c b/rpython/translator/c/src/dtoa.c
--- a/rpython/translator/c/src/dtoa.c
+++ b/rpython/translator/c/src/dtoa.c
@@ -122,6 +122,7 @@
 #define PY_UINT32_T unsigned int
 #define PY_INT32_T int
 #define PY_UINT64_T unsigned long long
+#include <limits.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <assert.h>
@@ -221,7 +222,24 @@
    MAX_ABS_EXP in absolute value get truncated to +-MAX_ABS_EXP.  MAX_ABS_EXP
    should fit into an int. */
 #ifndef MAX_ABS_EXP
-#define MAX_ABS_EXP 19999U
+#define MAX_ABS_EXP 1100000000U
+#endif
+/* Bound on length of pieces of input strings in _Py_dg_strtod; specifically,
+   this is used to bound the total number of digits ignoring leading zeros and
+   the number of digits that follow the decimal point.  Ideally, MAX_DIGITS
+   should satisfy MAX_DIGITS + 400 < MAX_ABS_EXP; that ensures that the
+   exponent clipping in _Py_dg_strtod can't affect the value of the output. */
+#ifndef MAX_DIGITS
+#define MAX_DIGITS 1000000000U
+#endif
+
+/* Guard against trying to use the above values on unusual platforms with ints
+ * of width less than 32 bits. */
+#if MAX_ABS_EXP > INT_MAX
+#error "MAX_ABS_EXP should fit in an int"
+#endif
+#if MAX_DIGITS > INT_MAX
+#error "MAX_DIGITS should fit in an int"
 #endif
 
 /* The following definition of Storeinc is appropriate for MIPS processors.
@@ -1515,6 +1533,7 @@
     Long L;
     BCinfo bc;
     Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+    size_t ndigits, fraclen;
 
     dval(&rv) = 0.;
 
@@ -1537,40 +1556,53 @@
         c = *++s;
     lz = s != s1;
 
-    /* Point s0 at the first nonzero digit (if any).  nd0 will be the position
-       of the point relative to s0.  nd will be the total number of digits
-       ignoring leading zeros. */
+    /* Point s0 at the first nonzero digit (if any).  fraclen will be the
+       number of digits between the decimal point and the end of the
+       digit string.  ndigits will be the total number of digits ignoring
+       leading zeros. */
     s0 = s1 = s;
     while ('0' <= c && c <= '9')
         c = *++s;
-    nd0 = nd = s - s1;
+    ndigits = s - s1;
+    fraclen = 0;
 
     /* Parse decimal point and following digits. */
     if (c == '.') {
         c = *++s;
-        if (!nd) {
+        if (!ndigits) {
             s1 = s;
             while (c == '0')
                 c = *++s;
             lz = lz || s != s1;
-            nd0 -= s - s1;
+            fraclen += (s - s1);
             s0 = s;
         }
         s1 = s;
         while ('0' <= c && c <= '9')
             c = *++s;
-        nd += s - s1;
+        ndigits += s - s1;
+        fraclen += s - s1;
     }
 
-    /* Now lz is true if and only if there were leading zero digits, and nd
-       gives the total number of digits ignoring leading zeros.  A valid input
-       must have at least one digit. */
-    if (!nd && !lz) {
+    /* Now lz is true if and only if there were leading zero digits, and
+       ndigits gives the total number of digits ignoring leading zeros.  A
+       valid input must have at least one digit. */
+    if (!ndigits && !lz) {
         if (se)
             *se = (char *)s00;
         goto parse_error;
     }
 
+    /* Range check ndigits and fraclen to make sure that they, and values
+       computed with them, can safely fit in an int. */
+    if (ndigits > MAX_DIGITS || fraclen > MAX_DIGITS) {
+        if (se)
+            *se = (char *)s00;
+        goto parse_error;
+    }
+    nd = (int)ndigits;
+    nd0 = (int)ndigits - (int)fraclen;
+
     /* Parse exponent. */
     e = 0;
     if (c == 'e' || c == 'E') {
@@ -1903,20 +1935,20 @@
         bd2++;
 
         /* At this stage bd5 - bb5 == e == bd2 - bb2 + bbe, bb2 - bs2 == 1,
-	   and bs == 1, so:
+           and bs == 1, so:
 
               tdv == bd * 10**e = bd * 2**(bbe - bb2 + bd2) * 5**(bd5 - bb5)
               srv == bb * 2**bbe = bb * 2**(bbe - bb2 + bb2)
-	      0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2)
+              0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2)
 
-	   It follows that:
+           It follows that:
 
               M * tdv = bd * 2**bd2 * 5**bd5
               M * srv = bb * 2**bb2 * 5**bb5
               M * 0.5 ulp(srv) = bs * 2**bs2 * 5**bb5
 
-	   for some constant M.  (Actually, M == 2**(bb2 - bbe) * 5**bb5, but
-	   this fact is not needed below.)
+           for some constant M.  (Actually, M == 2**(bb2 - bbe) * 5**bb5, but
+           this fact is not needed below.)
         */
 
         /* Remove factor of 2**i, where i = min(bb2, bd2, bs2). */


More information about the pypy-commit mailing list