Skip to content

Commit d96619c

Browse files
Issue #15204: Deprecated the 'U' mode in file-like objects.
1 parent 94cbcb9 commit d96619c

File tree

13 files changed

+45
-13
lines changed

13 files changed

+45
-13
lines changed

Doc/library/fileinput.rst

+3
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ available for subclassing as well:
160160
.. versionchanged:: 3.2
161161
Can be used as a context manager.
162162

163+
.. deprecated:: 3.4
164+
The ``'rU'`` and ``'U'`` modes.
165+
163166

164167
**Optional in-place filtering:** if the keyword argument ``inplace=True`` is
165168
passed to :func:`fileinput.input` or to the :class:`FileInput` constructor, the

Doc/library/functions.rst

+4-2
Original file line numberDiff line numberDiff line change
@@ -872,8 +872,7 @@ are always available. They are listed here in alphabetical order.
872872
``'b'`` binary mode
873873
``'t'`` text mode (default)
874874
``'+'`` open a disk file for updating (reading and writing)
875-
``'U'`` universal newlines mode (for backwards compatibility; should
876-
not be used in new code)
875+
``'U'`` :term:`universal newlines` mode (deprecated)
877876
========= ===============================================================
878877

879878
The default mode is ``'r'`` (open for reading text, synonym of ``'rt'``).
@@ -1029,6 +1028,9 @@ are always available. They are listed here in alphabetical order.
10291028
.. versionchanged:: 3.4
10301029
The file is now non-inheritable.
10311030

1031+
.. deprecated-removed:: 3.4 4.0
1032+
The ``'U'`` mode.
1033+
10321034

10331035
.. XXX works for bytes too, but should it?
10341036
.. function:: ord(c)

Doc/library/zipfile.rst

+3
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ ZipFile Objects
234234
or a :class:`ZipInfo` object. You will appreciate this when trying to read a
235235
ZIP file that contains members with duplicate names.
236236

237+
.. deprecated-removed:: 3.4 3.6
238+
The ``'U'`` or ``'rU'`` mode. Use :class:`io.TextIOWrapper` for reading
239+
compressed text files in :term:`universal newlines` mode.
237240

238241
.. method:: ZipFile.extract(member, path=None, pwd=None)
239242

Lib/_pyio.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
6262
'b' binary mode
6363
't' text mode (default)
6464
'+' open a disk file for updating (reading and writing)
65-
'U' universal newline mode (for backwards compatibility; unneeded
66-
for new code)
65+
'U' universal newline mode (deprecated)
6766
========= ===============================================================
6867
6968
The default mode is 'rt' (open for reading text). For binary random
@@ -79,6 +78,10 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
7978
returned as strings, the bytes having been first decoded using a
8079
platform-dependent encoding or using the specified encoding if given.
8180
81+
'U' mode is deprecated and will raise an exception in future versions
82+
of Python. It has no effect in Python 3. Use newline to control
83+
universal newlines mode.
84+
8285
buffering is an optional integer used to set the buffering policy.
8386
Pass 0 to switch buffering off (only allowed in binary mode), 1 to select
8487
line buffering (only usable in text mode), and an integer > 1 to indicate
@@ -174,6 +177,9 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
174177
if "U" in modes:
175178
if creating or writing or appending:
176179
raise ValueError("can't use U and writing mode at once")
180+
import warnings
181+
warnings.warn("'U' mode is deprecated",
182+
DeprecationWarning, 2)
177183
reading = True
178184
if text and binary:
179185
raise ValueError("can't have text and binary mode at once")

Lib/fileinput.py

+4
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ def __init__(self, files=None, inplace=False, backup="", bufsize=0,
222222
if mode not in ('r', 'rU', 'U', 'rb'):
223223
raise ValueError("FileInput opening mode must be one of "
224224
"'r', 'rU', 'U' and 'rb'")
225+
if 'U' in mode:
226+
import warnings
227+
warnings.warn("Use of 'U' mode is deprecated",
228+
DeprecationWarning, 2)
225229
self._mode = mode
226230
if openhook:
227231
if inplace:

Lib/imp.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def source_from_cache(path):
103103
def get_suffixes():
104104
"""**DEPRECATED**"""
105105
extensions = [(s, 'rb', C_EXTENSION) for s in machinery.EXTENSION_SUFFIXES]
106-
source = [(s, 'U', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES]
106+
source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES]
107107
bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES]
108108

109109
return extensions + source + bytecode
@@ -297,7 +297,7 @@ def find_module(name, path=None):
297297
raise ImportError(_ERR_MSG.format(name), name=name)
298298

