Skip to content

Commit 655759b

Browse files
committed
gh-133036: deprecate codecs.open
1 parent 4f18916 commit 655759b

File tree

5 files changed

+34
-14
lines changed

5 files changed

+34
-14
lines changed

Doc/library/codecs.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ wider range of codecs when working with binary files:
208208
.. versionchanged:: 3.11
209209
The ``'U'`` mode has been removed.
210210

211+
.. deprecated:: next
212+
213+
:func:`codecs.open` has been superseded by :func:`open`.
214+
211215

212216
.. function:: EncodedFile(file, data_encoding, file_encoding=None, errors='strict')
213217

Doc/whatsnew/3.14.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,10 @@ Deprecated
15751575
as a single positional argument.
15761576
(Contributed by Serhiy Storchaka in :gh:`109218`.)
15771577

1578+
* :mod:`codecs`:
1579+
:func:`codecs.open` is now deprecated. Use :func:`open` instead.
1580+
(Contributed by Inada Naoki in :gh:`133036`.)
1581+
15781582
* :mod:`functools`:
15791583
Calling the Python implementation of :func:`functools.reduce` with *function*
15801584
or *sequence* as keyword arguments is now deprecated.

Lib/codecs.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,6 @@ def __reduce_ex__(self, proto):
884884
### Shortcuts
885885

886886
def open(filename, mode='r', encoding=None, errors='strict', buffering=-1):
887-
888887
""" Open an encoded file using the given mode and return
889888
a wrapped version providing transparent encoding/decoding.
890889
@@ -912,8 +911,11 @@ def open(filename, mode='r', encoding=None, errors='strict', buffering=-1):
912911
.encoding which allows querying the used encoding. This
913912
attribute is only available if an encoding was specified as
914913
parameter.
915-
916914
"""
915+
import warnings
916+
warnings.warn("codecs.open() is deprecated. Use open() instead.",
917+
DeprecationWarning, stacklevel=2)
918+
917919
if encoding is not None and \
918920
'b' not in mode:
919921
# Force opening of the file in binary mode

Lib/test/test_codecs.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import unittest
88
import encodings
99
from unittest import mock
10+
import warnings
1011

1112
from test import support
1213
from test.support import os_helper
@@ -28,6 +29,13 @@
2829
else:
2930
SIZEOF_WCHAR_T = ctypes.sizeof(ctypes.c_wchar)
3031

