Lint explicit files even when excluded

This commit is contained in:
Sean Doherty 2026-05-16 20:22:22 -05:00
parent ee03327c82
commit a6645fa8e6
4 changed files with 37 additions and 17 deletions

View file

@ -10,7 +10,7 @@ import logging
import os.path
from typing import Any
from flake8.discover_files import expand_paths
from flake8 import utils
from flake8.formatting import base as formatter
from flake8.main import application as app
from flake8.options.parse_args import parse_args
@ -129,15 +129,12 @@ class StyleGuide:
"""
def excluded(path: str) -> bool:
paths = tuple(
expand_paths(
paths=[path],
stdin_display_name=self.options.stdin_display_name,
filename_patterns=self.options.filename,
exclude=self.options.exclude,
),
return utils.matches_filename(
path,
patterns=self.options.exclude,
log_message='"%(path)s" has %(whether)sbeen excluded',
logger=LOG,
)
return not paths
return excluded(filename) or (
parent is not None and excluded(os.path.join(parent, filename))

View file

@ -22,17 +22,19 @@ def _filenames_from(
:param arg:
Parameter from the command-line.
:param predicate:
Predicate to use to filter out filenames. If the predicate
returns ``True`` we will exclude the filename, otherwise we
will yield it. By default, we include every filename
generated.
Predicate to use to filter out paths discovered from directories
or stdin aliases. Direct file arguments are yielded even if the
predicate matches them.
:returns:
Generator of paths
"""
if predicate(arg):
if arg == "-" and predicate(arg):
return
if os.path.isdir(arg):
if predicate(arg):
return
for root, sub_directories, files in os.walk(arg):
# NOTE(sigmavirus24): os.walk() will skip a directory if you
# remove it from the list of sub-directories.

View file

@ -135,6 +135,20 @@ def test_extend_exclude(tmpdir, capsys):
assert err == ""
def test_explicit_file_ignores_exclude(tmpdir, capsys):
tmpdir.join("test/module.py").ensure()
tmpdir.join("test/module.py").write("import os\n")
tmpdir.join(".flake8").write("[flake8]\nexclude = module.py\n")
with tmpdir.as_cwd():
assert cli.main(["test/module.py"]) == 1
expected_out = "test/module.py:1:1: F401 'os' imported but unused\n"
out, err = capsys.readouterr()
assert out == expected_out.replace("/", os.sep)
assert err == ""
def test_malformed_per_file_ignores_error(tmpdir, capsys):
"""Test the error message for malformed `per-file-ignores`."""
setup_cfg = """\

View file

@ -95,11 +95,11 @@ def test_filenames_from_exclude_doesnt_exclude_directory_names(tmpdir):
assert filenames == [os.path.join(".", "2", "1", "return_me.py")]
def test_filenames_from_predicate_applies_to_initial_arg(tmp_path):
"""Test that the predicate is also applied to the passed argument."""
def test_filenames_from_predicate_does_not_apply_to_initial_file(tmp_path):
"""Test that the predicate is not applied to a directly passed file."""
fname = str(tmp_path.joinpath("f.py"))
ret = tuple(_filenames_from(fname, predicate=lambda _: True))
assert ret == ()
assert ret == (fname,)
def test_filenames_from_predicate_applies_to_dirname(tmp_path):
@ -164,3 +164,10 @@ def test_alternate_stdin_name_is_filtered():
def test_filename_included_even_if_not_matching_include(tmp_path):
some_file = str(tmp_path.joinpath("some/file"))
assert _expand_paths(paths=(some_file,)) == {some_file}
def test_filename_included_even_if_matching_exclude(tmp_path):
some_file = str(tmp_path.joinpath("some/file.py"))
assert _expand_paths(paths=(some_file,), exclude=("file.py",)) == {
some_file,
}