# Path: pre_commit/envcontext.py
# @contextlib.contextmanager
# def envcontext(
#         patch: PatchesT,
#         _env: MutableMapping[str, str] | None = None,
# ) -> Generator[None, None, None]:
#     """In this context, `os.environ` is modified according to `patch`.
# 
#     `patch` is an iterable of 2-tuples (key, value):
#         `key`: string
#         `value`:
#             - string: `environ[key] == value` inside the context.
#             - UNSET: `key not in environ` inside the context.
#             - template: A template is a tuple of strings and Var which will be
#               replaced with the previous environment
#     """
#     env = os.environ if _env is None else _env
#     before = dict(env)
# 
#     for k, v in patch:
#         if v is UNSET:
#             env.pop(k, None)
#         elif isinstance(v, tuple):
#             env[k] = format_env(v, before)
#         else:
#             env[k] = v
# 
#     try:
#         yield
#     finally:
#         env.clear()
#         env.update(before)
# 
# Path: pre_commit/languages/python.py
# ENVIRONMENT_DIR = 'py_env'
# def _version_info(exe: str) -> str:
# def _read_pyvenv_cfg(filename: str) -> dict[str, str]:
# def bin_dir(venv: str) -> str:
# def get_env_patch(venv: str) -> PatchesT:
# def _find_by_py_launcher(
#         version: str,
# ) -> str | None:  # pragma: no cover (windows only)
# def _find_by_sys_executable() -> str | None:
#     def _norm(path: str) -> str | None:
# def get_default_version() -> str:  # pragma: no cover (platform dependent)
# def _sys_executable_matches(version: str) -> bool:
# def norm_version(version: str) -> str | None:
# def in_env(
#         prefix: Prefix,
#         language_version: str,
# ) -> Generator[None, None, None]:
# def healthy(prefix: Prefix, language_version: str) -> bool:
# def install_environment(
#         prefix: Prefix,
#         version: str,
#         additional_dependencies: Sequence[str],
# ) -> None:
# def run_hook(
#         hook: Hook,
#         file_args: Sequence[str],
#         color: bool,
# ) -> tuple[int, bytes]:
# 
# Path: pre_commit/prefix.py
# class Prefix(NamedTuple):
#     prefix_dir: str
# 
#     def path(self, *parts: str) -> str:
#         return os.path.normpath(os.path.join(self.prefix_dir, *parts))
# 
#     def exists(self, *parts: str) -> bool:
#         return os.path.exists(self.path(*parts))
# 
#     def star(self, end: str) -> tuple[str, ...]:
#         paths = os.listdir(self.prefix_dir)
#         return tuple(path for path in paths if path.endswith(end))
# 
# Path: pre_commit/util.py
# def make_executable(filename: str) -> None:
#     original_mode = os.stat(filename).st_mode
#     new_mode = original_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
#     os.chmod(filename, new_mode)
# 
# Path: pre_commit/util.py
# def win_exe(s: str) -> str:
#     return s if sys.platform != 'win32' else f'{s}.exe'


import os.path
import sys
import pytest
import pre_commit.constants as C
from unittest import mock
from pre_commit.envcontext import envcontext
from pre_commit.languages import python
from pre_commit.prefix import Prefix
from pre_commit.util import make_executable
from pre_commit.util import win_exe
        assert python.norm_version(v) is None


@pytest.mark.parametrize('v', ('notpython', 'python3.x'))
def test_sys_executable_matches_does_not_match(v):
    with mock.patch.object(sys, 'version_info', (3, 9, 10)):
        assert not python._sys_executable_matches(v)


@pytest.mark.parametrize(
    ('exe', 'realpath', 'expected'), (
        ('/usr/bin/python3', '/usr/bin/python3.7', 'python3'),
        ('/usr/bin/python', '/usr/bin/python3.7', 'python3.7'),
        ('/usr/bin/python', '/usr/bin/python', None),
        ('/usr/bin/python3.7m', '/usr/bin/python3.7m', 'python3.7m'),
        ('v/bin/python', 'v/bin/pypy', 'pypy'),
    ),
)
def test_find_by_sys_executable(exe, realpath, expected):
    with mock.patch.object(sys, 'executable', exe):
        with mock.patch.object(os.path, 'realpath', return_value=realpath):
            with mock.patch.object(python, 'find_executable', lambda x: x):
                assert python._find_by_sys_executable() == expected


@pytest.fixture
def python_dir(tmpdir):
    with tmpdir.as_cwd():
        prefix = tmpdir.join('prefix').ensure_dir()
        prefix.join('setup.py').write('import setuptools; setuptools.setup()')

