From ff442891ea6b1f663dae3ce91d871d2ab50cc68c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Sun, 4 Aug 2019 18:12:17 +0300 Subject: Shebang detection improvements (#438) * Recognize python with arguments in shebang * Recognize python with d/m/u suffix in shebang https://www.python.org/dev/peps/pep-3149/#proposal * Recognize python with minor version in shebang * Avoid unnecessary line splitting in shebang search * Add test for python shebang-like not on the first line --- pyflakes/api.py | 5 ++--- pyflakes/test/test_api.py | 28 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/pyflakes/api.py b/pyflakes/api.py index 6226e5d..50e8ad8 100644 --- a/pyflakes/api.py +++ b/pyflakes/api.py @@ -14,7 +14,7 @@ from pyflakes import reporter as modReporter __all__ = ['check', 'checkPath', 'checkRecursive', 'iterSourceCode', 'main'] -PYTHON_SHEBANG_REGEX = re.compile(br'^#!.*\bpython[23w]?\b\s*$') +PYTHON_SHEBANG_REGEX = re.compile(br'^#!.*\bpython([23](\.\d+)?|w)?[dmu]?\s') def check(codeString, filename, reporter=None): @@ -118,8 +118,7 @@ def isPythonFile(filename): except IOError: return False - first_line = text.splitlines()[0] - return PYTHON_SHEBANG_REGEX.match(first_line) + return PYTHON_SHEBANG_REGEX.match(text) def iterSourceCode(paths): diff --git a/pyflakes/test/test_api.py b/pyflakes/test/test_api.py index ee205f9..93b3886 100644 --- a/pyflakes/test/test_api.py +++ b/pyflakes/test/test_api.py @@ -214,9 +214,35 @@ class TestIterSourceCode(TestCase): with open(pythonw, 'w') as fd: fd.write('#!/usr/bin/env pythonw\n') + python3args = os.path.join(self.tempdir, 'g') + with open(python3args, 'w') as fd: + fd.write('#!/usr/bin/python3 -u\n') + + python2u = os.path.join(self.tempdir, 'h') + with open(python2u, 'w') as fd: + fd.write('#!/usr/bin/python2u\n') + + python3d = os.path.join(self.tempdir, 'i') + with open(python3d, 'w') as fd: + fd.write('#!/usr/local/bin/python3d\n') + + python38m = os.path.join(self.tempdir, 'j') + with open(python38m, 'w') as fd: + fd.write('#! /usr/bin/env python3.8m\n') + + python27 = os.path.join(self.tempdir, 'k') + with open(python27, 'w') as fd: + fd.write('#!/usr/bin/python2.7 \n') + + # Should NOT be treated as Python source + notfirst = os.path.join(self.tempdir, 'l') + with open(notfirst, 'w') as fd: + fd.write('#!/bin/sh\n#!/usr/bin/python\n') + self.assertEqual( sorted(iterSourceCode([self.tempdir])), - sorted([python, python2, python3, pythonw])) + sorted([python, python2, python3, pythonw, python3args, python2u, + python3d, python38m, python27])) def test_multipleDirectories(self): """ -- cgit v1.2.1