def METHOD_NAME(
    check_path: pathlib.Path,
    ignore: Optional[Iterable[pathlib.Path]] = None,
    *,
    repo_root: Optional[pathlib.Path] = None,
    get_previous: Callable[[pathlib.Path], Optional[str]] = _get_previous,
) -> List[LicenseHeaderError]:
    """
    Validate license headers under `check_path` and return a list of validation errors.
    Paths on `ignore` will be ignored, as well as their subpaths.
    Assumptions regarding which files require license header validation:
    - Only python (*.py) files need a license header
    - Code under hidden folders (starting with `.`) are ignored
    """
    ignoreset = set(ignore or [])
    def walk_recursively(path, gitignore_matcher):
        for child in path.iterdir():
            # Skip gitignored files
            if gitignore_matcher.match(child):
                return
            # For directories, keep recursing unless folder is blacklisted
            if child.is_dir():
                # Skip hidden folders
                if child.relative_to(child.parent).as_posix().startswith('.'):
                    continue
                relpath = child.relative_to(check_path)
                # Skip blacklisted folders
                if relpath in ignoreset:
                    continue
                yield from walk_recursively(child, gitignore_matcher.for_path(path))
                continue
            # Skip non-python files
            if child.suffix == '.py':
                yield child
    def validate_license_header(path):
        with open(path, encoding='utf-8-sig') as f:
            contents = f.read()
        license_header = parse_license_header(contents)
        relpath = path.relative_to(check_path).as_posix()
        previous = get_previous(path)
        # When file already existed
        if previous is not None:
            original_header = parse_license_header(previous)
            # Check whether the license has changed
            if original_header and license_header != original_header:
                return LicenseHeaderError(
                    "existing file has changed license", relpath, _replace_header(contents, original_header)
                )
            # If the original file didn't have a header and the current one doesn't either
            # we report as missing, but we can't suggest an automatic fix.
            elif not original_header and not license_header:
                return LicenseHeaderError("missing license header", relpath, None)
        # License is missing altogether
        elif not license_header:
            return LicenseHeaderError("missing license header", relpath, f"{get_default_license_header()}\n{contents}")
        # When it's a new file and a license header is found, compare it to the current header template
        elif license_header != get_default_license_header():
            return LicenseHeaderError(
                "file does not match expected license format",
                relpath,
                _replace_header(contents, get_default_license_header()),
            )
    if repo_root:
        gitignore_matcher = _GitIgnoreMatcher.from_path_to_root(check_path, repo_root)
    else:
        gitignore_matcher = _GitIgnoreMatcher(check_path)
    # Walk through subdirs and validate files
    errors = []
    for candidate in walk_recursively(check_path, gitignore_matcher):
        if error := validate_license_header(candidate):
            errors.append(error)
    return errors