1import compileall 2import imp 3import os 4import py_compile 5import shutil 6import struct 7import tempfile 8from test import test_support 9import unittest 10 11 12class CompileallTests(unittest.TestCase): 13 14 def setUp(self): 15 self.directory = tempfile.mkdtemp() 16 self.source_path = os.path.join(self.directory, '_test.py') 17 self.bc_path = self.source_path + ('c' if __debug__ else 'o') 18 with open(self.source_path, 'w') as file: 19 file.write('x = 123\n') 20 self.source_path2 = os.path.join(self.directory, '_test2.py') 21 self.bc_path2 = self.source_path2 + ('c' if __debug__ else 'o') 22 shutil.copyfile(self.source_path, self.source_path2) 23 24 def tearDown(self): 25 shutil.rmtree(self.directory) 26 27 def data(self): 28 with open(self.bc_path, 'rb') as file: 29 data = file.read(8) 30 mtime = int(os.stat(self.source_path).st_mtime) 31 compare = struct.pack('<4sl', imp.get_magic(), mtime) 32 return data, compare 33 34 @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()') 35 def recreation_check(self, metadata): 36 """Check that compileall recreates bytecode when the new metadata is 37 used.""" 38 py_compile.compile(self.source_path) 39 self.assertEqual(*self.data()) 40 with open(self.bc_path, 'rb') as file: 41 bc = file.read()[len(metadata):] 42 with open(self.bc_path, 'wb') as file: 43 file.write(metadata) 44 file.write(bc) 45 self.assertNotEqual(*self.data()) 46 compileall.compile_dir(self.directory, force=False, quiet=True) 47 self.assertTrue(*self.data()) 48 49 def test_mtime(self): 50 # Test a change in mtime leads to a new .pyc. 51 self.recreation_check(struct.pack('<4sl', imp.get_magic(), 1)) 52 53 def test_magic_number(self): 54 # Test a change in mtime leads to a new .pyc. 55 self.recreation_check(b'\0\0\0\0') 56 57 def test_compile_files(self): 58 # Test compiling a single file, and complete directory 59 for fn in (self.bc_path, self.bc_path2): 60 try: 61 os.unlink(fn) 62 except: 63 pass 64 compileall.compile_file(self.source_path, force=False, quiet=True) 65 self.assertTrue(os.path.isfile(self.bc_path) \ 66 and not os.path.isfile(self.bc_path2)) 67 os.unlink(self.bc_path) 68 compileall.compile_dir(self.directory, force=False, quiet=True) 69 self.assertTrue(os.path.isfile(self.bc_path) \ 70 and os.path.isfile(self.bc_path2)) 71 os.unlink(self.bc_path) 72 os.unlink(self.bc_path2) 73 74def test_main(): 75 test_support.run_unittest(CompileallTests) 76 77 78if __name__ == "__main__": 79 test_main() 80