"""
Test harness for the venv module.

Copyright (C) 2011-2012 Vinay Sajip.
Licensed to the PSF under a contributor agreement.
"""

import contextlib
import ensurepip
import os
import os.path
import pathlib
import re
import shutil
import struct
import subprocess
import sys
import sysconfig
import tempfile
from test.support import (captured_stdout, captured_stderr,
                          skip_if_broken_multiprocessing_synchronize, verbose,
                          requires_subprocess, is_android, is_apple_mobile,
                          is_emscripten, is_wasi,
                          requires_venv_with_pip, TEST_HOME_DIR,
                          requires_resource, copy_python_src_ignore)
from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree,
                                    TESTFN, FakePath)
import unittest
import venv
from unittest.mock import patch, Mock

try:
    import ctypes
except ImportError:
    ctypes = None

# Platforms that set sys._base_executable can create venvs from within
# another venv, so no need to skip tests that require venv.create().
requireVenvCreate = unittest.skipUnless(
    sys.prefix == sys.base_prefix
    or sys._base_executable != sys.executable,
    'cannot run venv.create from within a venv on this platform')

if is_android or is_apple_mobile or is_emscripten or is_wasi:
    raise unittest.SkipTest("venv is not available on this platform")

@requires_subprocess()
def check_output(cmd, encoding=None):
    p = subprocess.Popen(cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        env={**os.environ, "PYTHONHOME": ""})
    out, err = p.communicate()
    if p.returncode:
        if verbose and err:
            print(err.decode(encoding or 'utf-8', 'backslashreplace'))
        raise subprocess.CalledProcessError(
            p.returncode, cmd, out, err)
    if encoding:
        return (
            out.decode(encoding, 'backslashreplace'),
            err.decode(encoding, 'backslashreplace'),
        )
    return out, err

class BaseTest(unittest.TestCase):
    """Base class for venv tests."""
    maxDiff = 80 * 50

    def setUp(self):
        self.env_dir = os.path.realpath(tempfile.mkdtemp())
        if os.name == 'nt':
            self.bindir = 'Scripts'
            self.lib = ('Lib',)
            self.include = 'Include'
        else:
            self.bindir = 'bin'
            self.lib = ('lib', f'python{sysconfig._get_python_version_abi()}')
            self.include = 'include'
        executable = sys._base_executable
        self.exe = os.path.split(executable)[-1]
        if (sys.platform == 'win32'
            and os.path.lexists(executable)
            and not os.path.exists(executable)):
            self.cannot_link_exe = True
        else:
            self.cannot_link_exe = False

    def tearDown(self):
        rmtree(self.env_dir)

    def envpy(self, *, real_env_dir=False):
        if real_env_dir:
            env_dir = os.path.realpath(self.env_dir)
        else:
            env_dir = self.env_dir
        return os.path.join(env_dir, self.bindir, self.exe)

    def run_with_capture(self, func, *args, **kwargs):
        with captured_stdout() as output:
            with captured_stderr() as error:
                func(*args, **kwargs)
        return output.getvalue(), error.getvalue()

    def get_env_file(self, *args):
        return os.path.join(self.env_dir, *args)

    def get_text_file_contents(self, *args, encoding='utf-8'):
        with open(self.get_env_file(*args), 'r', encoding=encoding) as f:
            result = f.read()
        return result

