diff --git a/pre_commit/parse_shebang.py b/pre_commit/parse_shebang.py index 5a2ba72f..ab2c9eec 100644 --- a/pre_commit/parse_shebang.py +++ b/pre_commit/parse_shebang.py @@ -51,10 +51,12 @@ def normexe(orig): if exe is None: _error('not found') return exe - elif not os.access(orig, os.X_OK): - _error('not found') elif os.path.isdir(orig): _error('is a directory') + elif not os.path.isfile(orig): + _error('not found') + elif not os.access(orig, os.X_OK): # pragma: windows no cover + _error('is not executable') else: return orig diff --git a/tests/parse_shebang_test.py b/tests/parse_shebang_test.py index 400a287c..58953322 100644 --- a/tests/parse_shebang_test.py +++ b/tests/parse_shebang_test.py @@ -91,6 +91,14 @@ def test_normexe_does_not_exist_sep(): assert excinfo.value.args == ('Executable `./i-dont-exist-lol` not found',) +@pytest.mark.xfail(os.name == 'nt', reason='posix only',) +def test_normexe_not_executable(tmpdir): # pragma: windows no cover + tmpdir.join('exe').ensure() + with tmpdir.as_cwd(), pytest.raises(OSError) as excinfo: + parse_shebang.normexe('./exe') + assert excinfo.value.args == ('Executable `./exe` is not executable',) + + def test_normexe_is_a_directory(tmpdir): with tmpdir.as_cwd(): tmpdir.join('exe').ensure_dir()