1  """Tests for distutils.command.build_py."""
       2  
       3  import os
       4  import sys
       5  import unittest
       6  
       7  from distutils.command.build_py import build_py
       8  from distutils.core import Distribution
       9  from distutils.errors import DistutilsFileError
      10  
      11  from distutils.tests import support
      12  from test.support import requires_subprocess
      13  
      14  
      15  class ESC[4;38;5;81mBuildPyTestCase(ESC[4;38;5;149msupportESC[4;38;5;149m.ESC[4;38;5;149mTempdirManager,
      16                        ESC[4;38;5;149msupportESC[4;38;5;149m.ESC[4;38;5;149mLoggingSilencer,
      17                        ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      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  
     177  if __name__ == "__main__":
     178      unittest.main()