mirror of
https://github.com/pre-commit/pre-commit-hooks.git
synced 2026-04-09 21:04:17 +00:00
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
This commit is contained in:
parent
72ad6dc953
commit
f4cd1ba0d6
813 changed files with 66015 additions and 58839 deletions
|
|
@ -1,31 +1,31 @@
|
|||
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
|
||||
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
|
||||
|
||||
"""File wrangling."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import ntpath
|
||||
import os
|
||||
import os.path
|
||||
import posixpath
|
||||
import re
|
||||
import sys
|
||||
|
||||
from typing import Callable, Iterable
|
||||
from typing import Callable
|
||||
from typing import Iterable
|
||||
|
||||
from coverage import env
|
||||
from coverage.exceptions import ConfigError
|
||||
from coverage.misc import human_sorted, isolate_module, join_regex
|
||||
from coverage.misc import human_sorted
|
||||
from coverage.misc import isolate_module
|
||||
from coverage.misc import join_regex
|
||||
|
||||
|
||||
os = isolate_module(os)
|
||||
|
||||
|
||||
RELATIVE_DIR: str = ""
|
||||
RELATIVE_DIR: str = ''
|
||||
CANONICAL_FILENAME_CACHE: dict[str, str] = {}
|
||||
|
||||
|
||||
def set_relative_directory() -> None:
|
||||
"""Set the directory that `relative_filename` will be relative to."""
|
||||
global RELATIVE_DIR, CANONICAL_FILENAME_CACHE
|
||||
|
|
@ -73,7 +73,7 @@ def canonical_filename(filename: str) -> str:
|
|||
if not os.path.isabs(filename):
|
||||
for path in [os.curdir] + sys.path:
|
||||
if path is None:
|
||||
continue # type: ignore[unreachable]
|
||||
continue # type: ignore[unreachable]
|
||||
f = os.path.join(path, filename)
|
||||
try:
|
||||
exists = os.path.exists(f)
|
||||
|
|
@ -89,6 +89,7 @@ def canonical_filename(filename: str) -> str:
|
|||
|
||||
MAX_FLAT = 100
|
||||
|
||||
|
||||
def flat_rootname(filename: str) -> str:
|
||||
"""A base for a flat file name to correspond to this file.
|
||||
|
||||
|
|
@ -101,11 +102,11 @@ def flat_rootname(filename: str) -> str:
|
|||
"""
|
||||
dirname, basename = ntpath.split(filename)
|
||||
if dirname:
|
||||
fp = hashlib.new("sha3_256", dirname.encode("UTF-8")).hexdigest()[:16]
|
||||
prefix = f"d_{fp}_"
|
||||
fp = hashlib.new('sha3_256', dirname.encode('UTF-8')).hexdigest()[:16]
|
||||
prefix = f'd_{fp}_'
|
||||
else:
|
||||
prefix = ""
|
||||
return prefix + basename.replace(".", "_")
|
||||
prefix = ''
|
||||
return prefix + basename.replace('.', '_')
|
||||
|
||||
|
||||
if env.WINDOWS:
|
||||
|
|
@ -163,7 +164,7 @@ def zip_location(filename: str) -> tuple[str, str] | None:
|
|||
name is in the zipfile.
|
||||
|
||||
"""
|
||||
for ext in [".zip", ".whl", ".egg", ".pex"]:
|
||||
for ext in ['.zip', '.whl', '.egg', '.pex']:
|
||||
zipbase, extension, inner = filename.partition(ext + sep(filename))
|
||||
if extension:
|
||||
zipfile = zipbase + ext
|
||||
|
|
@ -210,7 +211,7 @@ def prep_patterns(patterns: Iterable[str]) -> list[str]:
|
|||
prepped = []
|
||||
for p in patterns or []:
|
||||
prepped.append(p)
|
||||
if not p.startswith(("*", "?")):
|
||||
if not p.startswith(('*', '?')):
|
||||
prepped.append(abs_file(p))
|
||||
return prepped
|
||||
|
||||
|
|
@ -223,14 +224,15 @@ class TreeMatcher:
|
|||
somewhere in a subtree rooted at one of the directories.
|
||||
|
||||
"""
|
||||
def __init__(self, paths: Iterable[str], name: str = "unknown") -> None:
|
||||
|
||||
def __init__(self, paths: Iterable[str], name: str = 'unknown') -> None:
|
||||
self.original_paths: list[str] = human_sorted(paths)
|
||||
#self.paths = list(map(os.path.normcase, paths))
|
||||
self.paths = [os.path.normcase(p) for p in paths]
|
||||
self.name = name
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<TreeMatcher {self.name} {self.original_paths!r}>"
|
||||
return f'<TreeMatcher {self.name} {self.original_paths!r}>'
|
||||
|
||||
def info(self) -> list[str]:
|
||||
"""A list of strings for displaying when dumping state."""
|
||||
|
|
@ -252,12 +254,13 @@ class TreeMatcher:
|
|||
|
||||
class ModuleMatcher:
|
||||
"""A matcher for modules in a tree."""
|
||||
def __init__(self, module_names: Iterable[str], name:str = "unknown") -> None:
|
||||
|
||||
def __init__(self, module_names: Iterable[str], name: str = 'unknown') -> None:
|
||||
self.modules = list(module_names)
|
||||
self.name = name
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<ModuleMatcher {self.name} {self.modules!r}>"
|
||||
return f'<ModuleMatcher {self.name} {self.modules!r}>'
|
||||
|
||||
def info(self) -> list[str]:
|
||||
"""A list of strings for displaying when dumping state."""
|
||||
|
|
@ -272,7 +275,7 @@ class ModuleMatcher:
|
|||
if module_name.startswith(m):
|
||||
if module_name == m:
|
||||
return True
|
||||
if module_name[len(m)] == ".":
|
||||
if module_name[len(m)] == '.':
|
||||
# This is a module in the package
|
||||
return True
|
||||
|
||||
|
|
@ -281,13 +284,14 @@ class ModuleMatcher:
|
|||
|
||||
class GlobMatcher:
|
||||
"""A matcher for files by file name pattern."""
|
||||
def __init__(self, pats: Iterable[str], name: str = "unknown") -> None:
|
||||
|
||||
def __init__(self, pats: Iterable[str], name: str = 'unknown') -> None:
|
||||
self.pats = list(pats)
|
||||
self.re = globs_to_regex(self.pats, case_insensitive=env.WINDOWS)
|
||||
self.name = name
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<GlobMatcher {self.name} {self.pats!r}>"
|
||||
return f'<GlobMatcher {self.name} {self.pats!r}>'
|
||||
|
||||
def info(self) -> list[str]:
|
||||
"""A list of strings for displaying when dumping state."""
|
||||
|
|
@ -300,7 +304,7 @@ class GlobMatcher:
|
|||
|
||||
def sep(s: str) -> str:
|
||||
"""Find the path separator used in this string, or os.sep if none."""
|
||||
if sep_match := re.search(r"[\\/]", s):
|
||||
if sep_match := re.search(r'[\\/]', s):
|
||||
the_sep = sep_match[0]
|
||||
else:
|
||||
the_sep = os.sep
|
||||
|
|
@ -309,29 +313,32 @@ def sep(s: str) -> str:
|
|||
|
||||
# Tokenizer for _glob_to_regex.
|
||||
# None as a sub means disallowed.
|
||||
G2RX_TOKENS = [(re.compile(rx), sub) for rx, sub in [
|
||||
(r"\*\*\*+", None), # Can't have ***
|
||||
(r"[^/]+\*\*+", None), # Can't have x**
|
||||
(r"\*\*+[^/]+", None), # Can't have **x
|
||||
(r"\*\*/\*\*", None), # Can't have **/**
|
||||
(r"^\*+/", r"(.*[/\\\\])?"), # ^*/ matches any prefix-slash, or nothing.
|
||||
(r"/\*+$", r"[/\\\\].*"), # /*$ matches any slash-suffix.
|
||||
(r"\*\*/", r"(.*[/\\\\])?"), # **/ matches any subdirs, including none
|
||||
(r"/", r"[/\\\\]"), # / matches either slash or backslash
|
||||
(r"\*", r"[^/\\\\]*"), # * matches any number of non slash-likes
|
||||
(r"\?", r"[^/\\\\]"), # ? matches one non slash-like
|
||||
(r"\[.*?\]", r"\g<0>"), # [a-f] matches [a-f]
|
||||
(r"[a-zA-Z0-9_-]+", r"\g<0>"), # word chars match themselves
|
||||
(r"[\[\]]", None), # Can't have single square brackets
|
||||
(r".", r"\\\g<0>"), # Anything else is escaped to be safe
|
||||
]]
|
||||
G2RX_TOKENS = [
|
||||
(re.compile(rx), sub) for rx, sub in [
|
||||
(r'\*\*\*+', None), # Can't have ***
|
||||
(r'[^/]+\*\*+', None), # Can't have x**
|
||||
(r'\*\*+[^/]+', None), # Can't have **x
|
||||
(r'\*\*/\*\*', None), # Can't have **/**
|
||||
(r'^\*+/', r'(.*[/\\\\])?'), # ^*/ matches any prefix-slash, or nothing.
|
||||
(r'/\*+$', r'[/\\\\].*'), # /*$ matches any slash-suffix.
|
||||
(r'\*\*/', r'(.*[/\\\\])?'), # **/ matches any subdirs, including none
|
||||
(r'/', r'[/\\\\]'), # / matches either slash or backslash
|
||||
(r'\*', r'[^/\\\\]*'), # * matches any number of non slash-likes
|
||||
(r'\?', r'[^/\\\\]'), # ? matches one non slash-like
|
||||
(r'\[.*?\]', r'\g<0>'), # [a-f] matches [a-f]
|
||||
(r'[a-zA-Z0-9_-]+', r'\g<0>'), # word chars match themselves
|
||||
(r'[\[\]]', None), # Can't have single square brackets
|
||||
(r'.', r'\\\g<0>'), # Anything else is escaped to be safe
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
def _glob_to_regex(pattern: str) -> str:
|
||||
"""Convert a file-path glob pattern into a regex."""
|
||||
# Turn all backslashes into slashes to simplify the tokenizer.
|
||||
pattern = pattern.replace("\\", "/")
|
||||
if "/" not in pattern:
|
||||
pattern = "**/" + pattern
|
||||
pattern = pattern.replace('\\', '/')
|
||||
if '/' not in pattern:
|
||||
pattern = '**/' + pattern
|
||||
path_rx = []
|
||||
pos = 0
|
||||
while pos < len(pattern):
|
||||
|
|
@ -342,7 +349,7 @@ def _glob_to_regex(pattern: str) -> str:
|
|||
path_rx.append(m.expand(sub))
|
||||
pos = m.end()
|
||||
break
|
||||
return "".join(path_rx)
|
||||
return ''.join(path_rx)
|
||||
|
||||
|
||||
def globs_to_regex(
|
||||
|
|
@ -371,7 +378,7 @@ def globs_to_regex(
|
|||
flags |= re.IGNORECASE
|
||||
rx = join_regex(map(_glob_to_regex, patterns))
|
||||
if not partial:
|
||||
rx = fr"(?:{rx})\Z"
|
||||
rx = fr'(?:{rx})\Z'
|
||||
compiled = re.compile(rx, flags=flags)
|
||||
return compiled
|
||||
|
||||
|
|
@ -387,6 +394,7 @@ class PathAliases:
|
|||
map a path through those aliases to produce a unified path.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
debugfn: Callable[[str], None] | None = None,
|
||||
|
|
@ -400,9 +408,9 @@ class PathAliases:
|
|||
|
||||
def pprint(self) -> None:
|
||||
"""Dump the important parts of the PathAliases, for debugging."""
|
||||
self.debugfn(f"Aliases (relative={self.relative}):")
|
||||
self.debugfn(f'Aliases (relative={self.relative}):')
|
||||
for original_pattern, regex, result in self.aliases:
|
||||
self.debugfn(f" Rule: {original_pattern!r} -> {result!r} using regex {regex.pattern!r}")
|
||||
self.debugfn(f' Rule: {original_pattern!r} -> {result!r} using regex {regex.pattern!r}')
|
||||
|
||||
def add(self, pattern: str, result: str) -> None:
|
||||
"""Add the `pattern`/`result` pair to the list of aliases.
|
||||
|
|
@ -421,16 +429,16 @@ class PathAliases:
|
|||
pattern_sep = sep(pattern)
|
||||
|
||||
if len(pattern) > 1:
|
||||
pattern = pattern.rstrip(r"\/")
|
||||
pattern = pattern.rstrip(r'\/')
|
||||
|
||||
# The pattern can't end with a wildcard component.
|
||||
if pattern.endswith("*"):
|
||||
raise ConfigError("Pattern must not end with wildcards.")
|
||||
if pattern.endswith('*'):
|
||||
raise ConfigError('Pattern must not end with wildcards.')
|
||||
|
||||
# The pattern is meant to match a file path. Let's make it absolute
|
||||
# unless it already is, or is meant to match any prefix.
|
||||
if not self.relative:
|
||||
if not pattern.startswith("*") and not isabs_anywhere(pattern + pattern_sep):
|
||||
if not pattern.startswith('*') and not isabs_anywhere(pattern + pattern_sep):
|
||||
pattern = abs_file(pattern)
|
||||
if not pattern.endswith(pattern_sep):
|
||||
pattern += pattern_sep
|
||||
|
|
@ -440,10 +448,10 @@ class PathAliases:
|
|||
|
||||
# Normalize the result: it must end with a path separator.
|
||||
result_sep = sep(result)
|
||||
result = result.rstrip(r"\/") + result_sep
|
||||
result = result.rstrip(r'\/') + result_sep
|
||||
self.aliases.append((original_pattern, regex, result))
|
||||
|
||||
def map(self, path: str, exists:Callable[[str], bool] = source_exists) -> str:
|
||||
def map(self, path: str, exists: Callable[[str], bool] = source_exists) -> str:
|
||||
"""Map `path` through the aliases.
|
||||
|
||||
`path` is checked against all of the patterns. The first pattern to
|
||||
|
|
@ -472,18 +480,18 @@ class PathAliases:
|
|||
new = new.replace(sep(path), sep(result))
|
||||
if not self.relative:
|
||||
new = canonical_filename(new)
|
||||
dot_start = result.startswith(("./", ".\\")) and len(result) > 2
|
||||
if new.startswith(("./", ".\\")) and not dot_start:
|
||||
dot_start = result.startswith(('./', '.\\')) and len(result) > 2
|
||||
if new.startswith(('./', '.\\')) and not dot_start:
|
||||
new = new[2:]
|
||||
if not exists(new):
|
||||
self.debugfn(
|
||||
f"Rule {original_pattern!r} changed {path!r} to {new!r} " +
|
||||
f'Rule {original_pattern!r} changed {path!r} to {new!r} ' +
|
||||
"which doesn't exist, continuing",
|
||||
)
|
||||
continue
|
||||
self.debugfn(
|
||||
f"Matched path {path!r} to rule {original_pattern!r} -> {result!r}, " +
|
||||
f"producing {new!r}",
|
||||
f'Matched path {path!r} to rule {original_pattern!r} -> {result!r}, ' +
|
||||
f'producing {new!r}',
|
||||
)
|
||||
return new
|
||||
|
||||
|
|
@ -494,21 +502,21 @@ class PathAliases:
|
|||
|
||||
if self.relative and not isabs_anywhere(path):
|
||||
# Auto-generate a pattern to implicitly match relative files
|
||||
parts = re.split(r"[/\\]", path)
|
||||
parts = re.split(r'[/\\]', path)
|
||||
if len(parts) > 1:
|
||||
dir1 = parts[0]
|
||||
pattern = f"*/{dir1}"
|
||||
regex_pat = fr"^(.*[\\/])?{re.escape(dir1)}[\\/]"
|
||||
result = f"{dir1}{os.sep}"
|
||||
pattern = f'*/{dir1}'
|
||||
regex_pat = fr'^(.*[\\/])?{re.escape(dir1)}[\\/]'
|
||||
result = f'{dir1}{os.sep}'
|
||||
# Only add a new pattern if we don't already have this pattern.
|
||||
if not any(p == pattern for p, _, _ in self.aliases):
|
||||
self.debugfn(
|
||||
f"Generating rule: {pattern!r} -> {result!r} using regex {regex_pat!r}",
|
||||
f'Generating rule: {pattern!r} -> {result!r} using regex {regex_pat!r}',
|
||||
)
|
||||
self.aliases.append((pattern, re.compile(regex_pat), result))
|
||||
return self.map(path, exists=exists)
|
||||
|
||||
self.debugfn(f"No rules match, path {path!r} is unchanged")
|
||||
self.debugfn(f'No rules match, path {path!r} is unchanged')
|
||||
return path
|
||||
|
||||
|
||||
|
|
@ -530,7 +538,7 @@ def find_python_files(dirname: str, include_namespace_packages: bool) -> Iterabl
|
|||
"""
|
||||
for i, (dirpath, dirnames, filenames) in enumerate(os.walk(dirname)):
|
||||
if not include_namespace_packages:
|
||||
if i > 0 and "__init__.py" not in filenames:
|
||||
if i > 0 and '__init__.py' not in filenames:
|
||||
# If a directory doesn't have __init__.py, then it isn't
|
||||
# importable and neither are its files
|
||||
del dirnames[:]
|
||||
|
|
@ -539,7 +547,7 @@ def find_python_files(dirname: str, include_namespace_packages: bool) -> Iterabl
|
|||
# We're only interested in files that look like reasonable Python
|
||||
# files: Must end with .py or .pyw, and must not have certain funny
|
||||
# characters that probably mean they are editor junk.
|
||||
if re.match(r"^[^.#~!$@%^&*()+=,]+\.pyw?$", filename):
|
||||
if re.match(r'^[^.#~!$@%^&*()+=,]+\.pyw?$', filename):
|
||||
yield os.path.join(dirpath, filename)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue