1"""Tests for distutils.command.build_py."""
2
3import os
4import sys
5import StringIO
6import unittest
7
8from distutils.command.build_py import build_py
9from distutils.core import Distribution
10from distutils.errors import DistutilsFileError
11
12from distutils.tests import support
13from test.test_support import run_unittest
14
15
16class BuildPyTestCase(support.TempdirManager,
17                      support.LoggingSilencer,
18                      unittest.TestCase):
19
20    def test_package_data(self):
21        sources = self.mkdtemp()
22        f = open(os.path.join(sources, "__init__.py"), "w")
23        try:
24            f.write("# Pretend this is a package.")
25        finally:
26            f.close()
27        f = open(os.path.join(sources, "README.txt"), "w")
28        try:
29            f.write("Info about this package")
30        finally:
31            f.close()
32
33        destination = self.mkdtemp()
34
35        dist = Distribution({"packages": ["pkg"],
36                             "package_dir": {"pkg": sources}})
37        # script_name need not exist, it just need to be initialized
38        dist.script_name = os.path.join(sources, "setup.py")
39        dist.command_obj["build"] = support.DummyCommand(
40            force=0,
41            build_lib=destination)
42        dist.packages = ["pkg"]
43        dist.package_data = {"pkg": ["README.txt"]}
44        dist.package_dir = {"pkg": sources}
45
46        cmd = build_py(dist)
47        cmd.compile = 1
48        cmd.ensure_finalized()
49        self.assertEqual(cmd.package_data, dist.package_data)
50
51        cmd.run()
52
53        # This makes sure the list of outputs includes byte-compiled
54        # files for Python modules but not for package data files
55        # (there shouldn't *be* byte-code files for those!).
56        #
57        self.assertEqual(len(cmd.get_outputs()), 3)
58        pkgdest = os.path.join(destination, "pkg")
59        files = os.listdir(pkgdest)
60        self.assertIn("__init__.py", files)
61        self.assertIn("README.txt", files)
62        # XXX even with -O, distutils writes pyc, not pyo; bug?
63        if sys.dont_write_bytecode:
64            self.assertNotIn("__init__.pyc", files)
65        else:
66            self.assertIn("__init__.pyc", files)
67
68    def test_empty_package_dir(self):
69        # See SF 1668596/1720897.
70        cwd = os.getcwd()
71
72        # create the distribution files.
73        sources = self.mkdtemp()
74        open(os.path.join(sources, "__init__.py"), "w").close()
75
76        testdir = os.path.join(sources, "doc")
77        os.mkdir(testdir)
78        open(os.path.join(testdir, "testfile"), "w").close()
79
80        os.chdir(sources)
81        old_stdout = sys.stdout
82        sys.stdout = StringIO.StringIO()
83
84        try:
85            dist = Distribution({"packages": ["pkg"],
86                                 "package_dir": {"pkg": ""},
87                                 "package_data": {"pkg": ["doc/*"]}})
88            # script_name need not exist, it just need to be initialized
89            dist.script_name = os.path.join(sources, "setup.py")
90            dist.script_args = ["build"]
91            dist.parse_command_line()
92
93            try:
94                dist.run_commands()
95            except DistutilsFileError:
96                self.fail("failed package_data test when package_dir is ''")
97        finally:
98            # Restore state.
99            os.chdir(cwd)
100            sys.stdout = old_stdout
101
102    def test_dont_write_bytecode(self):
103        # makes sure byte_compile is not used
104        pkg_dir, dist = self.create_dist()
105        cmd = build_py(dist)
106        cmd.compile = 1
107        cmd.optimize = 1
108
109        old_dont_write_bytecode = sys.dont_write_bytecode
110        sys.dont_write_bytecode = True
111        try:
112            cmd.byte_compile([])
113        finally:
114            sys.dont_write_bytecode = old_dont_write_bytecode
115
116        self.assertIn('byte-compiling is disabled', self.logs[0][1])
117
118def test_suite():
119    return unittest.makeSuite(BuildPyTestCase)
120
121if __name__ == "__main__":
122    run_unittest(test_suite())
123