1"""Tests for distutils._msvccompiler.""" 2import sys 3import unittest 4import os 5 6from distutils.errors import DistutilsPlatformError 7from distutils.tests import support 8from test.support import run_unittest 9 10 11SKIP_MESSAGE = (None if sys.platform == "win32" else 12 "These tests are only for win32") 13 14@unittest.skipUnless(SKIP_MESSAGE is None, SKIP_MESSAGE) 15class msvccompilerTestCase(support.TempdirManager, 16 unittest.TestCase): 17 18 def test_no_compiler(self): 19 import distutils._msvccompiler as _msvccompiler 20 # makes sure query_vcvarsall raises 21 # a DistutilsPlatformError if the compiler 22 # is not found 23 def _find_vcvarsall(plat_spec): 24 return None, None 25 26 old_find_vcvarsall = _msvccompiler._find_vcvarsall 27 _msvccompiler._find_vcvarsall = _find_vcvarsall 28 try: 29 self.assertRaises(DistutilsPlatformError, 30 _msvccompiler._get_vc_env, 31 'wont find this version') 32 finally: 33 _msvccompiler._find_vcvarsall = old_find_vcvarsall 34 35 def test_compiler_options(self): 36 import distutils._msvccompiler as _msvccompiler 37 # suppress path to vcruntime from _find_vcvarsall to 38 # check that /MT is added to compile options 39 old_find_vcvarsall = _msvccompiler._find_vcvarsall 40 def _find_vcvarsall(plat_spec): 41 return old_find_vcvarsall(plat_spec)[0], None 42 _msvccompiler._find_vcvarsall = _find_vcvarsall 43 try: 44 compiler = _msvccompiler.MSVCCompiler() 45 compiler.initialize() 46 47 self.assertIn('/MT', compiler.compile_options) 48 self.assertNotIn('/MD', compiler.compile_options) 49 finally: 50 _msvccompiler._find_vcvarsall = old_find_vcvarsall 51 52 def test_vcruntime_copy(self): 53 import distutils._msvccompiler as _msvccompiler 54 # force path to a known file - it doesn't matter 55 # what we copy as long as its name is not in 56 # _msvccompiler._BUNDLED_DLLS 57 old_find_vcvarsall = _msvccompiler._find_vcvarsall 58 def _find_vcvarsall(plat_spec): 59 return old_find_vcvarsall(plat_spec)[0], __file__ 60 _msvccompiler._find_vcvarsall = _find_vcvarsall 61 try: 62 tempdir = self.mkdtemp() 63 compiler = _msvccompiler.MSVCCompiler() 64 compiler.initialize() 65 compiler._copy_vcruntime(tempdir) 66 67 self.assertTrue(os.path.isfile(os.path.join( 68 tempdir, os.path.basename(__file__)))) 69 finally: 70 _msvccompiler._find_vcvarsall = old_find_vcvarsall 71 72 def test_vcruntime_skip_copy(self): 73 import distutils._msvccompiler as _msvccompiler 74 75 tempdir = self.mkdtemp() 76 compiler = _msvccompiler.MSVCCompiler() 77 compiler.initialize() 78 dll = compiler._vcruntime_redist 79 self.assertTrue(os.path.isfile(dll), dll or "<None>") 80 81 compiler._copy_vcruntime(tempdir) 82 83 self.assertFalse(os.path.isfile(os.path.join( 84 tempdir, os.path.basename(dll))), dll or "<None>") 85 86 def test_get_vc_env_unicode(self): 87 import distutils._msvccompiler as _msvccompiler 88 89 test_var = 'ṰḖṤṪ┅ṼẨṜ' 90 test_value = '₃⁴₅' 91 92 # Ensure we don't early exit from _get_vc_env 93 old_distutils_use_sdk = os.environ.pop('DISTUTILS_USE_SDK', None) 94 os.environ[test_var] = test_value 95 try: 96 env = _msvccompiler._get_vc_env('x86') 97 self.assertIn(test_var.lower(), env) 98 self.assertEqual(test_value, env[test_var.lower()]) 99 finally: 100 os.environ.pop(test_var) 101 if old_distutils_use_sdk: 102 os.environ['DISTUTILS_USE_SDK'] = old_distutils_use_sdk 103 104 def test_get_vc2017(self): 105 import distutils._msvccompiler as _msvccompiler 106 107 # This function cannot be mocked, so pass it if we find VS 2017 108 # and mark it skipped if we do not. 109 version, path = _msvccompiler._find_vc2017() 110 if version: 111 self.assertGreaterEqual(version, 15) 112 self.assertTrue(os.path.isdir(path)) 113 else: 114 raise unittest.SkipTest("VS 2017 is not installed") 115 116 def test_get_vc2015(self): 117 import distutils._msvccompiler as _msvccompiler 118 119 # This function cannot be mocked, so pass it if we find VS 2015 120 # and mark it skipped if we do not. 121 version, path = _msvccompiler._find_vc2015() 122 if version: 123 self.assertGreaterEqual(version, 14) 124 self.assertTrue(os.path.isdir(path)) 125 else: 126 raise unittest.SkipTest("VS 2015 is not installed") 127 128def test_suite(): 129 return unittest.makeSuite(msvccompilerTestCase) 130 131if __name__ == "__main__": 132 run_unittest(test_suite()) 133