1"""Tests for distutils.core.""" 2 3import io 4import distutils.core 5import os 6import shutil 7import sys 8from test.support import captured_stdout, run_unittest 9from test.support import os_helper 10import unittest 11from distutils.tests import support 12from distutils import log 13 14# setup script that uses __file__ 15setup_using___file__ = """\ 16 17__file__ 18 19from distutils.core import setup 20setup() 21""" 22 23setup_prints_cwd = """\ 24 25import os 26print(os.getcwd()) 27 28from distutils.core import setup 29setup() 30""" 31 32setup_does_nothing = """\ 33from distutils.core import setup 34setup() 35""" 36 37 38setup_defines_subclass = """\ 39from distutils.core import setup 40from distutils.command.install import install as _install 41 42class install(_install): 43 sub_commands = _install.sub_commands + ['cmd'] 44 45setup(cmdclass={'install': install}) 46""" 47 48class CoreTestCase(support.EnvironGuard, unittest.TestCase): 49 50 def setUp(self): 51 super(CoreTestCase, self).setUp() 52 self.old_stdout = sys.stdout 53 self.cleanup_testfn() 54 self.old_argv = sys.argv, sys.argv[:] 55 self.addCleanup(log.set_threshold, log._global_log.threshold) 56 57 def tearDown(self): 58 sys.stdout = self.old_stdout 59 self.cleanup_testfn() 60 sys.argv = self.old_argv[0] 61 sys.argv[:] = self.old_argv[1] 62 super(CoreTestCase, self).tearDown() 63 64 def cleanup_testfn(self): 65 path = os_helper.TESTFN 66 if os.path.isfile(path): 67 os.remove(path) 68 elif os.path.isdir(path): 69 shutil.rmtree(path) 70 71 def write_setup(self, text, path=os_helper.TESTFN): 72 f = open(path, "w") 73 try: 74 f.write(text) 75 finally: 76 f.close() 77 return path 78 79 def test_run_setup_provides_file(self): 80 # Make sure the script can use __file__; if that's missing, the test 81 # setup.py script will raise NameError. 82 distutils.core.run_setup( 83 self.write_setup(setup_using___file__)) 84 85 def test_run_setup_preserves_sys_argv(self): 86 # Make sure run_setup does not clobber sys.argv 87 argv_copy = sys.argv.copy() 88 distutils.core.run_setup( 89 self.write_setup(setup_does_nothing)) 90 self.assertEqual(sys.argv, argv_copy) 91 92 def test_run_setup_defines_subclass(self): 93 # Make sure the script can use __file__; if that's missing, the test 94 # setup.py script will raise NameError. 95 dist = distutils.core.run_setup( 96 self.write_setup(setup_defines_subclass)) 97 install = dist.get_command_obj('install') 98 self.assertIn('cmd', install.sub_commands) 99 100 def test_run_setup_uses_current_dir(self): 101 # This tests that the setup script is run with the current directory 102 # as its own current directory; this was temporarily broken by a 103 # previous patch when TESTFN did not use the current directory. 104 sys.stdout = io.StringIO() 105 cwd = os.getcwd() 106 107 # Create a directory and write the setup.py file there: 108 os.mkdir(os_helper.TESTFN) 109 setup_py = os.path.join(os_helper.TESTFN, "setup.py") 110 distutils.core.run_setup( 111 self.write_setup(setup_prints_cwd, path=setup_py)) 112 113 output = sys.stdout.getvalue() 114 if output.endswith("\n"): 115 output = output[:-1] 116 self.assertEqual(cwd, output) 117 118 def test_debug_mode(self): 119 # this covers the code called when DEBUG is set 120 sys.argv = ['setup.py', '--name'] 121 with captured_stdout() as stdout: 122 distutils.core.setup(name='bar') 123 stdout.seek(0) 124 self.assertEqual(stdout.read(), 'bar\n') 125 126 distutils.core.DEBUG = True 127 try: 128 with captured_stdout() as stdout: 129 distutils.core.setup(name='bar') 130 finally: 131 distutils.core.DEBUG = False 132 stdout.seek(0) 133 wanted = "options (after parsing config files):\n" 134 self.assertEqual(stdout.readlines()[0], wanted) 135 136def test_suite(): 137 return unittest.makeSuite(CoreTestCase) 138 139if __name__ == "__main__": 140 run_unittest(test_suite()) 141