summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Myint <git@stevenmyint.com>2017-05-30 19:42:07 -0700
committerSteven Myint <git@stevenmyint.com>2017-06-01 17:21:49 -0700
commite71a72fc7aab8938b2ec2be64a850f6ab6251e53 (patch)
tree8b060e331951edf39d5af33efd2d73ed300b4090
parentbce5564f52dded5a7302d200deb5d1ed36a42d7f (diff)
downloadpyflakes-e71a72fc7aab8938b2ec2be64a850f6ab6251e53.tar.gz
Find Python files without extensions
Previously, only files ending with `*.py` would be detected as Python files while recursing a directory. This closes #149.
-rw-r--r--pyflakes/api.py28
-rw-r--r--pyflakes/test/test_api.py16
2 files changed, 42 insertions, 2 deletions
diff --git a/pyflakes/api.py b/pyflakes/api.py
index a535bff..e30f920 100644
--- a/pyflakes/api.py
+++ b/pyflakes/api.py
@@ -5,6 +5,7 @@ from __future__ import with_statement
import sys
import os
+import re
import _ast
from pyflakes import checker, __version__
@@ -13,6 +14,9 @@ from pyflakes import reporter as modReporter
__all__ = ['check', 'checkPath', 'checkRecursive', 'iterSourceCode', 'main']
+PYTHON_SHEBANG_REGEX = re.compile(br'^#!.*\bpython[23]?\b\s*$')
+
+
def check(codeString, filename, reporter=None):
"""
Check the Python source given by C{codeString} for flakes.
@@ -108,6 +112,25 @@ def checkPath(filename, reporter=None):
return check(codestr, filename, reporter)
+def isPythonFile(filename):
+ """Return True if filename points to a Python file."""
+ if filename.endswith('.py'):
+ return True
+
+ max_bytes = 128
+
+ try:
+ with open(filename, 'rb') as f:
+ text = f.read(max_bytes)
+ if not text:
+ return False
+ except IOError:
+ return False
+
+ first_line = text.splitlines()[0]
+ return PYTHON_SHEBANG_REGEX.match(first_line)
+
+
def iterSourceCode(paths):
"""
Iterate over all Python source files in C{paths}.
@@ -120,8 +143,9 @@ def iterSourceCode(paths):
if os.path.isdir(path):
for dirpath, dirnames, filenames in os.walk(path):
for filename in filenames:
- if filename.endswith('.py'):
- yield os.path.join(dirpath, filename)
+ full_path = os.path.join(dirpath, filename)
+ if isPythonFile(full_path):
+ yield full_path
else:
yield path
diff --git a/pyflakes/test/test_api.py b/pyflakes/test/test_api.py
index 51b0027..a1e0be2 100644
--- a/pyflakes/test/test_api.py
+++ b/pyflakes/test/test_api.py
@@ -187,6 +187,22 @@ class TestIterSourceCode(TestCase):
sorted(iterSourceCode([self.tempdir])),
sorted([apath, bpath, cpath]))
+ def test_shebang(self):
+ """
+ Find Python files that don't end with `.py`, but contain a Python
+ shebang.
+ """
+ apath = os.path.join(self.tempdir, 'a')
+ fd = open(apath, 'w')
+ fd.write('#!/usr/bin/env python\n')
+ fd.close()
+
+ self.makeEmptyFile('b')
+
+ self.assertEqual(
+ list(iterSourceCode([self.tempdir])),
+ list([apath]))
+
def test_multipleDirectories(self):
"""
L{iterSourceCode} can be given multiple directories. It will recurse