diff env/lib/python3.7/site-packages/setuptools/msvc.py @ 5:9b1c78e6ba9c draft default tip

"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
author shellac
date Mon, 01 Jun 2020 08:59:25 -0400
parents 79f47841a781
children
line wrap: on
line diff
--- a/env/lib/python3.7/site-packages/setuptools/msvc.py	Thu May 14 16:47:39 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1301 +0,0 @@
-"""
-Improved support for Microsoft Visual C++ compilers.
-
-Known supported compilers:
---------------------------
-Microsoft Visual C++ 9.0:
-    Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64)
-    Microsoft Windows SDK 6.1 (x86, x64, ia64)
-    Microsoft Windows SDK 7.0 (x86, x64, ia64)
-
-Microsoft Visual C++ 10.0:
-    Microsoft Windows SDK 7.1 (x86, x64, ia64)
-
-Microsoft Visual C++ 14.0:
-    Microsoft Visual C++ Build Tools 2015 (x86, x64, arm)
-    Microsoft Visual Studio 2017 (x86, x64, arm, arm64)
-    Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64)
-"""
-
-import os
-import sys
-import platform
-import itertools
-import distutils.errors
-from setuptools.extern.packaging.version import LegacyVersion
-
-from setuptools.extern.six.moves import filterfalse
-
-from .monkey import get_unpatched
-
-if platform.system() == 'Windows':
-    from setuptools.extern.six.moves import winreg
-    safe_env = os.environ
-else:
-    """
-    Mock winreg and environ so the module can be imported
-    on this platform.
-    """
-
-    class winreg:
-        HKEY_USERS = None
-        HKEY_CURRENT_USER = None
-        HKEY_LOCAL_MACHINE = None
-        HKEY_CLASSES_ROOT = None
-
-    safe_env = dict()
-
-_msvc9_suppress_errors = (
-    # msvc9compiler isn't available on some platforms
-    ImportError,
-
-    # msvc9compiler raises DistutilsPlatformError in some
-    # environments. See #1118.
-    distutils.errors.DistutilsPlatformError,
-)
-
-try:
-    from distutils.msvc9compiler import Reg
-except _msvc9_suppress_errors:
-    pass
-
-
-def msvc9_find_vcvarsall(version):
-    """
-    Patched "distutils.msvc9compiler.find_vcvarsall" to use the standalone
-    compiler build for Python (VCForPython). Fall back to original behavior
-    when the standalone compiler is not available.
-
-    Redirect the path of "vcvarsall.bat".
-
-    Known supported compilers
-    -------------------------
-    Microsoft Visual C++ 9.0:
-        Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64)
-
-    Parameters
-    ----------
-    version: float
-        Required Microsoft Visual C++ version.
-
-    Return
-    ------
-    vcvarsall.bat path: str
-    """
-    VC_BASE = r'Software\%sMicrosoft\DevDiv\VCForPython\%0.1f'
-    key = VC_BASE % ('', version)
-    try:
-        # Per-user installs register the compiler path here
-        productdir = Reg.get_value(key, "installdir")
-    except KeyError:
-        try:
-            # All-user installs on a 64-bit system register here
-            key = VC_BASE % ('Wow6432Node\\', version)
-            productdir = Reg.get_value(key, "installdir")
-        except KeyError:
-            productdir = None
-
-    if productdir:
-        vcvarsall = os.path.os.path.join(productdir, "vcvarsall.bat")
-        if os.path.isfile(vcvarsall):
-            return vcvarsall
-
-    return get_unpatched(msvc9_find_vcvarsall)(version)
-
-
-def msvc9_query_vcvarsall(ver, arch='x86', *args, **kwargs):
-    """
-    Patched "distutils.msvc9compiler.query_vcvarsall" for support extra
-    compilers.
-
-    Set environment without use of "vcvarsall.bat".
-
-    Known supported compilers
-    -------------------------
-    Microsoft Visual C++ 9.0:
-        Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64)
-        Microsoft Windows SDK 6.1 (x86, x64, ia64)
-        Microsoft Windows SDK 7.0 (x86, x64, ia64)
-
-    Microsoft Visual C++ 10.0:
-        Microsoft Windows SDK 7.1 (x86, x64, ia64)
-
-    Parameters
-    ----------
-    ver: float
-        Required Microsoft Visual C++ version.
-    arch: str
-        Target architecture.
-
-    Return
-    ------
-    environment: dict
-    """
-    # Try to get environement from vcvarsall.bat (Classical way)
-    try:
-        orig = get_unpatched(msvc9_query_vcvarsall)
-        return orig(ver, arch, *args, **kwargs)
-    except distutils.errors.DistutilsPlatformError:
-        # Pass error if Vcvarsall.bat is missing
-        pass
-    except ValueError:
-        # Pass error if environment not set after executing vcvarsall.bat
-        pass
-
-    # If error, try to set environment directly
-    try:
-        return EnvironmentInfo(arch, ver).return_env()
-    except distutils.errors.DistutilsPlatformError as exc:
-        _augment_exception(exc, ver, arch)
-        raise
-
-
-def msvc14_get_vc_env(plat_spec):
-    """
-    Patched "distutils._msvccompiler._get_vc_env" for support extra
-    compilers.
-
-    Set environment without use of "vcvarsall.bat".
-
-    Known supported compilers
-    -------------------------
-    Microsoft Visual C++ 14.0:
-        Microsoft Visual C++ Build Tools 2015 (x86, x64, arm)
-        Microsoft Visual Studio 2017 (x86, x64, arm, arm64)
-        Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64)
-
-    Parameters
-    ----------
-    plat_spec: str
-        Target architecture.
-
-    Return
-    ------
-    environment: dict
-    """
-    # Try to get environment from vcvarsall.bat (Classical way)
-    try:
-        return get_unpatched(msvc14_get_vc_env)(plat_spec)
-    except distutils.errors.DistutilsPlatformError:
-        # Pass error Vcvarsall.bat is missing
-        pass
-
-    # If error, try to set environment directly
-    try:
-        return EnvironmentInfo(plat_spec, vc_min_ver=14.0).return_env()
-    except distutils.errors.DistutilsPlatformError as exc:
-        _augment_exception(exc, 14.0)
-        raise
-
-
-def msvc14_gen_lib_options(*args, **kwargs):
-    """
-    Patched "distutils._msvccompiler.gen_lib_options" for fix
-    compatibility between "numpy.distutils" and "distutils._msvccompiler"
-    (for Numpy < 1.11.2)
-    """
-    if "numpy.distutils" in sys.modules:
-        import numpy as np
-        if LegacyVersion(np.__version__) < LegacyVersion('1.11.2'):
-            return np.distutils.ccompiler.gen_lib_options(*args, **kwargs)
-    return get_unpatched(msvc14_gen_lib_options)(*args, **kwargs)
-
-
-def _augment_exception(exc, version, arch=''):
-    """
-    Add details to the exception message to help guide the user
-    as to what action will resolve it.
-    """
-    # Error if MSVC++ directory not found or environment not set
-    message = exc.args[0]
-
-    if "vcvarsall" in message.lower() or "visual c" in message.lower():
-        # Special error message if MSVC++ not installed
-        tmpl = 'Microsoft Visual C++ {version:0.1f} is required.'
-        message = tmpl.format(**locals())
-        msdownload = 'www.microsoft.com/download/details.aspx?id=%d'
-        if version == 9.0:
-            if arch.lower().find('ia64') > -1:
-                # For VC++ 9.0, if IA64 support is needed, redirect user
-                # to Windows SDK 7.0
-                message += ' Get it with "Microsoft Windows SDK 7.0": '
-                message += msdownload % 3138
-            else:
-                # For VC++ 9.0 redirect user to Vc++ for Python 2.7 :
-                # This redirection link is maintained by Microsoft.
-                # Contact vspython@microsoft.com if it needs updating.
-                message += ' Get it from http://aka.ms/vcpython27'
-        elif version == 10.0:
-            # For VC++ 10.0 Redirect user to Windows SDK 7.1
-            message += ' Get it with "Microsoft Windows SDK 7.1": '
-            message += msdownload % 8279
-        elif version >= 14.0:
-            # For VC++ 14.0 Redirect user to Visual C++ Build Tools
-            message += (' Get it with "Microsoft Visual C++ Build Tools": '
-                        r'https://visualstudio.microsoft.com/downloads/')
-
-    exc.args = (message, )
-
-
-class PlatformInfo:
-    """
-    Current and Target Architectures informations.
-
-    Parameters
-    ----------
-    arch: str
-        Target architecture.
-    """
-    current_cpu = safe_env.get('processor_architecture', '').lower()
-
-    def __init__(self, arch):
-        self.arch = arch.lower().replace('x64', 'amd64')
-
-    @property
-    def target_cpu(self):
-        return self.arch[self.arch.find('_') + 1:]
-
-    def target_is_x86(self):
-        return self.target_cpu == 'x86'
-
-    def current_is_x86(self):
-        return self.current_cpu == 'x86'
-
-    def current_dir(self, hidex86=False, x64=False):
-        """
-        Current platform specific subfolder.
-
-        Parameters
-        ----------
-        hidex86: bool
-            return '' and not '\x86' if architecture is x86.
-        x64: bool
-            return '\x64' and not '\amd64' if architecture is amd64.
-
-        Return
-        ------
-        subfolder: str
-            '\target', or '' (see hidex86 parameter)
-        """
-        return (
-            '' if (self.current_cpu == 'x86' and hidex86) else
-            r'\x64' if (self.current_cpu == 'amd64' and x64) else
-            r'\%s' % self.current_cpu
-        )
-
-    def target_dir(self, hidex86=False, x64=False):
-        r"""
-        Target platform specific subfolder.
-
-        Parameters
-        ----------
-        hidex86: bool
-            return '' and not '\x86' if architecture is x86.
-        x64: bool
-            return '\x64' and not '\amd64' if architecture is amd64.
-
-        Return
-        ------
-        subfolder: str
-            '\current', or '' (see hidex86 parameter)
-        """
-        return (
-            '' if (self.target_cpu == 'x86' and hidex86) else
-            r'\x64' if (self.target_cpu == 'amd64' and x64) else
-            r'\%s' % self.target_cpu
-        )
-
-    def cross_dir(self, forcex86=False):
-        r"""
-        Cross platform specific subfolder.
-
-        Parameters
-        ----------
-        forcex86: bool
-            Use 'x86' as current architecture even if current acritecture is
-            not x86.
-
-        Return
-        ------
-        subfolder: str
-            '' if target architecture is current architecture,
-            '\current_target' if not.
-        """
-        current = 'x86' if forcex86 else self.current_cpu
-        return (
-            '' if self.target_cpu == current else
-            self.target_dir().replace('\\', '\\%s_' % current)
-        )
-
-
-class RegistryInfo:
-    """
-    Microsoft Visual Studio related registry informations.
-
-    Parameters
-    ----------
-    platform_info: PlatformInfo
-        "PlatformInfo" instance.
-    """
-    HKEYS = (winreg.HKEY_USERS,
-             winreg.HKEY_CURRENT_USER,
-             winreg.HKEY_LOCAL_MACHINE,
-             winreg.HKEY_CLASSES_ROOT)
-
-    def __init__(self, platform_info):
-        self.pi = platform_info
-
-    @property
-    def visualstudio(self):
-        """
-        Microsoft Visual Studio root registry key.
-        """
-        return 'VisualStudio'
-
-    @property
-    def sxs(self):
-        """
-        Microsoft Visual Studio SxS registry key.
-        """
-        return os.path.join(self.visualstudio, 'SxS')
-
-    @property
-    def vc(self):
-        """
-        Microsoft Visual C++ VC7 registry key.
-        """
-        return os.path.join(self.sxs, 'VC7')
-
-    @property
-    def vs(self):
-        """
-        Microsoft Visual Studio VS7 registry key.
-        """
-        return os.path.join(self.sxs, 'VS7')
-
-    @property
-    def vc_for_python(self):
-        """
-        Microsoft Visual C++ for Python registry key.
-        """
-        return r'DevDiv\VCForPython'
-
-    @property
-    def microsoft_sdk(self):
-        """
-        Microsoft SDK registry key.
-        """
-        return 'Microsoft SDKs'
-
-    @property
-    def windows_sdk(self):
-        """
-        Microsoft Windows/Platform SDK registry key.
-        """
-        return os.path.join(self.microsoft_sdk, 'Windows')
-
-    @property
-    def netfx_sdk(self):
-        """
-        Microsoft .NET Framework SDK registry key.
-        """
-        return os.path.join(self.microsoft_sdk, 'NETFXSDK')
-
-    @property
-    def windows_kits_roots(self):
-        """
-        Microsoft Windows Kits Roots registry key.
-        """
-        return r'Windows Kits\Installed Roots'
-
-    def microsoft(self, key, x86=False):
-        """
-        Return key in Microsoft software registry.
-
-        Parameters
-        ----------
-        key: str
-            Registry key path where look.
-        x86: str
-            Force x86 software registry.
-
-        Return
-        ------
-        str: value
-        """
-        node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node'
-        return os.path.join('Software', node64, 'Microsoft', key)
-
-    def lookup(self, key, name):
-        """
-        Look for values in registry in Microsoft software registry.
-
-        Parameters
-        ----------
-        key: str
-            Registry key path where look.
-        name: str
-            Value name to find.
-
-        Return
-        ------
-        str: value
-        """
-        KEY_READ = winreg.KEY_READ
-        openkey = winreg.OpenKey
-        ms = self.microsoft
-        for hkey in self.HKEYS:
-            try:
-                bkey = openkey(hkey, ms(key), 0, KEY_READ)
-            except (OSError, IOError):
-                if not self.pi.current_is_x86():
-                    try:
-                        bkey = openkey(hkey, ms(key, True), 0, KEY_READ)
-                    except (OSError, IOError):
-                        continue
-                else:
-                    continue
-            try:
-                return winreg.QueryValueEx(bkey, name)[0]
-            except (OSError, IOError):
-                pass
-
-
-class SystemInfo:
-    """
-    Microsoft Windows and Visual Studio related system inormations.
-
-    Parameters
-    ----------
-    registry_info: RegistryInfo
-        "RegistryInfo" instance.
-    vc_ver: float
-        Required Microsoft Visual C++ version.
-    """
-
-    # Variables and properties in this class use originals CamelCase variables
-    # names from Microsoft source files for more easy comparaison.
-    WinDir = safe_env.get('WinDir', '')
-    ProgramFiles = safe_env.get('ProgramFiles', '')
-    ProgramFilesx86 = safe_env.get('ProgramFiles(x86)', ProgramFiles)
-
-    def __init__(self, registry_info, vc_ver=None):
-        self.ri = registry_info
-        self.pi = self.ri.pi
-        self.vc_ver = vc_ver or self._find_latest_available_vc_ver()
-
-    def _find_latest_available_vc_ver(self):
-        try:
-            return self.find_available_vc_vers()[-1]
-        except IndexError:
-            err = 'No Microsoft Visual C++ version found'
-            raise distutils.errors.DistutilsPlatformError(err)
-
-    def find_available_vc_vers(self):
-        """
-        Find all available Microsoft Visual C++ versions.
-        """
-        ms = self.ri.microsoft
-        vckeys = (self.ri.vc, self.ri.vc_for_python, self.ri.vs)
-        vc_vers = []
-        for hkey in self.ri.HKEYS:
-            for key in vckeys:
-                try:
-                    bkey = winreg.OpenKey(hkey, ms(key), 0, winreg.KEY_READ)
-                except (OSError, IOError):
-                    continue
-                subkeys, values, _ = winreg.QueryInfoKey(bkey)
-                for i in range(values):
-                    try:
-                        ver = float(winreg.EnumValue(bkey, i)[0])
-                        if ver not in vc_vers:
-                            vc_vers.append(ver)
-                    except ValueError:
-                        pass
-                for i in range(subkeys):
-                    try:
-                        ver = float(winreg.EnumKey(bkey, i))
-                        if ver not in vc_vers:
-                            vc_vers.append(ver)
-                    except ValueError:
-                        pass
-        return sorted(vc_vers)
-
-    @property
-    def VSInstallDir(self):
-        """
-        Microsoft Visual Studio directory.
-        """
-        # Default path
-        name = 'Microsoft Visual Studio %0.1f' % self.vc_ver
-        default = os.path.join(self.ProgramFilesx86, name)
-
-        # Try to get path from registry, if fail use default path
-        return self.ri.lookup(self.ri.vs, '%0.1f' % self.vc_ver) or default
-
-    @property
-    def VCInstallDir(self):
-        """
-        Microsoft Visual C++ directory.
-        """
-        self.VSInstallDir
-
-        guess_vc = self._guess_vc() or self._guess_vc_legacy()
-
-        # Try to get "VC++ for Python" path from registry as default path
-        reg_path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver)
-        python_vc = self.ri.lookup(reg_path, 'installdir')
-        default_vc = os.path.join(python_vc, 'VC') if python_vc else guess_vc
-
-        # Try to get path from registry, if fail use default path
-        path = self.ri.lookup(self.ri.vc, '%0.1f' % self.vc_ver) or default_vc
-
-        if not os.path.isdir(path):
-            msg = 'Microsoft Visual C++ directory not found'
-            raise distutils.errors.DistutilsPlatformError(msg)
-
-        return path
-
-    def _guess_vc(self):
-        """
-        Locate Visual C for 2017
-        """
-        if self.vc_ver <= 14.0:
-            return
-
-        default = r'VC\Tools\MSVC'
-        guess_vc = os.path.join(self.VSInstallDir, default)
-        # Subdir with VC exact version as name
-        try:
-            vc_exact_ver = os.listdir(guess_vc)[-1]
-            return os.path.join(guess_vc, vc_exact_ver)
-        except (OSError, IOError, IndexError):
-            pass
-
-    def _guess_vc_legacy(self):
-        """
-        Locate Visual C for versions prior to 2017
-        """
-        default = r'Microsoft Visual Studio %0.1f\VC' % self.vc_ver
-        return os.path.join(self.ProgramFilesx86, default)
-
-    @property
-    def WindowsSdkVersion(self):
-        """
-        Microsoft Windows SDK versions for specified MSVC++ version.
-        """
-        if self.vc_ver <= 9.0:
-            return ('7.0', '6.1', '6.0a')
-        elif self.vc_ver == 10.0:
-            return ('7.1', '7.0a')
-        elif self.vc_ver == 11.0:
-            return ('8.0', '8.0a')
-        elif self.vc_ver == 12.0:
-            return ('8.1', '8.1a')
-        elif self.vc_ver >= 14.0:
-            return ('10.0', '8.1')
-
-    @property
-    def WindowsSdkLastVersion(self):
-        """
-        Microsoft Windows SDK last version
-        """
-        return self._use_last_dir_name(os.path.join(
-            self.WindowsSdkDir, 'lib'))
-
-    @property
-    def WindowsSdkDir(self):
-        """
-        Microsoft Windows SDK directory.
-        """
-        sdkdir = ''
-        for ver in self.WindowsSdkVersion:
-            # Try to get it from registry
-            loc = os.path.join(self.ri.windows_sdk, 'v%s' % ver)
-            sdkdir = self.ri.lookup(loc, 'installationfolder')
-            if sdkdir:
-                break
-        if not sdkdir or not os.path.isdir(sdkdir):
-            # Try to get "VC++ for Python" version from registry
-            path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver)
-            install_base = self.ri.lookup(path, 'installdir')
-            if install_base:
-                sdkdir = os.path.join(install_base, 'WinSDK')
-        if not sdkdir or not os.path.isdir(sdkdir):
-            # If fail, use default new path
-            for ver in self.WindowsSdkVersion:
-                intver = ver[:ver.rfind('.')]
-                path = r'Microsoft SDKs\Windows Kits\%s' % (intver)
-                d = os.path.join(self.ProgramFiles, path)
-                if os.path.isdir(d):
-                    sdkdir = d
-        if not sdkdir or not os.path.isdir(sdkdir):
-            # If fail, use default old path
-            for ver in self.WindowsSdkVersion:
-                path = r'Microsoft SDKs\Windows\v%s' % ver
-                d = os.path.join(self.ProgramFiles, path)
-                if os.path.isdir(d):
-                    sdkdir = d
-        if not sdkdir:
-            # If fail, use Platform SDK
-            sdkdir = os.path.join(self.VCInstallDir, 'PlatformSDK')
-        return sdkdir
-
-    @property
-    def WindowsSDKExecutablePath(self):
-        """
-        Microsoft Windows SDK executable directory.
-        """
-        # Find WinSDK NetFx Tools registry dir name
-        if self.vc_ver <= 11.0:
-            netfxver = 35
-            arch = ''
-        else:
-            netfxver = 40
-            hidex86 = True if self.vc_ver <= 12.0 else False
-            arch = self.pi.current_dir(x64=True, hidex86=hidex86)
-        fx = 'WinSDK-NetFx%dTools%s' % (netfxver, arch.replace('\\', '-'))
-
-        # liste all possibles registry paths
-        regpaths = []
-        if self.vc_ver >= 14.0:
-            for ver in self.NetFxSdkVersion:
-                regpaths += [os.path.join(self.ri.netfx_sdk, ver, fx)]
-
-        for ver in self.WindowsSdkVersion:
-            regpaths += [os.path.join(self.ri.windows_sdk, 'v%sA' % ver, fx)]
-
-        # Return installation folder from the more recent path
-        for path in regpaths:
-            execpath = self.ri.lookup(path, 'installationfolder')
-            if execpath:
-                break
-        return execpath
-
-    @property
-    def FSharpInstallDir(self):
-        """
-        Microsoft Visual F# directory.
-        """
-        path = r'%0.1f\Setup\F#' % self.vc_ver
-        path = os.path.join(self.ri.visualstudio, path)
-        return self.ri.lookup(path, 'productdir') or ''
-
-    @property
-    def UniversalCRTSdkDir(self):
-        """
-        Microsoft Universal CRT SDK directory.
-        """
-        # Set Kit Roots versions for specified MSVC++ version
-        if self.vc_ver >= 14.0:
-            vers = ('10', '81')
-        else:
-            vers = ()
-
-        # Find path of the more recent Kit
-        for ver in vers:
-            sdkdir = self.ri.lookup(self.ri.windows_kits_roots,
-                                    'kitsroot%s' % ver)
-            if sdkdir:
-                break
-        return sdkdir or ''
-
-    @property
-    def UniversalCRTSdkLastVersion(self):
-        """
-        Microsoft Universal C Runtime SDK last version
-        """
-        return self._use_last_dir_name(os.path.join(
-            self.UniversalCRTSdkDir, 'lib'))
-
-    @property
-    def NetFxSdkVersion(self):
-        """
-        Microsoft .NET Framework SDK versions.
-        """
-        # Set FxSdk versions for specified MSVC++ version
-        if self.vc_ver >= 14.0:
-            return ('4.6.1', '4.6')
-        else:
-            return ()
-
-    @property
-    def NetFxSdkDir(self):
-        """
-        Microsoft .NET Framework SDK directory.
-        """
-        for ver in self.NetFxSdkVersion:
-            loc = os.path.join(self.ri.netfx_sdk, ver)
-            sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder')
-            if sdkdir:
-                break
-        return sdkdir or ''
-
-    @property
-    def FrameworkDir32(self):
-        """
-        Microsoft .NET Framework 32bit directory.
-        """
-        # Default path
-        guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework')
-
-        # Try to get path from registry, if fail use default path
-        return self.ri.lookup(self.ri.vc, 'frameworkdir32') or guess_fw
-
-    @property
-    def FrameworkDir64(self):
-        """
-        Microsoft .NET Framework 64bit directory.
-        """
-        # Default path
-        guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework64')
-
-        # Try to get path from registry, if fail use default path
-        return self.ri.lookup(self.ri.vc, 'frameworkdir64') or guess_fw
-
-    @property
-    def FrameworkVersion32(self):
-        """
-        Microsoft .NET Framework 32bit versions.
-        """
-        return self._find_dot_net_versions(32)
-
-    @property
-    def FrameworkVersion64(self):
-        """
-        Microsoft .NET Framework 64bit versions.
-        """
-        return self._find_dot_net_versions(64)
-
-    def _find_dot_net_versions(self, bits):
-        """
-        Find Microsoft .NET Framework versions.
-
-        Parameters
-        ----------
-        bits: int
-            Platform number of bits: 32 or 64.
-        """
-        # Find actual .NET version in registry
-        reg_ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits)
-        dot_net_dir = getattr(self, 'FrameworkDir%d' % bits)
-        ver = reg_ver or self._use_last_dir_name(dot_net_dir, 'v') or ''
-
-        # Set .NET versions for specified MSVC++ version
-        if self.vc_ver >= 12.0:
-            frameworkver = (ver, 'v4.0')
-        elif self.vc_ver >= 10.0:
-            frameworkver = ('v4.0.30319' if ver.lower()[:2] != 'v4' else ver,
-                            'v3.5')
-        elif self.vc_ver == 9.0:
-            frameworkver = ('v3.5', 'v2.0.50727')
-        if self.vc_ver == 8.0:
-            frameworkver = ('v3.0', 'v2.0.50727')
-        return frameworkver
-
-    def _use_last_dir_name(self, path, prefix=''):
-        """
-        Return name of the last dir in path or '' if no dir found.
-
-        Parameters
-        ----------
-        path: str
-            Use dirs in this path
-        prefix: str
-            Use only dirs startings by this prefix
-        """
-        matching_dirs = (
-            dir_name
-            for dir_name in reversed(os.listdir(path))
-            if os.path.isdir(os.path.join(path, dir_name)) and
-            dir_name.startswith(prefix)
-        )
-        return next(matching_dirs, None) or ''
-
-
-class EnvironmentInfo:
-    """
-    Return environment variables for specified Microsoft Visual C++ version
-    and platform : Lib, Include, Path and libpath.
-
-    This function is compatible with Microsoft Visual C++ 9.0 to 14.0.
-
-    Script created by analysing Microsoft environment configuration files like
-    "vcvars[...].bat", "SetEnv.Cmd", "vcbuildtools.bat", ...
-
-    Parameters
-    ----------
-    arch: str
-        Target architecture.
-    vc_ver: float
-        Required Microsoft Visual C++ version. If not set, autodetect the last
-        version.
-    vc_min_ver: float
-        Minimum Microsoft Visual C++ version.
-    """
-
-    # Variables and properties in this class use originals CamelCase variables
-    # names from Microsoft source files for more easy comparaison.
-
-    def __init__(self, arch, vc_ver=None, vc_min_ver=0):
-        self.pi = PlatformInfo(arch)
-        self.ri = RegistryInfo(self.pi)
-        self.si = SystemInfo(self.ri, vc_ver)
-
-        if self.vc_ver < vc_min_ver:
-            err = 'No suitable Microsoft Visual C++ version found'
-            raise distutils.errors.DistutilsPlatformError(err)
-
-    @property
-    def vc_ver(self):
-        """
-        Microsoft Visual C++ version.
-        """
-        return self.si.vc_ver
-
-    @property
-    def VSTools(self):
-        """
-        Microsoft Visual Studio Tools
-        """
-        paths = [r'Common7\IDE', r'Common7\Tools']
-
-        if self.vc_ver >= 14.0:
-            arch_subdir = self.pi.current_dir(hidex86=True, x64=True)
-            paths += [r'Common7\IDE\CommonExtensions\Microsoft\TestWindow']
-            paths += [r'Team Tools\Performance Tools']
-            paths += [r'Team Tools\Performance Tools%s' % arch_subdir]
-
-        return [os.path.join(self.si.VSInstallDir, path) for path in paths]
-
-    @property
-    def VCIncludes(self):
-        """
-        Microsoft Visual C++ & Microsoft Foundation Class Includes
-        """
-        return [os.path.join(self.si.VCInstallDir, 'Include'),
-                os.path.join(self.si.VCInstallDir, r'ATLMFC\Include')]
-
-    @property
-    def VCLibraries(self):
-        """
-        Microsoft Visual C++ & Microsoft Foundation Class Libraries
-        """
-        if self.vc_ver >= 15.0:
-            arch_subdir = self.pi.target_dir(x64=True)
-        else:
-            arch_subdir = self.pi.target_dir(hidex86=True)
-        paths = ['Lib%s' % arch_subdir, r'ATLMFC\Lib%s' % arch_subdir]
-
-        if self.vc_ver >= 14.0:
-            paths += [r'Lib\store%s' % arch_subdir]
-
-        return [os.path.join(self.si.VCInstallDir, path) for path in paths]
-
-    @property
-    def VCStoreRefs(self):
-        """
-        Microsoft Visual C++ store references Libraries
-        """
-        if self.vc_ver < 14.0:
-            return []
-        return [os.path.join(self.si.VCInstallDir, r'Lib\store\references')]
-
-    @property
-    def VCTools(self):
-        """
-        Microsoft Visual C++ Tools
-        """
-        si = self.si
-        tools = [os.path.join(si.VCInstallDir, 'VCPackages')]
-
-        forcex86 = True if self.vc_ver <= 10.0 else False
-        arch_subdir = self.pi.cross_dir(forcex86)
-        if arch_subdir:
-            tools += [os.path.join(si.VCInstallDir, 'Bin%s' % arch_subdir)]
-
-        if self.vc_ver == 14.0:
-            path = 'Bin%s' % self.pi.current_dir(hidex86=True)
-            tools += [os.path.join(si.VCInstallDir, path)]
-
-        elif self.vc_ver >= 15.0:
-            host_dir = (r'bin\HostX86%s' if self.pi.current_is_x86() else
-                        r'bin\HostX64%s')
-            tools += [os.path.join(
-                si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))]
-
-            if self.pi.current_cpu != self.pi.target_cpu:
-                tools += [os.path.join(
-                    si.VCInstallDir, host_dir % self.pi.current_dir(x64=True))]
-
-        else:
-            tools += [os.path.join(si.VCInstallDir, 'Bin')]
-
-        return tools
-
-    @property
-    def OSLibraries(self):
-        """
-        Microsoft Windows SDK Libraries
-        """
-        if self.vc_ver <= 10.0:
-            arch_subdir = self.pi.target_dir(hidex86=True, x64=True)
-            return [os.path.join(self.si.WindowsSdkDir, 'Lib%s' % arch_subdir)]
-
-        else:
-            arch_subdir = self.pi.target_dir(x64=True)
-            lib = os.path.join(self.si.WindowsSdkDir, 'lib')
-            libver = self._sdk_subdir
-            return [os.path.join(lib, '%sum%s' % (libver , arch_subdir))]
-
-    @property
-    def OSIncludes(self):
-        """
-        Microsoft Windows SDK Include
-        """
-        include = os.path.join(self.si.WindowsSdkDir, 'include')
-
-        if self.vc_ver <= 10.0:
-            return [include, os.path.join(include, 'gl')]
-
-        else:
-            if self.vc_ver >= 14.0:
-                sdkver = self._sdk_subdir
-            else:
-                sdkver = ''
-            return [os.path.join(include, '%sshared' % sdkver),
-                    os.path.join(include, '%sum' % sdkver),
-                    os.path.join(include, '%swinrt' % sdkver)]
-
-    @property
-    def OSLibpath(self):
-        """
-        Microsoft Windows SDK Libraries Paths
-        """
-        ref = os.path.join(self.si.WindowsSdkDir, 'References')
-        libpath = []
-
-        if self.vc_ver <= 9.0:
-            libpath += self.OSLibraries
-
-        if self.vc_ver >= 11.0:
-            libpath += [os.path.join(ref, r'CommonConfiguration\Neutral')]
-
-        if self.vc_ver >= 14.0:
-            libpath += [
-                ref,
-                os.path.join(self.si.WindowsSdkDir, 'UnionMetadata'),
-                os.path.join(
-                    ref,
-                    'Windows.Foundation.UniversalApiContract',
-                    '1.0.0.0',
-                ),
-                os.path.join(
-                    ref,
-                    'Windows.Foundation.FoundationContract',
-                    '1.0.0.0',
-                ),
-                os.path.join(
-                    ref,
-                    'Windows.Networking.Connectivity.WwanContract',
-                    '1.0.0.0',
-                ),
-                os.path.join(
-                    self.si.WindowsSdkDir,
-                    'ExtensionSDKs',
-                    'Microsoft.VCLibs',
-                    '%0.1f' % self.vc_ver,
-                    'References',
-                    'CommonConfiguration',
-                    'neutral',
-                ),
-            ]
-        return libpath
-
-    @property
-    def SdkTools(self):
-        """
-        Microsoft Windows SDK Tools
-        """
-        return list(self._sdk_tools())
-
-    def _sdk_tools(self):
-        """
-        Microsoft Windows SDK Tools paths generator
-        """
-        if self.vc_ver < 15.0:
-            bin_dir = 'Bin' if self.vc_ver <= 11.0 else r'Bin\x86'
-            yield os.path.join(self.si.WindowsSdkDir, bin_dir)
-
-        if not self.pi.current_is_x86():
-            arch_subdir = self.pi.current_dir(x64=True)
-            path = 'Bin%s' % arch_subdir
-            yield os.path.join(self.si.WindowsSdkDir, path)
-
-        if self.vc_ver == 10.0 or self.vc_ver == 11.0:
-            if self.pi.target_is_x86():
-                arch_subdir = ''
-            else:
-                arch_subdir = self.pi.current_dir(hidex86=True, x64=True)
-            path = r'Bin\NETFX 4.0 Tools%s' % arch_subdir
-            yield os.path.join(self.si.WindowsSdkDir, path)
-
-        elif self.vc_ver >= 15.0:
-            path = os.path.join(self.si.WindowsSdkDir, 'Bin')
-            arch_subdir = self.pi.current_dir(x64=True)
-            sdkver = self.si.WindowsSdkLastVersion
-            yield os.path.join(path, '%s%s' % (sdkver, arch_subdir))
-
-        if self.si.WindowsSDKExecutablePath:
-            yield self.si.WindowsSDKExecutablePath
-
-    @property
-    def _sdk_subdir(self):
-        """
-        Microsoft Windows SDK version subdir
-        """
-        ucrtver = self.si.WindowsSdkLastVersion
-        return ('%s\\' % ucrtver) if ucrtver else ''
-
-    @property
-    def SdkSetup(self):
-        """
-        Microsoft Windows SDK Setup
-        """
-        if self.vc_ver > 9.0:
-            return []
-
-        return [os.path.join(self.si.WindowsSdkDir, 'Setup')]
-
-    @property
-    def FxTools(self):
-        """
-        Microsoft .NET Framework Tools
-        """
-        pi = self.pi
-        si = self.si
-
-        if self.vc_ver <= 10.0:
-            include32 = True
-            include64 = not pi.target_is_x86() and not pi.current_is_x86()
-        else:
-            include32 = pi.target_is_x86() or pi.current_is_x86()
-            include64 = pi.current_cpu == 'amd64' or pi.target_cpu == 'amd64'
-
-        tools = []
-        if include32:
-            tools += [os.path.join(si.FrameworkDir32, ver)
-                      for ver in si.FrameworkVersion32]
-        if include64:
-            tools += [os.path.join(si.FrameworkDir64, ver)
-                      for ver in si.FrameworkVersion64]
-        return tools
-
-    @property
-    def NetFxSDKLibraries(self):
-        """
-        Microsoft .Net Framework SDK Libraries
-        """
-        if self.vc_ver < 14.0 or not self.si.NetFxSdkDir:
-            return []
-
-        arch_subdir = self.pi.target_dir(x64=True)
-        return [os.path.join(self.si.NetFxSdkDir, r'lib\um%s' % arch_subdir)]
-
-    @property
-    def NetFxSDKIncludes(self):
-        """
-        Microsoft .Net Framework SDK Includes
-        """
-        if self.vc_ver < 14.0 or not self.si.NetFxSdkDir:
-            return []
-
-        return [os.path.join(self.si.NetFxSdkDir, r'include\um')]
-
-    @property
-    def VsTDb(self):
-        """
-        Microsoft Visual Studio Team System Database
-        """
-        return [os.path.join(self.si.VSInstallDir, r'VSTSDB\Deploy')]
-
-    @property
-    def MSBuild(self):
-        """
-        Microsoft Build Engine
-        """
-        if self.vc_ver < 12.0:
-            return []
-        elif self.vc_ver < 15.0:
-            base_path = self.si.ProgramFilesx86
-            arch_subdir = self.pi.current_dir(hidex86=True)
-        else:
-            base_path = self.si.VSInstallDir
-            arch_subdir = ''
-
-        path = r'MSBuild\%0.1f\bin%s' % (self.vc_ver, arch_subdir)
-        build = [os.path.join(base_path, path)]
-
-        if self.vc_ver >= 15.0:
-            # Add Roslyn C# & Visual Basic Compiler
-            build += [os.path.join(base_path, path, 'Roslyn')]
-
-        return build
-
-    @property
-    def HTMLHelpWorkshop(self):
-        """
-        Microsoft HTML Help Workshop
-        """
-        if self.vc_ver < 11.0:
-            return []
-
-        return [os.path.join(self.si.ProgramFilesx86, 'HTML Help Workshop')]
-
-    @property
-    def UCRTLibraries(self):
-        """
-        Microsoft Universal C Runtime SDK Libraries
-        """
-        if self.vc_ver < 14.0:
-            return []
-
-        arch_subdir = self.pi.target_dir(x64=True)
-        lib = os.path.join(self.si.UniversalCRTSdkDir, 'lib')
-        ucrtver = self._ucrt_subdir
-        return [os.path.join(lib, '%sucrt%s' % (ucrtver, arch_subdir))]
-
-    @property
-    def UCRTIncludes(self):
-        """
-        Microsoft Universal C Runtime SDK Include
-        """
-        if self.vc_ver < 14.0:
-            return []
-
-        include = os.path.join(self.si.UniversalCRTSdkDir, 'include')
-        return [os.path.join(include, '%sucrt' % self._ucrt_subdir)]
-
-    @property
-    def _ucrt_subdir(self):
-        """
-        Microsoft Universal C Runtime SDK version subdir
-        """
-        ucrtver = self.si.UniversalCRTSdkLastVersion
-        return ('%s\\' % ucrtver) if ucrtver else ''
-
-    @property
-    def FSharp(self):
-        """
-        Microsoft Visual F#
-        """
-        if self.vc_ver < 11.0 and self.vc_ver > 12.0:
-            return []
-
-        return self.si.FSharpInstallDir
-
-    @property
-    def VCRuntimeRedist(self):
-        """
-        Microsoft Visual C++ runtime redistribuable dll
-        """
-        arch_subdir = self.pi.target_dir(x64=True)
-        if self.vc_ver < 15:
-            redist_path = self.si.VCInstallDir
-            vcruntime = 'redist%s\\Microsoft.VC%d0.CRT\\vcruntime%d0.dll'
-        else:
-            redist_path = self.si.VCInstallDir.replace('\\Tools', '\\Redist')
-            vcruntime = 'onecore%s\\Microsoft.VC%d0.CRT\\vcruntime%d0.dll'
-
-        # Visual Studio 2017  is still Visual C++ 14.0
-        dll_ver = 14.0 if self.vc_ver == 15 else self.vc_ver
-
-        vcruntime = vcruntime % (arch_subdir, self.vc_ver, dll_ver)
-        return os.path.join(redist_path, vcruntime)
-
-    def return_env(self, exists=True):
-        """
-        Return environment dict.
-
-        Parameters
-        ----------
-        exists: bool
-            It True, only return existing paths.
-        """
-        env = dict(
-            include=self._build_paths('include',
-                                      [self.VCIncludes,
-                                       self.OSIncludes,
-                                       self.UCRTIncludes,
-                                       self.NetFxSDKIncludes],
-                                      exists),
-            lib=self._build_paths('lib',
-                                  [self.VCLibraries,
-                                   self.OSLibraries,
-                                   self.FxTools,
-                                   self.UCRTLibraries,
-                                   self.NetFxSDKLibraries],
-                                  exists),
-            libpath=self._build_paths('libpath',
-                                      [self.VCLibraries,
-                                       self.FxTools,
-                                       self.VCStoreRefs,
-                                       self.OSLibpath],
-                                      exists),
-            path=self._build_paths('path',
-                                   [self.VCTools,
-                                    self.VSTools,
-                                    self.VsTDb,
-                                    self.SdkTools,
-                                    self.SdkSetup,
-                                    self.FxTools,
-                                    self.MSBuild,
-                                    self.HTMLHelpWorkshop,
-                                    self.FSharp],
-                                   exists),
-        )
-        if self.vc_ver >= 14 and os.path.isfile(self.VCRuntimeRedist):
-            env['py_vcruntime_redist'] = self.VCRuntimeRedist
-        return env
-
-    def _build_paths(self, name, spec_path_lists, exists):
-        """
-        Given an environment variable name and specified paths,
-        return a pathsep-separated string of paths containing
-        unique, extant, directories from those paths and from
-        the environment variable. Raise an error if no paths
-        are resolved.
-        """
-        # flatten spec_path_lists
-        spec_paths = itertools.chain.from_iterable(spec_path_lists)
-        env_paths = safe_env.get(name, '').split(os.pathsep)
-        paths = itertools.chain(spec_paths, env_paths)
-        extant_paths = list(filter(os.path.isdir, paths)) if exists else paths
-        if not extant_paths:
-            msg = "%s environment variable is empty" % name.upper()
-            raise distutils.errors.DistutilsPlatformError(msg)
-        unique_paths = self._unique_everseen(extant_paths)
-        return os.pathsep.join(unique_paths)
-
-    # from Python docs
-    def _unique_everseen(self, iterable, key=None):
-        """
-        List unique elements, preserving order.
-        Remember all elements ever seen.
-
-        _unique_everseen('AAAABBBCCDAABBB') --> A B C D
-
-        _unique_everseen('ABBCcAD', str.lower) --> A B C D
-        """
-        seen = set()
-        seen_add = seen.add
-        if key is None:
-            for element in filterfalse(seen.__contains__, iterable):
-                seen_add(element)
-                yield element
-        else:
-            for element in iterable:
-                k = key(element)
-                if k not in seen:
-                    seen_add(k)
-                    yield element