1"""Tests for distutils.command.build_py.""" 2 3import os 4import sys 5import unittest 6 7from distutils.command.build_py import build_py 8from distutils.core import Distribution 9from distutils.errors import DistutilsFileError 10 11from distutils.tests import support 12from test.support import run_unittest, requires_subprocess 13 14 15class BuildPyTestCase(support.TempdirManager, 16 support.LoggingSilencer, 17 unittest.TestCase): 18 19 def test_package_data(self): 20 sources = self.mkdtemp() 21 f = open(os.path.join(sources, "__init__.py"), "w") 22 try: 23 f.write("# Pretend this is a package.") 24 finally: 25 f.close() 26 f = open(os.path.join(sources, "README.txt"), "w") 27 try: 28 f.write("Info about this package") 29 finally: 30 f.close() 31 32 destination = self.mkdtemp() 33 34 dist = Distribution({"packages": ["pkg"], 35 "package_dir": {"pkg": sources}}) 36 # script_name need not exist, it just need to be initialized 37 dist.script_name = os.path.join(sources, "setup.py") 38 dist.command_obj["build"] = support.DummyCommand( 39 force=0, 40 build_lib=destination) 41 dist.packages = ["pkg"] 42 dist.package_data = {"pkg": ["README.txt"]} 43 dist.package_dir = {"pkg": sources} 44 45 cmd = build_py(dist) 46 cmd.compile = 1 47 cmd.ensure_finalized() 48 self.assertEqual(cmd.package_data, dist.package_data) 49 50 cmd.run() 51 52 # This makes sure the list of outputs includes byte-compiled 53 # files for Python modules but not for package data files 54 # (there shouldn't *be* byte-code files for those!). 55 self.assertEqual(len(cmd.get_outputs()), 3) 56 pkgdest = os.path.join(destination, "pkg") 57 files = os.listdir(pkgdest) 58 pycache_dir = os.path.join(pkgdest, "__pycache__") 59 self.assertIn("__init__.py", files) 60 self.assertIn("README.txt", files) 61 if sys.dont_write_bytecode: 62 self.assertFalse(os.path.exists(pycache_dir)) 63 else: 64 pyc_files = os.listdir(pycache_dir) 65 self.assertIn("__init__.%s.pyc" % sys.implementation.cache_tag, 66 pyc_files) 67 68 def test_empty_package_dir(self): 69 # See bugs #1668596/#1720897 70 sources = self.mkdtemp() 71 open(os.path.join(sources, "__init__.py"), "w").close() 72 73 testdir = os.path.join(sources, "doc") 74 os.mkdir(testdir) 75 open(os.path.join(testdir, "testfile"), "w").close() 76 77 os.chdir(sources) 78 dist = Distribution({"packages": ["pkg"], 79 "package_dir": {"pkg": ""}, 80 "package_data": {"pkg": ["doc/*"]}}) 81 # script_name need not exist, it just need to be initialized 82 dist.script_name = os.path.join(sources, "setup.py") 83 dist.script_args = ["build"] 84 dist.parse_command_line() 85 86 try: 87 dist.run_commands() 88 except DistutilsFileError: 89 self.fail("failed package_data test when package_dir is ''") 90 91 @unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled') 92 @requires_subprocess() 93 def test_byte_compile(self): 94 project_dir, dist = self.create_dist(py_modules=['boiledeggs']) 95 os.chdir(project_dir) 96 self.write_file('boiledeggs.py', 'import antigravity') 97 cmd = build_py(dist) 98 cmd.compile = 1 99 cmd.build_lib = 'here' 100 cmd.finalize_options() 101 cmd.run() 102 103 found = os.listdir(cmd.build_lib) 104 self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py']) 105 found = os.listdir(os.path.join(cmd.build_lib, '__pycache__')) 106 self.assertEqual(found, 107 ['boiledeggs.%s.pyc' % sys.implementation.cache_tag]) 108 109 @unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled') 110 @requires_subprocess() 111 def test_byte_compile_optimized(self): 112 project_dir, dist = self.create_dist(py_modules=['boiledeggs']) 113 os.chdir(project_dir) 114 self.write_file('boiledeggs.py', 'import antigravity') 115 cmd = build_py(dist) 116 cmd.compile = 0 117 cmd.optimize = 1 118 cmd.build_lib = 'here' 119 cmd.finalize_options() 120 cmd.run() 121 122 found = os.listdir(cmd.build_lib) 123 self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py']) 124 found = os.listdir(os.path.join(cmd.build_lib, '__pycache__')) 125 expect = 'boiledeggs.{}.opt-1.pyc'.format(sys.implementation.cache_tag) 126 self.assertEqual(sorted(found), [expect]) 127 128 def test_dir_in_package_data(self): 129 """ 130 A directory in package_data should not be added to the filelist. 131 """ 132 # See bug 19286 133 sources = self.mkdtemp() 134 pkg_dir = os.path.join(sources, "pkg") 135 136 os.mkdir(pkg_dir) 137 open(os.path.join(pkg_dir, "__init__.py"), "w").close() 138 139 docdir = os.path.join(pkg_dir, "doc") 140 os.mkdir(docdir) 141 open(os.path.join(docdir, "testfile"), "w").close() 142 143 # create the directory that could be incorrectly detected as a file 144 os.mkdir(os.path.join(docdir, 'otherdir')) 145 146 os.chdir(sources) 147 dist = Distribution({"packages": ["pkg"], 148 "package_data": {"pkg": ["doc/*"]}}) 149 # script_name need not exist, it just need to be initialized 150 dist.script_name = os.path.join(sources, "setup.py") 151 dist.script_args = ["build"] 152 dist.parse_command_line() 153 154 try: 155 dist.run_commands() 156 except DistutilsFileError: 157 self.fail("failed package_data when data dir includes a dir") 158 159 def test_dont_write_bytecode(self): 160 # makes sure byte_compile is not used 161 dist = self.create_dist()[1] 162 cmd = build_py(dist) 163 cmd.compile = 1 164 cmd.optimize = 1 165 166 old_dont_write_bytecode = sys.dont_write_bytecode 167 sys.dont_write_bytecode = True 168 try: 169 cmd.byte_compile([]) 170 finally: 171 sys.dont_write_bytecode = old_dont_write_bytecode 172 173 self.assertIn('byte-compiling is disabled', 174 self.logs[0][1] % self.logs[0][2]) 175 176 177def test_suite(): 178 return unittest.TestLoader().loadTestsFromTestCase(BuildPyTestCase) 179 180if __name__ == "__main__": 181 run_unittest(test_suite()) 182