fix(installer): install hash-pinned dependencies and build tools (#856)
* fix(installer): install hash-pinned dependencies and build tools * fix(installer): add cairo-devel for the pinned pycairo build * fix(installer): reject missing or empty bootstrap exports * fix(installer): preserve remote behavior for older tags --------- Co-authored-by: Jatin K Malik <jatinkrmalik@gmail.com>
This commit is contained in:
co-authored by
Jatin K Malik
parent
4df612dd7a
commit
acd90fdd05
@@ -108,7 +108,7 @@ Website: `web/AGENTS.md`, `web/PRODUCT.md`, `web/DESIGN.md`. Do not duplicate si
|
||||
|
||||
## Dependencies (uv)
|
||||
|
||||
`uv.lock` is authoritative. `just lock` regenerates it, the hash-pinned `requirements/*.txt` exports, and `packaging/flatpak/python3-dependencies.yaml`. The AppImage build installs from `runtime`/`vad` plus `appimage.txt`; `install.sh` still resolves at install time (phase 2 of #701). **Do not edit `requirements/*.txt` by hand**, nor the url/sha256 pairs in `packaging/flatpak/python3-dependencies.yaml`. Change `pyproject.toml` (or `requirements/whisper.in` for the Whisper engine, `requirements/appimage*.in` for the AppImage), run `just lock`, and commit the lock plus the exports with the manifest change.
|
||||
`uv.lock` is authoritative. `just lock` regenerates it, the hash-pinned `requirements/*.txt` exports, and `packaging/flatpak/python3-dependencies.yaml`. The AppImage build installs from `runtime`/`vad` plus `appimage.txt`; `install.sh` consumes the runtime and selected extras with `--require-hashes --no-deps --no-build-isolation`, then installs the project with `--no-deps --no-build-isolation`. **Do not edit `requirements/*.txt` by hand**, nor the url/sha256 pairs in `packaging/flatpak/python3-dependencies.yaml`. Change `pyproject.toml` (or `requirements/whisper.in` for the Whisper engine, `requirements/appimage*.in` for the AppImage), run `just lock`, and commit the lock plus the exports with the manifest change.
|
||||
|
||||
| Constraint | Rule |
|
||||
|---|---|
|
||||
@@ -116,6 +116,9 @@ Website: `web/AGENTS.md`, `web/PRODUCT.md`, `web/DESIGN.md`. Do not duplicate si
|
||||
| `[vosk]` extra | Wheel-only on PyPI (no sdist). Never part of a source-buildable lock. `install.sh --engine=vosk` installs it |
|
||||
| Whisper CPU torch | `requirements/whisper.txt` is compiled from `requirements/whisper.in`. Pin `torch`/`torchaudio` together to `+cpu` local versions — PyPI CUDA wheels win resolution regardless of index order, and torchaudio lags torch on the CPU index |
|
||||
| pywhispercpp | Pinned in `install.sh` as `PYWHISPERCPP_VERSION` (keep in sync with `uv.lock`) |
|
||||
| Installer build tools | `[dependency-groups].installer-build` exports to `requirements/installer-build.txt`. Bootstrap uses hashed wheels on new and reused venvs; source builds use these tools without build isolation. Its setuptools `<82` cap is for CPU torch only; do not add it to `[build-system]` (Arch). Backend rebuilds select pywhispercpp's complete hash block from `runtime.txt` via `scripts/installer_requirements.py`, with `--no-deps` so they cannot replace the runtime |
|
||||
| Installer Whisper export | Compiled universally from Python 3.11, constrained by `runtime.txt` and `installer-build.txt` to keep shared pins consistent. Uses `+cpu` pins and best-match index resolution so the CPU index's older copies of shared packages do not downgrade the runtime |
|
||||
| Remote installer | After cloning, hand off to the tagged `install.sh` with the original arguments and remote venv path. The installer and its exports must come from the same revision, including when the tag predates the pinned installer |
|
||||
| `[vad]` extra | `onnxruntime` for Silero VAD |
|
||||
| One export per extra | Every extra in `pyproject.toml` needs a hash-pinned `requirements/<extra>.txt` (underscores become dashes), written by a `uv export` line in `just lock`. `install.sh` installs six of them, so an extra with no export is an install path with nothing pinned, which is how `[parakeet]`, `[faster_whisper]` and `[vosk]` reached users. `tests/test_dependency_exports.py` enumerates the extras and the installer's call sites rather than trusting the recipe to stay complete; `docs` is the one exemption and it carries its reason in `EXPORT_EXEMPT` |
|
||||
| Exports match the lock | `just export-check` re-runs every `uv export` line in `just lock` and fails if a committed export is behind `uv.lock`. It reads those lines out of the recipe, so an export added there is checked without touching `scripts/check_exports.py`, and it runs under `UV_OFFLINE=1`: `uv export` reads the lock and nothing else. The lint job runs it, because an export named in the recipe and never regenerated is a snapshot, not a pin. `uv pip compile` targets are out of scope by design (they resolve against live indexes) |
|
||||
|
||||
@@ -32,6 +32,16 @@ The installer:
|
||||
- Downloads the default whisper.cpp tiny model (~74MB), verified against pinned checksums
|
||||
- Sets up desktop integration and launch wrappers
|
||||
|
||||
The source installer uses committed, hash-verified Python dependency exports,
|
||||
including its pip and source-build tools. GTK/PyGObject still comes from your
|
||||
distribution, and the venv retains access to system packages. A missing export
|
||||
or unavailable pinned package causes that installation step to fail; the
|
||||
existing optional-engine and VAD fallbacks still apply.
|
||||
|
||||
Remote installs run the installer from the selected release tag. Older tags
|
||||
therefore retain their original dependency-install behavior; downloading a new
|
||||
bootstrap script does not change an older release's pins.
|
||||
|
||||
### Installer modes
|
||||
|
||||
```bash
|
||||
|
||||
+94
-85
@@ -6,6 +6,7 @@
|
||||
# -e: exit on unhandled command failure -u: error on unset variables
|
||||
# -o pipefail: a pipeline fails if any stage fails
|
||||
set -Eeuo pipefail
|
||||
INSTALLER_ARGS=("$@")
|
||||
|
||||
# Exit codes (see --help). 1 remains the generic/unclassified failure.
|
||||
EXIT_OK=0
|
||||
@@ -487,7 +488,27 @@ resolve_install_tag
|
||||
# Check if running from within the vocalinux repo or remotely (via curl)
|
||||
REPO_URL="https://github.com/VocaHQ/vocalinux.git"
|
||||
INSTALL_DIR=""
|
||||
CLEANUP_ON_EXIT="no"
|
||||
CLEANUP_ON_EXIT="${VOCALINUX_REMOTE_INSTALL:-no}"
|
||||
|
||||
handoff_to_tagged_installer() {
|
||||
local tagged_installer="$INSTALL_DIR/install.sh"
|
||||
local remote_venv="$HOME/.local/share/vocalinux/venv"
|
||||
|
||||
if grep -q 'CLEANUP_ON_EXIT="${VOCALINUX_REMOTE_INSTALL:-no}"' "$tagged_installer"; then
|
||||
export VOCALINUX_REMOTE_INSTALL=yes
|
||||
export TMPDIR="$(dirname "$VOCALINUX_TMP_DIR")"
|
||||
rmdir "$VOCALINUX_TMP_DIR"
|
||||
exec bash "$tagged_installer" "${INSTALLER_ARGS[@]}" "--venv-dir=$remote_venv"
|
||||
fi
|
||||
|
||||
bash "$tagged_installer" "${INSTALLER_ARGS[@]}" "--venv-dir=$remote_venv" || return $?
|
||||
if [ ! -f "$INSTALL_DIR/activate-vocalinux.sh" ]; then
|
||||
print_error "The tagged installer did not create activate-vocalinux.sh."
|
||||
return 1
|
||||
fi
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
mv "$INSTALL_DIR/activate-vocalinux.sh" "$HOME/.local/bin/activate-vocalinux.sh"
|
||||
}
|
||||
|
||||
# Function to check and install git if needed
|
||||
ensure_git_installed() {
|
||||
@@ -661,8 +682,10 @@ else
|
||||
CLEANUP_ON_EXIT="yes"
|
||||
print_info "Repository cloned to: $INSTALL_DIR"
|
||||
|
||||
# When running remotely, install venv to user's home directory
|
||||
VENV_DIR="$HOME/.local/share/vocalinux/venv"
|
||||
# Keep the installer and exports on the selected tag. Legacy tags do not
|
||||
# understand the remote marker, so the handoff relocates their helper.
|
||||
handoff_to_tagged_installer
|
||||
exit "$EXIT_OK"
|
||||
fi
|
||||
|
||||
# Change to install directory
|
||||
@@ -1767,7 +1790,8 @@ install_system_dependencies() {
|
||||
local APT_PACKAGES_DEBIAN_BASE="python3-pip python3-gi python3-gi-cairo gir1.2-gtk-3.0 gir1.2-ibus-1.0 libcairo2-dev cmake python3-dev build-essential portaudio19-dev python3-venv pkg-config wget curl unzip vulkan-tools libvulkan-dev $VULKAN_SHADER_PKG xclip xsel wl-clipboard $PYWHISPERCPP_BUILD_DEPS"
|
||||
local APT_PACKAGES_DEBIAN_11_12="$APT_PACKAGES_DEBIAN_BASE libgirepository1.0-dev gir1.2-ayatanaappindicator3-0.1"
|
||||
local APT_PACKAGES_DEBIAN_13_PLUS="$APT_PACKAGES_DEBIAN_BASE libgirepository-2.0-dev gir1.2-ayatanaappindicator3-0.1"
|
||||
local DNF_PACKAGES="python3-pip python3-gobject gtk3 ibus-devel gobject-introspection-devel python3-devel portaudio-devel python3-virtualenv pkg-config cmake wget curl unzip vulkan-tools vulkan-loader-devel glslc patchelf xclip xsel wl-clipboard"
|
||||
# cairo-devel: the pinned pycairo builds from source; Fedora splits its headers/.pc out.
|
||||
local DNF_PACKAGES="python3-pip python3-gobject gtk3 ibus-devel gobject-introspection-devel python3-devel portaudio-devel cairo-devel python3-virtualenv pkg-config cmake wget curl unzip vulkan-tools vulkan-loader-devel glslc patchelf xclip xsel wl-clipboard"
|
||||
local PACMAN_PACKAGES="python-pip python-gobject gtk3 ibus gobject-introspection python-cairo portaudio python-virtualenv pkg-config cmake wget curl unzip base-devel vulkan-tools vulkan-headers shaderc patchelf xclip xsel wl-clipboard"
|
||||
# ibus + typelib-1_0-IBus-1_0, not ibus-devel: the headers are not needed
|
||||
# (IBus is reached through GI at runtime), and requiring them pulls gtk-doc,
|
||||
@@ -2625,10 +2649,6 @@ setup_virtual_environment() {
|
||||
# Activate virtual environment
|
||||
source "$VENV_DIR/bin/activate" || { print_error "Failed to activate virtual environment"; exit "$EXIT_MISSING_DEPS"; }
|
||||
|
||||
# Update pip and setuptools
|
||||
print_info "Updating pip, setuptools, and wheel..."
|
||||
pip install --upgrade pip setuptools wheel || { print_error "Failed to update pip, setuptools, and wheel"; exit "$EXIT_NETWORK"; }
|
||||
|
||||
print_info "Virtual environment activated successfully."
|
||||
}
|
||||
|
||||
@@ -2644,6 +2664,24 @@ fi
|
||||
# Set up virtual environment
|
||||
setup_virtual_environment
|
||||
|
||||
# Also run for reused venvs: setup_virtual_environment returns early for those.
|
||||
# Wheels only here so bootstrapping cannot itself resolve unpinned build deps.
|
||||
install_pinned_build_tools() {
|
||||
local reqs_file="$INSTALL_DIR/requirements/installer-build.txt"
|
||||
if [ ! -s "$reqs_file" ]; then
|
||||
print_error "Missing or empty pinned requirements: $reqs_file"
|
||||
return 1
|
||||
fi
|
||||
print_info "Installing pinned pip and source-build tools..."
|
||||
"$VENV_DIR/bin/python" -m pip install --require-hashes --no-deps \
|
||||
--only-binary=:all: --ignore-installed \
|
||||
-r "$reqs_file" --log "$VOCALINUX_TMP_DIR/bootstrap.log"
|
||||
}
|
||||
install_pinned_build_tools || {
|
||||
print_error "Failed to install the pinned build tools. Check requirements/installer-build.txt."
|
||||
exit "$EXIT_NETWORK"
|
||||
}
|
||||
|
||||
# Create activation script for users
|
||||
# Put it in ~/.local/bin when running remotely, or current dir when running locally
|
||||
if [[ "$CLEANUP_ON_EXIT" == "yes" ]]; then
|
||||
@@ -2872,7 +2910,19 @@ install_cpu_pywhispercpp() {
|
||||
PYWHISPERCPP_CMAKE_ARGS=$(get_pywhispercpp_cmake_args)
|
||||
|
||||
CMAKE_ARGS="${CMAKE_ARGS:+$CMAKE_ARGS }$PYWHISPERCPP_CMAKE_ARGS" \
|
||||
pip install --verbose --force-reinstall --no-cache-dir "pywhispercpp==${PYWHISPERCPP_VERSION}" --log "$PIP_LOG_FILE"
|
||||
pip_reinstall_pywhispercpp "$PIP_LOG_FILE"
|
||||
}
|
||||
|
||||
pip_reinstall_pywhispercpp() {
|
||||
local pip_log="$1"
|
||||
shift
|
||||
local reqs_file="$VOCALINUX_TMP_DIR/pywhispercpp.txt"
|
||||
"$VENV_DIR/bin/python" "$INSTALL_DIR/scripts/installer_requirements.py" \
|
||||
"$INSTALL_DIR/requirements/runtime.txt" "$reqs_file" --package pywhispercpp || return 1
|
||||
# --no-deps preserves the locked runtime and avoids reinstalling numpy
|
||||
# while replacing only the backend. Build tools were bootstrapped above.
|
||||
"$VENV_DIR/bin/python" -m pip install --require-hashes --no-deps --no-build-isolation \
|
||||
--verbose --force-reinstall --no-cache-dir -r "$reqs_file" --log "$pip_log" "$@"
|
||||
}
|
||||
|
||||
is_pywhispercpp_installed() {
|
||||
@@ -3028,7 +3078,7 @@ install_whispercpp_with_gpu_support() {
|
||||
print_info "Installing pywhispercpp ($GPU_BACKEND backend)..."
|
||||
if CMAKE_ARGS="${CMAKE_ARGS:+$CMAKE_ARGS }$PYWHISPERCPP_CMAKE_ARGS" \
|
||||
GGML_VULKAN=1 \
|
||||
pip install --verbose --force-reinstall --no-cache-dir --no-binary pywhispercpp "pywhispercpp==${PYWHISPERCPP_VERSION}" --log "$PIP_LOG_FILE" 2>&1; then
|
||||
pip_reinstall_pywhispercpp "$PIP_LOG_FILE" --no-binary pywhispercpp 2>&1; then
|
||||
if verify_pywhispercpp_backend_install "$GPU_BACKEND"; then
|
||||
GPU_INSTALL_SUCCESS=true
|
||||
else
|
||||
@@ -3054,7 +3104,7 @@ install_whispercpp_with_gpu_support() {
|
||||
print_info "Installing pywhispercpp ($GPU_BACKEND backend)..."
|
||||
if CMAKE_ARGS="${CMAKE_ARGS:+$CMAKE_ARGS }$PYWHISPERCPP_CMAKE_ARGS $CUDA_CMAKE_ARGS" \
|
||||
GGML_CUDA=1 \
|
||||
pip install --verbose --force-reinstall --no-cache-dir --no-binary pywhispercpp "pywhispercpp==${PYWHISPERCPP_VERSION}" --log "$PIP_LOG_FILE" 2>&1; then
|
||||
pip_reinstall_pywhispercpp "$PIP_LOG_FILE" --no-binary pywhispercpp 2>&1; then
|
||||
if verify_pywhispercpp_backend_install "$GPU_BACKEND"; then
|
||||
GPU_INSTALL_SUCCESS=true
|
||||
else
|
||||
@@ -3191,49 +3241,9 @@ FALLBACK_VOSK_CONFIG
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Distro python3-gi provides `gi`, but apt does not drop pip-visible
|
||||
# PyGObject dist-info. `pip install .` then tries to build pygobject from
|
||||
# sdist and dies (needs girepository-2.0). Same skip as uv export's
|
||||
# --no-emit-package pygobject: install the other deps, then the project
|
||||
# with --no-deps. Do not use requirements/*.txt hashes here (Phase 2).
|
||||
write_pip_reqs_skip_pygobject() {
|
||||
local dest="$1"
|
||||
shift
|
||||
"$VENV_DIR/bin/python" - "$dest" "$@" <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
dest = Path(sys.argv[1])
|
||||
extras = sys.argv[2:]
|
||||
text = Path("pyproject.toml").read_text()
|
||||
|
||||
|
||||
def quoted_strings(block: str):
|
||||
return re.findall(r'"([^"]+)"', block)
|
||||
|
||||
|
||||
reqs = []
|
||||
if not extras:
|
||||
match = re.search(r"^dependencies = \[(.*?)\]", text, re.M | re.S)
|
||||
for req in quoted_strings(match.group(1) if match else ""):
|
||||
pkg = re.split(r"[<>=!~;\[]", req, 1)[0].strip()
|
||||
if pkg.lower() == "pygobject":
|
||||
continue
|
||||
reqs.append(req)
|
||||
else:
|
||||
opt = re.search(
|
||||
r"^\[project\.optional-dependencies\](.*?)(\n\[|\Z)", text, re.M | re.S
|
||||
)
|
||||
opt_text = opt.group(1) if opt else ""
|
||||
for extra in extras:
|
||||
match = re.search(rf"^{re.escape(extra)} = \[(.*?)\]", opt_text, re.M | re.S)
|
||||
if match:
|
||||
reqs.extend(quoted_strings(match.group(1)))
|
||||
|
||||
dest.write_text("\n".join(reqs) + ("\n" if reqs else ""))
|
||||
PY
|
||||
}
|
||||
# Exports use --no-emit-package pygobject: distro GI remains visible through
|
||||
# --system-site-packages. Install the locked dependencies first, then the local
|
||||
# project with --no-deps and --no-build-isolation so neither step re-resolves.
|
||||
|
||||
require_distro_gi() {
|
||||
if ! "$VENV_DIR/bin/python" -c "import gi" 2>/dev/null; then
|
||||
@@ -3248,25 +3258,33 @@ pip_install_reqs_file() {
|
||||
local pip_log="$1"
|
||||
local reqs_file="$2"
|
||||
if [ ! -s "$reqs_file" ]; then
|
||||
return 0
|
||||
print_error "Missing or empty pinned requirements: $reqs_file"
|
||||
return 1
|
||||
fi
|
||||
pip install -r "$reqs_file" --log "$pip_log"
|
||||
"$VENV_DIR/bin/python" -m pip install --require-hashes --no-deps --no-build-isolation \
|
||||
-r "$reqs_file" --log "$pip_log"
|
||||
}
|
||||
|
||||
pip_install_project_skip_pygobject() {
|
||||
local pip_log="$1"
|
||||
shift
|
||||
require_distro_gi
|
||||
write_pip_reqs_skip_pygobject "$VOCALINUX_TMP_DIR/runtime-deps.txt"
|
||||
pip_install_reqs_file "$pip_log" "$VOCALINUX_TMP_DIR/runtime-deps.txt" || return 1
|
||||
pip install --no-deps --log "$pip_log" "$@"
|
||||
require_distro_gi || return 1
|
||||
pip_install_reqs_file "$pip_log" "$INSTALL_DIR/requirements/runtime.txt" || return 1
|
||||
"$VENV_DIR/bin/python" -m pip install --no-deps --no-build-isolation --log "$pip_log" "$@"
|
||||
}
|
||||
|
||||
pip_install_extras_skip_pygobject() {
|
||||
local pip_log="$1"
|
||||
shift
|
||||
write_pip_reqs_skip_pygobject "$VOCALINUX_TMP_DIR/extra-deps.txt" "$@"
|
||||
pip_install_reqs_file "$pip_log" "$VOCALINUX_TMP_DIR/extra-deps.txt"
|
||||
local extra
|
||||
for extra in "$@"; do
|
||||
# uv normalizes underscores to dashes in export filenames.
|
||||
case "$extra" in
|
||||
vad|vosk|parakeet|faster_whisper|whisper|dev) ;;
|
||||
*) print_error "Unknown dependency extra: $extra"; return 1 ;;
|
||||
esac
|
||||
pip_install_reqs_file "$pip_log" "$INSTALL_DIR/requirements/${extra//_/-}.txt" || return 1
|
||||
done
|
||||
}
|
||||
|
||||
# Function to install Python package with error handling and verification
|
||||
@@ -3340,13 +3358,13 @@ PY
|
||||
|
||||
# Install test dependencies
|
||||
print_info "Installing test dependencies..."
|
||||
pip install pytest pytest-mock pytest-cov --log "$PIP_LOG_FILE" || {
|
||||
pip_install_extras_skip_pygobject "$PIP_LOG_FILE" dev || {
|
||||
print_warning "Failed to install some test dependencies. Tests may not run correctly."
|
||||
}
|
||||
|
||||
# Install all optional dependencies for development
|
||||
print_info "Installing all optional dependencies for development..."
|
||||
pip_install_extras_skip_pygobject "$PIP_LOG_FILE" whisper dev || {
|
||||
pip_install_extras_skip_pygobject "$PIP_LOG_FILE" whisper || {
|
||||
print_warning "Failed to install some optional dependencies."
|
||||
print_warning "Some features may not work correctly."
|
||||
}
|
||||
@@ -3384,25 +3402,16 @@ PY
|
||||
|
||||
local WHISPER_INSTALL_SUCCESS=false
|
||||
|
||||
# Install PyTorch and whisper
|
||||
print_info "Installing PyTorch..."
|
||||
if pip install torch torchaudio --index-url https://download.pytorch.org/whl/cpu --log "$PIP_LOG_FILE" 2>&1; then
|
||||
print_success "PyTorch installed successfully"
|
||||
|
||||
print_info "Installing openai-whisper..."
|
||||
if pip install openai-whisper --log "$PIP_LOG_FILE" 2>&1; then
|
||||
# Verify the installation by importing the module
|
||||
if "$VENV_DIR/bin/python" -c "import whisper" 2>/dev/null; then
|
||||
WHISPER_INSTALL_SUCCESS=true
|
||||
print_success "Whisper installed and verified successfully"
|
||||
else
|
||||
print_error "Whisper package installed but import failed"
|
||||
fi
|
||||
print_info "Installing pinned Whisper and CPU PyTorch..."
|
||||
if pip_install_extras_skip_pygobject "$PIP_LOG_FILE" whisper; then
|
||||
if "$VENV_DIR/bin/python" -c "import whisper" 2>/dev/null; then
|
||||
WHISPER_INSTALL_SUCCESS=true
|
||||
print_success "Whisper installed and verified successfully"
|
||||
else
|
||||
print_error "Failed to install openai-whisper package"
|
||||
print_error "Whisper package installed but import failed"
|
||||
fi
|
||||
else
|
||||
print_error "Failed to install PyTorch"
|
||||
print_error "Failed to install pinned Whisper dependencies"
|
||||
fi
|
||||
|
||||
if [[ "$WHISPER_INSTALL_SUCCESS" == "true" ]]; then
|
||||
@@ -3586,10 +3595,9 @@ PARAKEET_CONFIG
|
||||
print_info "╚════════════════════════════════════════════════════════╝"
|
||||
print_info ""
|
||||
|
||||
# Ensure requests library is installed
|
||||
print_info "Installing requests library..."
|
||||
pip install requests --log "$PIP_LOG_FILE" || {
|
||||
print_error "Failed to install requests library"
|
||||
# requests is already installed from the runtime export.
|
||||
"$VENV_DIR/bin/python" -c "import requests" || {
|
||||
print_error "The pinned requests library is not importable"
|
||||
return 1
|
||||
}
|
||||
print_success "requests library installed"
|
||||
@@ -4530,7 +4538,8 @@ run_tests() {
|
||||
# Check if pytest is installed in the virtual environment
|
||||
if ! "$VENV_DIR/bin/python" -c "import pytest" &>/dev/null; then
|
||||
print_info "Installing pytest and related packages..."
|
||||
pip install pytest pytest-mock pytest-cov || {
|
||||
local PIP_LOG_FILE="$VOCALINUX_TMP_DIR/test-deps.log"
|
||||
pip_install_extras_skip_pygobject "$PIP_LOG_FILE" dev || {
|
||||
print_error "Failed to install pytest. Cannot run tests."
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -151,6 +151,7 @@ verify-release tag="":
|
||||
# when you want newer CPU builds (torchaudio on the CPU index lags torch).
|
||||
lock:
|
||||
uv lock
|
||||
uv export --only-group installer-build --no-emit-project -o requirements/installer-build.txt
|
||||
uv export --no-dev --no-emit-project --no-emit-package pygobject -o requirements/runtime.txt
|
||||
uv export --no-dev --extra vad --no-emit-project --no-emit-package pygobject -o requirements/vad.txt
|
||||
# One export per selectable engine. install.sh installs each of these as an
|
||||
@@ -168,7 +169,8 @@ lock:
|
||||
uv pip compile requirements/whisper.in --generate-hashes --emit-index-url \
|
||||
--index-url https://pypi.org/simple \
|
||||
--extra-index-url https://download.pytorch.org/whl/cpu \
|
||||
--python-platform x86_64-unknown-linux-gnu -o requirements/whisper.txt
|
||||
--index-strategy unsafe-best-match --universal --python-version 3.11 \
|
||||
-c requirements/runtime.txt -c requirements/installer-build.txt -o requirements/whisper.txt
|
||||
# Compiled rather than exported: what the AppImage bundles on top of the
|
||||
# lock, and what builds it, are pinned away from uv.lock on purpose --
|
||||
# see requirements/appimage.in. --universal so one file covers both arches.
|
||||
|
||||
@@ -83,6 +83,20 @@ docs = [
|
||||
# --only-group lint` installs them without the project, so the lint job needs
|
||||
# no portaudio/girepository headers to build pyaudio and PyGObject.
|
||||
[dependency-groups]
|
||||
# install.sh installs this wheel-only toolchain before any source builds, then
|
||||
# disables build isolation so pip cannot resolve another unpinned environment.
|
||||
installer-build = [
|
||||
"pip>=25.3,<27",
|
||||
# CPU torch still requires pkg_resources; this cap applies only to the
|
||||
# installer venv, not build-system.requires used by Arch's toolchain.
|
||||
"setuptools>=77,<82",
|
||||
"wheel",
|
||||
"meson-python>=0.16",
|
||||
"cmake==3.31.10",
|
||||
"ninja==1.13.0",
|
||||
"repairwheel",
|
||||
"setuptools-scm>=8",
|
||||
]
|
||||
lint = [
|
||||
"black>=23.0.0",
|
||||
"isort>=5.12.0",
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv export --only-group installer-build --no-emit-project -o requirements/installer-build.txt
|
||||
altgraph==0.17.5 \
|
||||
--hash=sha256:c87b395dd12fabde9c99573a9749d67da8d29ef9de0125c7f536699b4a9bc9e7 \
|
||||
--hash=sha256:f3a22400bce1b0c701683820ac4f3b159cd301acab067c51c653e06961600597
|
||||
# via macholib
|
||||
cmake==3.31.10 \
|
||||
--hash=sha256:1debc3a0823ce5d8d1bc17154599bbbb337c2681f93622b618bc78f46576e42a \
|
||||
--hash=sha256:2f766bb46367e5e0559fa33184653754bce044583a06014dcaebf8e6dff8a1f1 \
|
||||
--hash=sha256:3c17bb24dba15f8ecc3fd706afe04264410ef88796f4115c119327c961d5dc57 \
|
||||
--hash=sha256:422a54711aa977af19d59b8f6010354cdda0b72a2e6d702b6d892e3e2cdf98a2 \
|
||||
--hash=sha256:4cefb0a28ac1268b4eed4b595bf3aaff8de9704089066027700ec36584eccab8 \
|
||||
--hash=sha256:678fc23db37cc69f01e18eb28790450ecc9401fd2fcd43364cc18f92330c12c2 \
|
||||
--hash=sha256:6970bb75c4dfc28cc31ff0cd848194d09094ae00d605181e1345b2ff70b61050 \
|
||||
--hash=sha256:7c300e4ae68fbc1414a85505f7feb262cee82ff3304a286885ebf803b11a997c \
|
||||
--hash=sha256:8d2ec5fc45d305227020c82213140a51a0cebe3c84f0299036f05716b3a52f60 \
|
||||
--hash=sha256:91410816db3beefe2f6032d721f9978c98dc7646e9992c0325486597164fab81 \
|
||||
--hash=sha256:a4a5615f31f692c9b9aa8b365704e4b76172348af6fa40e16fea3f118bb01194 \
|
||||
--hash=sha256:a7864605238759a4ae8e3bd1fda2bb03978e3e37df310852662dcf53866413c8 \
|
||||
--hash=sha256:ad697643a00d9ba85179590a383c4f7401169b55ebf4b8b2938daf28c6bdeb6d \
|
||||
--hash=sha256:b059a1810a2ce766b3e531bdc8d730bc192e260a9fa7dec7a0eb7a053d6063c7 \
|
||||
--hash=sha256:b331984de38dbda22d676f8812c8905526341ba7b397fe8c359255ff4d051193 \
|
||||
--hash=sha256:c2e5361dea9754ed3b06cf834894fb47dcbe7036d5e5d87acaeb10ff3dd5fd10 \
|
||||
--hash=sha256:e135d5f1e59f1dc1c80eea87321977d6c0eff86cb601c28e0965a1dd457ea587 \
|
||||
--hash=sha256:ec3d14a0e72e401b3665034dc37901df17f0b4e9c5b163be6cfedfb93470ac0f \
|
||||
--hash=sha256:f1ea1fe826355560e8976c3d5794d9357444209bc0e0d56676c71e6a571fd474
|
||||
delvewheel==1.13.1 \
|
||||
--hash=sha256:1b3bc696193a57e322b8bfd644de240be6e003066aae44cc3d5aef8cbee22ca3 \
|
||||
--hash=sha256:ae445f35f411c367f5b350431ac5f1435af8128bff31ccf34035a409704da8c6
|
||||
# via repairwheel
|
||||
macholib==1.16.4 \
|
||||
--hash=sha256:da1a3fa8266e30f0ce7e97c6a54eefaae8edd1e5f86f3eb8b95457cae90265ea \
|
||||
--hash=sha256:f408c93ab2e995cd2c46e34fe328b130404be143469e41bc366c807448979362
|
||||
# via repairwheel
|
||||
meson==1.12.0 \
|
||||
--hash=sha256:71f133147fa0fcfe8f4df49fa1045771064947834538409e5d97b3613aac8b4e \
|
||||
--hash=sha256:88afe0c20e52030218924ac37d0c81c59b4b5f3ae3752c8c6d7470c7d365886c
|
||||
# via meson-python
|
||||
meson-python==0.21.1 \
|
||||
--hash=sha256:270bc9b78957c47e0aa1758ad616dba3f943d8f9cbdb944d318c3c1c7a49e4bd \
|
||||
--hash=sha256:78b3345dcbc0fed7b939e7e37a9faab35bddaae07bf62e7542c8ad479c395af5
|
||||
ninja==1.13.0 \
|
||||
--hash=sha256:11be2d22027bde06f14c343f01d31446747dbb51e72d00decca2eb99be911e2f \
|
||||
--hash=sha256:1c97223cdda0417f414bf864cfb73b72d8777e57ebb279c5f6de368de0062988 \
|
||||
--hash=sha256:3c0b40b1f0bba764644385319028650087b4c1b18cdfa6f45cb39a3669b81aa9 \
|
||||
--hash=sha256:3d00c692fb717fd511abeb44b8c5d00340c36938c12d6538ba989fe764e79630 \
|
||||
--hash=sha256:3d7d7779d12cb20c6d054c61b702139fd23a7a964ec8f2c823f1ab1b084150db \
|
||||
--hash=sha256:4a40ce995ded54d9dc24f8ea37ff3bf62ad192b547f6c7126e7e25045e76f978 \
|
||||
--hash=sha256:4be9c1b082d244b1ad7ef41eb8ab088aae8c109a9f3f0b3e56a252d3e00f42c1 \
|
||||
--hash=sha256:5f8e1e8a1a30835eeb51db05cf5a67151ad37542f5a4af2a438e9490915e5b72 \
|
||||
--hash=sha256:60056592cf495e9a6a4bea3cd178903056ecb0943e4de45a2ea825edb6dc8d3e \
|
||||
--hash=sha256:6739d3352073341ad284246f81339a384eec091d9851a886dfa5b00a6d48b3e2 \
|
||||
--hash=sha256:8cfbb80b4a53456ae8a39f90ae3d7a2129f45ea164f43fadfa15dc38c4aef1c9 \
|
||||
--hash=sha256:aa45b4037b313c2f698bc13306239b8b93b4680eb47e287773156ac9e9304714 \
|
||||
--hash=sha256:b4f2a072db3c0f944c32793e91532d8948d20d9ab83da9c0c7c15b5768072200 \
|
||||
--hash=sha256:be7f478ff9f96a128b599a964fc60a6a87b9fa332ee1bd44fa243ac88d50291c \
|
||||
--hash=sha256:d741a5e6754e0bda767e3274a0f0deeef4807f1fec6c0d7921a0244018926ae5 \
|
||||
--hash=sha256:e8bad11f8a00b64137e9b315b137d8bb6cbf3086fbdc43bf1f90fd33324d2e96 \
|
||||
--hash=sha256:fa2a8bfc62e31b08f83127d1613d10821775a0eb334197154c4d6067b7068ff1 \
|
||||
--hash=sha256:fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa \
|
||||
--hash=sha256:fb8ee8719f8af47fed145cced4a85f0755dd55d45b2bddaf7431fa89803c5f3e
|
||||
packaging==26.3 \
|
||||
--hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \
|
||||
--hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
|
||||
# via
|
||||
# meson-python
|
||||
# pyproject-metadata
|
||||
# repairwheel
|
||||
# setuptools-scm
|
||||
# vcs-versioning
|
||||
# wheel
|
||||
pefile==2024.8.26 \
|
||||
--hash=sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632 \
|
||||
--hash=sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f
|
||||
# via
|
||||
# delvewheel
|
||||
# repairwheel
|
||||
pip==26.2.1 \
|
||||
--hash=sha256:71138adf1f4ca900cdb7d289c21b7494329f2332b6d85f0e1c42108c0384ed3e \
|
||||
--hash=sha256:f6ad667e89a1fe78046c8f13232b247200f5258d7828f3f7883d660878e0813f
|
||||
pyelftools==0.33 \
|
||||
--hash=sha256:660d82dcbeb8e83d1702bd97f223f761625da06111c0cc988eac6b8ab0c1b61f \
|
||||
--hash=sha256:f215ad5f47d3f1373a21496a6c9e0707c622840d0622f23ff7ce08678b020036
|
||||
# via repairwheel
|
||||
pyproject-metadata==0.12.1 \
|
||||
--hash=sha256:8809a4df6fe08279b39a8890669506ed3158e0617855ac9aff098fcbe772ae4c \
|
||||
--hash=sha256:f7162d580a96386a8eb096da06215f981f547d1490f03055ef99e323bc2da427
|
||||
# via meson-python
|
||||
repairwheel==0.7.0 \
|
||||
--hash=sha256:46083dad76e35595712ae593c1c9f112fb3f37a0e63268906e6de8182de55122 \
|
||||
--hash=sha256:7fff43ed5abbf9710ef5ea6478c10cfd551aae043f445fd46307d4b602674ce0
|
||||
setuptools==81.0.0 \
|
||||
--hash=sha256:487b53915f52501f0a79ccfd0c02c165ffe06631443a886740b91af4b7a5845a \
|
||||
--hash=sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6
|
||||
# via setuptools-scm
|
||||
setuptools-scm==10.2.3 \
|
||||
--hash=sha256:7fcf8ff55c95eb8b572a23c81495e5559b9b90f3e82fcf0952bb76c37de27a81 \
|
||||
--hash=sha256:f179ed3e2a63cf5823e5ee9aa9ca08386219400443a0553224d72dde3f206b44
|
||||
typing-extensions==4.16.0 \
|
||||
--hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8 \
|
||||
--hash=sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5
|
||||
# via repairwheel
|
||||
vcs-versioning==2.4.1 \
|
||||
--hash=sha256:b7089ec9bef67b2cad82148366e8eac4d63173f440ec62628282b59eb96bbcb0 \
|
||||
--hash=sha256:d4575de3115ec9434393c87c80ffb0eb98a16056bfe2b11ce0f3a97aff67fe0a
|
||||
# via setuptools-scm
|
||||
wheel==0.48.0 \
|
||||
--hash=sha256:3217dcc807155e45db462d7ef2431f5ddda0d7273b700d05a67b271ceb1287ab \
|
||||
--hash=sha256:94800765601e9171bf5d58d066e640662842bcedcbab982b2c90787a2c987322
|
||||
@@ -4,6 +4,9 @@
|
||||
# CUDA-bundled PyPI wheels can never match, regardless of index order.
|
||||
# Bump these pins together in step with each other when regenerating
|
||||
# (`just lock`).
|
||||
# Resolve across supported Python versions and constrain shared packages to
|
||||
# runtime.txt / installer-build.txt; otherwise this export can downgrade the
|
||||
# runtime (or select a numpy requiring a newer Python than the installer).
|
||||
#
|
||||
# The extra-index line below propagates into whisper.txt so plain
|
||||
# `pip install -r requirements/whisper.txt` resolves against the CPU index.
|
||||
|
||||
+301
-25
@@ -1,14 +1,195 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile requirements/whisper.in --generate-hashes --emit-index-url --index-url https://pypi.org/simple --extra-index-url https://download.pytorch.org/whl/cpu --python-platform x86_64-unknown-linux-gnu -o requirements/whisper.txt
|
||||
# uv pip compile requirements/whisper.in --generate-hashes --emit-index-url --index-url https://pypi.org/simple --extra-index-url https://download.pytorch.org/whl/cpu --index-strategy unsafe-best-match --universal --python-version 3.11 -c requirements/runtime.txt -c requirements/installer-build.txt -o requirements/whisper.txt
|
||||
--index-url https://pypi.org/simple
|
||||
--extra-index-url https://download.pytorch.org/whl/cpu
|
||||
|
||||
certifi==2022.12.7 \
|
||||
--hash=sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18
|
||||
# via requests
|
||||
charset-normalizer==2.1.1 \
|
||||
--hash=sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f
|
||||
# via requests
|
||||
certifi==2026.7.22 \
|
||||
--hash=sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775 \
|
||||
--hash=sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# requests
|
||||
charset-normalizer==3.5.1 \
|
||||
--hash=sha256:00668ebb0609751758682eb0b5857e7c35b9f00e84dfdef062e103244ec94d45 \
|
||||
--hash=sha256:012a22b88a77ca2e59b98ac5889b0deb604147666032f45e6d6e217634d2550d \
|
||||
--hash=sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5 \
|
||||
--hash=sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b \
|
||||
--hash=sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f \
|
||||
--hash=sha256:07ffd07412fc5d5e84cd8952acf9ff7e4ed7a708e69d1bada19d8ba91711353f \
|
||||
--hash=sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5 \
|
||||
--hash=sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22 \
|
||||
--hash=sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5 \
|
||||
--hash=sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac \
|
||||
--hash=sha256:13e3afe97712e8887cd516e960c63f0b93122971e5b5e4b2622fe7701771e838 \
|
||||
--hash=sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90 \
|
||||
--hash=sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626 \
|
||||
--hash=sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4 \
|
||||
--hash=sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369 \
|
||||
--hash=sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b \
|
||||
--hash=sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e \
|
||||
--hash=sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee \
|
||||
--hash=sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1 \
|
||||
--hash=sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102 \
|
||||
--hash=sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8 \
|
||||
--hash=sha256:29880d17a8eb0b5cfdfd8944b468322928059aa35f1f5fa8ff22b149ec0b42f8 \
|
||||
--hash=sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9 \
|
||||
--hash=sha256:2e9cf9253119d8e5d111f05d71626786fd3d6193817316eab1ca088cdb8593cf \
|
||||
--hash=sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0 \
|
||||
--hash=sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031 \
|
||||
--hash=sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e \
|
||||
--hash=sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235 \
|
||||
--hash=sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072 \
|
||||
--hash=sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb \
|
||||
--hash=sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c \
|
||||
--hash=sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950 \
|
||||
--hash=sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2 \
|
||||
--hash=sha256:366ec70f5547c640d3ce1985722490f23faf4eb5216a7eeba78277490e78dacb \
|
||||
--hash=sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e \
|
||||
--hash=sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6 \
|
||||
--hash=sha256:3e5e1224c0a6a90e05843e07adfec669edebec17801c67072f51e59561d63c0b \
|
||||
--hash=sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2 \
|
||||
--hash=sha256:433c5a81eade63b47e522303bad236f59dba55ea6951746f5558355eeed8c75d \
|
||||
--hash=sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa \
|
||||
--hash=sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2 \
|
||||
--hash=sha256:494b70049a4d69aec6e8137c13af4cf8db8c9f9820a1392ac293b0dd2987a818 \
|
||||
--hash=sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032 \
|
||||
--hash=sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71 \
|
||||
--hash=sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96 \
|
||||
--hash=sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687 \
|
||||
--hash=sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8 \
|
||||
--hash=sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3 \
|
||||
--hash=sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61 \
|
||||
--hash=sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9 \
|
||||
--hash=sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1 \
|
||||
--hash=sha256:55261ac0d2941c42f196dd576f543d87a8ee03cd6f5e30dfb4d807b2e3b9121a \
|
||||
--hash=sha256:56490c595a28b1bb27dfc583e816152a9767721ef58b2c03b13f954d2f707420 \
|
||||
--hash=sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4 \
|
||||
--hash=sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65 \
|
||||
--hash=sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663 \
|
||||
--hash=sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f \
|
||||
--hash=sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591 \
|
||||
--hash=sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a \
|
||||
--hash=sha256:5ca0555312ae2fe82715cada7fac375530c2f3349e1eaa1bcb33d0283ac79a18 \
|
||||
--hash=sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e \
|
||||
--hash=sha256:5e2d0e146dcb57034f8b97dc58d2d512cb90aba253960ce449f695fec6a82c6f \
|
||||
--hash=sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7 \
|
||||
--hash=sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3 \
|
||||
--hash=sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c \
|
||||
--hash=sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3 \
|
||||
--hash=sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7 \
|
||||
--hash=sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96 \
|
||||
--hash=sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486 \
|
||||
--hash=sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3 \
|
||||
--hash=sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6 \
|
||||
--hash=sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b \
|
||||
--hash=sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731 \
|
||||
--hash=sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959 \
|
||||
--hash=sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9 \
|
||||
--hash=sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf \
|
||||
--hash=sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8 \
|
||||
--hash=sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e \
|
||||
--hash=sha256:789b8982559ae28dad2356519f841655756cdcd96616410590ae0b17454ee64f \
|
||||
--hash=sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885 \
|
||||
--hash=sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0 \
|
||||
--hash=sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506 \
|
||||
--hash=sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2 \
|
||||
--hash=sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0 \
|
||||
--hash=sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e \
|
||||
--hash=sha256:85de3134b5379856e323ba37c19c9256d39425f7b76a63af52b09fb4664c2e8f \
|
||||
--hash=sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e \
|
||||
--hash=sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491 \
|
||||
--hash=sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a \
|
||||
--hash=sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20 \
|
||||
--hash=sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449 \
|
||||
--hash=sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af \
|
||||
--hash=sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c \
|
||||
--hash=sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712 \
|
||||
--hash=sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7 \
|
||||
--hash=sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a \
|
||||
--hash=sha256:94fbf1c0c6cc0d3d5e50f9a9313a8cdca90dd696d34b381cd1704f8c9e939f20 \
|
||||
--hash=sha256:950f23cb393f85543777b0433f082cddd25b51ab398eac7971146495679efe5f \
|
||||
--hash=sha256:96eefc178f8636b9c760c5829345307fd81cfae9ab1e80997dbddeb0f54ee9a3 \
|
||||
--hash=sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9 \
|
||||
--hash=sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e \
|
||||
--hash=sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5 \
|
||||
--hash=sha256:994e883d17c559cdfd38c84003c8b27d25424a1077272a17e7cd27bfe0bf57b2 \
|
||||
--hash=sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36 \
|
||||
--hash=sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263 \
|
||||
--hash=sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4 \
|
||||
--hash=sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11 \
|
||||
--hash=sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a \
|
||||
--hash=sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3 \
|
||||
--hash=sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375 \
|
||||
--hash=sha256:a545775cfe815855ea32d7c27731d79da358ef2055b4a25830231b1622dd18aa \
|
||||
--hash=sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d \
|
||||
--hash=sha256:a6d095662e73e74f0a49988e0593373e243e3a52e27bfeea0a859e88acf4a0f5 \
|
||||
--hash=sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99 \
|
||||
--hash=sha256:a951ad59cad9145664a730d3036b40b844e74d2d3683da40111463cd3a83845d \
|
||||
--hash=sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c \
|
||||
--hash=sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488 \
|
||||
--hash=sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6 \
|
||||
--hash=sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc \
|
||||
--hash=sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b \
|
||||
--hash=sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f \
|
||||
--hash=sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00 \
|
||||
--hash=sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10 \
|
||||
--hash=sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598 \
|
||||
--hash=sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6 \
|
||||
--hash=sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962 \
|
||||
--hash=sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c \
|
||||
--hash=sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08 \
|
||||
--hash=sha256:ba2f37ee79e6338845261a3c5b1784e5d1acdff2c0785b284f1b633033d136ab \
|
||||
--hash=sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573 \
|
||||
--hash=sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90 \
|
||||
--hash=sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5 \
|
||||
--hash=sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18 \
|
||||
--hash=sha256:be47f99644b208bff7766314013f9acf57b056b04191d570d68ad14022cf5b1d \
|
||||
--hash=sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af \
|
||||
--hash=sha256:c1dcc36dcb96abc02236e182d17e0f71430152a6c2c7447421da2d2dc144edea \
|
||||
--hash=sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c \
|
||||
--hash=sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b \
|
||||
--hash=sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6 \
|
||||
--hash=sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8 \
|
||||
--hash=sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774 \
|
||||
--hash=sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004 \
|
||||
--hash=sha256:ce854f5f478050ade5a238731c4ca985a7d3b3cb53ff600a9b5c3b689b5f0a7a \
|
||||
--hash=sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a \
|
||||
--hash=sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2 \
|
||||
--hash=sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2 \
|
||||
--hash=sha256:d1ee1e296209fdce05b81b663250eefa02213a2da7b41bf26f7829b8ba3545aa \
|
||||
--hash=sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe \
|
||||
--hash=sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3 \
|
||||
--hash=sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc \
|
||||
--hash=sha256:e06efa066f7dbadbc84ebc126a97c452a6451dfcf589d89d788484949e1cf795 \
|
||||
--hash=sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d \
|
||||
--hash=sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc \
|
||||
--hash=sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893 \
|
||||
--hash=sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef \
|
||||
--hash=sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d \
|
||||
--hash=sha256:e9fbdce1e47394b09bc9f26ab117dfc8d6491977a11d86f592bb42c779db2fda \
|
||||
--hash=sha256:eb12fb2ba69ffa05f8695f61c69e591dc4b4a12ac3757ac8af8adb259bf56d17 \
|
||||
--hash=sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30 \
|
||||
--hash=sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7 \
|
||||
--hash=sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5 \
|
||||
--hash=sha256:f5542f9b941279d82d41eb0aa9f98eba36fe4df5c7086c651df7944935b37182 \
|
||||
--hash=sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f \
|
||||
--hash=sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9 \
|
||||
--hash=sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada \
|
||||
--hash=sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876 \
|
||||
--hash=sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a \
|
||||
--hash=sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348 \
|
||||
--hash=sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3 \
|
||||
--hash=sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f \
|
||||
--hash=sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0 \
|
||||
--hash=sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# requests
|
||||
colorama==0.4.6 ; sys_platform == 'win32' \
|
||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# tqdm
|
||||
filelock==3.32.3 \
|
||||
--hash=sha256:0ffa185a3540854c95caa7fa76b76cb219d907415e2c5dc9af25fd970563487f \
|
||||
--hash=sha256:7f0ca4bcc0e181c60dbbd8aa9ab5b120ebb99e4e064e83636340056f833a1f09
|
||||
@@ -17,9 +198,12 @@ fsspec==2026.7.0 \
|
||||
--hash=sha256:b57ddbafedfaef7018c1ecab32aa200a9d7ca26b77965f64e48b70061249d279 \
|
||||
--hash=sha256:c803c40f4cf860b49dea58ee3e1c33cb9c790520e233537e1340049f89b82a88
|
||||
# via torch
|
||||
idna==3.4 \
|
||||
--hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
|
||||
# via requests
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# requests
|
||||
jinja2==3.1.6 \
|
||||
--hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \
|
||||
--hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67
|
||||
@@ -183,7 +367,84 @@ numba==0.67.0 \
|
||||
--hash=sha256:f63d43db06b4756424d6d2484737c902e0ae944a0eec3e8b0b4de2c695b15caa \
|
||||
--hash=sha256:f99f880ff25f418a67f9a1d00d0ddfbc63430f627b523e515085a592a7567f4b
|
||||
# via openai-whisper
|
||||
numpy==2.5.2 \
|
||||
numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \
|
||||
--hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \
|
||||
--hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \
|
||||
--hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \
|
||||
--hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \
|
||||
--hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \
|
||||
--hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \
|
||||
--hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \
|
||||
--hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \
|
||||
--hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \
|
||||
--hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \
|
||||
--hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \
|
||||
--hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \
|
||||
--hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \
|
||||
--hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \
|
||||
--hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \
|
||||
--hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \
|
||||
--hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \
|
||||
--hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \
|
||||
--hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \
|
||||
--hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \
|
||||
--hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \
|
||||
--hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \
|
||||
--hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \
|
||||
--hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \
|
||||
--hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \
|
||||
--hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \
|
||||
--hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \
|
||||
--hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \
|
||||
--hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \
|
||||
--hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \
|
||||
--hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \
|
||||
--hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \
|
||||
--hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \
|
||||
--hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \
|
||||
--hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \
|
||||
--hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \
|
||||
--hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \
|
||||
--hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \
|
||||
--hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \
|
||||
--hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \
|
||||
--hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \
|
||||
--hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \
|
||||
--hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \
|
||||
--hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \
|
||||
--hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \
|
||||
--hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \
|
||||
--hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \
|
||||
--hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \
|
||||
--hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \
|
||||
--hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \
|
||||
--hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \
|
||||
--hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \
|
||||
--hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \
|
||||
--hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \
|
||||
--hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \
|
||||
--hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \
|
||||
--hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \
|
||||
--hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \
|
||||
--hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \
|
||||
--hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \
|
||||
--hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \
|
||||
--hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \
|
||||
--hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \
|
||||
--hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \
|
||||
--hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \
|
||||
--hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \
|
||||
--hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \
|
||||
--hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \
|
||||
--hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \
|
||||
--hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# numba
|
||||
# openai-whisper
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
--hash=sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7 \
|
||||
@@ -251,6 +512,7 @@ numpy==2.5.2 \
|
||||
--hash=sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# numba
|
||||
# openai-whisper
|
||||
openai-whisper==20250625 \
|
||||
@@ -372,12 +634,18 @@ regex==2026.7.19 \
|
||||
--hash=sha256:fe31f28c94402043161876a258a9c6f757cb485905c7614ce8d6cd40e6b7bdc1 \
|
||||
--hash=sha256:ffd8893ccc1c2fce6e0d6ca402d716fe1b29db70c7132609a05955e31b2aa8f2
|
||||
# via tiktoken
|
||||
requests==2.28.1 \
|
||||
--hash=sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349
|
||||
# via tiktoken
|
||||
setuptools==78.1.0 \
|
||||
--hash=sha256:3e386e96793c8702ae83d17b853fb93d3e09ef82ec62722e61da5cd22376dcd8
|
||||
# via torch
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# tiktoken
|
||||
setuptools==81.0.0 \
|
||||
--hash=sha256:487b53915f52501f0a79ccfd0c02c165ffe06631443a886740b91af4b7a5845a \
|
||||
--hash=sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6
|
||||
# via
|
||||
# -c requirements/installer-build.txt
|
||||
# torch
|
||||
sympy==1.14.0 \
|
||||
--hash=sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517 \
|
||||
--hash=sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5
|
||||
@@ -503,10 +771,13 @@ torchaudio==2.11.0+cpu \
|
||||
--hash=sha256:fa0c22f58f60c3537b7d28ed2501e0995acb2a65d9af2708f21edaad67186cd8 \
|
||||
--hash=sha256:fae220128cbfe060c663fbb2a1967b88c605f9eb49b535903cca694011662534
|
||||
# via -r requirements/whisper.in
|
||||
tqdm==4.66.5 \
|
||||
--hash=sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd
|
||||
# via openai-whisper
|
||||
triton==3.7.1 \
|
||||
tqdm==4.70.0 \
|
||||
--hash=sha256:55b0b0dbd97462d06ebee91e4dac24ed4d4702be82b24f07e6c1d27e08cea220 \
|
||||
--hash=sha256:7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# openai-whisper
|
||||
triton==3.7.1 ; (platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'linux2' \
|
||||
--hash=sha256:10ba85fa2cca4a2fbdeb36bf1cb082f2c252bda55bf9fccd74f65ec5bc647e68 \
|
||||
--hash=sha256:2020153b08280415ec0da6607834e79166442147e78e144df06b508c75b186d2 \
|
||||
--hash=sha256:3daf64305d6cea88d3334c65ebc9bcd0c64c9564a977084366aa768d57cbcf64 \
|
||||
@@ -523,7 +794,12 @@ triton==3.7.1 \
|
||||
typing-extensions==4.16.0 \
|
||||
--hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8 \
|
||||
--hash=sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5
|
||||
# via torch
|
||||
urllib3==1.26.13 \
|
||||
--hash=sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc
|
||||
# via requests
|
||||
# via
|
||||
# -c requirements/installer-build.txt
|
||||
# torch
|
||||
urllib3==2.7.0 \
|
||||
--hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \
|
||||
--hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# requests
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Select committed requirement blocks without changing pins, markers or hashes.
|
||||
|
||||
The installer uses complete exports for normal installs and just pywhispercpp's
|
||||
block for backend rebuilds. Missing exports or packages are errors, never an
|
||||
empty successful install. Only the standard library is needed before bootstrap.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def select_requirements(source: Path, package: str | None = None) -> str:
|
||||
"""Return an export, optionally retaining only one distribution's blocks."""
|
||||
text = source.read_text(encoding="utf-8")
|
||||
blocks = re.split(r"(?=^[A-Za-z0-9_.-]+==)", text, flags=re.MULTILINE)
|
||||
requirements = blocks[1:]
|
||||
if not requirements:
|
||||
raise ValueError(f"No pinned requirements in {source}")
|
||||
if package is not None:
|
||||
normalize = lambda name: re.sub(r"[-_.]+", "-", name).lower()
|
||||
requirements = [
|
||||
block
|
||||
for block in requirements
|
||||
if normalize(block.split("==", 1)[0]) == normalize(package)
|
||||
]
|
||||
if not requirements:
|
||||
raise ValueError(f"No pin for {package} in {source}")
|
||||
return blocks[0] + "".join(requirements)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Write the selected export to the installer's scratch directory."""
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("source", type=Path)
|
||||
parser.add_argument("destination", type=Path)
|
||||
parser.add_argument("--package")
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
text = select_requirements(args.source, args.package)
|
||||
except (OSError, ValueError) as error:
|
||||
parser.exit(1, f"Cannot install pinned dependencies: {error}\n")
|
||||
args.destination.write_text(text, encoding="utf-8")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,349 @@
|
||||
"""Exercise pinned installer calls, including fail-closed and rebuild paths."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
import tomllib
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from packaging.requirements import Requirement
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
INSTALLER = ROOT / "install.sh"
|
||||
SELECTOR = ROOT / "scripts/installer_requirements.py"
|
||||
|
||||
|
||||
def _run(tmp_path: Path, command: str, *, fail_pip: bool = False) -> subprocess.CompletedProcess:
|
||||
"""Run real shell helpers with a recording interpreter in a path with spaces."""
|
||||
venv = tmp_path / "test venv"
|
||||
(venv / "bin").mkdir(parents=True)
|
||||
python = venv / "bin/python"
|
||||
python.write_text(
|
||||
f"#!{sys.executable}\n"
|
||||
"import json, os, subprocess, sys\n"
|
||||
"if sys.argv[1:3] == ['-m', 'pip']:\n"
|
||||
" with open(os.environ['PIP_CALLS'], 'a') as log:\n"
|
||||
" log.write(json.dumps(sys.argv[3:]) + '\\n')\n"
|
||||
" sys.exit(int(os.environ.get('FAIL_PIP', '0')))\n"
|
||||
f"sys.exit(subprocess.call([{sys.executable!r}, *sys.argv[1:]]))\n"
|
||||
)
|
||||
python.chmod(0o755)
|
||||
functions = [
|
||||
"pip_install_reqs_file",
|
||||
"pip_install_project_skip_pygobject",
|
||||
"pip_install_extras_skip_pygobject",
|
||||
"pip_reinstall_pywhispercpp",
|
||||
"install_cpu_pywhispercpp",
|
||||
"get_pywhispercpp_cmake_args",
|
||||
"install_pinned_build_tools",
|
||||
]
|
||||
source = "\n".join(
|
||||
f"source <(sed -n '/^{name}() {{$/,/^}}$/p' {shlex.quote(str(INSTALLER))})"
|
||||
for name in functions
|
||||
)
|
||||
script = f"""
|
||||
set -euo pipefail
|
||||
print_error() {{ echo "$*" >&2; }}
|
||||
print_info() {{ :; }}
|
||||
require_distro_gi() {{ :; }}
|
||||
VENV_DIR={shlex.quote(str(venv))}
|
||||
INSTALL_DIR={shlex.quote(str(ROOT))}
|
||||
VOCALINUX_TMP_DIR={shlex.quote(str(tmp_path))}
|
||||
{source}
|
||||
{command}
|
||||
"""
|
||||
return subprocess.run(
|
||||
["bash", "-c", script],
|
||||
env={**os.environ, "PIP_CALLS": str(tmp_path / "calls"), "FAIL_PIP": str(int(fail_pip))},
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10,
|
||||
)
|
||||
|
||||
|
||||
def _calls(tmp_path: Path) -> list[list[str]]:
|
||||
path = tmp_path / "calls"
|
||||
return [json.loads(line) for line in path.read_text().splitlines()] if path.exists() else []
|
||||
|
||||
|
||||
@pytest.mark.parametrize("extra", ["vad", "vosk", "parakeet", "faster_whisper", "whisper", "dev"])
|
||||
def test_extras_use_committed_hashes(tmp_path: Path, extra: str) -> None:
|
||||
result = _run(tmp_path, f'pip_install_extras_skip_pygobject "install log" {extra}')
|
||||
assert result.returncode == 0, result.stderr
|
||||
(call,) = _calls(tmp_path)
|
||||
assert {"--require-hashes", "--no-deps", "--no-build-isolation"} <= set(call)
|
||||
assert call[call.index("-r") + 1] == str(ROOT / f"requirements/{extra.replace('_', '-')}.txt")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("editable", [False, True])
|
||||
def test_project_follows_locked_runtime_without_resolution(tmp_path: Path, editable: bool) -> None:
|
||||
args = '-e "project directory"' if editable else '"project directory"'
|
||||
result = _run(tmp_path, f"pip_install_project_skip_pygobject log {args}")
|
||||
assert result.returncode == 0, result.stderr
|
||||
runtime, project = _calls(tmp_path)
|
||||
assert runtime[runtime.index("-r") + 1].endswith("/requirements/runtime.txt")
|
||||
assert "--require-hashes" in runtime
|
||||
assert {"--no-deps", "--no-build-isolation"} <= set(project)
|
||||
assert ("-e" in project) == editable
|
||||
assert project[-1] == "project directory"
|
||||
|
||||
|
||||
def test_failed_dependencies_never_install_project(tmp_path: Path) -> None:
|
||||
result = _run(tmp_path, "pip_install_project_skip_pygobject log .", fail_pip=True)
|
||||
assert result.returncode != 0
|
||||
assert len(_calls(tmp_path)) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize("kind", ["missing", "empty", "unknown-extra"])
|
||||
def test_missing_pins_fail_before_pip(tmp_path: Path, kind: str) -> None:
|
||||
path = tmp_path / "missing.txt"
|
||||
if kind == "empty":
|
||||
path.touch()
|
||||
command = (
|
||||
"pip_install_extras_skip_pygobject log typo"
|
||||
if kind == "unknown-extra"
|
||||
else f"pip_install_reqs_file log {shlex.quote(str(path))}"
|
||||
)
|
||||
result = _run(tmp_path, command)
|
||||
assert result.returncode != 0
|
||||
assert not _calls(tmp_path)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("backend", ["cpu", "vulkan", "cuda"])
|
||||
def test_rebuild_uses_only_locked_pywhispercpp(tmp_path: Path, backend: str) -> None:
|
||||
command = (
|
||||
"install_cpu_pywhispercpp log"
|
||||
if backend == "cpu"
|
||||
else f"GGML_{backend.upper()}=1 pip_reinstall_pywhispercpp log --no-binary pywhispercpp"
|
||||
)
|
||||
result = _run(tmp_path, command)
|
||||
assert result.returncode == 0, result.stderr
|
||||
(call,) = _calls(tmp_path)
|
||||
assert {"--require-hashes", "--no-deps", "--no-build-isolation", "--force-reinstall"} <= set(
|
||||
call
|
||||
)
|
||||
selected = (tmp_path / "pywhispercpp.txt").read_text()
|
||||
assert re.findall(r"^([\w.-]+)==", selected, re.M) == ["pywhispercpp"]
|
||||
lock = tomllib.loads((ROOT / "uv.lock").read_text())
|
||||
package = next(p for p in lock["package"] if p["name"] == "pywhispercpp")
|
||||
assert f"pywhispercpp=={package['version']}" in selected
|
||||
for artifact in [package["sdist"], *package["wheels"]]:
|
||||
assert artifact["hash"] in selected
|
||||
|
||||
|
||||
def test_bootstrap_uses_only_hashed_wheels(tmp_path: Path) -> None:
|
||||
result = _run(tmp_path, "install_pinned_build_tools")
|
||||
assert result.returncode == 0, result.stderr
|
||||
(call,) = _calls(tmp_path)
|
||||
assert {"--require-hashes", "--only-binary=:all:", "--ignore-installed", "--no-deps"} <= set(
|
||||
call
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("kind", ["missing", "empty"])
|
||||
def test_bootstrap_rejects_missing_or_empty_export(tmp_path: Path, kind: str) -> None:
|
||||
"""Reject missing pins before invoking pip, including in a conditional."""
|
||||
requirements = tmp_path / "requirements"
|
||||
requirements.mkdir()
|
||||
export = requirements / "installer-build.txt"
|
||||
if kind == "empty":
|
||||
export.touch()
|
||||
result = _run(
|
||||
tmp_path,
|
||||
f"INSTALL_DIR={shlex.quote(str(tmp_path))}\n" "install_pinned_build_tools || exit 23",
|
||||
)
|
||||
assert result.returncode == 23, result.stdout + result.stderr
|
||||
assert f"Missing or empty pinned requirements: {export}" in result.stderr
|
||||
assert not _calls(tmp_path)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("remote_aware", [False, True])
|
||||
def test_remote_handoff_preserves_tagged_behavior(tmp_path: Path, remote_aware: bool) -> None:
|
||||
"""A main bootstrap must preserve remote behavior for every tag."""
|
||||
clone = tmp_path / "old tagged tree"
|
||||
clone.mkdir()
|
||||
marker = 'CLEANUP_ON_EXIT="${VOCALINUX_REMOTE_INSTALL:-no}"\n' if remote_aware else ""
|
||||
(clone / "install.sh").write_text(
|
||||
"#!/bin/bash\n"
|
||||
+ marker
|
||||
+ 'printf "%s\\n" "${VOCALINUX_REMOTE_INSTALL:-no}" "$PWD" "$@"\n'
|
||||
+ "helper=activate-vocalinux.sh\n"
|
||||
+ 'if [ "${VOCALINUX_REMOTE_INSTALL:-no}" = yes ]; then\n'
|
||||
+ ' mkdir -p "$HOME/.local/bin"\n'
|
||||
+ ' helper="$HOME/.local/bin/activate-vocalinux.sh"\n'
|
||||
+ "fi\n"
|
||||
+ 'printf helper > "$helper"\n'
|
||||
)
|
||||
scratch = tmp_path / "scratch"
|
||||
scratch.mkdir()
|
||||
text = INSTALLER.read_text()
|
||||
start = text.index("handoff_to_tagged_installer() {")
|
||||
end = text.index("\n}", start) + 2
|
||||
handoff = text[start:end]
|
||||
home = tmp_path / "home"
|
||||
home.mkdir()
|
||||
result = subprocess.run(
|
||||
[
|
||||
"bash",
|
||||
"-c",
|
||||
f"set -eu\n{handoff}\ncd {shlex.quote(str(clone))}\n"
|
||||
f"INSTALL_DIR={shlex.quote(str(clone))}\n"
|
||||
f"VOCALINUX_TMP_DIR={shlex.quote(str(scratch))}\n"
|
||||
"INSTALLER_ARGS=(--auto --tag=v0.17.0 --engine=remote_api)\n"
|
||||
'print_error() { echo "$*" >&2; }\n'
|
||||
"handoff_to_tagged_installer",
|
||||
],
|
||||
env={**os.environ, "HOME": str(home)},
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10,
|
||||
)
|
||||
assert result.returncode == 0, result.stderr
|
||||
assert result.stdout.splitlines() == [
|
||||
"yes" if remote_aware else "no",
|
||||
str(clone),
|
||||
"--auto",
|
||||
"--tag=v0.17.0",
|
||||
"--engine=remote_api",
|
||||
f"--venv-dir={home}/.local/share/vocalinux/venv",
|
||||
]
|
||||
assert scratch.exists() != remote_aware
|
||||
helper = home / ".local/bin/activate-vocalinux.sh"
|
||||
assert helper.read_text() == "helper"
|
||||
assert not (clone / "activate-vocalinux.sh").exists()
|
||||
|
||||
|
||||
def test_every_pip_install_has_an_explicit_resolution_boundary() -> None:
|
||||
"""Catch a new engine adding a bare pip install outside the shared helpers."""
|
||||
source = INSTALLER.read_text().replace("\\\n", " ")
|
||||
installs = [
|
||||
line.strip()
|
||||
for line in source.splitlines()
|
||||
if re.match(r'^\s*(?:pip |"\$VENV_DIR/bin/python" -m pip )install ', line)
|
||||
]
|
||||
assert len(installs) >= 4
|
||||
for line in installs:
|
||||
assert "--no-deps" in line, line
|
||||
if "--require-hashes" in line:
|
||||
assert "--no-build-isolation" in line or "--only-binary=:all:" in line, line
|
||||
else:
|
||||
assert '--log "$pip_log" "$@"' in line, line # the local project only
|
||||
assert "--no-build-isolation" in line, line
|
||||
|
||||
|
||||
def test_selector_preserves_python_markers_and_rejects_absent_package(tmp_path: Path) -> None:
|
||||
spec = importlib.util.spec_from_file_location("installer_requirements", SELECTOR)
|
||||
assert spec and spec.loader
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
source = ROOT / "requirements/runtime.txt"
|
||||
selected = module.select_requirements(source, "numpy")
|
||||
assert "python_full_version < '3.12'" in selected
|
||||
assert "python_full_version >= '3.12'" in selected
|
||||
assert selected.count("numpy==") == 2
|
||||
with pytest.raises(ValueError, match="No pin"):
|
||||
module.select_requirements(source, "typo")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("minor", [11, 12, 13, 14])
|
||||
def test_whisper_does_not_replace_runtime_or_build_pins(minor: int) -> None:
|
||||
environment = {
|
||||
"python_version": f"3.{minor}",
|
||||
"python_full_version": f"3.{minor}.0",
|
||||
"sys_platform": "linux",
|
||||
"platform_machine": "x86_64",
|
||||
}
|
||||
|
||||
def pins(name: str) -> dict[str, str]:
|
||||
result = {}
|
||||
for line in (ROOT / f"requirements/{name}.txt").read_text().splitlines():
|
||||
if re.match(r"^[\w.-]+==", line):
|
||||
requirement = Requirement(line.rstrip(" \\"))
|
||||
if requirement.marker is None or requirement.marker.evaluate(environment):
|
||||
result[requirement.name] = str(requirement.specifier)
|
||||
return result
|
||||
|
||||
base = pins("runtime") | pins("installer-build")
|
||||
whisper = pins("whisper")
|
||||
assert whisper["torch"].endswith("+cpu")
|
||||
for name in base.keys() & whisper.keys():
|
||||
assert base[name] == whisper[name], name
|
||||
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
@pytest.mark.parametrize("tamper", [False, True])
|
||||
def test_real_pip_checks_hash_before_install(tmp_path: Path, tamper: bool) -> None:
|
||||
"""Use a local wheel and no index: exercise pip, not a mocked hash checker."""
|
||||
venv = tmp_path / "venv"
|
||||
subprocess.run([sys.executable, "-m", "venv", "--system-site-packages", str(venv)], check=True)
|
||||
wheel = tmp_path / "pinned_fixture-1.0-py3-none-any.whl"
|
||||
with zipfile.ZipFile(wheel, "w") as archive:
|
||||
archive.writestr("pinned_fixture.py", "VALUE = 1\n")
|
||||
archive.writestr(
|
||||
"pinned_fixture-1.0.dist-info/METADATA",
|
||||
"Metadata-Version: 2.1\nName: pinned-fixture\nVersion: 1.0\n",
|
||||
)
|
||||
archive.writestr(
|
||||
"pinned_fixture-1.0.dist-info/WHEEL",
|
||||
"Wheel-Version: 1.0\nGenerator: test\nRoot-Is-Purelib: true\nTag: py3-none-any\n",
|
||||
)
|
||||
archive.writestr("pinned_fixture-1.0.dist-info/RECORD", "")
|
||||
digest = hashlib.sha256(wheel.read_bytes()).hexdigest()
|
||||
if tamper:
|
||||
with zipfile.ZipFile(wheel, "a") as archive:
|
||||
archive.writestr("tampered.txt", "changed bytes")
|
||||
requirements = tmp_path / "requirements.txt"
|
||||
requirements.write_text(f"pinned-fixture==1.0 --hash=sha256:{digest}\n")
|
||||
source = (
|
||||
f"source <(sed -n '/^pip_install_reqs_file() {{$/,/^}}$/p' {shlex.quote(str(INSTALLER))})"
|
||||
)
|
||||
result = subprocess.run(
|
||||
[
|
||||
"bash",
|
||||
"-c",
|
||||
f'{source}\nVENV_DIR={shlex.quote(str(venv))}\nprint_error() {{ echo "$*" >&2; }}\npip_install_reqs_file {shlex.quote(str(tmp_path / "pip.log"))} {shlex.quote(str(requirements))}',
|
||||
],
|
||||
env={
|
||||
**os.environ,
|
||||
"PIP_NO_INDEX": "1",
|
||||
"PIP_FIND_LINKS": str(tmp_path),
|
||||
"PIP_DISABLE_PIP_VERSION_CHECK": "1",
|
||||
},
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
)
|
||||
assert (result.returncode != 0) == tamper, result.stdout + result.stderr
|
||||
if tamper:
|
||||
assert "HASHES" in result.stderr
|
||||
|
||||
|
||||
def test_source_built_runtime_packages_have_build_deps_on_split_devel_distros() -> None:
|
||||
"""The pinned runtime builds these from source; distro lists that split
|
||||
-devel packages must carry their build deps."""
|
||||
runtime = (ROOT / "requirements/runtime.txt").read_text(encoding="utf-8")
|
||||
installer = INSTALLER.read_text(encoding="utf-8")
|
||||
|
||||
def package_line(prefix: str) -> str:
|
||||
return next(line for line in installer.splitlines() if f"local {prefix}=" in line)
|
||||
|
||||
build_deps = {
|
||||
"pycairo": ("cairo-devel", "libcairo2-dev"),
|
||||
"pyaudio": ("portaudio-devel", "portaudio19-dev"),
|
||||
"evdev": ("python3-devel", "python3-dev"),
|
||||
}
|
||||
for name, (dnf_pkg, apt_pkg) in build_deps.items():
|
||||
if not re.search(rf"^{name}==", runtime, re.MULTILINE):
|
||||
continue # wheels-only or dropped: nothing to build
|
||||
assert dnf_pkg in package_line("DNF_PACKAGES"), name
|
||||
assert apt_pkg in package_line("APT_PACKAGES_UBUNTU"), name
|
||||
assert apt_pkg in package_line("APT_PACKAGES_DEBIAN_BASE"), name
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
@@ -64,9 +62,8 @@ def test_system_dep_and_venv_failures_use_structured_exit_codes() -> None:
|
||||
in source
|
||||
)
|
||||
assert 'exit "$EXIT_MISSING_DEPS"' in source
|
||||
assert (
|
||||
'print_error "Failed to update pip, setuptools, and wheel"; exit "$EXIT_NETWORK"' in source
|
||||
)
|
||||
bootstrap_failure = source.split("install_pinned_build_tools || {", 1)[1].split("}", 1)[0]
|
||||
assert 'exit "$EXIT_NETWORK"' in bootstrap_failure
|
||||
assert (
|
||||
'print_error "Failed to install Vocalinux package. Installation cannot continue."' in source
|
||||
)
|
||||
@@ -90,7 +87,7 @@ def test_whispercpp_fallback_installs_vosk_extra() -> None:
|
||||
|
||||
def test_project_pip_install_skips_pygobject() -> None:
|
||||
source = _installer_source()
|
||||
assert "write_pip_reqs_skip_pygobject()" in source
|
||||
assert "write_pip_reqs_skip_pygobject()" not in source
|
||||
assert "pip_install_project_skip_pygobject()" in source
|
||||
assert "pip install --no-deps" in source
|
||||
assert "--no-emit-package pygobject" in source
|
||||
@@ -101,46 +98,6 @@ def test_project_pip_install_skips_pygobject() -> None:
|
||||
assert 'pip install -e ".[whisper,dev]"' not in source
|
||||
|
||||
|
||||
def _run_reqs_writer(dest: Path, *extras: str) -> None:
|
||||
source = _installer_source()
|
||||
start = source.index("from pathlib import Path\nimport re\nimport sys\n")
|
||||
end = source.index("\nPY\n}", start)
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-", str(dest), *extras],
|
||||
check=False,
|
||||
cwd=INSTALLER.parent,
|
||||
input=source[start:end],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stderr
|
||||
|
||||
|
||||
def test_write_pip_reqs_skip_pygobject_runtime(tmp_path) -> None:
|
||||
dest = tmp_path / "runtime.txt"
|
||||
_run_reqs_writer(dest)
|
||||
reqs = dest.read_text().splitlines()
|
||||
assert reqs
|
||||
assert all("pygobject" not in req.lower() for req in reqs)
|
||||
assert any(req.startswith("pyaudio") for req in reqs)
|
||||
assert any(req.startswith("pywhispercpp") for req in reqs)
|
||||
|
||||
|
||||
def test_write_pip_reqs_skip_pygobject_vosk_extra(tmp_path) -> None:
|
||||
"""The writer copies an extra's specifiers through, bounds and all.
|
||||
|
||||
Read out of pyproject.toml rather than written here as a literal. This
|
||||
assertion was `["vosk>=0.3.45"]` and failed the day the extra gained an
|
||||
upper bound, reporting an intentional pyproject edit as an installer defect.
|
||||
"""
|
||||
with PYPROJECT.open("rb") as handle:
|
||||
expected = tomllib.load(handle)["project"]["optional-dependencies"]["vosk"]
|
||||
assert expected, "the vosk extra declares nothing; this would compare [] to []"
|
||||
dest = tmp_path / "vosk.txt"
|
||||
_run_reqs_writer(dest, "vosk")
|
||||
assert dest.read_text().splitlines() == expected
|
||||
|
||||
|
||||
def test_settings_uses_engine_flag_not_removed_with_whisper() -> None:
|
||||
text = SETTINGS.read_text(encoding="utf-8")
|
||||
assert "./install.sh --engine=whisper" in text
|
||||
|
||||
@@ -2,9 +2,12 @@ version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.11"
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.15'",
|
||||
"python_full_version >= '3.12' and python_full_version < '3.15'",
|
||||
"python_full_version < '3.12'",
|
||||
"python_full_version >= '3.15' and sys_platform != 'ios'",
|
||||
"python_full_version >= '3.15' and sys_platform == 'ios'",
|
||||
"python_full_version >= '3.12' and python_full_version < '3.15' and sys_platform != 'ios'",
|
||||
"python_full_version >= '3.12' and python_full_version < '3.15' and sys_platform == 'ios'",
|
||||
"python_full_version < '3.12' and sys_platform != 'ios'",
|
||||
"python_full_version < '3.12' and sys_platform == 'ios'",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -16,6 +19,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "altgraph"
|
||||
version = "0.17.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7e/f8/97fdf103f38fed6792a1601dbc16cc8aac56e7459a9fff08c812d8ae177a/altgraph-0.17.5.tar.gz", hash = "sha256:c87b395dd12fabde9c99573a9749d67da8d29ef9de0125c7f536699b4a9bc9e7", size = 48428, upload-time = "2025-11-21T20:35:50.583Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/ba/000a1996d4308bc65120167c21241a3b205464a2e0b58deda26ae8ac21d1/altgraph-0.17.5-py2.py3-none-any.whl", hash = "sha256:f3a22400bce1b0c701683820ac4f3b159cd301acab067c51c653e06961600597", size = 21228, upload-time = "2025-11-21T20:35:49.444Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.15.1"
|
||||
@@ -440,6 +452,32 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "3.31.10"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/37/7b/fbadb3f4fe90ad6ef57f9f5f9e4f721af8e86376fbdf11da2c6ed099830e/cmake-3.31.10.tar.gz", hash = "sha256:ec3d14a0e72e401b3665034dc37901df17f0b4e9c5b163be6cfedfb93470ac0f", size = 34499, upload-time = "2025-11-20T17:07:54.664Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/99/3b/6ed408a99709808df4014bead522e075f0e8d1100e6d886eb5bc30fee04e/cmake-3.31.10-py3-none-macosx_10_10_universal2.whl", hash = "sha256:ad697643a00d9ba85179590a383c4f7401169b55ebf4b8b2938daf28c6bdeb6d", size = 48001731, upload-time = "2025-11-20T17:06:57.473Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/59/acc2f79180d8aaf55b707ee65b5296ae76a3295ebff9e65d840849b6abc0/cmake-3.31.10-py3-none-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7c300e4ae68fbc1414a85505f7feb262cee82ff3304a286885ebf803b11a997c", size = 27579802, upload-time = "2025-11-20T17:07:00.676Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/0a/2f17b5cc0d3ac1ce2324364c044d170d06167f8d6b7464ee76857114d95e/cmake-3.31.10-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3c17bb24dba15f8ecc3fd706afe04264410ef88796f4115c119327c961d5dc57", size = 26832178, upload-time = "2025-11-20T17:07:03.475Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/6c/d629c3b6a30105f5946e754b42d6ce84be36c190cc70b70fb2eb8a0ffc37/cmake-3.31.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4a5615f31f692c9b9aa8b365704e4b76172348af6fa40e16fea3f118bb01194", size = 27165148, upload-time = "2025-11-20T17:07:06.895Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/d8/9842811ec5615598003499e2d38062d42651a20d022f93f9a590807d76b3/cmake-3.31.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d2ec5fc45d305227020c82213140a51a0cebe3c84f0299036f05716b3a52f60", size = 28889720, upload-time = "2025-11-20T17:07:09.597Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/e9/7042b018121ceaae48416d37edb9924646e3cc8bbb417374cafdf8c2fa58/cmake-3.31.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7864605238759a4ae8e3bd1fda2bb03978e3e37df310852662dcf53866413c8", size = 30757069, upload-time = "2025-11-20T17:07:12.537Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/a8/4e320cd6dfae630c5d9532d822c20a095565bcb159be839919ff7ea2952f/cmake-3.31.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1debc3a0823ce5d8d1bc17154599bbbb337c2681f93622b618bc78f46576e42a", size = 26932214, upload-time = "2025-11-20T17:07:16.075Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/2e/cefc60143950ca1a8dda26d4c8484e6fc406db16e7ca098ebae549de35f9/cmake-3.31.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f766bb46367e5e0559fa33184653754bce044583a06014dcaebf8e6dff8a1f1", size = 27808794, upload-time = "2025-11-20T17:07:18.974Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/55/3f7d68d03f116142ce1076d65898e3d31c24d72985e827bfd9c601c8bc65/cmake-3.31.10-py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:91410816db3beefe2f6032d721f9978c98dc7646e9992c0325486597164fab81", size = 24986234, upload-time = "2025-11-20T17:07:21.596Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/2e/634e46413472be742f3f422f159c41079bdc8ffba67538228f94a166c9ee/cmake-3.31.10-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:c2e5361dea9754ed3b06cf834894fb47dcbe7036d5e5d87acaeb10ff3dd5fd10", size = 27849273, upload-time = "2025-11-20T17:07:24.369Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/af/fac7ee4d79b688b94b4f6a6e5c4b080dca7594342576ad88a52b02a2d4eb/cmake-3.31.10-py3-none-musllinux_1_1_i686.whl", hash = "sha256:6970bb75c4dfc28cc31ff0cd848194d09094ae00d605181e1345b2ff70b61050", size = 31391299, upload-time = "2025-11-20T17:07:27.228Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/14/62339280a675106227ff650166c2899fe9f822ef9b855365563e71115125/cmake-3.31.10-py3-none-musllinux_1_1_ppc64le.whl", hash = "sha256:4cefb0a28ac1268b4eed4b595bf3aaff8de9704089066027700ec36584eccab8", size = 32105563, upload-time = "2025-11-20T17:07:34.352Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/19/a3014beb02b344599e7a879f9c91d5e388aa76924b1369e13ffd535d613d/cmake-3.31.10-py3-none-musllinux_1_1_s390x.whl", hash = "sha256:b331984de38dbda22d676f8812c8905526341ba7b397fe8c359255ff4d051193", size = 27972718, upload-time = "2025-11-20T17:07:37.492Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/53/63b70d583c93352beeb692f0ec6bf4dede96f92df85c009577a663be304a/cmake-3.31.10-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:678fc23db37cc69f01e18eb28790450ecc9401fd2fcd43364cc18f92330c12c2", size = 29497491, upload-time = "2025-11-20T17:07:40.316Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/a3/9d3a3881e70b947abe2d779e4c37d1aa9ac7f8339354e78d6036d520a220/cmake-3.31.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e135d5f1e59f1dc1c80eea87321977d6c0eff86cb601c28e0965a1dd457ea587", size = 33183971, upload-time = "2025-11-20T17:07:43.392Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/f2/8e13be79373ef808659e52680643e0388057060e2627757b90df72c50681/cmake-3.31.10-py3-none-win32.whl", hash = "sha256:b059a1810a2ce766b3e531bdc8d730bc192e260a9fa7dec7a0eb7a053d6063c7", size = 33416497, upload-time = "2025-11-20T17:07:46.467Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/4b/e433ab430c580ec8e3d54cb2ec5c7ea76ae0b1e6ef2c2998c854f21d7780/cmake-3.31.10-py3-none-win_amd64.whl", hash = "sha256:f1ea1fe826355560e8976c3d5794d9357444209bc0e0d56676c71e6a571fd474", size = 36630429, upload-time = "2025-11-20T17:07:49.445Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/c3/4eb3288ccd779556fee4b7b0955bdb14545bbae83f85f7c819dde8013708/cmake-3.31.10-py3-none-win_arm64.whl", hash = "sha256:422a54711aa977af19d59b8f6010354cdda0b72a2e6d702b6d892e3e2cdf98a2", size = 35457178, upload-time = "2025-11-20T17:07:52.367Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
@@ -682,6 +720,18 @@ nvtx = [
|
||||
{ name = "nvidia-nvtx", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "delvewheel"
|
||||
version = "1.13.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pefile" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/36/8d/ad1ecad995732a6c53086ce3bf20479d37a970acc80b7bdb4ab1eb156f2e/delvewheel-1.13.1.tar.gz", hash = "sha256:ae445f35f411c367f5b350431ac5f1435af8128bff31ccf34035a409704da8c6", size = 64796, upload-time = "2026-08-28T18:31:07.461Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/d0/fc48bf4c00b80c1ced5ce3740ea0c5d040758dafce385275e5de559375a4/delvewheel-1.13.1-py3-none-any.whl", hash = "sha256:1b3bc696193a57e322b8bfd644de240be6e003066aae44cc3d5aef8cbee22ca3", size = 60375, upload-time = "2026-08-28T18:31:06.18Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "distlib"
|
||||
version = "0.4.3"
|
||||
@@ -1045,6 +1095,18 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/c6/32d68bfbf1d0c36888530ef6fd72864861af23dc546302b41033471a8c3a/llvmlite-0.49.0-cp314-cp314t-win_amd64.whl", hash = "sha256:be637e465010bc9c50f070468f7f1cf5385e92fee364d192dd5e6cea790ecba9", size = 42986602, upload-time = "2026-08-11T16:25:57.69Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macholib"
|
||||
version = "1.16.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "altgraph" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/10/2f/97589876ea967487978071c9042518d28b958d87b17dceb7cdc1d881f963/macholib-1.16.4.tar.gz", hash = "sha256:f408c93ab2e995cd2c46e34fe328b130404be143469e41bc366c807448979362", size = 59427, upload-time = "2025-11-22T08:28:38.373Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/d1/a9f36f8ecdf0fb7c9b1e78c8d7af12b8c8754e74851ac7b94a8305540fc7/macholib-1.16.4-py2.py3-none-any.whl", hash = "sha256:da1a3fa8266e30f0ce7e97c6a54eefaae8edd1e5f86f3eb8b95457cae90265ea", size = 38117, upload-time = "2025-11-22T08:28:36.939Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "3.0.3"
|
||||
@@ -1128,6 +1190,29 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "meson"
|
||||
version = "1.12.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/48/91/d58a3eb45ed54bf32b96806dd2f4efd407f7a9675953e15e8ef257840a0d/meson-1.12.0.tar.gz", hash = "sha256:88afe0c20e52030218924ac37d0c81c59b4b5f3ae3752c8c6d7470c7d365886c", size = 2518280, upload-time = "2026-08-10T22:10:27.439Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/07/68/b0117422eb0a46d9d8d9e328f0c5b5c835179bfc058688bca35c90c89eba/meson-1.12.0-py3-none-any.whl", hash = "sha256:71f133147fa0fcfe8f4df49fa1045771064947834538409e5d97b3613aac8b4e", size = 1106208, upload-time = "2026-08-10T22:10:23.093Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "meson-python"
|
||||
version = "0.21.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "meson" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pyproject-metadata" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ed/f2/ab554fe4f020ec5f0ab4e4af04318e6ab99660f8d8d14e3d064db2b786a6/meson_python-0.21.1.tar.gz", hash = "sha256:78b3345dcbc0fed7b939e7e37a9faab35bddaae07bf62e7542c8ad479c395af5", size = 113878, upload-time = "2026-09-11T14:00:59.641Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/4f/03aeed5a32e7e8158d8c617fe65b622410db974fe02e3bd78da9689a44fd/meson_python-0.21.1-py3-none-any.whl", hash = "sha256:270bc9b78957c47e0aa1758ad616dba3f943d8f9cbdb944d318c3c1c7a49e4bd", size = 29579, upload-time = "2026-09-11T14:00:58.133Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "more-itertools"
|
||||
version = "11.1.0"
|
||||
@@ -1224,6 +1309,32 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ninja"
|
||||
version = "1.13.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/43/73/79a0b22fc731989c708068427579e840a6cf4e937fe7ae5c5d0b7356ac22/ninja-1.13.0.tar.gz", hash = "sha256:4a40ce995ded54d9dc24f8ea37ff3bf62ad192b547f6c7126e7e25045e76f978", size = 242558, upload-time = "2025-08-11T15:10:19.421Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/74/d02409ed2aa865e051b7edda22ad416a39d81a84980f544f8de717cab133/ninja-1.13.0-py3-none-macosx_10_9_universal2.whl", hash = "sha256:fa2a8bfc62e31b08f83127d1613d10821775a0eb334197154c4d6067b7068ff1", size = 310125, upload-time = "2025-08-11T15:09:50.971Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/de/6e1cd6b84b412ac1ef327b76f0641aeb5dcc01e9d3f9eee0286d0c34fd93/ninja-1.13.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3d00c692fb717fd511abeb44b8c5d00340c36938c12d6538ba989fe764e79630", size = 177467, upload-time = "2025-08-11T15:09:52.767Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/83/49320fb6e58ae3c079381e333575fdbcf1cca3506ee160a2dcce775046fa/ninja-1.13.0-py3-none-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:be7f478ff9f96a128b599a964fc60a6a87b9fa332ee1bd44fa243ac88d50291c", size = 187834, upload-time = "2025-08-11T15:09:54.115Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/c7/ba22748fb59f7f896b609cd3e568d28a0a367a6d953c24c461fe04fc4433/ninja-1.13.0-py3-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:60056592cf495e9a6a4bea3cd178903056ecb0943e4de45a2ea825edb6dc8d3e", size = 202736, upload-time = "2025-08-11T15:09:55.745Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/22/d1de07632b78ac8e6b785f41fa9aad7a978ec8c0a1bf15772def36d77aac/ninja-1.13.0-py3-none-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:1c97223cdda0417f414bf864cfb73b72d8777e57ebb279c5f6de368de0062988", size = 179034, upload-time = "2025-08-11T15:09:57.394Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa", size = 180716, upload-time = "2025-08-11T15:09:58.696Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/28/938b562f9057aaa4d6bfbeaa05e81899a47aebb3ba6751e36c027a7f5ff7/ninja-1.13.0-py3-none-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4be9c1b082d244b1ad7ef41eb8ab088aae8c109a9f3f0b3e56a252d3e00f42c1", size = 146843, upload-time = "2025-08-11T15:10:00.046Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/fb/d06a3838de4f8ab866e44ee52a797b5491df823901c54943b2adb0389fbb/ninja-1.13.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:6739d3352073341ad284246f81339a384eec091d9851a886dfa5b00a6d48b3e2", size = 154402, upload-time = "2025-08-11T15:10:01.657Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/bf/0d7808af695ceddc763cf251b84a9892cd7f51622dc8b4c89d5012779f06/ninja-1.13.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:11be2d22027bde06f14c343f01d31446747dbb51e72d00decca2eb99be911e2f", size = 552388, upload-time = "2025-08-11T15:10:03.349Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/70/c99d0c2c809f992752453cce312848abb3b1607e56d4cd1b6cded317351a/ninja-1.13.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:aa45b4037b313c2f698bc13306239b8b93b4680eb47e287773156ac9e9304714", size = 472501, upload-time = "2025-08-11T15:10:04.735Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/43/c217b1153f0e499652f5e0766da8523ce3480f0a951039c7af115e224d55/ninja-1.13.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5f8e1e8a1a30835eeb51db05cf5a67151ad37542f5a4af2a438e9490915e5b72", size = 638280, upload-time = "2025-08-11T15:10:06.512Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/45/9151bba2c8d0ae2b6260f71696330590de5850e5574b7b5694dce6023e20/ninja-1.13.0-py3-none-musllinux_1_2_ppc64le.whl", hash = "sha256:3d7d7779d12cb20c6d054c61b702139fd23a7a964ec8f2c823f1ab1b084150db", size = 642420, upload-time = "2025-08-11T15:10:08.35Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/fb/95752eb635bb8ad27d101d71bef15bc63049de23f299e312878fc21cb2da/ninja-1.13.0-py3-none-musllinux_1_2_riscv64.whl", hash = "sha256:d741a5e6754e0bda767e3274a0f0deeef4807f1fec6c0d7921a0244018926ae5", size = 585106, upload-time = "2025-08-11T15:10:09.818Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/31/aa56a1a286703800c0cbe39fb4e82811c277772dc8cd084f442dd8e2938a/ninja-1.13.0-py3-none-musllinux_1_2_s390x.whl", hash = "sha256:e8bad11f8a00b64137e9b315b137d8bb6cbf3086fbdc43bf1f90fd33324d2e96", size = 707138, upload-time = "2025-08-11T15:10:11.366Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/6f/5f5a54a1041af945130abdb2b8529cbef0cdcbbf9bcf3f4195378319d29a/ninja-1.13.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b4f2a072db3c0f944c32793e91532d8948d20d9ab83da9c0c7c15b5768072200", size = 581758, upload-time = "2025-08-11T15:10:13.295Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/97/51359c77527d45943fe7a94d00a3843b81162e6c4244b3579fe8fc54cb9c/ninja-1.13.0-py3-none-win32.whl", hash = "sha256:8cfbb80b4a53456ae8a39f90ae3d7a2129f45ea164f43fadfa15dc38c4aef1c9", size = 267201, upload-time = "2025-08-11T15:10:15.158Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/45/c0adfbfb0b5895aa18cec400c535b4f7ff3e52536e0403602fc1a23f7de9/ninja-1.13.0-py3-none-win_amd64.whl", hash = "sha256:fb8ee8719f8af47fed145cced4a85f0755dd55d45b2bddaf7431fa89803c5f3e", size = 309975, upload-time = "2025-08-11T15:10:16.697Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/93/a7b983643d1253bb223234b5b226e69de6cda02b76cdca7770f684b795f5/ninja-1.13.0-py3-none-win_arm64.whl", hash = "sha256:3c0b40b1f0bba764644385319028650087b4c1b18cdfa6f45cb39a3669b81aa9", size = 290806, upload-time = "2025-08-11T15:10:18.018Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodeenv"
|
||||
version = "1.10.0"
|
||||
@@ -1272,7 +1383,8 @@ name = "numpy"
|
||||
version = "2.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version < '3.12'",
|
||||
"python_full_version < '3.12' and sys_platform != 'ios'",
|
||||
"python_full_version < '3.12' and sys_platform == 'ios'",
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" }
|
||||
wheels = [
|
||||
@@ -1354,8 +1466,10 @@ name = "numpy"
|
||||
version = "2.5.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.15'",
|
||||
"python_full_version >= '3.12' and python_full_version < '3.15'",
|
||||
"python_full_version >= '3.15' and sys_platform != 'ios'",
|
||||
"python_full_version >= '3.15' and sys_platform == 'ios'",
|
||||
"python_full_version >= '3.12' and python_full_version < '3.15' and sys_platform != 'ios'",
|
||||
"python_full_version >= '3.12' and python_full_version < '3.15' and sys_platform == 'ios'",
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9a/80/db0b4559e57ec36362bedbb05530a87fafbcb6067708c946967a41d449e7/numpy-2.5.2.tar.gz", hash = "sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860", size = 20773161, upload-time = "2026-08-09T13:48:27.962Z" }
|
||||
wheels = [
|
||||
@@ -1650,6 +1764,24 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pefile"
|
||||
version = "2024.8.26"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/03/4f/2750f7f6f025a1507cd3b7218691671eecfd0bbebebe8b39aa0fe1d360b8/pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632", size = 76008, upload-time = "2024-08-26T20:58:38.155Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/54/16/12b82f791c7f50ddec566873d5bdd245baa1491bac11d15ffb98aecc8f8b/pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f", size = 74766, upload-time = "2024-08-26T21:01:02.632Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pip"
|
||||
version = "26.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ae/15/4500e320e6b101ec3b719ae85b697d9940b6cda672bc555bd6016fc60c6f/pip-26.2.1.tar.gz", hash = "sha256:f6ad667e89a1fe78046c8f13232b247200f5258d7828f3f7883d660878e0813f", size = 1848877, upload-time = "2026-08-04T22:51:14.148Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/6e/1736e5b4ae2b778ef2f81c47d797de9f891d4d8acb047a24ca37a60294dd/pip-26.2.1-py3-none-any.whl", hash = "sha256:71138adf1f4ca900cdb7d289c21b7494329f2332b6d85f0e1c42108c0384ed3e", size = 1816632, upload-time = "2026-08-04T22:51:12.472Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "4.11.3"
|
||||
@@ -1765,6 +1897,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyelftools"
|
||||
version = "0.33"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a3/11/767522582afab1b884d277de0e6e011640cb9d7292a38694b4b1a1df1ae8/pyelftools-0.33.tar.gz", hash = "sha256:660d82dcbeb8e83d1702bd97f223f761625da06111c0cc988eac6b8ab0c1b61f", size = 15068655, upload-time = "2026-05-29T12:56:22.553Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/46/2a/f9697576603dae937727827505a6126a066affb227034e77e6f9068910da/pyelftools-0.33-py3-none-any.whl", hash = "sha256:f215ad5f47d3f1373a21496a6c9e0707c622840d0622f23ff7ce08678b020036", size = 201178, upload-time = "2026-05-29T12:56:20.587Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyflakes"
|
||||
version = "3.4.0"
|
||||
@@ -1906,6 +2047,18 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/eb/5fb627c2457046883c6fd12d25c44db40c12bcde4622dc0f30851108e106/pyobjc_framework_quartz-12.2.2-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:8f58c589b5a76ba98f186b1f3b19fb1c8b730e82351f81fb62e6194f64a71622", size = 224767, upload-time = "2026-08-11T19:40:30.991Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyproject-metadata"
|
||||
version = "0.12.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "packaging" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4f/76/1cae539918a7b1746d624c2f01560b793c22cd8c081157505bb9bbf0e34d/pyproject_metadata-0.12.1.tar.gz", hash = "sha256:8809a4df6fe08279b39a8890669506ed3158e0617855ac9aff098fcbe772ae4c", size = 48457, upload-time = "2026-07-04T02:19:32.029Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/8e/d883718e872abc214ba053f60f7e6edc2abd5ffbd1544beb01a9c92ddd3c/pyproject_metadata-0.12.1-py3-none-any.whl", hash = "sha256:f7162d580a96386a8eb096da06215f981f547d1490f03055ef99e323bc2da427", size = 23452, upload-time = "2026-07-04T02:19:30.657Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "9.1.1"
|
||||
@@ -2227,6 +2380,23 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/b6/26e41975febae63b7a6e3e02f32cff6cff2e4f10d19c929082f56aebf7c6/regex-2026.7.19-cp314-cp314t-win_arm64.whl", hash = "sha256:9a15e785f244f3e07847b984ce8773fc3da10a9f3c131cc49a4c5b4d672b4547", size = 283451, upload-time = "2026-07-19T00:19:46.639Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "repairwheel"
|
||||
version = "0.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "delvewheel" },
|
||||
{ name = "macholib" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pefile" },
|
||||
{ name = "pyelftools" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fb/74/e4c2ed3d34cde8cf790f4f5d99fb7b06933864ca8b5b6eed1dd237c7b763/repairwheel-0.7.0.tar.gz", hash = "sha256:46083dad76e35595712ae593c1c9f112fb3f37a0e63268906e6de8182de55122", size = 286421, upload-time = "2026-08-29T04:07:10.422Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/14/12/bbc4f17fa2661e40342a1e36ad099f085bb83d6dbd025fb00c69e313182f/repairwheel-0.7.0-py3-none-any.whl", hash = "sha256:7fff43ed5abbf9710ef5ea6478c10cfd551aae043f445fd46307d4b602674ce0", size = 146908, upload-time = "2026-08-29T04:07:11.442Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.34.2"
|
||||
@@ -2253,11 +2423,25 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "84.0.0"
|
||||
version = "81.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6d/44/f5da03a8ef95d369145c5bb53050e7877c9f3d312e128605fd9504829143/setuptools-84.0.0.tar.gz", hash = "sha256:f4695c21257f0d9b537ec2692c941d02ee143b7cc1276941349a546573b2ef73", size = 1168449, upload-time = "2026-08-08T18:27:58.365Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0d/1c/73e719955c59b8e424d015ab450f51c0af856ae46ea2da83eba51cc88de1/setuptools-81.0.0.tar.gz", hash = "sha256:487b53915f52501f0a79ccfd0c02c165ffe06631443a886740b91af4b7a5845a", size = 1198299, upload-time = "2026-02-06T21:10:39.601Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl", hash = "sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670", size = 818216, upload-time = "2026-08-08T18:27:56.719Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl", hash = "sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6", size = 1062021, upload-time = "2026-02-06T21:10:37.175Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools-scm"
|
||||
version = "10.2.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "packaging" },
|
||||
{ name = "setuptools" },
|
||||
{ name = "vcs-versioning" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/3c/87/1ff7adcf6e03021ae58ce401565be3c9b8c739a44d14a8253d38b3754117/setuptools_scm-10.2.3.tar.gz", hash = "sha256:f179ed3e2a63cf5823e5ee9aa9ca08386219400443a0553224d72dde3f206b44", size = 67696, upload-time = "2026-09-03T13:03:29.565Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/00/e9c0591b77186f6c1a8479500456ee72cd30730836c58b7a8a2654909c23/setuptools_scm-10.2.3-py3-none-any.whl", hash = "sha256:7fcf8ff55c95eb8b572a23c81495e5559b9b90f3e82fcf0952bb76c37de27a81", size = 29123, upload-time = "2026-09-03T13:03:28.346Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2331,7 +2515,8 @@ name = "sphinx"
|
||||
version = "9.0.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version < '3.12'",
|
||||
"python_full_version < '3.12' and sys_platform != 'ios'",
|
||||
"python_full_version < '3.12' and sys_platform == 'ios'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "alabaster" },
|
||||
@@ -2362,8 +2547,10 @@ name = "sphinx"
|
||||
version = "9.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.15'",
|
||||
"python_full_version >= '3.12' and python_full_version < '3.15'",
|
||||
"python_full_version >= '3.15' and sys_platform != 'ios'",
|
||||
"python_full_version >= '3.15' and sys_platform == 'ios'",
|
||||
"python_full_version >= '3.12' and python_full_version < '3.15' and sys_platform != 'ios'",
|
||||
"python_full_version >= '3.12' and python_full_version < '3.15' and sys_platform == 'ios'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "alabaster" },
|
||||
@@ -2752,6 +2939,18 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcs-versioning"
|
||||
version = "2.4.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "packaging" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/3e/97/792a4ef20344f9af3e16098b58b45eb5d6202259b84fc80c43bc000a5e6c/vcs_versioning-2.4.1.tar.gz", hash = "sha256:d4575de3115ec9434393c87c80ffb0eb98a16056bfe2b11ce0f3a97aff67fe0a", size = 164222, upload-time = "2026-09-16T07:47:40.267Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/20/29378edc8d7d2ce41892adc1356f4c6c6ae03b945d04ca6ade61afa3d5dc/vcs_versioning-2.4.1-py3-none-any.whl", hash = "sha256:b7089ec9bef67b2cad82148366e8eac4d63173f440ec62628282b59eb96bbcb0", size = 122157, upload-time = "2026-09-16T07:47:38.811Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "virtualenv"
|
||||
version = "21.7.4"
|
||||
@@ -2815,6 +3014,16 @@ whisper = [
|
||||
]
|
||||
|
||||
[package.dev-dependencies]
|
||||
installer-build = [
|
||||
{ name = "cmake" },
|
||||
{ name = "meson-python" },
|
||||
{ name = "ninja" },
|
||||
{ name = "pip" },
|
||||
{ name = "repairwheel" },
|
||||
{ name = "setuptools" },
|
||||
{ name = "setuptools-scm" },
|
||||
{ name = "wheel" },
|
||||
]
|
||||
lint = [
|
||||
{ name = "black" },
|
||||
{ name = "flake8" },
|
||||
@@ -2850,6 +3059,16 @@ requires-dist = [
|
||||
provides-extras = ["vosk", "whisper", "parakeet", "faster-whisper", "vad", "dev", "docs"]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
installer-build = [
|
||||
{ name = "cmake", specifier = "==3.31.10" },
|
||||
{ name = "meson-python", specifier = ">=0.16" },
|
||||
{ name = "ninja", specifier = "==1.13.0" },
|
||||
{ name = "pip", specifier = ">=25.3,<27" },
|
||||
{ name = "repairwheel" },
|
||||
{ name = "setuptools", specifier = ">=77,<82" },
|
||||
{ name = "setuptools-scm", specifier = ">=8" },
|
||||
{ name = "wheel" },
|
||||
]
|
||||
lint = [
|
||||
{ name = "black", specifier = ">=23.0.0" },
|
||||
{ name = "flake8", specifier = ">=6.0.0" },
|
||||
@@ -2988,3 +3207,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/e3/91e297e41381d9131f3142a9c1a50389fd96b98125ce9b81526fa4e14b9f/websockets-17.0.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:afbce6e3f0fac32dc87c2a0d84869d1a706460d64f39f3889386413e6e4d3d26", size = 213434, upload-time = "2026-07-31T11:31:24.707Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/ce/3929538b2b9918f5eee623fbf3346893973191f6df93f19bbda097bd7bb7/websockets-17.0.1-py3-none-any.whl", hash = "sha256:c6be9cba65c65cc76dfa3d4619e359ff02a4476c74e179b215236c11a0b32345", size = 206718, upload-time = "2026-07-31T11:31:26.037Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wheel"
|
||||
version = "0.48.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "packaging" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d0/20/50ed6bdf27dec98b568a8ae25dc599f35baa3d9709f9e83fd1edb56b9a90/wheel-0.48.0.tar.gz", hash = "sha256:94800765601e9171bf5d58d066e640662842bcedcbab982b2c90787a2c987322", size = 66471, upload-time = "2026-08-11T22:02:27.327Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/29/69cfbb602cd91690c55d38ba9fe53e6a7e76a6fa647bf38f19c138d25449/wheel-0.48.0-py3-none-any.whl", hash = "sha256:3217dcc807155e45db462d7ef2431f5ddda0d7273b700d05a67b271ceb1287ab", size = 33320, upload-time = "2026-08-11T22:02:26.1Z" },
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user