summaryrefslogtreecommitdiffstats
path: root/Lib/importlib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/importlib')
-rw-r--r--Lib/importlib/_bootstrap.py4
-rw-r--r--Lib/importlib/test/source/test_file_loader.py26
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