Anonymous committed 09333d4 Merge


Comments (0)

Files changed (12)


    Create a memoryview object from an object that provides the buffer interface.
    If *obj* supports writable buffer exports, the memoryview object will be
-   readable and writable, other it will be read-only.
+   readable and writable, otherwise it will be read-only.
 .. c:function:: PyObject *PyMemoryView_FromBuffer(Py_buffer *view)
    Create a memoryview object to a contiguous chunk of memory (in either
    'C' or 'F'ortran *order*) from an object that defines the buffer
    interface. If memory is contiguous, the memoryview object points to the
-   original memory. Otherwise copy is made and the memoryview points to a
+   original memory. Otherwise, a copy is made and the memoryview points to a
    new bytes object.


 See the :ref:`unicode-howto`.
+What is the most efficient way to concatenate many strings together?
+:class:`str` and :class:`bytes` objects are immutable, therefore concatenating
+many strings together is inefficient as each concatenation creates a new
+object.  In the general case, the total runtime cost is quadratic in the
+total string length.
+To accumulate many :class:`str` objects, the recommended idiom is to place
+them into a list and call :meth:`str.join` at the end::
+   chunks = []
+   for s in my_strings:
+       chunks.append(s)
+   result = ''.join(chunks)
+(another reasonably efficient idiom is to use :class:`io.StringIO`)
+To accumulate many :class:`bytes` objects, the recommended idiom is to extend
+a :class:`bytearray` object using in-place concatenation (the ``+=`` operator)::
+   result = bytearray()
+   for b in my_bytes_objects:
+       result += b
 Sequences (Tuples/Lists)


    If *k* is ``None``, it is treated like ``1``.
-   .. impl-detail::
-      If *s* and *t* are both strings, some Python implementations such as
-      CPython can usually perform an in-place optimization for assignments of
-      the form ``s = s + t`` or ``s += t``.  When applicable, this optimization
-      makes quadratic run-time much less likely.  This optimization is both
-      version and implementation dependent.  For performance sensitive code, it
-      is preferable to use the :meth:`str.join` method which assures consistent
-      linear concatenation performance across versions and implementations.
+   Concatenating immutable strings always results in a new object.  This means
+   that building up a string by repeated concatenation will have a quadratic
+   runtime cost in the total string length.  To get a linear runtime cost,
+   you must switch to one of the alternatives below:
+   * if concatenating :class:`str` objects, you can build a list and use
+     :meth:`str.join` at the end;
+   * if concatenating :class:`bytes` objects, you can similarly use
+     :meth:`bytes.join`, or you can do in-place concatenation with a
+     :class:`bytearray` object.  :class:`bytearray` objects are mutable and
+     have an efficient overallocation mechanism.
 .. _string-methods:


+The ``count()``, ``find()``, ``rfind()``, ``index()`` and ``rindex()``
+methods of :class:`bytes` and :class:`bytearray` objects now accept an
+integer between 0 and 255 as their first argument.
 New and Improved Modules
     def tell(self):
         return self._file.tell()
-    def truncate(self):
-        self._file.truncate()
+    def truncate(self, size=None):
+        if size is None:
+            self._file.truncate()
+        else:
+            if size > self._max_size:
+                self.rollover()
+            self._file.truncate(size)
     def write(self, s):
         file = self._file


         self.assertRaises(ValueError, use_closed)
+    def test_truncate_with_size_parameter(self):
+        # A SpooledTemporaryFile can be truncated to zero size
+        f = tempfile.SpooledTemporaryFile(max_size=10)
+        f.write(b'abcdefg\n')
+        f.truncate()
+        self.assertFalse(f._rolled)
+        self.assertEqual(f._file.getvalue(), b'')
+        # A SpooledTemporaryFile can be truncated to a specific size
+        f = tempfile.SpooledTemporaryFile(max_size=10)
+        f.write(b'abcdefg\n')
+        f.truncate(4)
+        self.assertFalse(f._rolled)
+        self.assertEqual(f._file.getvalue(), b'abcd')
+        # A SpooledTemporaryFile rolls over if truncated to large size
+        f = tempfile.SpooledTemporaryFile(max_size=10)
+        f.write(b'abcdefg\n')
+        f.truncate(20)
+        self.assertTrue(f._rolled)
+        if has_stat:
+            self.assertEqual(os.fstat(f.fileno()).st_size, 20)


             return attrname.startswith(prefix) and \
                 callable(getattr(testCaseClass, attrname))
-        testFnNames = testFnNames = list(filter(isTestMethod,
-                                                dir(testCaseClass)))
+        testFnNames = list(filter(isTestMethod, dir(testCaseClass)))
         if self.sortTestMethodsUsing:
         return testFnNames
 - Issue #12380: The rjust, ljust and center methods of bytes and bytearray
   now accept a bytearray argument.
+- Issue #9957: SpooledTemporaryFile.truncate() now accepts an optional size
+  parameter, as other file-like objects.  Patch by Ryan Kelly.
 - Issue #13458: Fix a memory leak in the ssl module when decoding a
   certificate with a subjectAltName.  Patch by Robert Xiao.


 posix_unsetenv(PyObject *self, PyObject *args)
     PyObject *name;
     int err;
     if (!PyArg_ParseTuple(args, "O&:unsetenv",
                           PyUnicode_FSConverter, &name))
         return NULL;
+    unsetenv(PyBytes_AS_STRING(name));
     err = unsetenv(PyBytes_AS_STRING(name));
     if (err) {
         return posix_error();
     /* Remove the key from posix_putenv_garbage;
      * this will cause it to be collected.  This has to
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken unsetenv" >&5
+$as_echo_n "checking for broken unsetenv... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+main ()
+int res = unsetenv("DUMMY")
+  ;
+  return 0;
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "#define HAVE_BROKEN_UNSETENV 1" >>confdefs.h
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 for ac_prog in true
   # Extract the first word of "$ac_prog", so it can be a program name with args.
+AC_MSG_CHECKING(for broken unsetenv)
+#include <stdlib.h>
+]], [[int res = unsetenv("DUMMY")]])],
+  [AC_MSG_RESULT(no)],
+  [AC_DEFINE(HAVE_BROKEN_UNSETENV, 1, Define if `unsetenv` does not return an int.)
+   AC_MSG_RESULT(yes)
 dnl check for true
 AC_CHECK_PROGS(TRUE, true, /bin/true)
 /* define to 1 if your sem_getvalue is broken. */
+/* Define if `unsetenv` does not return an int. */
 /* Define this if you have the type _Bool. */
 #undef HAVE_C99_BOOL