32+
def codecs_open_nowarn(filename, mode='r', encoding=None, errors='strict', buffering=-1):
33+
with warnings.catch_warnings():
34+
warnings.simplefilter("ignore")
35+
return codecs.open(
36+
filename, mode, encoding=encoding, errors=errors,
37+
buffering=buffering)
38+
3139
def coding_checker(self, coder):
3240
def check(input, expect):
3341
self.assertEqual(coder(input), (expect, len(input)))
@@ -719,19 +727,19 @@ def test_bug691291(self):
719727
self.addCleanup(os_helper.unlink, os_helper.TESTFN)
720728
with open(os_helper.TESTFN, 'wb') as fp:
721729
fp.write(s)
722-
with codecs.open(os_helper.TESTFN, 'r',
730+
with codecs_open_nowarn(os_helper.TESTFN, 'r',
723731
encoding=self.encoding) as reader:
724732
self.assertEqual(reader.read(), s1)
725733

726734
def test_invalid_modes(self):
727735
for mode in ('U', 'rU', 'r+U'):
728736
with self.assertRaises(ValueError) as cm:
729-
codecs.open(os_helper.TESTFN, mode, encoding=self.encoding)
737+
codecs_open_nowarn(os_helper.TESTFN, mode, encoding=self.encoding)
730738
self.assertIn('invalid mode', str(cm.exception))
731739

732740
for mode in ('rt', 'wt', 'at', 'r+t'):
733741
with self.assertRaises(ValueError) as cm:
734-
codecs.open(os_helper.TESTFN, mode, encoding=self.encoding)
742+
codecs_open_nowarn(os_helper.TESTFN, mode, encoding=self.encoding)
735743
self.assertIn("can't have text and binary mode at once",
736744
str(cm.exception))
737745

@@ -1844,9 +1852,9 @@ def test_all(self):
18441852
def test_open(self):
18451853
self.addCleanup(os_helper.unlink, os_helper.TESTFN)
18461854
for mode in ('w', 'r', 'r+', 'w+', 'a', 'a+'):
1847-
with self.subTest(mode), \
1848-
codecs.open(os_helper.TESTFN, mode, 'ascii') as file:
1849-
self.assertIsInstance(file, codecs.StreamReaderWriter)
1855+
with self.subTest(mode), self.assertWarns(DeprecationWarning):
1856+
with codecs.open(os_helper.TESTFN, mode, 'ascii') as file:
1857+
self.assertIsInstance(file, codecs.StreamReaderWriter)
18501858

18511859
def test_undefined(self):
18521860
self.assertRaises(UnicodeError, codecs.encode, 'abc', 'undefined')
@@ -1863,7 +1871,7 @@ def test_file_closes_if_lookup_error_raised(self):
18631871
mock_open = mock.mock_open()
18641872
with mock.patch('builtins.open', mock_open) as file:
18651873
with self.assertRaises(LookupError):
1866-
codecs.open(os_helper.TESTFN, 'wt', 'invalid-encoding')
1874+
codecs_open_nowarn(os_helper.TESTFN, 'wt', 'invalid-encoding')
18671875

18681876
file().close.assert_called()
18691877

@@ -2883,7 +2891,7 @@ def test_seek0(self):
28832891
self.addCleanup(os_helper.unlink, os_helper.TESTFN)
28842892
for encoding in tests:
28852893
# Check if the BOM is written only once
2886-
with codecs.open(os_helper.TESTFN, 'w+', encoding=encoding) as f:
2894+
with codecs_open_nowarn(os_helper.TESTFN, 'w+', encoding=encoding) as f:
28872895
f.write(data)
28882896
f.write(data)
28892897
f.seek(0)
@@ -2892,7 +2900,7 @@ def test_seek0(self):
28922900
self.assertEqual(f.read(), data * 2)
28932901

28942902
# Check that the BOM is written after a seek(0)
2895-
with codecs.open(os_helper.TESTFN, 'w+', encoding=encoding) as f:
2903+
with codecs_open_nowarn(os_helper.TESTFN, 'w+', encoding=encoding) as f:
28962904
f.write(data[0])
28972905
self.assertNotEqual(f.tell(), 0)
28982906
f.seek(0)
@@ -2901,7 +2909,7 @@ def test_seek0(self):
29012909
self.assertEqual(f.read(), data)
29022910

29032911
# (StreamWriter) Check that the BOM is written after a seek(0)
2904-
with codecs.open(os_helper.TESTFN, 'w+', encoding=encoding) as f:
2912+
with codecs_open_nowarn(os_helper.TESTFN, 'w+', encoding=encoding) as f:
29052913
f.writer.write(data[0])
29062914
self.assertNotEqual(f.writer.tell(), 0)
29072915
f.writer.seek(0)
@@ -2911,7 +2919,7 @@ def test_seek0(self):
29112919

29122920
# Check that the BOM is not written after a seek() at a position
29132921
# different than the start
2914-
with codecs.open(os_helper.TESTFN, 'w+', encoding=encoding) as f:
2922+
with codecs_open_nowarn(os_helper.TESTFN, 'w+', encoding=encoding) as f:
29152923
f.write(data)
29162924
f.seek(f.tell())
29172925
f.write(data)
@@ -2920,7 +2928,7 @@ def test_seek0(self):
29202928

29212929
# (StreamWriter) Check that the BOM is not written after a seek()
29222930
# at a position different than the start
2923-
with codecs.open(os_helper.TESTFN, 'w+', encoding=encoding) as f:
2931+
with codecs_open_nowarn(os_helper.TESTFN, 'w+', encoding=encoding) as f:
29242932
f.writer.write(data)
29252933
f.writer.seek(f.writer.tell())
29262934
f.writer.write(data)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:func:`codecs.open` is now deprecated. Use :func:`open` instead. Contributed
2+
by Inada Naoki.

0 commit comments

Comments
 (0)