# Path: pre_commit/envcontext.py
# @contextlib.contextmanager
# def envcontext(
#         patch: PatchesT,
#         _env: MutableMapping[str, str] | None = None,
# ) -> Generator[None, None, None]:
#     """In this context, `os.environ` is modified according to `patch`.
# 
#     `patch` is an iterable of 2-tuples (key, value):
#         `key`: string
#         `value`:
#             - string: `environ[key] == value` inside the context.
#             - UNSET: `key not in environ` inside the context.
#             - template: A template is a tuple of strings and Var which will be
#               replaced with the previous environment
#     """
#     env = os.environ if _env is None else _env
#     before = dict(env)
# 
#     for k, v in patch:
#         if v is UNSET:
#             env.pop(k, None)
#         elif isinstance(v, tuple):
#             env[k] = format_env(v, before)
#         else:
#             env[k] = v
# 
#     try:
#         yield
#     finally:
#         env.clear()
#         env.update(before)
# 
# Path: pre_commit/languages/python.py
# ENVIRONMENT_DIR = 'py_env'
# def _version_info(exe: str) -> str:
# def _read_pyvenv_cfg(filename: str) -> dict[str, str]:
# def bin_dir(venv: str) -> str:
# def get_env_patch(venv: str) -> PatchesT:
# def _find_by_py_launcher(
#         version: str,
# ) -> str | None:  # pragma: no cover (windows only)
# def _find_by_sys_executable() -> str | None:
#     def _norm(path: str) -> str | None:
# def get_default_version() -> str:  # pragma: no cover (platform dependent)
# def _sys_executable_matches(version: str) -> bool:
# def norm_version(version: str) -> str | None:
# def in_env(
#         prefix: Prefix,
#         language_version: str,
# ) -> Generator[None, None, None]:
# def healthy(prefix: Prefix, language_version: str) -> bool:
# def install_environment(
#         prefix: Prefix,
#         version: str,
#         additional_dependencies: Sequence[str],
# ) -> None:
# def run_hook(
#         hook: Hook,
#         file_args: Sequence[str],
#         color: bool,
# ) -> tuple[int, bytes]:
# 
# Path: pre_commit/prefix.py
# class Prefix(NamedTuple):
#     prefix_dir: str
# 
#     def path(self, *parts: str) -> str:
#         return os.path.normpath(os.path.join(self.prefix_dir, *parts))
# 
#     def exists(self, *parts: str) -> bool:
#         return os.path.exists(self.path(*parts))
# 
#     def star(self, end: str) -> tuple[str, ...]:
#         paths = os.listdir(self.prefix_dir)
#         return tuple(path for path in paths if path.endswith(end))
# 
# Path: pre_commit/util.py
# def make_executable(filename: str) -> None:
#     original_mode = os.stat(filename).st_mode
#     new_mode = original_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
#     os.chmod(filename, new_mode)
# 
# Path: pre_commit/util.py
# def win_exe(s: str) -> str:
#     return s if sys.platform != 'win32' else f'{s}.exe'


# Path: tests/languages/python_test.py
import os.path
import sys
import pytest
import pre_commit.constants as C
from unittest import mock
from pre_commit.envcontext import envcontext
from pre_commit.languages import python
from pre_commit.prefix import Prefix
from pre_commit.util import make_executable
from pre_commit.util import win_exe

        assert python.norm_version(v) is None


@pytest.mark.parametrize('v', ('notpython', 'python3.x'))
def test_sys_executable_matches_does_not_match(v):
    with mock.patch.object(sys, 'version_info', (3, 9, 10)):
        assert not python._sys_executable_matches(v)


@pytest.mark.parametrize(
    ('exe', 'realpath', 'expected'), (
        ('/usr/bin/python3', '/usr/bin/python3.7', 'python3'),
        ('/usr/bin/python', '/usr/bin/python3.7', 'python3.7'),
        ('/usr/bin/python', '/usr/bin/python', None),
        ('/usr/bin/python3.7m', '/usr/bin/python3.7m', 'python3.7m'),
        ('v/bin/python', 'v/bin/pypy', 'pypy'),
    ),
)
def test_find_by_sys_executable(exe, realpath, expected):
    with mock.patch.object(sys, 'executable', exe):
        with mock.patch.object(os.path, 'realpath', return_value=realpath):
            with mock.patch.object(python, 'find_executable', lambda x: x):
                assert python._find_by_sys_executable() == expected


@pytest.fixture
def python_dir(tmpdir):
    with tmpdir.as_cwd():
        prefix = tmpdir.join('prefix').ensure_dir()
        prefix.join('setup.py').write('import setuptools; setuptools.setup()')

        prefix = Prefix(str(prefix))