From f956f421be39078617cbb3858796f7562ae26f9e Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 1 Jul 2017 20:12:47 -0700 Subject: [PATCH] Replace our implementation of shebang parsing with identify's --- pre_commit/parse_shebang.py | 35 ++++------------------------------- tests/parse_shebang_test.py | 26 -------------------------- 2 files changed, 4 insertions(+), 57 deletions(-) diff --git a/pre_commit/parse_shebang.py b/pre_commit/parse_shebang.py index be38d15f..4419cbfc 100644 --- a/pre_commit/parse_shebang.py +++ b/pre_commit/parse_shebang.py @@ -1,13 +1,9 @@ from __future__ import absolute_import from __future__ import unicode_literals -import io import os.path -import shlex -import string - -printable = frozenset(string.printable) +from identify.identify import parse_shebang_from_file class ExecutableNotFoundError(OSError): @@ -15,34 +11,11 @@ class ExecutableNotFoundError(OSError): return (1, self.args[0].encode('UTF-8'), b'') -def parse_bytesio(bytesio): - """Parse the shebang from a file opened for reading binary.""" - if bytesio.read(2) != b'#!': - return () - first_line = bytesio.readline() - try: - first_line = first_line.decode('US-ASCII') - except UnicodeDecodeError: - return () - - # Require only printable ascii - for c in first_line: - if c not in printable: - return () - - cmd = tuple(shlex.split(first_line)) - if cmd[0] == '/usr/bin/env': - cmd = cmd[1:] - return cmd - - def parse_filename(filename): - """Parse the shebang given a filename.""" - if not os.path.exists(filename) or not os.access(filename, os.X_OK): + if not os.path.exists(filename): return () - - with io.open(filename, 'rb') as f: - return parse_bytesio(f) + else: + return parse_shebang_from_file(filename) def find_executable(exe, _environ=None): diff --git a/tests/parse_shebang_test.py b/tests/parse_shebang_test.py index 46ca2db8..3f87aea8 100644 --- a/tests/parse_shebang_test.py +++ b/tests/parse_shebang_test.py @@ -15,36 +15,10 @@ from pre_commit.envcontext import Var from pre_commit.util import make_executable -@pytest.mark.parametrize( - ('s', 'expected'), - ( - (b'', ()), - (b'#!/usr/bin/python', ('/usr/bin/python',)), - (b'#!/usr/bin/env python', ('python',)), - (b'#! /usr/bin/python', ('/usr/bin/python',)), - (b'#!/usr/bin/foo python', ('/usr/bin/foo', 'python')), - (b'\xf9\x93\x01\x42\xcd', ()), - (b'#!\xf9\x93\x01\x42\xcd', ()), - (b'#!\x00\x00\x00\x00', ()), - ), -) -def test_parse_bytesio(s, expected): - assert parse_shebang.parse_bytesio(io.BytesIO(s)) == expected - - def test_file_doesnt_exist(): assert parse_shebang.parse_filename('herp derp derp') == () -@pytest.mark.xfail( - sys.platform == 'win32', reason='Windows says everything is X_OK', -) -def test_file_not_executable(tmpdir): - x = tmpdir.join('f') - x.write_text('#!/usr/bin/env python', encoding='UTF-8') - assert parse_shebang.parse_filename(x.strpath) == () - - def test_simple_case(tmpdir): x = tmpdir.join('f') x.write_text('#!/usr/bin/env python', encoding='UTF-8')