class BasicTest(BaseTest):
    """Test venv module functionality."""

    def isdir(self, *args):
        fn = self.get_env_file(*args)
        self.assertTrue(os.path.isdir(fn))

    def test_defaults_with_str_path(self):
        """
        Test the create function with default arguments and a str path.
        """
        rmtree(self.env_dir)
        self.run_with_capture(venv.create, self.env_dir)
        self._check_output_of_default_create()

    def test_defaults_with_pathlike(self):
        """
        Test the create function with default arguments and a path-like path.
        """
        rmtree(self.env_dir)
        self.run_with_capture(venv.create, FakePath(self.env_dir))
        self._check_output_of_default_create()

    def _check_output_of_default_create(self):
        self.isdir(self.bindir)
        self.isdir(self.include)
        self.isdir(*self.lib)
        # Issue 21197
        p = self.get_env_file('lib64')
        conditions = ((struct.calcsize('P') == 8) and (os.name == 'posix') and
                      (sys.platform != 'darwin'))
        if conditions:
            self.assertTrue(os.path.islink(p))
        else:
            self.assertFalse(os.path.exists(p))
        data = self.get_text_file_contents('pyvenv.cfg')
        executable = sys._base_executable
        path = os.path.dirname(executable)
        self.assertIn('home = %s' % path, data)
        self.assertIn('executable = %s' %
                      os.path.realpath(sys.executable), data)
        copies = '' if os.name=='nt' else ' --copies'
        cmd = (f'command = {sys.executable} -m venv{copies} --without-pip '
               f'--without-scm-ignore-files {self.env_dir}')
        self.assertIn(cmd, data)
        fn = self.get_env_file(self.bindir, self.exe)
        if not os.path.exists(fn):  # diagnostics for Windows buildbot failures
            bd = self.get_env_file(self.bindir)
            print('Contents of %r:' % bd)
            print('    %r' % os.listdir(bd))
        self.assertTrue(os.path.exists(fn), 'File %r should exist.' % fn)

    def test_config_file_command_key(self):
        options = [
            (None, None, None),  # Default case.
            ('--copies', 'symlinks', False),
            ('--without-pip', 'with_pip', False),
            ('--system-site-packages', 'system_site_packages', True),
            ('--clear', 'clear', True),
            ('--upgrade', 'upgrade', True),
            ('--upgrade-deps', 'upgrade_deps', True),
            ('--prompt="foobar"', 'prompt', 'foobar'),
            ('--without-scm-ignore-files', 'scm_ignore_files', frozenset()),
        ]
        for opt, attr, value in options:
            with self.subTest(opt=opt, attr=attr, value=value):
                rmtree(self.env_dir)
                if not attr:
                    kwargs = {}
                else:
                    kwargs = {attr: value}
                b = venv.EnvBuilder(**kwargs)
                b.upgrade_dependencies = Mock() # avoid pip command to upgrade deps
                b._setup_pip = Mock() # avoid pip setup
                self.run_with_capture(b.create, self.env_dir)
                data = self.get_text_file_contents('pyvenv.cfg')
                if not attr or opt.endswith('git'):
                    for opt in ('--system-site-packages', '--clear', '--upgrade',
                                '--upgrade-deps', '--prompt'):
                        self.assertNotRegex(data, rf'command = .* {opt}')
                elif os.name=='nt' and attr=='symlinks':
                    pass
                else:
                    self.assertRegex(data, rf'command = .* {opt}')

    def test_prompt(self):
        env_name = os.path.split(self.env_dir)[1]

        rmtree(self.env_dir)
        builder = venv.EnvBuilder()
        self.run_with_capture(builder.create, self.env_dir)
        context = builder.ensure_directories(self.env_dir)
        data = self.get_text_file_contents('pyvenv.cfg')
        self.assertEqual(context.prompt, env_name)
        self.assertNotIn("prompt = ", data)

        rmtree(self.env_dir)
        builder = venv.EnvBuilder(prompt='My prompt')
        self.run_with_capture(builder.create, self.env_dir)
        context = builder.ensure_directories(self.env_dir)
        data = self.get_text_file_contents('pyvenv.cfg')
        self.assertEqual(context.prompt, 'My prompt')
        self.assertIn("prompt = 'My prompt'\n", data)

        rmtree(self.env_dir)
        builder = venv.EnvBuilder(prompt='.')
        cwd = os.path.basename(os.getcwd())
        self.run_with_capture(builder.create, self.env_dir)
        context = builder.ensure_directories(self.env_dir)
        data = self.get_text_file_contents('pyvenv.cfg')
        self.assertEqual(context.prompt, cwd)
        self.assertIn("prompt = '%s'\n" % cwd, data)

    def test_upgrade_dependencies(self):
        builder = venv.EnvBuilder()
        bin_path = 'bin'
        python_exe = os.path.split(sys.executable)[1]
        if sys.platform == 'win32':
            bin_path = 'Scripts'
            if os.path.normcase(os.path.splitext(python_exe)[0]).endswith('_d'):
                python_exe = 'python_d.exe'
            else:
                python_exe = 'python.exe'
        with tempfile.TemporaryDirectory() as fake_env_dir:
            expect_exe = os.path.normcase(
                os.path.join(fake_env_dir, bin_path, python_exe)
            )
            if sys.platform == 'win32':
                expect_exe = os.path.normcase(os.path.realpath(expect_exe))

            def pip_cmd_checker(cmd, **kwargs):
                cmd[0] = os.path.normcase(cmd[0])
                self.assertEqual(
                    cmd,
                    [
                        expect_exe,
                        '-m',
                        'pip',
                        'install',
                        '--upgrade',
                        'pip',
                    ]
                )

            fake_context = builder.ensure_directories(fake_env_dir)
            with patch('venv.subprocess.check_output', pip_cmd_checker):
                builder.upgrade_dependencies(fake_context)

    @requireVenvCreate
    def test_prefixes(self):
        """
        Test that the prefix values are as expected.
        """
        # check a venv's prefixes
        rmtree(self.env_dir)
        self.run_with_capture(venv.create, self.env_dir)
        cmd = [self.envpy(), '-c', None]
        for prefix, expected in (
            ('prefix', self.env_dir),
            ('exec_prefix', self.env_dir),
            ('base_prefix', sys.base_prefix),
            ('base_exec_prefix', sys.base_exec_prefix)):
            cmd[2] = 'import sys; print(sys.%s)' % prefix
            out, err = check_output(cmd)
            self.assertEqual(pathlib.Path(out.strip().decode()),
                             pathlib.Path(expected), prefix)

    @requireVenvCreate
    def test_sysconfig(self):
        """
        Test that the sysconfig functions work in a virtual environment.
        """
        rmtree(self.env_dir)
        self.run_with_capture(venv.create, self.env_dir, symlinks=False)
        cmd = [self.envpy(), '-c', None]
        for call, expected in (
            # installation scheme
            ('get_preferred_scheme("prefix")', 'venv'),
            ('get_default_scheme()', 'venv'),
            # build environment
            ('is_python_build()', str(sysconfig.is_python_build())),
            ('get_makefile_filename()', sysconfig.get_makefile_filename()),
            ('get_config_h_filename()', sysconfig.get_config_h_filename()),
            ('get_config_var("Py_GIL_DISABLED")',
             str(sysconfig.get_config_var("Py_GIL_DISABLED")))):
            with self.subTest(call):
                cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call
                out, err = check_output(cmd, encoding='utf-8')
                self.assertEqual(out.strip(), expected, err)
        for attr, expected in (
            ('executable', self.envpy()),
            # Usually compare to sys.executable, but if we're running in our own
            # venv then we really need to compare to our base executable
            ('_base_executable', sys._base_executable),
        ):
            with self.subTest(attr):
                cmd[2] = f'import sys; print(sys.{attr})'
                out, err = check_output(cmd, encoding='utf-8')
                self.assertEqual(out.strip(), expected, err)

    @requireVenvCreate
    @unittest.skipUnless(can_symlink(), 'Needs symlinks')
    def test_sysconfig_symlinks(self):
        """
        Test that the sysconfig functions work in a virtual environment.
        """
        rmtree(self.env_dir)
        self.run_with_capture(venv.create, self.env_dir, symlinks=True)
        cmd = [self.envpy(), '-c', None]
        for call, expected in (
            # installation scheme
            ('get_preferred_scheme("prefix")', 'venv'),
            ('get_default_scheme()', 'venv'),
            # build environment
            ('is_python_build()', str(sysconfig.is_python_build())),
            ('get_makefile_filename()', sysconfig.get_makefile_filename()),
            ('get_config_h_filename()', sysconfig.get_config_h_filename()),
            ('get_config_var("Py_GIL_DISABLED")',
             str(sysconfig.get_config_var("Py_GIL_DISABLED")))):
            with self.subTest(call):
                cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call
                out, err = check_output(cmd, encoding='utf-8')
                self.assertEqual(out.strip(), expected, err)
        for attr, expected in (
            ('executable', self.envpy()),
            # Usually compare to sys.executable, but if we're running in our own
            # venv then we really need to compare to our base executable
            # HACK: Test fails on POSIX with unversioned binary (PR gh-113033)
            #('_base_executable', sys._base_executable),
        ):
            with self.subTest(attr):
                cmd[2] = f'import sys; print(sys.{attr})'
                out, err = check_output(cmd, encoding='utf-8')
                self.assertEqual(out.strip(), expected, err)

    if sys.platform == 'win32':
        ENV_SUBDIRS = (
            ('Scripts',),
            ('Include',),
            ('Lib',),
            ('Lib', 'site-packages'),
        )
    else:
        ENV_SUBDIRS = (
            ('bin',),
            ('include',),
            ('lib',),
            ('lib', 'python%d.%d' % sys.version_info[:2]),
            ('lib', 'python%d.%d' % sys.version_info[:2], 'site-packages'),
        )

    def create_contents(self, paths, filename):
        """
        Create some files in the environment which are unrelated
        to the virtual environment.
        """
        for subdirs in paths:
            d = os.path.join(self.env_dir, *subdirs)
            os.mkdir(d)
            fn = os.path.join(d, filename)
            with open(fn, 'wb') as f:
                f.write(b'Still here?')

    def test_overwrite_existing(self):
        """
        Test creating environment in an existing directory.
        """
        self.create_contents(self.ENV_SUBDIRS, 'foo')
        venv.create(self.env_dir)
        for subdirs in self.ENV_SUBDIRS:
            fn = os.path.join(self.env_dir, *(subdirs + ('foo',)))
            self.assertTrue(os.path.exists(fn))
            with open(fn, 'rb') as f:
                self.assertEqual(f.read(), b'Still here?')

        builder = venv.EnvBuilder(clear=True)
        builder.create(self.env_dir)
        for subdirs in self.ENV_SUBDIRS:
            fn = os.path.join(self.env_dir, *(subdirs + ('foo',)))
            self.assertFalse(os.path.exists(fn))

    def clear_directory(self, path):
        for fn in os.listdir(path):
            fn = os.path.join(path, fn)
            if os.path.islink(fn) or os.path.isfile(fn):
                os.remove(fn)
            elif os.path.isdir(fn):
                rmtree(fn)

    def test_unoverwritable_fails(self):
        #create a file clashing with directories in the env dir
        for paths in self.ENV_SUBDIRS[:3]:
            fn = os.path.join(self.env_dir, *paths)
            with open(fn, 'wb') as f:
                f.write(b'')
            self.assertRaises((ValueError, OSError), venv.create, self.env_dir)
            self.clear_directory(self.env_dir)

    def test_upgrade(self):
        """
        Test upgrading an existing environment directory.
        """
        # See Issue #21643: the loop needs to run twice to ensure
        # that everything works on the upgrade (the first run just creates
        # the venv).
        for upgrade in (False, True):
            builder = venv.EnvBuilder(upgrade=upgrade)
            self.run_with_capture(builder.create, self.env_dir)
            self.isdir(self.bindir)
            self.isdir(self.include)
            self.isdir(*self.lib)
            fn = self.get_env_file(self.bindir, self.exe)
            if not os.path.exists(fn):
                # diagnostics for Windows buildbot failures
                bd = self.get_env_file(self.bindir)
                print('Contents of %r:' % bd)
                print('    %r' % os.listdir(bd))
            self.assertTrue(os.path.exists(fn), 'File %r should exist.' % fn)

    def test_isolation(self):
        """
        Test isolation from system site-packages
        """
        for ssp, s in ((True, 'true'), (False, 'false')):
            builder = venv.EnvBuilder(clear=True, system_site_packages=ssp)
            builder.create(self.env_dir)
            data = self.get_text_file_contents('pyvenv.cfg')
            self.assertIn('include-system-site-packages = %s\n' % s, data)

    @unittest.skipUnless(can_symlink(), 'Needs symlinks')
    def test_symlinking(self):
        """
        Test symlinking works as expected
        """
        for usl in (False, True):
            builder = venv.EnvBuilder(clear=True, symlinks=usl)
            builder.create(self.env_dir)
            fn = self.get_env_file(self.bindir, self.exe)
            # Don't test when False, because e.g. 'python' is always
            # symlinked to 'python3.3' in the env, even when symlinking in
            # general isn't wanted.
            if usl:
                if self.cannot_link_exe:
                    # Symlinking is skipped when our executable is already a
                    # special app symlink
                    self.assertFalse(os.path.islink(fn))
                else:
                    self.assertTrue(os.path.islink(fn))

    # If a venv is created from a source build and that venv is used to
    # run the test, the pyvenv.cfg in the venv created in the test will
    # point to the venv being used to run the test, and we lose the link
    # to the source build - so Python can't initialise properly.
    @requireVenvCreate
    def test_executable(self):
        """
        Test that the sys.executable value is as expected.
        """
        rmtree(self.env_dir)
        self.run_with_capture(venv.create, self.env_dir)
        envpy = self.envpy(real_env_dir=True)
        out, err = check_output([envpy, '-c',
            'import sys; print(sys.executable)'])
        self.assertEqual(out.strip(), envpy.encode())

    @unittest.skipUnless(can_symlink(), 'Needs symlinks')
    def test_executable_symlinks(self):
        """
        Test that the sys.executable value is as expected.
        """
        rmtree(self.env_dir)
        builder = venv.EnvBuilder(clear=True, symlinks=True)
        builder.create(self.env_dir)
        envpy = self.envpy(real_env_dir=True)
        out, err = check_output([envpy, '-c',
            'import sys; print(sys.executable)'])
        self.assertEqual(out.strip(), envpy.encode())

    @unittest.skipUnless(os.name == 'nt', 'only relevant on Windows')
    def test_unicode_in_batch_file(self):
        """
        Test handling of Unicode paths
        """
        rmtree(self.env_dir)
        env_dir = os.path.join(os.path.realpath(self.env_dir), 'ϼўТλФЙ')
        builder = venv.EnvBuilder(clear=True)
        builder.create(env_dir)
        activate = os.path.join(env_dir, self.bindir, 'activate.bat')
        out, err = check_output(
            [activate, '&', self.exe, '-c', 'print(0)'],
            encoding='oem',
        )
        self.assertEqual(out.strip(), '0')

    @requireVenvCreate
    def test_multiprocessing(self):
        """
        Test that the multiprocessing is able to spawn.
        """
        # bpo-36342: Instantiation of a Pool object imports the
        # multiprocessing.synchronize module. Skip the test if this module
        # cannot be imported.
        skip_if_broken_multiprocessing_synchronize()

        rmtree(self.env_dir)
        self.run_with_capture(venv.create, self.env_dir)
        out, err = check_output([self.envpy(real_env_dir=True), '-c',
            'from multiprocessing import Pool; '
            'pool = Pool(1); '
            'print(pool.apply_async("Python".lower).get(3)); '
            'pool.terminate()'])
        self.assertEqual(out.strip(), "python".encode())

    @requireVenvCreate
    def test_multiprocessing_recursion(self):
        """
        Test that the multiprocessing is able to spawn itself
        """
        skip_if_broken_multiprocessing_synchronize()

        rmtree(self.env_dir)
        self.run_with_capture(venv.create, self.env_dir)
        script = os.path.join(TEST_HOME_DIR, '_test_venv_multiprocessing.py')
        subprocess.check_call([self.envpy(real_env_dir=True), "-I", script])

    @unittest.skipIf(os.name == 'nt', 'not relevant on Windows')
    def test_deactivate_with_strict_bash_opts(self):
        bash = shutil.which("bash")
        if bash is None:
            self.skipTest("bash required for this test")
        rmtree(self.env_dir)
        builder = venv.EnvBuilder(clear=True)
        builder.create(self.env_dir)
        activate = os.path.join(self.env_dir, self.bindir, "activate")
        test_script = os.path.join(self.env_dir, "test_strict.sh")
        with open(test_script, "w") as f:
            f.write("set -euo pipefail\n"
                    f"source {activate}\n"
                    "deactivate\n")
        out, err = check_output([bash, test_script])
        self.assertEqual(out, "".encode())
        self.assertEqual(err, "".encode())


    @unittest.skipUnless(sys.platform == 'darwin', 'only relevant on macOS')
    def test_macos_env(self):
        rmtree(self.env_dir)
        builder = venv.EnvBuilder()
        builder.create(self.env_dir)

        out, err = check_output([self.envpy(real_env_dir=True), '-c',
            'import os; print("__PYVENV_LAUNCHER__" in os.environ)'])
        self.assertEqual(out.strip(), 'False'.encode())

    def test_pathsep_error(self):
        """
        Test that venv creation fails when the target directory contains
        the path separator.
        """
        rmtree(self.env_dir)
        bad_itempath = self.env_dir + os.pathsep
        self.assertRaises(ValueError, venv.create, bad_itempath)
        self.assertRaises(ValueError, venv.create, FakePath(bad_itempath))

    @unittest.skipIf(os.name == 'nt', 'not relevant on Windows')
    @requireVenvCreate
    def test_zippath_from_non_installed_posix(self):
        """
        Test that when create venv from non-installed python, the zip path
        value is as expected.
        """
        rmtree(self.env_dir)
        # First try to create a non-installed python. It's not a real full
        # functional non-installed python, but enough for this test.
        platlibdir = sys.platlibdir
        non_installed_dir = os.path.realpath(tempfile.mkdtemp())
        self.addCleanup(rmtree, non_installed_dir)
        bindir = os.path.join(non_installed_dir, self.bindir)
        os.mkdir(bindir)
        shutil.copy2(sys.executable, bindir)
        libdir = os.path.join(non_installed_dir, platlibdir, self.lib[1])
        os.makedirs(libdir)
        landmark = os.path.join(libdir, "os.py")
        abi_thread = "t" if sysconfig.get_config_var("Py_GIL_DISABLED") else ""
        stdlib_zip = f"python{sys.version_info.major}{sys.version_info.minor}{abi_thread}"
        zip_landmark = os.path.join(non_installed_dir,
                                    platlibdir,
                                    stdlib_zip)
        additional_pythonpath_for_non_installed = []

        # Copy stdlib files to the non-installed python so venv can
        # correctly calculate the prefix.
        for eachpath in sys.path:
            if eachpath.endswith(".zip"):
                if os.path.isfile(eachpath):
                    shutil.copyfile(
                        eachpath,
                        os.path.join(non_installed_dir, platlibdir))
            elif os.path.isfile(os.path.join(eachpath, "os.py")):
                names = os.listdir(eachpath)
                ignored_names = copy_python_src_ignore(eachpath, names)
                for name in names:
                    if name in ignored_names:
                        continue
                    if name == "site-packages":
                        continue
                    fn = os.path.join(eachpath, name)
                    if os.path.isfile(fn):
                        shutil.copy(fn, libdir)
                    elif os.path.isdir(fn):
                        shutil.copytree(fn, os.path.join(libdir, name),
                                        ignore=copy_python_src_ignore)
            else:
                additional_pythonpath_for_non_installed.append(
                    eachpath)
        cmd = [os.path.join(non_installed_dir, self.bindir, self.exe),
               "-m",
               "venv",
               "--without-pip",
               "--without-scm-ignore-files",
               self.env_dir]
        # Our fake non-installed python is not fully functional because
        # it cannot find the extensions. Set PYTHONPATH so it can run the
        # venv module correctly.
        pythonpath = os.pathsep.join(
            additional_pythonpath_for_non_installed)
        # For python built with shared enabled. We need to set
        # LD_LIBRARY_PATH so the non-installed python can find and link
        # libpython.so
        ld_library_path = sysconfig.get_config_var("LIBDIR")
        if not ld_library_path or sysconfig.is_python_build():
            ld_library_path = os.path.abspath(os.path.dirname(sys.executable))
        if sys.platform == 'darwin':
            ld_library_path_env = "DYLD_LIBRARY_PATH"
        else:
            ld_library_path_env = "LD_LIBRARY_PATH"
        child_env = {
                "PYTHONPATH": pythonpath,
                ld_library_path_env: ld_library_path,
        }
        if asan_options := os.environ.get("ASAN_OPTIONS"):
            # prevent https://github.com/python/cpython/issues/104839
            child_env["ASAN_OPTIONS"] = asan_options
        subprocess.check_call(cmd, env=child_env)
        # Now check the venv created from the non-installed python has
        # correct zip path in pythonpath.
        cmd = [self.envpy(), '-S', '-c', 'import sys; print(sys.path)']
        out, err = check_output(cmd)
        self.assertTrue(zip_landmark.encode() in out)

    @requireVenvCreate
    def test_activate_shell_script_has_no_dos_newlines(self):
        """
        Test that the `activate` shell script contains no CR LF.
        This is relevant for Cygwin, as the Windows build might have
        converted line endings accidentally.
        """
        venv_dir = pathlib.Path(self.env_dir)
        rmtree(venv_dir)
        [[scripts_dir], *_] = self.ENV_SUBDIRS
        script_path = venv_dir / scripts_dir / "activate"
        venv.create(venv_dir)
        with open(script_path, 'rb') as script:
            for i, line in enumerate(script, 1):
                error_message = f"CR LF found in line {i}"
                self.assertFalse(line.endswith(b'\r\n'), error_message)

    @requireVenvCreate
    def test_scm_ignore_files_git(self):
        """
        Test that a .gitignore file is created when "git" is specified.
        The file should contain a `*\n` line.
        """
        self.run_with_capture(venv.create, self.env_dir,
                              scm_ignore_files={'git'})
        file_lines = self.get_text_file_contents('.gitignore').splitlines()
        self.assertIn('*', file_lines)

    @requireVenvCreate
    def test_create_scm_ignore_files_multiple(self):
        """
        Test that ``scm_ignore_files`` can work with multiple SCMs.
        """
        bzrignore_name = ".bzrignore"
        contents = "# For Bazaar.\n*\n"

        class BzrEnvBuilder(venv.EnvBuilder):
            def create_bzr_ignore_file(self, context):
                gitignore_path = os.path.join(context.env_dir, bzrignore_name)
                with open(gitignore_path, 'w', encoding='utf-8') as file:
                    file.write(contents)

        builder = BzrEnvBuilder(scm_ignore_files={'git', 'bzr'})
        self.run_with_capture(builder.create, self.env_dir)

        gitignore_lines = self.get_text_file_contents('.gitignore').splitlines()
        self.assertIn('*', gitignore_lines)

        bzrignore = self.get_text_file_contents(bzrignore_name)
        self.assertEqual(bzrignore, contents)

    @requireVenvCreate
    def test_create_scm_ignore_files_empty(self):
        """
        Test that no default ignore files are created when ``scm_ignore_files``
        is empty.
        """
        # scm_ignore_files is set to frozenset() by default.
        self.run_with_capture(venv.create, self.env_dir)
        with self.assertRaises(FileNotFoundError):
            self.get_text_file_contents('.gitignore')

        self.assertIn("--without-scm-ignore-files",
                      self.get_text_file_contents('pyvenv.cfg'))

    @requireVenvCreate
    def test_cli_with_scm_ignore_files(self):
        """
        Test that default SCM ignore files are created by default via the CLI.
        """
        self.run_with_capture(venv.main, ['--without-pip', self.env_dir])

        gitignore_lines = self.get_text_file_contents('.gitignore').splitlines()
        self.assertIn('*', gitignore_lines)

    @requireVenvCreate
    def test_cli_without_scm_ignore_files(self):
        """
        Test that ``--without-scm-ignore-files`` doesn't create SCM ignore files.
        """
        args = ['--without-pip', '--without-scm-ignore-files', self.env_dir]
        self.run_with_capture(venv.main, args)

        with self.assertRaises(FileNotFoundError):
            self.get_text_file_contents('.gitignore')

    def test_venv_same_path(self):
        same_path = venv.EnvBuilder._same_path
        if sys.platform == 'win32':
            # Case-insensitive, and handles short/long names
            tests = [
                (True, TESTFN, TESTFN),
                (True, TESTFN.lower(), TESTFN.upper()),
            ]
            import _winapi
            # ProgramFiles is the most reliable path that will have short/long
            progfiles = os.getenv('ProgramFiles')
            if progfiles:
                tests = [
                    *tests,
                    (True, progfiles, progfiles),
                    (True, _winapi.GetShortPathName(progfiles), _winapi.GetLongPathName(progfiles)),
                ]
        else:
            # Just a simple case-sensitive comparison
            tests = [
                (True, TESTFN, TESTFN),
                (False, TESTFN.lower(), TESTFN.upper()),
            ]
        for r, path1, path2 in tests:
            with self.subTest(f"{path1}-{path2}"):
                if r:
                    self.assertTrue(same_path(path1, path2))
                else:
                    self.assertFalse(same_path(path1, path2))

