diff options
Diffstat (limited to '.venv/lib/python3.12/site-packages/setuptools/_distutils/_modified.py')
-rw-r--r-- | .venv/lib/python3.12/site-packages/setuptools/_distutils/_modified.py | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/setuptools/_distutils/_modified.py b/.venv/lib/python3.12/site-packages/setuptools/_distutils/_modified.py new file mode 100644 index 00000000..f64cab7d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/setuptools/_distutils/_modified.py @@ -0,0 +1,95 @@ +"""Timestamp comparison of files and groups of files.""" + +from __future__ import annotations + +import functools +import os.path +from collections.abc import Callable, Iterable +from typing import Literal, TypeVar + +from jaraco.functools import splat + +from .compat.py39 import zip_strict +from .errors import DistutilsFileError + +_SourcesT = TypeVar( + "_SourcesT", bound="str | bytes | os.PathLike[str] | os.PathLike[bytes]" +) +_TargetsT = TypeVar( + "_TargetsT", bound="str | bytes | os.PathLike[str] | os.PathLike[bytes]" +) + + +def _newer(source, target): + return not os.path.exists(target) or ( + os.path.getmtime(source) > os.path.getmtime(target) + ) + + +def newer( + source: str | bytes | os.PathLike[str] | os.PathLike[bytes], + target: str | bytes | os.PathLike[str] | os.PathLike[bytes], +) -> bool: + """ + Is source modified more recently than target. + + Returns True if 'source' is modified more recently than + 'target' or if 'target' does not exist. + + Raises DistutilsFileError if 'source' does not exist. + """ + if not os.path.exists(source): + raise DistutilsFileError(f"file {os.path.abspath(source)!r} does not exist") + + return _newer(source, target) + + +def newer_pairwise( + sources: Iterable[_SourcesT], + targets: Iterable[_TargetsT], + newer: Callable[[_SourcesT, _TargetsT], bool] = newer, +) -> tuple[list[_SourcesT], list[_TargetsT]]: + """ + Filter filenames where sources are newer than targets. + + Walk two filename iterables in parallel, testing if each source is newer + than its corresponding target. Returns a pair of lists (sources, + targets) where source is newer than target, according to the semantics + of 'newer()'. + """ + newer_pairs = filter(splat(newer), zip_strict(sources, targets)) + return tuple(map(list, zip(*newer_pairs))) or ([], []) + + +def newer_group( + sources: Iterable[str | bytes | os.PathLike[str] | os.PathLike[bytes]], + target: str | bytes | os.PathLike[str] | os.PathLike[bytes], + missing: Literal["error", "ignore", "newer"] = "error", +) -> bool: + """ + Is target out-of-date with respect to any file in sources. + + Return True if 'target' is out-of-date with respect to any file + listed in 'sources'. In other words, if 'target' exists and is newer + than every file in 'sources', return False; otherwise return True. + ``missing`` controls how to handle a missing source file: + + - error (default): allow the ``stat()`` call to fail. + - ignore: silently disregard any missing source files. + - newer: treat missing source files as "target out of date". This + mode is handy in "dry-run" mode: it will pretend to carry out + commands that wouldn't work because inputs are missing, but + that doesn't matter because dry-run won't run the commands. + """ + + def missing_as_newer(source): + return missing == 'newer' and not os.path.exists(source) + + ignored = os.path.exists if missing == 'ignore' else None + return not os.path.exists(target) or any( + missing_as_newer(source) or _newer(source, target) + for source in filter(ignored, sources) + ) + + +newer_pairwise_group = functools.partial(newer_pairwise, newer=newer_group) |