From b63b37ac36caf89de55a7ae45bb57d981b1b1e36 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 23 Aug 2020 09:55:29 -0700 Subject: [PATCH] fix cache of invalidated unhealthy environment version info --- pre_commit/languages/python.py | 3 ++- tests/languages/python_test.py | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pre_commit/languages/python.py b/pre_commit/languages/python.py index 6f7c9005..7a685808 100644 --- a/pre_commit/languages/python.py +++ b/pre_commit/languages/python.py @@ -191,7 +191,8 @@ def healthy(prefix: Prefix, language_version: str) -> bool: return ( 'version_info' in cfg and - _version_info(py_exe) == cfg['version_info'] and ( + # always use uncached lookup here in case we replaced an unhealthy env + _version_info.__wrapped__(py_exe) == cfg['version_info'] and ( 'base-executable' not in cfg or _version_info(cfg['base-executable']) == cfg['version_info'] ) diff --git a/tests/languages/python_test.py b/tests/languages/python_test.py index c419ad62..29c5a9bf 100644 --- a/tests/languages/python_test.py +++ b/tests/languages/python_test.py @@ -8,6 +8,7 @@ import pre_commit.constants as C 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 def test_read_pyvenv_cfg(tmpdir): @@ -141,3 +142,26 @@ def test_unhealthy_old_virtualenv(python_dir): os.remove(prefix.path('py_env-default/pyvenv.cfg')) assert python.healthy(prefix, C.DEFAULT) is False + + +def test_unhealthy_then_replaced(python_dir): + prefix, tmpdir = python_dir + + python.install_environment(prefix, C.DEFAULT, ()) + + # simulate an exe which returns an old version + exe_name = 'python.exe' if sys.platform == 'win32' else 'python' + py_exe = prefix.path(python.bin_dir('py_env-default'), exe_name) + os.rename(py_exe, f'{py_exe}.tmp') + + with open(py_exe, 'w') as f: + f.write('#!/usr/bin/env bash\necho 1.2.3\n') + make_executable(py_exe) + + # should be unhealthy due to version mismatch + assert python.healthy(prefix, C.DEFAULT) is False + + # now put the exe back and it should be healthy again + os.replace(f'{py_exe}.tmp', py_exe) + + assert python.healthy(prefix, C.DEFAULT) is True