| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- """Functions related to discovering paths."""
- import logging
- import os.path
- from typing import Callable
- from typing import Generator
- from typing import Sequence
- from flake8 import utils
- LOG = logging.getLogger(__name__)
- def _filenames_from(
- arg: str,
- *,
- predicate: Callable[[str], bool],
- ) -> Generator[str, None, None]:
- """Generate filenames from an argument.
- :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.
- :returns:
- Generator of paths
- """
- if predicate(arg):
- return
- if os.path.isdir(arg):
- 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.
- for directory in tuple(sub_directories):
- joined = os.path.join(root, directory)
- if predicate(joined):
- sub_directories.remove(directory)
- for filename in files:
- joined = os.path.join(root, filename)
- if not predicate(joined):
- yield joined
- else:
- yield arg
- def expand_paths(
- *,
- paths: Sequence[str],
- stdin_display_name: str,
- filename_patterns: Sequence[str],
- exclude: Sequence[str],
- is_running_from_diff: bool,
- ) -> Generator[str, None, None]:
- """Expand out ``paths`` from commandline to the lintable files."""
- if not paths:
- paths = ["."]
- def is_excluded(arg: str) -> bool:
- if arg == "-":
- # if the stdin_display_name is the default, always include it
- if stdin_display_name == "stdin":
- return False
- arg = stdin_display_name
- return utils.matches_filename(
- arg,
- patterns=exclude,
- log_message='"%(path)s" has %(whether)sbeen excluded',
- logger=LOG,
- )
- def is_included(arg: str, fname: str) -> bool:
- # while running from a diff, the arguments aren't _explicitly_
- # listed so we still filter them
- if is_running_from_diff:
- return utils.fnmatch(fname, filename_patterns)
- else:
- return (
- # always lint `-`
- fname == "-"
- # always lint explicitly passed (even if not matching filter)
- or arg == fname
- # otherwise, check the file against filtered patterns
- or utils.fnmatch(fname, filename_patterns)
- )
- return (
- filename
- for path in paths
- for filename in _filenames_from(path, predicate=is_excluded)
- if is_included(path, filename)
- )
|