299299
encoding = None
300-
if mode == 'U':
300+
if 'b' not in mode:
301301
with open(file_path, 'rb') as file:
302302
encoding = tokenize.detect_encoding(file.readline)[0]
303303
file = open(file_path, mode, encoding=encoding)

Lib/test/test_imp.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def test_issue5604(self):
165165
self.assertIsNotNone(file)
166166
self.assertTrue(filename[:-3].endswith(temp_mod_name))
167167
self.assertEqual(info[0], '.py')
168-
self.assertEqual(info[1], 'U')
168+
self.assertEqual(info[1], 'r')
169169
self.assertEqual(info[2], imp.PY_SOURCE)
170170

171171
mod = imp.load_module(temp_mod_name, file, filename, info)

Lib/zipfile.py

+4
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,10 @@ def open(self, name, mode="r", pwd=None):
11171117
"""Return file-like object for 'name'."""
11181118
if mode not in ("r", "U", "rU"):
11191119
raise RuntimeError('open() requires mode "r", "U", or "rU"')
1120+
if 'U' in mode:
1121+
import warnings
1122+
warnings.warn("'U' mode is deprecated",
1123+
DeprecationWarning, 2)
11201124
if pwd and not isinstance(pwd, bytes):
11211125
raise TypeError("pwd: expected bytes, got %s" % type(pwd))
11221126
if not self.fp:

Misc/NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ Core and Builtins
6868
Library
6969
-------
7070

71+
- Issue #15204: Deprecated the 'U' mode in file-like objects.
72+
7173
- Issue #17810: Implement PEP 3154, pickle protocol 4.
7274

7375
- Issue #19668: Added support for the cp1125 encoding.

Modules/_io/_iomodule.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ PyDoc_STRVAR(open_doc,
126126
"'b' binary mode\n"
127127
"'t' text mode (default)\n"
128128
"'+' open a disk file for updating (reading and writing)\n"
129-
"'U' universal newline mode (for backwards compatibility; unneeded\n"
130-
" for new code)\n"
129+
"'U' universal newline mode (deprecated)\n"
131130
"========= ===============================================================\n"
132131
"\n"
133132
"The default mode is 'rt' (open for reading text). For binary random\n"
@@ -143,6 +142,10 @@ PyDoc_STRVAR(open_doc,
143142
"returned as strings, the bytes having been first decoded using a\n"
144143
"platform-dependent encoding or using the specified encoding if given.\n"
145144
"\n"
145+
"'U' mode is deprecated and will raise an exception in future versions\n"
146+
"of Python. It has no effect in Python 3. Use newline to control\n"
147+
"universal newlines mode.\n"
148+
"\n"
146149
"buffering is an optional integer used to set the buffering policy.\n"
147150
"Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n"
148151
"line buffering (only usable in text mode), and an integer > 1 to indicate\n"
@@ -310,6 +313,9 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds)
310313
"can't use U and writing mode at once");
311314
return NULL;
312315
}
316+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
317+
"'U' mode is deprecated", 1) < 0)
318+
return NULL;
313319
reading = 1;
314320
}
315321

Tools/iobench/iobench.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def text_open(fn, mode, encoding=None):
2424
try:
2525
return open(fn, mode, encoding=encoding or TEXT_ENCODING)
2626
except TypeError:
27+
if 'r' in mode:
28+
mode += 'U' # 'U' mode is needed only in Python 2.x
2729
return open(fn, mode)
2830

2931
def get_file_sizes():
@@ -380,7 +382,7 @@ def prepare_files():
380382
f.write(os.urandom(size))
381383
# Text files
382384
chunk = []
383-
with text_open(__file__, "rU", encoding='utf8') as f:
385+
with text_open(__file__, "r", encoding='utf8') as f:
384386
for line in f:
385387
if line.startswith("# <iobench text chunk marker>"):
386388
break

Tools/scripts/diff.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ def main():
3838

3939
fromdate = file_mtime(fromfile)
4040
todate = file_mtime(tofile)
41-
with open(fromfile, 'U') as ff:
41+
with open(fromfile) as ff:
4242
fromlines = ff.readlines()
43-
with open(tofile, 'U') as tf:
43+
with open(tofile) as tf:
4444
tolines = tf.readlines()
4545

4646
if options.u:

Tools/scripts/ndiff.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def fail(msg):
6060
# couldn't be opened
6161
def fopen(fname):
6262
try:
63-
return open(fname, 'U')
63+
return open(fname)
6464
except IOError as detail:
6565
return fail("couldn't open " + fname + ": " + str(detail))
6666

0 commit comments

Comments
 (0)