blob: 4a6caa571875d7705dfa2925604116499b12e399 [file] [log] [blame]
Brett Cannondf960682013-06-15 14:07:21 -04001import importlib.util
Meador Inge6f166602011-11-25 23:36:48 -06002import os
3import py_compile
4import shutil
Brett Cannonedfd6ae2013-04-14 12:48:15 -04005import stat
Barry Warsaw9d98c9b2014-12-01 18:15:26 -05006import sys
Meador Inge6f166602011-11-25 23:36:48 -06007import tempfile
8import unittest
9
Berker Peksaga42ad6b2014-09-01 12:33:12 +030010from test import support
11
Meador Inge6f166602011-11-25 23:36:48 -060012
13class PyCompileTests(unittest.TestCase):
14
15 def setUp(self):
16 self.directory = tempfile.mkdtemp()
17 self.source_path = os.path.join(self.directory, '_test.py')
18 self.pyc_path = self.source_path + 'c'
Brett Cannondf960682013-06-15 14:07:21 -040019 self.cache_path = importlib.util.cache_from_source(self.source_path)
Meador Ingefb36b3f2011-11-26 11:37:02 -060020 self.cwd_drive = os.path.splitdrive(os.getcwd())[0]
21 # In these tests we compute relative paths. When using Windows, the
22 # current working directory path and the 'self.source_path' might be
23 # on different drives. Therefore we need to switch to the drive where
24 # the temporary source file lives.
25 drive = os.path.splitdrive(self.source_path)[0]
26 if drive:
27 os.chdir(drive)
Meador Inge6f166602011-11-25 23:36:48 -060028 with open(self.source_path, 'w') as file:
29 file.write('x = 123\n')
30
31 def tearDown(self):
32 shutil.rmtree(self.directory)
Meador Ingefb36b3f2011-11-26 11:37:02 -060033 if self.cwd_drive:
34 os.chdir(self.cwd_drive)
Meador Inge6f166602011-11-25 23:36:48 -060035
36 def test_absolute_path(self):
37 py_compile.compile(self.source_path, self.pyc_path)
38 self.assertTrue(os.path.exists(self.pyc_path))
39 self.assertFalse(os.path.exists(self.cache_path))
40
Brett Cannon33915eb2013-06-14 18:33:00 -040041 def test_do_not_overwrite_symlinks(self):
42 # In the face of a cfile argument being a symlink, bail out.
43 # Issue #17222
44 try:
45 os.symlink(self.pyc_path + '.actual', self.pyc_path)
Brett Cannon0b16b0d2013-06-14 22:50:57 -040046 except (NotImplementedError, OSError):
Brett Cannon33915eb2013-06-14 18:33:00 -040047 self.skipTest('need to be able to create a symlink for a file')
48 else:
49 assert os.path.islink(self.pyc_path)
50 with self.assertRaises(FileExistsError):
51 py_compile.compile(self.source_path, self.pyc_path)
52
53 @unittest.skipIf(not os.path.exists(os.devnull) or os.path.isfile(os.devnull),
54 'requires os.devnull and for it to be a non-regular file')
55 def test_do_not_overwrite_nonregular_files(self):
56 # In the face of a cfile argument being a non-regular file, bail out.
57 # Issue #17222
58 with self.assertRaises(FileExistsError):
59 py_compile.compile(self.source_path, os.devnull)
60
Meador Inge6f166602011-11-25 23:36:48 -060061 def test_cache_path(self):
62 py_compile.compile(self.source_path)
63 self.assertTrue(os.path.exists(self.cache_path))
64
Meador Inge22b9b372011-11-28 09:27:32 -060065 def test_cwd(self):
Serhiy Storchaka2a23adf2015-09-06 14:13:25 +030066 with support.change_cwd(self.directory):
67 py_compile.compile(os.path.basename(self.source_path),
68 os.path.basename(self.pyc_path))
Meador Inge22b9b372011-11-28 09:27:32 -060069 self.assertTrue(os.path.exists(self.pyc_path))
70 self.assertFalse(os.path.exists(self.cache_path))
71
Meador Inge6f166602011-11-25 23:36:48 -060072 def test_relative_path(self):
73 py_compile.compile(os.path.relpath(self.source_path),
74 os.path.relpath(self.pyc_path))
75 self.assertTrue(os.path.exists(self.pyc_path))
76 self.assertFalse(os.path.exists(self.cache_path))
77
Christian Heimes349b04e2013-10-25 09:21:51 +020078 @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
79 'non-root user required')
Brett Cannon51460cc2013-04-24 16:34:07 -040080 @unittest.skipIf(os.name == 'nt',
81 'cannot control directory permissions on Windows')
Brett Cannonedfd6ae2013-04-14 12:48:15 -040082 def test_exceptions_propagate(self):
83 # Make sure that exceptions raised thanks to issues with writing
84 # bytecode.
85 # http://bugs.python.org/issue17244
86 mode = os.stat(self.directory)
87 os.chmod(self.directory, stat.S_IREAD)
88 try:
89 with self.assertRaises(IOError):
90 py_compile.compile(self.source_path, self.pyc_path)
91 finally:
92 os.chmod(self.directory, mode.st_mode)
93
Berker Peksag31f8a672014-08-22 20:17:32 +030094 def test_bad_coding(self):
95 bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py')
Berker Peksaga7614d02014-09-01 12:29:53 +030096 with support.captured_stderr():
97 self.assertIsNone(py_compile.compile(bad_coding, doraise=False))
Berker Peksag0242f792014-08-22 20:52:15 +030098 self.assertFalse(os.path.exists(
99 importlib.util.cache_from_source(bad_coding)))
Meador Inge6f166602011-11-25 23:36:48 -0600100
Brett Cannon9d2a01f2015-04-13 16:28:11 -0400101 @unittest.skipIf(sys.flags.optimize > 0, 'test does not work with -O')
Barry Warsaw2a413852014-12-01 17:10:10 -0500102 def test_double_dot_no_clobber(self):
103 # http://bugs.python.org/issue22966
104 # py_compile foo.bar.py -> __pycache__/foo.cpython-34.pyc
105 weird_path = os.path.join(self.directory, 'foo.bar.py')
106 cache_path = importlib.util.cache_from_source(weird_path)
107 pyc_path = weird_path + 'c'
Barry Warsaweb2763d2014-12-02 11:30:43 -0500108 head, tail = os.path.split(cache_path)
109 penultimate_tail = os.path.basename(head)
Barry Warsaw2a413852014-12-01 17:10:10 -0500110 self.assertEqual(
Barry Warsaweb2763d2014-12-02 11:30:43 -0500111 os.path.join(penultimate_tail, tail),
112 os.path.join(
113 '__pycache__',
114 'foo.bar.{}.pyc'.format(sys.implementation.cache_tag)))
Barry Warsaw2a413852014-12-01 17:10:10 -0500115 with open(weird_path, 'w') as file:
116 file.write('x = 123\n')
117 py_compile.compile(weird_path)
118 self.assertTrue(os.path.exists(cache_path))
119 self.assertFalse(os.path.exists(pyc_path))
120
Brett Cannonf299abd2015-04-13 14:21:02 -0400121 def test_optimization_path(self):
122 # Specifying optimized bytecode should lead to a path reflecting that.
123 self.assertIn('opt-2', py_compile.compile(self.source_path, optimize=2))
124
Barry Warsaw2a413852014-12-01 17:10:10 -0500125
Meador Inge6f166602011-11-25 23:36:48 -0600126if __name__ == "__main__":
Brett Cannon255fb3e2013-04-14 12:51:36 -0400127 unittest.main()