test_build_py.py 6.2 KB

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