@requireVenvCreate
class EnsurePipTest(BaseTest):
    """Test venv module installation of pip."""
    def assert_pip_not_installed(self):
        out, err = check_output([self.envpy(real_env_dir=True), '-c',
            'try:\n import pip\nexcept ImportError:\n print("OK")'])
        # We force everything to text, so unittest gives the detailed diff
        # if we get unexpected results
        err = err.decode("latin-1") # Force to text, prevent decoding errors
        self.assertEqual(err, "")
        out = out.decode("latin-1") # Force to text, prevent decoding errors
        self.assertEqual(out.strip(), "OK")


    def test_no_pip_by_default(self):
        rmtree(self.env_dir)
        self.run_with_capture(venv.create, self.env_dir)
        self.assert_pip_not_installed()

    def test_explicit_no_pip(self):
        rmtree(self.env_dir)
        self.run_with_capture(venv.create, self.env_dir, with_pip=False)
        self.assert_pip_not_installed()

    def test_devnull(self):
        # Fix for issue #20053 uses os.devnull to force a config file to
        # appear empty. However http://bugs.python.org/issue20541 means
        # that doesn't currently work properly on Windows. Once that is
        # fixed, the "win_location" part of test_with_pip should be restored
        with open(os.devnull, "rb") as f:
            self.assertEqual(f.read(), b"")

        self.assertTrue(os.path.exists(os.devnull))

    def do_test_with_pip(self, system_site_packages):
        rmtree(self.env_dir)
        with EnvironmentVarGuard() as envvars:
            # pip's cross-version compatibility may trigger deprecation
            # warnings in current versions of Python. Ensure related
            # environment settings don't cause venv to fail.
            envvars["PYTHONWARNINGS"] = "ignore"
            # ensurepip is different enough from a normal pip invocation
            # that we want to ensure it ignores the normal pip environment
            # variable settings. We set PIP_NO_INSTALL here specifically
            # to check that ensurepip (and hence venv) ignores it.
            # See http://bugs.python.org/issue19734
            envvars["PIP_NO_INSTALL"] = "1"
            # Also check that we ignore the pip configuration file
            # See http://bugs.python.org/issue20053
            with tempfile.TemporaryDirectory() as home_dir:
                envvars["HOME"] = home_dir
                bad_config = "[global]\nno-install=1"
                # Write to both config file names on all platforms to reduce
                # cross-platform variation in test code behaviour
                win_location = ("pip", "pip.ini")
                posix_location = (".pip", "pip.conf")
                # Skips win_location due to http://bugs.python.org/issue20541
                for dirname, fname in (posix_location,):
                    dirpath = os.path.join(home_dir, dirname)
                    os.mkdir(dirpath)
                    fpath = os.path.join(dirpath, fname)
                    with open(fpath, 'w') as f:
                        f.write(bad_config)

                # Actually run the create command with all that unhelpful
                # config in place to ensure we ignore it
                with self.nicer_error():
                    self.run_with_capture(venv.create, self.env_dir,
                                          system_site_packages=system_site_packages,
                                          with_pip=True)
        # Ensure pip is available in the virtual environment
        # Ignore DeprecationWarning since pip code is not part of Python
        out, err = check_output([self.envpy(real_env_dir=True),
               '-W', 'ignore::DeprecationWarning',
               '-W', 'ignore::ImportWarning', '-I',
               '-m', 'pip', '--version'])
        # We force everything to text, so unittest gives the detailed diff
        # if we get unexpected results
        err = err.decode("latin-1") # Force to text, prevent decoding errors
        self.assertEqual(err, "")
        out = out.decode("latin-1") # Force to text, prevent decoding errors
        expected_version = "pip {}".format(ensurepip.version())
        self.assertEqual(out[:len(expected_version)], expected_version)
        env_dir = os.fsencode(self.env_dir).decode("latin-1")
        self.assertIn(env_dir, out)

        # http://bugs.python.org/issue19728
        # Check the private uninstall command provided for the Windows
        # installers works (at least in a virtual environment)
        with EnvironmentVarGuard() as envvars:
            with self.nicer_error():
                # It seems ensurepip._uninstall calls subprocesses which do not
                # inherit the interpreter settings.
                envvars["PYTHONWARNINGS"] = "ignore"
                out, err = check_output([self.envpy(real_env_dir=True),
                    '-W', 'ignore::DeprecationWarning',
                    '-W', 'ignore::ImportWarning', '-I',
                    '-m', 'ensurepip._uninstall'])
        # We force everything to text, so unittest gives the detailed diff
        # if we get unexpected results
        err = err.decode("latin-1") # Force to text, prevent decoding errors
        # Ignore the warning:
        #   "The directory '$HOME/.cache/pip/http' or its parent directory
        #    is not owned by the current user and the cache has been disabled.
        #    Please check the permissions and owner of that directory. If
        #    executing pip with sudo, you may want sudo's -H flag."
        # where $HOME is replaced by the HOME environment variable.
        err = re.sub("^(WARNING: )?The directory .* or its parent directory "
                     "is not owned or is not writable by the current user.*$", "",
                     err, flags=re.MULTILINE)
        # Ignore warning about missing optional module:
        try:
            import ssl
        except ImportError:
            err = re.sub(
                "^WARNING: Disabling truststore since ssl support is missing$",
                "",
                err, flags=re.MULTILINE)
        self.assertEqual(err.rstrip(), "")
        # Being fairly specific regarding the expected behaviour for the
        # initial bundling phase in Python 3.4. If the output changes in
        # future pip versions, this test can likely be relaxed further.
        out = out.decode("latin-1") # Force to text, prevent decoding errors
        self.assertIn("Successfully uninstalled pip", out)
        # Check pip is now gone from the virtual environment. This only
        # applies in the system_site_packages=False case, because in the
        # other case, pip may still be available in the system site-packages
        if not system_site_packages:
            self.assert_pip_not_installed()

    @contextlib.contextmanager
    def nicer_error(self):
        """
        Capture output from a failed subprocess for easier debugging.

        The output this handler produces can be a little hard to read,
        but at least it has all the details.
        """
        try:
            yield
        except subprocess.CalledProcessError as exc:
            out = (exc.output or b'').decode(errors="replace")
            err = (exc.stderr or b'').decode(errors="replace")
            self.fail(
                f"{exc}\n\n"
                f"**Subprocess Output**\n{out}\n\n"
                f"**Subprocess Error**\n{err}"
            )

    @requires_venv_with_pip()
    @requires_resource('cpu')
    def test_with_pip(self):
        self.do_test_with_pip(False)
        self.do_test_with_pip(True)


if __name__ == "__main__":
    unittest.main()
