Skip to content

Commit cee386f

Browse files
committed
Use open() to write the bytecode
And drop the related tests, because we can't test partial writes any more. But, we're now relying on well-tested code.
1 parent c8ba03f commit cee386f

File tree

3 files changed

+3
-73
lines changed

3 files changed

+3
-73
lines changed

Lib/importlib/_bootstrap_external.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@ def _write_atomic(path, data, mode=0o666):
208208
try:
209209
# We first write data to a temporary file, and then use os.replace() to
210210
# perform an atomic rename.
211-
with _io.FileIO(fd, 'wb') as file, _io.BufferedWriter(file) as writer:
212-
writer.write(data)
211+
with open(fd, 'wb') as file:
212+
file.write(data)
213213
_os.replace(path_tmp, path)
214214
except OSError:
215215
try:

Lib/test/test_importlib/test_util.py

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
importlib_util = util.import_importlib('importlib.util')
77

88
import importlib.util
9-
from importlib import _bootstrap_external
109
import os
1110
import pathlib
1211
import string
@@ -788,74 +787,5 @@ def test_complete_multi_phase_init_module(self):
788787
self.run_with_own_gil(script)
789788

790789

791-
class PatchAtomicWrites():
792-
def __init__(self, truncate_at_length=100, never_complete=False):
793-
self.truncate_at_length = truncate_at_length
794-
self.never_complete = never_complete
795-
self.seen_write = False
796-
self._children = []
797-
798-
def __enter__(self):
799-
import _pyio
800-
801-
oldwrite = os.write
802-
803-
# Emulate an os.write that only writes partial data.
804-
def write(fd, data):
805-
if self.seen_write and self.never_complete:
806-
return None
807-
self.seen_write = True
808-
return oldwrite(fd, data[:self.truncate_at_length])
809-
810-
# Need to patch _io to be _pyio, so that io.FileIO is affected by the
811-
# os.write patch.
812-
self.children = [
813-
support.swap_attr(_bootstrap_external, '_io', _pyio),
814-
support.swap_attr(os, 'write', write)
815-
]
816-
for child in self.children:
817-
child.__enter__()
818-
return self
819-
820-
def __exit__(self, exc_type, exc_val, exc_tb):
821-
for child in self.children:
822-
child.__exit__(exc_type, exc_val, exc_tb)
823-
824-
825-
class MiscTests(unittest.TestCase):
826-
827-
def test_atomic_write_retries_incomplete_writes(self):
828-
truncate_at_length = 100
829-
length = truncate_at_length * 2
830-
831-
with PatchAtomicWrites(truncate_at_length=truncate_at_length) as cm:
832-
# Make sure we write something longer than the point where we
833-
# truncate.
834-
content = b'x' * length
835-
_bootstrap_external._write_atomic(os_helper.TESTFN, content)
836-
assert cm.seen_write
837-
838-
assert os.stat(support.os_helper.TESTFN).st_size == length
839-
os.unlink(support.os_helper.TESTFN)
840-
841-
def test_atomic_write_errors_if_unable_to_complete(self):
842-
truncate_at_length = 100
843-
844-
with (
845-
PatchAtomicWrites(
846-
truncate_at_length=truncate_at_length, never_complete=True,
847-
) as cm,
848-
self.assertRaises(OSError)
849-
):
850-
# Make sure we write something longer than the point where we
851-
# truncate.
852-
content = b'x' * (truncate_at_length * 2)
853-
_bootstrap_external._write_atomic(os_helper.TESTFN, content)
854-
assert cm.seen_write
855-
856-
with self.assertRaises(OSError):
857-
os.stat(support.os_helper.TESTFN) # Check that the file did not get written.
858-
859-
860790
if __name__ == '__main__':
861791
unittest.main()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Use ``BufferedWriter`` to ensure that writes to ``.pyc`` files are retried, or an appropriate error is raised.
1+
Use Python's regular file object to ensure that writes to ``.pyc`` files are retried, or an appropriate error is raised.

0 commit comments

Comments
 (0)