[Python-checkins] cpython (merge default -> default): Merge from v3.4.0a1 head.

larry.hastings python-checkins at python.org
Sun Aug 4 08:33:20 CEST 2013


http://hg.python.org/cpython/rev/edc668a667ad
changeset:   85012:edc668a667ad
parent:      85011:966bcde95e4f
parent:      84999:e9cecb612ff7
user:        Larry Hastings <larry at hastings.org>
date:        Sat Aug 03 13:01:39 2013 -0700
summary:
  Merge from v3.4.0a1 head.

files:
  Include/longobject.h |   1 +
  Lib/test/test_int.py |  47 ++++++++++-----
  Lib/test/test_re.py  |  10 +++
  Misc/NEWS            |   7 ++
  Modules/_sre.c       |  12 ++--
  Modules/sre.h        |   2 +-
  Objects/abstract.c   |  29 +--------
  Objects/longobject.c |  91 +++++++++++++++++++++----------
  Tools/msi/msi.py     |   5 +-
  9 files changed, 126 insertions(+), 78 deletions(-)


diff --git a/Include/longobject.h b/Include/longobject.h
--- a/Include/longobject.h
+++ b/Include/longobject.h
@@ -97,6 +97,7 @@
 #ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int);
 PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base);
+PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int);
 #endif
 
 #ifndef Py_LIMITED_API
diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py
--- a/Lib/test/test_int.py
+++ b/Lib/test/test_int.py
@@ -73,14 +73,6 @@
         x = -1-sys.maxsize
         self.assertEqual(x >> 1, x//2)
 
-        self.assertRaises(ValueError, int, '123\0')
-        self.assertRaises(ValueError, int, '53', 40)
-
-        # SF bug 1545497: embedded NULs were not detected with
-        # explicit base
-        self.assertRaises(ValueError, int, '123\0', 10)
-        self.assertRaises(ValueError, int, '123\x00 245', 20)
-
         x = int('1' * 600)
         self.assertIsInstance(x, int)
 
@@ -401,14 +393,37 @@
                     int(TruncReturnsBadInt())
 
     def test_error_message(self):
-        testlist = ('\xbd', '123\xbd', '  123 456  ')
-        for s in testlist:
-            try:
-                int(s)
-            except ValueError as e:
-                self.assertIn(s.strip(), e.args[0])
-            else:
-                self.fail("Expected int(%r) to raise a ValueError", s)
+        def check(s, base=None):
+            with self.assertRaises(ValueError,
+                                   msg="int(%r, %r)" % (s, base)) as cm:
+                if base is None:
+                    int(s)
+                else:
+                    int(s, base)
+            self.assertEqual(cm.exception.args[0],
+                "invalid literal for int() with base %d: %r" %
+                (10 if base is None else base, s))
+
+        check('\xbd')
+        check('123\xbd')
+        check('  123 456  ')
+
+        check('123\x00')
+        # SF bug 1545497: embedded NULs were not detected with explicit base
+        check('123\x00', 10)
+        check('123\x00 245', 20)
+        check('123\x00 245', 16)
+        check('123\x00245', 20)
+        check('123\x00245', 16)
+        # byte string with embedded NUL
+        check(b'123\x00')
+        check(b'123\x00', 10)
+        # non-UTF-8 byte string
+        check(b'123\xbd')
+        check(b'123\xbd', 10)
+        # lone surrogate in Unicode string
+        check('123\ud800')
+        check('123\ud800', 10)
 
 def test_main():
     support.run_unittest(IntTestCases)
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -1040,6 +1040,16 @@
         with self.assertRaisesRegex(sre_constants.error, '\?foo'):
             re.compile('(?P<?foo>)')
 
+    def test_issue17998(self):
+        for reps in '*', '+', '?', '{1}':
+            for mod in '', '?':
+                pattern = '.' + reps + mod + 'yz'
+                self.assertEqual(re.compile(pattern, re.S).findall('xyz'),
+                                 ['xyz'], msg=pattern)
+                pattern = pattern.encode()
+                self.assertEqual(re.compile(pattern, re.S).findall(b'xyz'),
+                                 [b'xyz'], msg=pattern)
+
 
 def run_re_tests():
     from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@
 Core and Builtins
 -----------------
 
+- Issue #16741: Fix an error reporting in int().
+
 - Issue #17899: Fix rare file descriptor leak in os.listdir().
 
 - Issue #9035: ismount now recognises volumes mounted below a drive root
@@ -181,6 +183,8 @@
 Library
 -------
 
+- Issue #17998: Fix an internal error in regular expression engine.
+
 - Issue #17557: Fix os.getgroups() to work with the modified behavior of
   getgroups(2) on OS X 10.8.  Original patch by Mateusz Lenik.
 
@@ -761,6 +765,9 @@
 Build
 -----
 
+- Issue #16067: Add description into MSI file to replace installer's 
+  temporary name.
+
 - Issue #18257: Fix readlink usage in python-config.  Install the python
   version again on Darwin.
 
diff --git a/Modules/_sre.c b/Modules/_sre.c
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -997,7 +997,7 @@
             TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
                    ctx->pattern[1], ctx->pattern[2]));
 
