summaryrefslogtreecommitdiffstats
path: root/Lib/distutils/tests/test_msvccompiler.py
blob: 70a9c93a4e8805e8baf84744a0b3328f2698019b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"""Tests for distutils._msvccompiler."""
import sys
import unittest
import os

from distutils.errors import DistutilsPlatformError
from distutils.tests import support
from test.support import run_unittest


SKIP_MESSAGE = (None if sys.platform == "win32" else
                "These tests are only for win32")

@unittest.skipUnless(SKIP_MESSAGE is None, SKIP_MESSAGE)
class msvccompilerTestCase(support.TempdirManager,
                            unittest.TestCase):

    def test_no_compiler(self):
        import distutils._msvccompiler as _msvccompiler
        # makes sure query_vcvarsall raises
        # a DistutilsPlatformError if the compiler
        # is not found
        def _find_vcvarsall(plat_spec):
            return None, None

        old_find_vcvarsall = _msvccompiler._find_vcvarsall
        _msvccompiler._find_vcvarsall = _find_vcvarsall
        try:
            self.assertRaises(DistutilsPlatformError,
                              _msvccompiler._get_vc_env,
                             'wont find this version')
        finally:
            _msvccompiler._find_vcvarsall = old_find_vcvarsall

    def test_compiler_options(self):
        import distutils._msvccompiler as _msvccompiler
        # suppress path to vcruntime from _find_vcvarsall to
        # check that /MT is added to compile options
        old_find_vcvarsall = _msvccompiler._find_vcvarsall
        def _find_vcvarsall(plat_spec):
            return old_find_vcvarsall(plat_spec)[0], None
        _msvccompiler._find_vcvarsall = _find_vcvarsall
        try:
            compiler = _msvccompiler.MSVCCompiler()
            compiler.initialize()

            self.assertIn('/MT', compiler.compile_options)
            self.assertNotIn('/MD', compiler.compile_options)
        finally:
            _msvccompiler._find_vcvarsall = old_find_vcvarsall

    def test_vcruntime_copy(self):
        import distutils._msvccompiler as _msvccompiler
        # force path to a known file - it doesn't matter
        # what we copy as long as its name is not in
        # _msvccompiler._BUNDLED_DLLS
        old_find_vcvarsall = _msvccompiler._find_vcvarsall
        def _find_vcvarsall(plat_spec):
            return old_find_vcvarsall(plat_spec)[0], __file__
        _msvccompiler._find_vcvarsall = _find_vcvarsall
        try:
            tempdir = self.mkdtemp()
            compiler = _msvccompiler.MSVCCompiler()
            compiler.initialize()
            compiler._copy_vcruntime(tempdir)

            self.assertTrue(os.path.isfile(os.path.join(
                tempdir, os.path.basename(__file__))))
        finally:
            _msvccompiler._find_vcvarsall = old_find_vcvarsall

    def test_vcruntime_skip_copy(self):
        import distutils._msvccompiler as _msvccompiler

        tempdir = self.mkdtemp()
        compiler = _msvccompiler.MSVCCompiler()
        compiler.initialize()
        dll = compiler._vcruntime_redist
        self.assertTrue(os.path.isfile(dll), dll or "<None>")

        compiler._copy_vcruntime(tempdir)

        self.assertFalse(os.path.isfile(os.path.join(
            tempdir, os.path.basename(dll))), dll or "<None>")

    def test_get_vc_env_unicode(self):
        import distutils._msvccompiler as _msvccompiler

        test_var = 'ṰḖṤṪ┅ṼẨṜ'
        test_value = '₃⁴₅'

        # Ensure we don't early exit from _get_vc_env
        old_distutils_use_sdk = os.environ.pop('DISTUTILS_USE_SDK', None)
        os.environ[test_var] = test_value
        try:
            env = _msvccompiler._get_vc_env('x86')
            self.assertIn(test_var.lower(), env)
            self.assertEqual(test_value, env[test_var.lower()])
        finally:
            os.environ.pop(test_var)
            if old_distutils_use_sdk:
                os.environ['DISTUTILS_USE_SDK'] = old_distutils_use_sdk

    def test_get_vc2017(self):
        import distutils._msvccompiler as _msvccompiler

        # This function cannot be mocked, so pass it if we find VS 2017
        # and mark it skipped if we do not.
        version, path = _msvccompiler._find_vc2017()
        if version:
            self.assertGreaterEqual(version, 15)
            self.assertTrue(os.path.isdir(path))
        else:
            raise unittest.SkipTest("VS 2017 is not installed")

    def test_get_vc2015(self):
        import distutils._msvccompiler as _msvccompiler

        # This function cannot be mocked, so pass it if we find VS 2015
        # and mark it skipped if we do not.
        version, path = _msvccompiler._find_vc2015()
        if version:
            self.assertGreaterEqual(version, 14)
            self.assertTrue(os.path.isdir(path))
        else:
            raise unittest.SkipTest("VS 2015 is not installed")

def test_suite():
    return unittest.makeSuite(msvccompilerTestCase)

if __name__ == "__main__":
    run_unittest(test_suite())