]> granicus.if.org Git - python/commitdiff
- Issue #2091: error correctly on open() with mode 'U' and '+'
authorRobert Collins <rbtcollins@hp.com>
Sat, 25 Jul 2015 18:43:13 +0000 (06:43 +1200)
committerRobert Collins <rbtcollins@hp.com>
Sat, 25 Jul 2015 18:43:13 +0000 (06:43 +1200)
open() accepted a 'U' mode string containing '+', but 'U' can only be used with
'r'. Patch from Jeff Balogh and John O'Connor.

Lib/_pyio.py
Lib/test/test_file.py
Misc/NEWS
Modules/_io/_iomodule.c

index 50ad9ff9962ee16f3c066b99f699690e082bafe4..33d8a3f8e0b38a263494ac0907173543f62fb508 100644 (file)
@@ -181,8 +181,8 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
     text = "t" in modes
     binary = "b" in modes
     if "U" in modes:
-        if creating or writing or appending:
-            raise ValueError("can't use U and writing mode at once")
+        if creating or writing or appending or updating:
+            raise ValueError("mode U cannot be combined with 'x', 'w', 'a', or '+'")
         import warnings
         warnings.warn("'U' mode is deprecated",
                       DeprecationWarning, 2)
index d54e9761434b1960720bce75e9918a41b0fb1983..94f189a4dcd0b6e2b1a0b6adc56a1e8b01fd6639 100644 (file)
@@ -139,7 +139,7 @@ class OtherFileTests:
 
     def testModeStrings(self):
         # check invalid mode strings
-        for mode in ("", "aU", "wU+"):
+        for mode in ("", "aU", "wU+", "U+", "+U", "rU+"):
             try:
                 f = self.open(TESTFN, mode)
             except ValueError:
index 81d5f30f81abe474d843ac2349cdbcd4208d65e5..f85eb163434e19c741cbc5070474fee5731aafbc 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -15,6 +15,9 @@ Library
 
 - Issue #13938: 2to3 converts StringTypes to a tuple. Patch from Mark Hammond.
 
+- Issue #2091: open() accepted a 'U' mode string containing '+', but 'U' can
+  only be used with 'r'. Patch from Jeff Balogh and John O'Connor.
+
 - Issue #8585: improved tests for zipimporter2. Patch from Mark Lawrence.
 
 - Issue #18622: unittest.mock.mock_open().reset_mock would recurse infinitely.
index 528bcd4ac10f2800df1c830f5bd27bbbdc6cb8f7..1c2d3a0c6ccaa1eeba4e6040009e689149fd6f53 100644 (file)
@@ -248,8 +248,8 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode,
     _Py_IDENTIFIER(close);
 
     if (!PyUnicode_Check(file) &&
-       !PyBytes_Check(file) &&
-       !PyNumber_Check(file)) {
+        !PyBytes_Check(file) &&
+        !PyNumber_Check(file)) {
         PyErr_Format(PyExc_TypeError, "invalid file: %R", file);
         return NULL;
     }
@@ -307,9 +307,9 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode,
 
     /* Parameters validation */
     if (universal) {
-        if (writing || appending) {
+        if (creating || writing || appending || updating) {
             PyErr_SetString(PyExc_ValueError,
-                            "can't use U and writing mode at once");
+                            "mode U cannot be combined with x', 'w', 'a', or '+'");
             return NULL;
         }
         if (PyErr_WarnEx(PyExc_DeprecationWarning,
@@ -437,10 +437,10 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode,
 
     /* wraps into a TextIOWrapper */
     wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type,
-                                   "Osssi",
-                                   buffer,
-                                   encoding, errors, newline,
-                                   line_buffering);
+                                    "Osssi",
+                                    buffer,
+                                    encoding, errors, newline,
+                                    line_buffering);
     if (wrapper == NULL)
         goto error;
     result = wrapper;