New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Types #551

merged 4 commits into from Jul 3, 2017
Jump to file or symbol
Failed to load files and symbols.
+4 鈭57
Diff settings


Just for now

Viewing a subset of changes. View all

Replace our implementation of shebang parsing with identify's

  • Loading branch information...
asottile committed Jul 2, 2017
commit f956f421be39078617cbb3858796f7562ae26f9e
@@ -1,48 +1,21 @@
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):
def to_output(self):
return (1, self.args[0].encode('UTF-8'), b'')
def parse_bytesio(bytesio):
"""Parse the shebang from a file opened for reading binary."""
if != b'#!':
return ()
first_line = bytesio.readline()
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, 'rb') as f:
return parse_bytesio(f)
return parse_shebang_from_file(filename)
def find_executable(exe, _environ=None):
@@ -15,36 +15,10 @@
from pre_commit.util import make_executable
('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') == ()
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')
ProTip! Use n and p to navigate between commits in a pull request.