diff options
Diffstat (limited to 'Lib/importlib')
-rw-r--r-- | Lib/importlib/_bootstrap.py | 4 | ||||
-rw-r--r-- | Lib/importlib/test/source/test_file_loader.py | 26 |
2 files changed, 28 insertions, 2 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 24bcff2..03350b5 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -522,9 +522,9 @@ class _PyPycFileLoader(PyPycLoader, _PyFileLoader): bytecode_path = self.bytecode_path(name) if not bytecode_path: bytecode_path = self._base_path + _suffix_list(imp.PY_COMPILED)[0] - file = _io.FileIO(bytecode_path, 'w') # Assuming bytes. try: - with _closing(file) as bytecode_file: + # Assuming bytes. + with _closing(_io.FileIO(bytecode_path, 'w')) as bytecode_file: bytecode_file.write(data) return True except IOError as exc: diff --git a/Lib/importlib/test/source/test_file_loader.py b/Lib/importlib/test/source/test_file_loader.py index 0384e7d..8b6efbf 100644 --- a/Lib/importlib/test/source/test_file_loader.py +++ b/Lib/importlib/test/source/test_file_loader.py @@ -6,6 +6,7 @@ from . import util as source_util import imp import os import py_compile +import stat import sys import unittest @@ -119,6 +120,10 @@ class BadBytecodeTest(unittest.TestCase): But if the marshal data is bad, even if the magic number and timestamp work, a ValueError is raised and the source is not used [bad marshal]. + The case of not being able to write out the bytecode must also be handled + as it's possible it was made read-only. In that instance the attempt to + write the bytecode should fail silently [bytecode read-only]. + """ def import_(self, file, module_name): @@ -157,6 +162,7 @@ class BadBytecodeTest(unittest.TestCase): self.assertEqual(bytecode_file.read(4), source_timestamp) # [bad marshal] + @source_util.writes_bytecode_files def test_bad_marshal(self): with source_util.create_modules('_temp') as mapping: bytecode_path = source_util.bytecode_path(mapping['_temp']) @@ -170,6 +176,26 @@ class BadBytecodeTest(unittest.TestCase): '_temp') self.assertTrue('_temp' not in sys.modules) + # [bytecode read-only] + @source_util.writes_bytecode_files + def test_read_only_bytecode(self): + with source_util.create_modules('_temp') as mapping: + # Create bytecode that will need to be re-created. + py_compile.compile(mapping['_temp']) + bytecode_path = source_util.bytecode_path(mapping['_temp']) + with open(bytecode_path, 'r+b') as bytecode_file: + bytecode_file.seek(0) + bytecode_file.write(b'\x00\x00\x00\x00') + # Make the bytecode read-only. + os.chmod(bytecode_path, + stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) + try: + # Should not raise IOError! + self.import_(mapping['_temp'], '_temp') + finally: + # Make writable for eventual clean-up. + os.chmod(bytecode_path, stat.S_IWUSR) + def test_main(): from test.support import run_unittest |