Skip to content

Commit 2565ede

Browse files
authored
bpo-38971: Open file in codecs.open() closes if exception raised. (GH-17666)
Open issue in the BPO indicated a desire to make the implementation of codecs.open() at parity with io.open(), which implements a try/except to assure file stream gets closed before an exception is raised.
1 parent 4edc95c commit 2565ede

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

Lib/codecs.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -905,11 +905,16 @@ def open(filename, mode='r', encoding=None, errors='strict', buffering=-1):
905905
file = builtins.open(filename, mode, buffering)
906906
if encoding is None:
907907
return file
908-
info = lookup(encoding)
909-
srw = StreamReaderWriter(file, info.streamreader, info.streamwriter, errors)
910-
# Add attributes to simplify introspection
911-
srw.encoding = encoding
912-
return srw
908+
909+
try:
910+
info = lookup(encoding)
911+
srw = StreamReaderWriter(file, info.streamreader, info.streamwriter, errors)
912+
# Add attributes to simplify introspection
913+
srw.encoding = encoding
914+
return srw
915+
except:
916+
file.close()
917+
raise
913918

914919
def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'):
915920

Lib/test/test_codecs.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,7 @@ def test_stream_bare(self):
11541154
got = ostream.getvalue()
11551155
self.assertEqual(got, unistring)
11561156

1157+
11571158
class EscapeDecodeTest(unittest.TestCase):
11581159
def test_empty(self):
11591160
self.assertEqual(codecs.escape_decode(b""), (b"", 0))
@@ -1725,6 +1726,14 @@ def test_undefined(self):
17251726
self.assertRaises(UnicodeError,
17261727
codecs.decode, b'abc', 'undefined', errors)
17271728

1729+
def test_file_closes_if_lookup_error_raised(self):
1730+
mock_open = mock.mock_open()
1731+
with mock.patch('builtins.open', mock_open) as file:
1732+
with self.assertRaises(LookupError):
1733+
codecs.open(support.TESTFN, 'wt', 'invalid-encoding')
1734+
1735+
file().close.assert_called()
1736+
17281737

17291738
class StreamReaderTest(unittest.TestCase):
17301739

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Open issue in the BPO indicated a desire to make the implementation of
2+
codecs.open() at parity with io.open(), which implements a try/except to
3+
assure file stream gets closed before an exception is raised.

0 commit comments

Comments
 (0)