add updates libs

This commit is contained in:
Christoph Brandau
2026-06-18 17:21:58 +02:00
parent 91ce762570
commit 41f331d4c4
150 changed files with 8249 additions and 2550 deletions
+33 -65
View File
@@ -1,11 +1,14 @@
import codecs
import os
import pathlib
import re
from typing import List, Optional
from collections import defaultdict
from pathlib import Path
from typing import Callable
import pathspec
from tclint.config import ExcludePattern
def register_codec_warning(name):
def replace_with_warning_handler(e):
@@ -16,73 +19,38 @@ def register_codec_warning(name):
codecs.register_error(name, replace_with_warning_handler)
def make_exclude_filter(exclude_patterns: List[str]):
exclude_patterns = [
re.sub(r"^\s*#", r"\#", pattern) for pattern in exclude_patterns
]
exclude_spec = pathspec.PathSpec.from_lines("gitwildmatch", exclude_patterns)
def make_exclude_filter(
exclude_patterns: list[ExcludePattern],
) -> Callable[[Path], bool]:
# Transform patterns into a data structure keyed on root.
patterns_by_root = defaultdict(list)
for pattern, root in exclude_patterns:
# I think this is escaping #, which would otherwise be treated like a comment.
# Not 100% sure though, I originally wrote this a while ago.
pattern = re.sub(r"^\s*#", r"\#", pattern)
patterns_by_root[root.resolve()].append(pattern)
def is_excluded(path: pathlib.Path, root: pathlib.Path) -> bool:
compiled_patterns = {}
for root in patterns_by_root.keys():
patterns = patterns_by_root[root]
spec = pathspec.PathSpec.from_lines("gitwildmatch", patterns)
compiled_patterns[root] = spec
def is_excluded(path: Path) -> bool:
abspath = path.resolve()
root = root.resolve()
try:
relpath = pathlib.Path(os.path.relpath(abspath, start=root))
except ValueError:
# We get here if path and exclude_root are on different drives (on Windows).
# Things should still behave roughly as expected without using a relative
# path. See test_cli_utils.py::test_exclude_filter_windows for test cases.
relpath = abspath
for root, exclude_spec in compiled_patterns.items():
try:
relpath = Path(os.path.relpath(abspath, start=root))
except ValueError:
# We get here if path and exclude_root are on different drives (on
# Windows).Things should still behave roughly as expected without
# using a relative path. See
# test_cli_utils.py::test_exclude_filter_windows for test cases.
relpath = abspath
if exclude_spec.match_file(relpath):
return True
if exclude_spec.match_file(relpath):
return True
return False
return is_excluded
def resolve_sources(
paths: List[pathlib.Path],
exclude_patterns: List[str],
exclude_root: pathlib.Path,
extensions: List[str],
) -> List[Optional[pathlib.Path]]:
"""Resolves paths passed via CLI to a list of filepaths to lint.
`paths` is a list of paths that may be files or directories. Files are
returned verbatim if they exist, and directories are recursively searched
for files that have an extension specified in `extensions`. Paths that match a
pattern in `exclude_patterns` are ignored (based on gitignore pattern
format, see https://git-scm.com/docs/gitignore#_pattern_format).
Raises FileNotFoundError if a supplied path does not exist.
"""
extensions = [f".{ext}" if not ext.startswith(".") else ext for ext in extensions]
is_excluded = make_exclude_filter(exclude_patterns)
sources: List[Optional[pathlib.Path]] = []
for path in paths:
if str(path) == "-":
sources.append(None)
continue
if not path.exists():
raise FileNotFoundError(f"path {path} does not exist")
if is_excluded(path, exclude_root):
continue
if not path.is_dir():
sources.append(path)
continue
for dirpath, _, filenames in os.walk(path):
for name in filenames:
_, ext = os.path.splitext(name)
if ext.lower() in extensions:
child = pathlib.Path(dirpath) / name
if not is_excluded(child, exclude_root):
sources.append(child)
return sources