-            if (ctx->pattern[1] > (end - ctx->ptr) / state->charsize)
+            if ((Py_ssize_t) ctx->pattern[1] > (end - ctx->ptr) / state->charsize)
                 RETURN_FAILURE; /* cannot match */
 
             state->ptr = ctx->ptr;
@@ -1081,7 +1081,7 @@
             TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
                    ctx->pattern[1], ctx->pattern[2]));
 
-            if (ctx->pattern[1] > (end - ctx->ptr) / state->charsize)
+            if ((Py_ssize_t) ctx->pattern[1] > (end - ctx->ptr) / state->charsize)
                 RETURN_FAILURE; /* cannot match */
 
             state->ptr = ctx->ptr;
@@ -1180,7 +1180,7 @@
             TRACE(("|%p|%p|MAX_UNTIL %d\n", ctx->pattern,
                    ctx->ptr, ctx->count));
 
-            if (ctx->count < ctx->u.rep->pattern[1]) {
+            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
                 /* not enough matches */
                 ctx->u.rep->count = ctx->count;
                 DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
@@ -1194,7 +1194,7 @@
                 RETURN_FAILURE;
             }
 
-            if ((ctx->count < ctx->u.rep->pattern[2] ||
+            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
                 ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
                 state->ptr != ctx->u.rep->last_ptr) {
                 /* we may have enough matches, but if we can
@@ -1243,7 +1243,7 @@
             TRACE(("|%p|%p|MIN_UNTIL %d %p\n", ctx->pattern,
                    ctx->ptr, ctx->count, ctx->u.rep->pattern));
 
-            if (ctx->count < ctx->u.rep->pattern[1]) {
+            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
                 /* not enough matches */
                 ctx->u.rep->count = ctx->count;
                 DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
@@ -1272,7 +1272,7 @@
 
             LASTMARK_RESTORE();
 
-            if ((ctx->count >= ctx->u.rep->pattern[2]
+            if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2]
                 && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) ||
                 state->ptr == ctx->u.rep->last_ptr)
                 RETURN_FAILURE;
diff --git a/Modules/sre.h b/Modules/sre.h
--- a/Modules/sre.h
+++ b/Modules/sre.h
@@ -19,7 +19,7 @@
 #if SIZEOF_SIZE_T > 4
 # define SRE_MAXREPEAT (~(SRE_CODE)0)
 #else
-# define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX + 1u)
+# define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX)
 #endif
 
 typedef struct {
diff --git a/Objects/abstract.c b/Objects/abstract.c
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1261,25 +1261,6 @@
 }
 
 
-/* Add a check for embedded NULL-bytes in the argument. */
-static PyObject *
-long_from_string(const char *s, Py_ssize_t len)
-{
-    char *end;
-    PyObject *x;
-
-    x = PyLong_FromString((char*)s, &end, 10);
-    if (x == NULL)
-        return NULL;
-    if (end != s + len) {
-        PyErr_SetString(PyExc_ValueError,
-                        "null byte in argument for int()");
-        Py_DECREF(x);
-        return NULL;
-    }
-    return x;
-}
-
 PyObject *
 PyNumber_Long(PyObject *o)
 {
@@ -1327,16 +1308,16 @@
 
     if (PyBytes_Check(o))
         /* need to do extra error checking that PyLong_FromString()
-         * doesn't do.  In particular int('9.5') must raise an
-         * exception, not truncate the float.
+         * doesn't do.  In particular int('9\x005') must raise an
+         * exception, not truncate at the null.
          */
-        return long_from_string(PyBytes_AS_STRING(o),
-                                PyBytes_GET_SIZE(o));
+        return _PyLong_FromBytes(PyBytes_AS_STRING(o),
+                                 PyBytes_GET_SIZE(o), 10);
     if (PyUnicode_Check(o))
         /* The above check is done in PyLong_FromUnicode(). */
         return PyLong_FromUnicodeObject(o, 10);
     if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
-        return long_from_string(buffer, buffer_len);
+        return _PyLong_FromBytes(buffer, buffer_len, 10);
 
     return type_error("int() argument must be a string or a "
                       "number, not '%.200s'", o);
diff --git a/Objects/longobject.c b/Objects/longobject.c
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -2000,6 +2000,14 @@
     return long_normalize(z);
 }
 
+/* Parses a long from a bytestring. Leading and trailing whitespace will be
+ * ignored.
+ *
+ * If successful, a PyLong object will be returned and 'pend' will be pointing
+ * to the first unused byte unless it's NULL.
+ *
+ * If unsuccessful, NULL will be returned.
+ */
 PyObject *
 PyLong_FromString(char *str, char **pend, int base)
 {
@@ -2262,24 +2270,54 @@
         str++;
     if (*str != '\0')
         goto onError;
-    if (pend)
+    long_normalize(z);
+    z = maybe_small_long(z);
+    if (z == NULL)
+        return NULL;
+    if (pend != NULL)
         *pend = str;
-    long_normalize(z);
-    return (PyObject *) maybe_small_long(z);
+    return (PyObject *) z;
 
   onError:
+    if (pend != NULL)
+        *pend = str;
     Py_XDECREF(z);
     slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200;
     strobj = PyUnicode_FromStringAndSize(orig_str, slen);
     if (strobj == NULL)
         return NULL;
     PyErr_Format(PyExc_ValueError,
-                 "invalid literal for int() with base %d: %R",
+                 "invalid literal for int() with base %d: %.200R",
                  base, strobj);
     Py_DECREF(strobj);
     return NULL;
 }
 
+/* Since PyLong_FromString doesn't have a length parameter,
+ * check here for possible NULs in the string.
+ *
+ * Reports an invalid literal as a bytes object.
+ */
+PyObject *
+_PyLong_FromBytes(const char *s, Py_ssize_t len, int base)
+{
+    PyObject *result, *strobj;
+    char *end = NULL;
+
+    result = PyLong_FromString((char*)s, &end, base);
+    if (end == NULL || (result != NULL && end == s + len))
+        return result;
+    Py_XDECREF(result);
+    strobj = PyBytes_FromStringAndSize(s, Py_MIN(len, 200));
+    if (strobj != NULL) {
+        PyErr_Format(PyExc_ValueError,
+                     "invalid literal for int() with base %d: %.200R",
+                     base, strobj);
+        Py_DECREF(strobj);
+    }
+    return NULL;
+}
+
 PyObject *
 PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
 {
@@ -2294,9 +2332,8 @@
 PyObject *
 PyLong_FromUnicodeObject(PyObject *u, int base)
 {
-    PyObject *result;
-    PyObject *asciidig;
-    char *buffer, *end;
+    PyObject *result, *asciidig;
+    char *buffer, *end = NULL;
     Py_ssize_t buflen;
 
     asciidig = _PyUnicode_TransformDecimalAndSpaceToASCII(u);
@@ -2305,17 +2342,22 @@
     buffer = PyUnicode_AsUTF8AndSize(asciidig, &buflen);
     if (buffer == NULL) {
         Py_DECREF(asciidig);
-        return NULL;
-    }
-    result = PyLong_FromString(buffer, &end, base);
-    if (result != NULL && end != buffer + buflen) {
-        PyErr_SetString(PyExc_ValueError,
-                        "null byte in argument for int()");
-        Py_DECREF(result);
-        result = NULL;
-    }
-    Py_DECREF(asciidig);
-    return result;
+        if (!PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
+            return NULL;
+    }
+    else {
+        result = PyLong_FromString(buffer, &end, base);
+        if (end == NULL || (result != NULL && end == buffer + buflen)) {
+            Py_DECREF(asciidig);
+            return result;
+        }
+        Py_DECREF(asciidig);
+        Py_XDECREF(result);
+    }
+    PyErr_Format(PyExc_ValueError,
+                 "invalid literal for int() with base %d: %.200R",
+                 base, u);
+    return NULL;
 }
 
 /* forward */
@@ -4319,23 +4361,12 @@
     if (PyUnicode_Check(x))
         return PyLong_FromUnicodeObject(x, (int)base);
     else if (PyByteArray_Check(x) || PyBytes_Check(x)) {
-        /* Since PyLong_FromString doesn't have a length parameter,
-         * check here for possible NULs in the string. */
         char *string;
-        Py_ssize_t size = Py_SIZE(x);
         if (PyByteArray_Check(x))
             string = PyByteArray_AS_STRING(x);
         else
             string = PyBytes_AS_STRING(x);
-        if (strlen(string) != (size_t)size || !size) {
-            /* We only see this if there's a null byte in x or x is empty,
-               x is a bytes or buffer, *and* a base is given. */
-            PyErr_Format(PyExc_ValueError,
-                         "invalid literal for int() with base %d: %R",
-                         (int)base, x);
-            return NULL;
-        }
-        return PyLong_FromString(string, NULL, (int)base);
+        return _PyLong_FromBytes(string, Py_SIZE(x), (int)base);
     }
     else {
         PyErr_SetString(PyExc_TypeError,
diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py
--- a/Tools/msi/msi.py
+++ b/Tools/msi/msi.py
@@ -1415,7 +1415,10 @@
 # certname (from config.py) should be (a substring of)
 # the certificate subject, e.g. "Python Software Foundation"
 if certname:
-    os.system('signtool sign /n "%s" /t http://timestamp.verisign.com/scripts/timestamp.dll %s' % (certname, msiname))
+    os.system('signtool sign /n "%s" '
+      '/t http://timestamp.verisign.com/scripts/timestamp.dll '
+      '/d "Python %s" '
+      '%s' % (certname, full_current_version, msiname))
 
 if pdbzip:
     build_pdbzip()

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list