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 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 def test_byte_compile(self): 93 project_dir, dist = self.create_dist(py_modules=['boiledeggs']) 94 os.chdir(project_dir) 95 self.write_file('boiledeggs.py', 'import antigravity') 96 cmd = build_py(dist) 97 cmd.compile = 1 98 cmd.build_lib = 'here' 99 cmd.finalize_options() 100 cmd.run() 101 102 found = os.listdir(cmd.build_lib) 103 self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py']) 104 found = os.listdir(os.path.join(cmd.build_lib, '__pycache__')) 105 self.assertEqual(found, 106 ['boiledeggs.%s.pyc' % sys.implementation.cache_tag]) 107 108 @unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled') 109 def test_byte_compile_optimized(self): 110 project_dir, dist = self.create_dist(py_modules=['boiledeggs']) 111 os.chdir(project_dir) 112 self.write_file('boiledeggs.py', 'import antigravity') 113 cmd = build_py(dist) 114 cmd.compile = 0 115 cmd.optimize = 1 116 cmd.build_lib = 'here' 117 cmd.finalize_options() 118 cmd.run() 119 120 found = os.listdir(cmd.build_lib) 121 self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py']) 122 found = os.listdir(os.path.join(cmd.build_lib, '__pycache__')) 123 expect = 'boiledeggs.{}.opt-1.pyc'.format(sys.implementation.cache_tag) 124 self.assertEqual(sorted(found), [expect]) 125 126 def test_dir_in_package_data(self): 127 """ 128 A directory in package_data should not be added to the filelist. 129 """ 130 # See bug 19286 131 sources = self.mkdtemp() 132 pkg_dir = os.path.join(sources, "pkg") 133 134 os.mkdir(pkg_dir) 135 open(os.path.join(pkg_dir, "__init__.py"), "w").close() 136 137 docdir = os.path.join(pkg_dir, "doc") 138 os.mkdir(docdir) 139 open(os.path.join(docdir, "testfile"), "w").close() 140 141 # create the directory that could be incorrectly detected as a file 142 os.mkdir(os.path.join(docdir, 'otherdir')) 143 144 os.chdir(sources) 145 dist = Distribution({"packages": ["pkg"], 146 "package_data": {"pkg": ["doc/*"]}}) 147 # script_name need not exist, it just need to be initialized 148 dist.script_name = os.path.join(sources, "setup.py") 149 dist.script_args = ["build"] 150 dist.parse_command_line() 151 152 try: 153 dist.run_commands() 154 except DistutilsFileError: 155 self.fail("failed package_data when data dir includes a dir") 156 157 def test_dont_write_bytecode(self): 158 # makes sure byte_compile is not used 159 dist = self.create_dist()[1] 160 cmd = build_py(dist) 161 cmd.compile = 1 162 cmd.optimize = 1 163 164 old_dont_write_bytecode = sys.dont_write_bytecode 165 sys.dont_write_bytecode = True 166 try: 167 cmd.byte_compile([]) 168 finally: 169 sys.dont_write_bytecode = old_dont_write_bytecode 170 171 self.assertIn('byte-compiling is disabled', 172 self.logs[0][1] % self.logs[0][2]) 173 174 175def test_suite(): 176 return unittest.makeSuite(BuildPyTestCase) 177 178if __name__ == "__main__": 179 run_unittest(test_suite()) 180