mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-12 15:44:17 +00:00
Add utility functions around filename matching
We add utils.fnmatch and utils.filenames_for in anticipation of our checker manager creating file checkers for each file. We also include tests for these functions and a couple previously untested utility functions.
This commit is contained in:
parent
a21c328870
commit
8792c30872
2 changed files with 101 additions and 0 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
"""Utility methods for flake8."""
|
"""Utility methods for flake8."""
|
||||||
|
import fnmatch as _fnmatch
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -89,3 +90,57 @@ def is_using_stdin(paths):
|
||||||
bool
|
bool
|
||||||
"""
|
"""
|
||||||
return '-' in paths
|
return '-' in paths
|
||||||
|
|
||||||
|
|
||||||
|
def _default_predicate(*args):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def filenames_from(arg, predicate=None):
|
||||||
|
# type: (str) -> Generator
|
||||||
|
"""Generate filenames from an argument.
|
||||||
|
|
||||||
|
:param str arg:
|
||||||
|
Parameter from the command-line.
|
||||||
|
:param callable predicate:
|
||||||
|
Predicate to use to filter out filenames. If the predicate
|
||||||
|
returns ``True`` we will exclude the filename, otherwise we
|
||||||
|
will yield it.
|
||||||
|
:returns:
|
||||||
|
Generator of paths
|
||||||
|
"""
|
||||||
|
if predicate is None:
|
||||||
|
predicate = _default_predicate
|
||||||
|
if os.path.isdir(arg):
|
||||||
|
for root, sub_directories, files in os.walk(arg):
|
||||||
|
for filename in files:
|
||||||
|
joined = os.path.join(root, filename)
|
||||||
|
if predicate(filename) or predicate(joined):
|
||||||
|
continue
|
||||||
|
yield joined
|
||||||
|
# NOTE(sigmavirus24): os.walk() will skip a directory if you
|
||||||
|
# remove it from the list of sub-directories.
|
||||||
|
for directory in sub_directories:
|
||||||
|
if predicate(directory):
|
||||||
|
sub_directories.remove(directory)
|
||||||
|
else:
|
||||||
|
yield arg
|
||||||
|
|
||||||
|
|
||||||
|
def fnmatch(filename, patterns, default=True):
|
||||||
|
# type: (str, List[str], bool) -> bool
|
||||||
|
"""Wrap :func:`fnmatch.fnmatch` to add some functionality.
|
||||||
|
|
||||||
|
:param str filename:
|
||||||
|
Name of the file we're trying to match.
|
||||||
|
:param list patterns:
|
||||||
|
Patterns we're using to try to match the filename.
|
||||||
|
:param bool default:
|
||||||
|
The default value if patterns is empty
|
||||||
|
:returns:
|
||||||
|
True if a pattern matches the filename, False if it doesn't.
|
||||||
|
``default`` if patterns is empty.
|
||||||
|
"""
|
||||||
|
if not patterns:
|
||||||
|
return default
|
||||||
|
return any(_fnmatch.fnmatch(filename, pattern) for pattern in patterns)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
"""Tests for flake8's utils module."""
|
"""Tests for flake8's utils module."""
|
||||||
import os
|
import os
|
||||||
|
import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
@ -40,3 +41,48 @@ def test_normalize_path(value, expected):
|
||||||
def test_normalize_paths(value, expected):
|
def test_normalize_paths(value, expected):
|
||||||
"""Verify we normalize comma-separated paths provided to the tool."""
|
"""Verify we normalize comma-separated paths provided to the tool."""
|
||||||
assert utils.normalize_paths(value) == expected
|
assert utils.normalize_paths(value) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_windows_checks_for_nt():
|
||||||
|
"""Verify that we correctly detect Windows."""
|
||||||
|
with mock.patch.object(os, 'name', 'nt'):
|
||||||
|
assert utils.is_windows() is True
|
||||||
|
|
||||||
|
with mock.patch.object(os, 'name', 'posix'):
|
||||||
|
assert utils.is_windows() is False
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('filename,patterns,expected', [
|
||||||
|
('foo.py', [], True),
|
||||||
|
('foo.py', ['*.pyc'], False),
|
||||||
|
('foo.pyc', ['*.pyc'], True),
|
||||||
|
('foo.pyc', ['*.swp', '*.pyc', '*.py'], True),
|
||||||
|
])
|
||||||
|
def test_fnmatch(filename, patterns, expected):
|
||||||
|
"""Verify that our fnmatch wrapper works as expected."""
|
||||||
|
assert utils.fnmatch(filename, patterns) is expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_filenames_from_a_directory():
|
||||||
|
"""Verify that filenames_from walks a directory."""
|
||||||
|
filenames = list(utils.filenames_from('flake8/'))
|
||||||
|
assert len(filenames) > 2
|
||||||
|
assert 'flake8/__init__.py' in filenames
|
||||||
|
|
||||||
|
|
||||||
|
def test_filenames_from_a_directory_with_a_predicate():
|
||||||
|
"""Verify that predicates filter filenames_from."""
|
||||||
|
filenames = list(utils.filenames_from(
|
||||||
|
arg='flake8/',
|
||||||
|
predicate=lambda filename: filename == 'flake8/__init__.py',
|
||||||
|
))
|
||||||
|
assert len(filenames) > 2
|
||||||
|
assert 'flake8/__init__.py' not in filenames
|
||||||
|
|
||||||
|
|
||||||
|
def test_filenames_from_a_single_file():
|
||||||
|
"""Verify that we simply yield that filename."""
|
||||||
|
filenames = list(utils.filenames_from('flake8/__init__.py'))
|
||||||
|
|
||||||
|
assert len(filenames) == 1
|
||||||
|
assert ['flake8/__init__.py'] == filenames
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue