mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	When trying to write new bytecode, importlib was not catching the IOError
thrown if the file happened to be read-only to keep the failure silent. Fixes issue #7187. Thanks, Dave Malcolm for the report and analysis of the problem.
This commit is contained in:
		
							parent
							
								
									1b184d547f
								
							
						
					
					
						commit
						e52c919d67
					
				
					 4 changed files with 32 additions and 2 deletions
				
			
		|  | @ -526,9 +526,9 @@ def write_bytecode(self, name, data): | |||
|         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: | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| import imp | ||||
| import os | ||||
| import py_compile | ||||
| import stat | ||||
| import sys | ||||
| import unittest | ||||
| 
 | ||||
|  | @ -121,6 +122,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): | ||||
|  | @ -159,6 +164,7 @@ def test_bad_bytecode(self): | |||
|                 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']) | ||||
|  | @ -172,6 +178,26 @@ def test_bad_marshal(self): | |||
|                 self.import_(mapping['_temp'], '_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 | ||||
|  |  | |||
|  | @ -472,6 +472,7 @@ Nick Maclaren | |||
| Don MacMillen | ||||
| Steve Majewski | ||||
| Grzegorz Makarewicz | ||||
| Dave Malcolm | ||||
| Ken Manheimer | ||||
| Vladimir Marangozov | ||||
| David Marek | ||||
|  |  | |||
|  | @ -123,6 +123,9 @@ C-API | |||
| Library | ||||
| ------- | ||||
| 
 | ||||
| - Issue #7187: Importlib would not silence the IOError raised when trying to | ||||
|   write new bytecode when it was made read-only. | ||||
| 
 | ||||
| - Issue #7264: Fix a possible deadlock when deallocating thread-local objects | ||||
|   which are part of a reference cycle. | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Brett Cannon
						Brett Cannon