blob: 4b6feba24eee5c25c583ae7f1e6c3602b4b1c978 [file] [log] [blame]
Martin v. Löwis4b003072010-03-16 13:19:21 +00001import sys
Brett Cannonbefb14f2009-02-10 02:10:16 +00002import compileall
3import imp
4import os
5import py_compile
6import shutil
7import struct
Brett Cannonbefb14f2009-02-10 02:10:16 +00008import tempfile
Brett Cannonbefb14f2009-02-10 02:10:16 +00009from test import support
10import unittest
Martin v. Löwis4b003072010-03-16 13:19:21 +000011import io
Brett Cannonbefb14f2009-02-10 02:10:16 +000012
13
14class CompileallTests(unittest.TestCase):
15
16 def setUp(self):
17 self.directory = tempfile.mkdtemp()
18 self.source_path = os.path.join(self.directory, '_test.py')
19 self.bc_path = self.source_path + ('c' if __debug__ else 'o')
20 with open(self.source_path, 'w') as file:
21 file.write('x = 123\n')
Matthias Klosec33b9022010-03-16 00:36:26 +000022 self.source_path2 = os.path.join(self.directory, '_test2.py')
23 self.bc_path2 = self.source_path2 + ('c' if __debug__ else 'o')
24 shutil.copyfile(self.source_path, self.source_path2)
Brett Cannonbefb14f2009-02-10 02:10:16 +000025
26 def tearDown(self):
27 shutil.rmtree(self.directory)
28
29 def data(self):
30 with open(self.bc_path, 'rb') as file:
31 data = file.read(8)
32 mtime = int(os.stat(self.source_path).st_mtime)
33 compare = struct.pack('<4sl', imp.get_magic(), mtime)
34 return data, compare
35
36 def recreation_check(self, metadata):
37 """Check that compileall recreates bytecode when the new metadata is
38 used."""
39 if not hasattr(os, 'stat'):
40 return
41 py_compile.compile(self.source_path)
42 self.assertEqual(*self.data())
43 with open(self.bc_path, 'rb') as file:
44 bc = file.read()[len(metadata):]
45 with open(self.bc_path, 'wb') as file:
46 file.write(metadata)
47 file.write(bc)
48 self.assertNotEqual(*self.data())
49 compileall.compile_dir(self.directory, force=False, quiet=True)
50 self.assertTrue(*self.data())
51
52 def test_mtime(self):
53 # Test a change in mtime leads to a new .pyc.
54 self.recreation_check(struct.pack('<4sl', imp.get_magic(), 1))
55
56 def test_magic_number(self):
57 # Test a change in mtime leads to a new .pyc.
58 self.recreation_check(b'\0\0\0\0')
59
Matthias Klosec33b9022010-03-16 00:36:26 +000060 def test_compile_files(self):
61 # Test compiling a single file, and complete directory
62 for fn in (self.bc_path, self.bc_path2):
63 try:
64 os.unlink(fn)
65 except:
66 pass
67 compileall.compile_file(self.source_path, force=False, quiet=True)
68 self.assertTrue(os.path.isfile(self.bc_path) \
69 and not os.path.isfile(self.bc_path2))
70 os.unlink(self.bc_path)
71 compileall.compile_dir(self.directory, force=False, quiet=True)
72 self.assertTrue(os.path.isfile(self.bc_path) \
73 and os.path.isfile(self.bc_path2))
74 os.unlink(self.bc_path)
75 os.unlink(self.bc_path2)
Brett Cannonbefb14f2009-02-10 02:10:16 +000076
Martin v. Löwis4b003072010-03-16 13:19:21 +000077class EncodingTest(unittest.TestCase):
78 'Issue 6716: compileall should escape source code when printing errors to stdout.'
79
80 def setUp(self):
81 self.directory = tempfile.mkdtemp()
82 self.source_path = os.path.join(self.directory, '_test.py')
83 with open(self.source_path, 'w', encoding='utf-8') as file:
84 file.write('# -*- coding: utf-8 -*-\n')
85 file.write('print u"\u20ac"\n')
86
87 def tearDown(self):
88 shutil.rmtree(self.directory)
89
90 def test_error(self):
91 try:
92 orig_stdout = sys.stdout
93 sys.stdout = io.TextIOWrapper(io.BytesIO(),encoding='ascii')
94 compileall.compile_dir(self.directory)
95 finally:
96 sys.stdout = orig_stdout
97
Brett Cannonbefb14f2009-02-10 02:10:16 +000098def test_main():
Martin v. Löwis4b003072010-03-16 13:19:21 +000099 support.run_unittest(CompileallTests,
100 EncodingTest)
Brett Cannonbefb14f2009-02-10 02:10:16 +0000101
102
103if __name__ == "__main__":
104 test_main()