diff --git a/.devcontainer/config/aliases/example.aliases.zsh b/.devcontainer/config/aliases/example.aliases.zsh new file mode 100644 index 0000000..9be85ba --- /dev/null +++ b/.devcontainer/config/aliases/example.aliases.zsh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +alias hello="echo 'Hello, world!'" diff --git a/.devcontainer/etc/bash-aliases/git--aliases.sh b/.devcontainer/config/aliases/git.aliases.zsh similarity index 92% rename from .devcontainer/etc/bash-aliases/git--aliases.sh rename to .devcontainer/config/aliases/git.aliases.zsh index 2d0a40a..baa4549 100755 --- a/.devcontainer/etc/bash-aliases/git--aliases.sh +++ b/.devcontainer/config/aliases/git.aliases.zsh @@ -1,3 +1,5 @@ +#!/usr/bin/env zsh + # Aliases for GIT shortcuts (https://laracasts.com/series/how-to-contribute-to-open-source/episodes/5) alias wip='git add . && git commit -m '\''Work in progress'\' alias nope='git reset --hard && git clean -f -d && git checkout HEAD' diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0fa7195..74d0494 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,27 +1,71 @@ { - "name": "Library python-pipeline", - "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "name": "python-pipeline", + "build": { + "dockerfile": "docker/devcontainer/Dockerfile", + "context": ".." + }, "customizations": { "vscode": { "extensions": [ + /** + * Common extensions + **/ "aaron-bond.better-comments", - "charliermarsh.ruff", - "DavidAnson.vscode-markdownlint", - "github.copilot", - "github.copilot-chat", "github.vscode-github-actions", "mikestead.dotenv", - "ms-python.debugpy", + /** + * Common file types support (highlighting, formatting, lintering, etc.) + **/ + "editorconfig.editorconfig", // .editorconfig + "tamasfe.even-better-toml", // .toml + "xshrim.txt-syntax", // .txt, .log, .conf, .ini, .properties, etc. + "redhat.vscode-yaml", // .yaml, .yml + "DavidAnson.vscode-markdownlint", // .md + /** + * AI extensions + **/ + "github.copilot", + "github.copilot-chat", + "chrisdias.promptboost", + /** + * Opinionated extensions (Themes, colors, etc.) + **/ + "pkief.material-icon-theme", // popular icon theme + "atomiks.moonlight", // default theme for cursor + /** + * Bash script extensions - .devcontainer scripts, .sh files, etc. + **/ + "mads-hartmann.bash-ide-vscode", + "rogalmic.bash-debug", + "jetmartin.bats", + "foxundermoon.shell-format", + "timonwong.shellcheck", + "jeff-hykin.better-shellscript-syntax", + /** + * Container/Docker extensions + **/ + "ms-azuretools.vscode-containers", + "jeff-hykin.better-dockerfile-syntax", + "exiasr.hadolint", + /** + * Python extensions + **/ "ms-python.python", - "ms-python.vscode-pylance", - "ms-toolsai.jupyter", - "pkief.material-icon-theme", - "redhat.vscode-yaml", - "tamasfe.even-better-toml", - "ms-vscode.vscode-websearchforcopilot", - "ms-vscode.vscode-commander" + // "ms-python.vscode-pylance", // language server (highlighting, intellisense, etc.) + "astral-sh.ty", // language server (highlighting, intellisense, etc.) + "charliermarsh.ruff", // linter and formatter + "njpwerner.autodocstring", // docstring generator + "ms-toolsai.jupyter", // Jupyter Notebooks + "ms-python.debugpy", // debugger + /** + * Auto-applied devcontainer feature extensions (docker-outside-of-docker) + **/ + "-ms-azuretools.vscode-docker" // removed, replaced by "vscode-containers" ], "settings": { + /** + * Common settings + **/ "editor.linkedEditing": true, "editor.formatOnSave": true, "editor.rulers": [ @@ -32,17 +76,42 @@ "editor.guides.highlightActiveIndentation": true, "explorer.sortOrderLexicographicOptions": "upper", "files.insertFinalNewline": true, + "files.eol": "\n", "files.trimTrailingWhitespace": true, - "ruff.nativeServer": "on", + "files.watcherExclude": { + "**/.git/*": true, + "**/node_modules/*": true, + "**/vendor/*": true + }, + "files.associations": { + "*.zsh": "shellscript" + }, "terminal.integrated.shell.linux": "/bin/zsh", + /** + * Settings for Opinionated Extensions (themes, colors, etc.) + **/ "workbench.iconTheme": "material-icon-theme", - // Jupyter Notebook - "notebook.formatOnSave.enabled": true, - "notebook.codeActionsOnSave": { - "notebook.source.fixAll": "explicit", - "notebook.source.organizeImports": "explicit" + "workbench.colorTheme": "Moonlight", + /** + * Settings for Extensions + **/ + // MkDocs + "yaml.schemas": { + "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml" }, + "yaml.customTags": [ + "!ENV scalar", + "!ENV sequence", + "!relative scalar", + "tag:yaml.org,2002:python/name:material.extensions.emoji.to_svg", + "tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji", + "tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format", + "tag:yaml.org,2002:python/object/apply:pymdownx.slugs.slugify mapping" + ], + // shell-format + "shellformat.flag": "-ci", // Python + "ruff.nativeServer": "on", "python.analysis.autoSearchPaths": true, "python.analysis.diagnosticMode": "workspace", "python.analysis.importFormat": "relative", @@ -51,7 +120,7 @@ "${containerWorkspaceFolder}/src" ], "python.envFile": "${containerWorkspaceFolder}/.env", - "python.terminal.activateEnvironment": true, + "python.terminal.activateEnvironment": false, "python.defaultInterpreterPath": "${containerWorkspaceFolder}/.venv/bin/python", // Test (python) "python.testing.pytestEnabled": true, @@ -59,20 +128,15 @@ "python.testing.cwd": "${containerWorkspaceFolder}/tests", "python.testing.pytestPath": "${containerWorkspaceFolder}/.venv/bin/pytest", "python.testing.autoTestDiscoverOnSaveEnabled": true, - // MkDocs schema for the YAML extension - "yaml.schemas": { - "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml" + // Jupyter Notebook (python) + "notebook.formatOnSave.enabled": true, + "notebook.codeActionsOnSave": { + "notebook.source.fixAll": "explicit", + "notebook.source.organizeImports": "explicit" }, - "yaml.customTags": [ - "!ENV scalar", - "!ENV sequence", - "!relative scalar", - "tag:yaml.org,2002:python/name:material.extensions.emoji.to_svg", - "tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji", - "tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format", - "tag:yaml.org,2002:python/object/apply:pymdownx.slugs.slugify mapping" - ], - // Settings per file type + /** + * Per-MIME settings + **/ "[toml]": { "editor.defaultFormatter": "tamasfe.even-better-toml", "editor.formatOnSave": true @@ -82,6 +146,9 @@ "editor.formatOnSave": true, "editor.wordWrap": "on" }, + "[shellscript]": { + "editor.defaultFormatter": "foxundermoon.shell-format" + }, "[python]": { "editor.formatOnSave": true, "editor.defaultFormatter": "charliermarsh.ruff", @@ -95,14 +162,26 @@ }, "features": { "ghcr.io/devcontainers/features/common-utils:2": { - "configureZshAsDefaultShell": true + "configureZshAsDefaultShell": true, + "installOhMyZsh": true, + "upgradePackages": true }, - "ghcr.io/thecodecrate/devcontainer-features/bash-aliases:1": {}, - "ghcr.io/thecodecrate/devcontainer-features/uv:1": {} + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/docker-in-docker:2": {}, + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {} }, "remoteUser": "vscode", - "postCreateCommand": "zsh -i .devcontainer/scripts/post-create.sh", + "onCreateCommand": ".devcontainer/lifecycle/_loaders/30-loader-on-container-create.zsh", + "postCreateCommand": ".devcontainer/lifecycle/_loaders/40-loader-on-container-created.zsh", + "postStartCommand": ".devcontainer/lifecycle/_loaders/60-loader-on-container-start.zsh", "containerEnv": { - "PYTHONPATH": "${containerWorkspaceFolder}/src" - } + "INSIDE_DEVCONTAINER": "true", + "HOST_DIR": "${localWorkspaceFolder}", + "WORKSPACE_DIR": "${containerWorkspaceFolder}", + "PYTHONPATH": "${containerWorkspaceFolder}/src", + "UV_LINK_MODE": "copy" + }, + "runArgs": [ + "--add-host=host.docker.internal:host-gateway" + ] } diff --git a/.devcontainer/docker/devcontainer/Dockerfile b/.devcontainer/docker/devcontainer/Dockerfile new file mode 100644 index 0000000..7327652 --- /dev/null +++ b/.devcontainer/docker/devcontainer/Dockerfile @@ -0,0 +1,8 @@ +FROM mcr.microsoft.com/devcontainers/base:ubuntu + +# Lifecycle scripts +USER vscode +ENV WORKSPACE_DIR=/tmp/workspace +COPY .devcontainer/tools ${WORKSPACE_DIR}/.devcontainer/tools +COPY .devcontainer/lifecycle ${WORKSPACE_DIR}/.devcontainer/lifecycle +RUN zsh ${WORKSPACE_DIR}/.devcontainer/lifecycle/_loaders/00-loader-on-dockerfile.zsh diff --git a/.devcontainer/etc/bash-aliases/clean-cache--aliases.sh b/.devcontainer/etc/bash-aliases/clean-cache--aliases.sh deleted file mode 100644 index 02cf9a2..0000000 --- a/.devcontainer/etc/bash-aliases/clean-cache--aliases.sh +++ /dev/null @@ -1,7 +0,0 @@ -alias _rm_python_cache='find . -type d -name "__pycache__" -exec rm -rf {} +' -alias _rm_pytest_cache='find . -type d -name ".pytest_cache" -exec rm -rf {} +' -alias _rm_egginfo='find . -type f -name "*.egg-info" -exec rm -rf {} +' -alias _rm_dist='find . -type d -name "dist" -exec rm -rf {} +' -alias _rm_uv_cache='uv cache clean' -alias _rm_ruff_cache='ruff clean' -alias clean='_rm_python_cache; _rm_pytest_cache; _rm_egginfo; _rm_dist; _rm_uv_cache; _rm_ruff_cache' diff --git a/.devcontainer/etc/bash-aliases/deploy--aliases.sh b/.devcontainer/etc/bash-aliases/deploy--aliases.sh deleted file mode 100755 index 4dca891..0000000 --- a/.devcontainer/etc/bash-aliases/deploy--aliases.sh +++ /dev/null @@ -1,5 +0,0 @@ -# Alias for publishing the package to pypi -alias _clean_dist='find . -type d -name "dist" -exec rm -rf {} +' -alias bump='bumpver update --minor' -alias build='_clean_dist; uv build' -alias deploy='uv publish' diff --git a/.devcontainer/lifecycle/00-on-dockerfile/03-make-local-bin-dir.zsh b/.devcontainer/lifecycle/00-on-dockerfile/03-make-local-bin-dir.zsh new file mode 100644 index 0000000..79afaf4 --- /dev/null +++ b/.devcontainer/lifecycle/00-on-dockerfile/03-make-local-bin-dir.zsh @@ -0,0 +1,4 @@ +#!/usr/bin/env zsh + +# Ensure local bin directory exists +mkdir -p "${HOME}/.local/bin" diff --git a/.devcontainer/lifecycle/00-on-dockerfile/05-install-tools.zsh b/.devcontainer/lifecycle/00-on-dockerfile/05-install-tools.zsh new file mode 100644 index 0000000..e5584ff --- /dev/null +++ b/.devcontainer/lifecycle/00-on-dockerfile/05-install-tools.zsh @@ -0,0 +1,18 @@ +#!/usr/bin/env zsh + +# Globals +SRC_TOOLS_DIR="${WORKSPACE_DIR}/.devcontainer/tools" +DST_TOOLS_DIR="/usr/local/bin/devcontainer-tools" +SHARED_BIN_DIR="/usr/local/bin" + +# Copy tools to the destination directory +sudo mkdir -p "${DST_TOOLS_DIR}" +sudo cp -r "${SRC_TOOLS_DIR}/." "${DST_TOOLS_DIR}/" +sudo chmod -R +x "${DST_TOOLS_DIR}/**/install.zsh" + +# Install tools for dev container setup +sudo "${DST_TOOLS_DIR}/enable-config-dir/install.zsh" --prefix "${SHARED_BIN_DIR}" --create-dirs +sudo "${DST_TOOLS_DIR}/setup-omz-plugins/install.zsh" --prefix "${SHARED_BIN_DIR}" --create-dirs +sudo "${DST_TOOLS_DIR}/switch-apt-mirror/install.zsh" --prefix "${SHARED_BIN_DIR}" --create-dirs + +# vim: set ft=sh: diff --git a/.devcontainer/lifecycle/00-on-dockerfile/10-switch-apt-mirror.zsh b/.devcontainer/lifecycle/00-on-dockerfile/10-switch-apt-mirror.zsh new file mode 100644 index 0000000..a3dc03a --- /dev/null +++ b/.devcontainer/lifecycle/00-on-dockerfile/10-switch-apt-mirror.zsh @@ -0,0 +1,4 @@ +#!/usr/bin/env zsh + +# Configure faster apt sources (Azure/Microsoft mirrors) +sudo switch-apt-mirror "http://azure.archive.ubuntu.com/ubuntu/" diff --git a/.devcontainer/lifecycle/00-on-dockerfile/11-install-scripting-tools.zsh b/.devcontainer/lifecycle/00-on-dockerfile/11-install-scripting-tools.zsh new file mode 100644 index 0000000..f4d6590 --- /dev/null +++ b/.devcontainer/lifecycle/00-on-dockerfile/11-install-scripting-tools.zsh @@ -0,0 +1,6 @@ +#!/usr/bin/env zsh + +# Shell Linter, Formatter +sudo apt install -qq -y --no-install-recommends \ + shellcheck \ + shfmt diff --git a/.devcontainer/lifecycle/00-on-dockerfile/15-docker-host.zsh b/.devcontainer/lifecycle/00-on-dockerfile/15-docker-host.zsh new file mode 100644 index 0000000..29e9665 --- /dev/null +++ b/.devcontainer/lifecycle/00-on-dockerfile/15-docker-host.zsh @@ -0,0 +1,16 @@ +#!/usr/bin/env zsh +# +# This script configures Docker contexts for dev container environments +# supporting both Docker-in-Docker (DinD) and Docker-outside-Docker patterns. +# +# NOTES: +# - Part 1/2 of the Docker host setup. Part 2 is in `30-on-container-create/15-docker-host.zsh`. +# + +# Create docker-host group with matching host GID for Docker socket access +HOST_DOCKER_GID=$(stat -c '%g' /var/run/docker-host.sock 2>/dev/null || echo "997") +sudo groupadd -g "$HOST_DOCKER_GID" docker-host + +# Add vscode user to docker-host group +[ -z "$USER" ] && USER=$(whoami 2>/dev/null || echo "vscode") +sudo usermod -aG docker-host "$USER" diff --git a/.devcontainer/lifecycle/00-on-dockerfile/16-set-www-to-vscode.zsh b/.devcontainer/lifecycle/00-on-dockerfile/16-set-www-to-vscode.zsh new file mode 100644 index 0000000..eb9372c --- /dev/null +++ b/.devcontainer/lifecycle/00-on-dockerfile/16-set-www-to-vscode.zsh @@ -0,0 +1,7 @@ +#!/usr/bin/env zsh + +# Set the user to 'vscode' if not already set +[ -z "$USER" ] && USER=$(whoami 2>/dev/null || echo "vscode") + +# Add vscode user to www-data group +sudo usermod -aG www-data "$USER" diff --git a/.devcontainer/lifecycle/00-on-dockerfile/20-meslo-font.zsh b/.devcontainer/lifecycle/00-on-dockerfile/20-meslo-font.zsh new file mode 100644 index 0000000..1c920f6 --- /dev/null +++ b/.devcontainer/lifecycle/00-on-dockerfile/20-meslo-font.zsh @@ -0,0 +1,17 @@ +#!/usr/bin/env zsh +# +# Download and install Meslo fonts +# +# Note: Font is already set up in `.vscode/settings.json` +# + +# Download Meslo fonts +wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttf -P "${HOME}/.local/share/fonts" +wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold.ttf -P "${HOME}/.local/share/fonts" +wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Italic.ttf -P "${HOME}/.local/share/fonts" +wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold%20Italic.ttf -P "${HOME}/.local/share/fonts" + +# Update font cache +sudo apt install -y fontconfig + +fc-cache -fv "${HOME}/.local/share/fonts" diff --git a/.devcontainer/lifecycle/00-on-dockerfile/33-install-uv.zsh b/.devcontainer/lifecycle/00-on-dockerfile/33-install-uv.zsh new file mode 100644 index 0000000..4d652f4 --- /dev/null +++ b/.devcontainer/lifecycle/00-on-dockerfile/33-install-uv.zsh @@ -0,0 +1,9 @@ +#!/usr/bin/env zsh +# This script installs uv/uvx, required for `.vscode/mcp.json` + +# Dowload and install uv +curl -LsSf https://astral.sh/uv/install.sh | sh + +# Auto-completion +echo 'eval "$(uv generate-shell-completion zsh)"' >> ~/.zshrc +echo 'eval "$(uvx --generate-shell-completion zsh)"' >> ~/.zshrc diff --git a/.devcontainer/lifecycle/00-on-dockerfile/65-hadolint.zsh b/.devcontainer/lifecycle/00-on-dockerfile/65-hadolint.zsh new file mode 100644 index 0000000..87f4815 --- /dev/null +++ b/.devcontainer/lifecycle/00-on-dockerfile/65-hadolint.zsh @@ -0,0 +1,8 @@ +#!/usr/bin/env zsh +# vim: set ft=sh: + +# Install HADOLINT +HADOLINT_URL=https://github.com/hadolint/hadolint/releases/download/v2.12.0/hadolint-Linux-x86_64 + +sudo wget -q -O /usr/local/bin/hadolint "$HADOLINT_URL" +sudo chmod +x /usr/local/bin/hadolint diff --git a/.devcontainer/lifecycle/30-on-container-create/05-build-apt-indexes.zsh b/.devcontainer/lifecycle/30-on-container-create/05-build-apt-indexes.zsh new file mode 100644 index 0000000..74ae385 --- /dev/null +++ b/.devcontainer/lifecycle/30-on-container-create/05-build-apt-indexes.zsh @@ -0,0 +1,4 @@ +#!/usr/bin/env zsh + +# Build apt sources index +sudo apt update diff --git a/.devcontainer/lifecycle/30-on-container-create/10-vscode-integration.zsh b/.devcontainer/lifecycle/30-on-container-create/10-vscode-integration.zsh new file mode 100644 index 0000000..6341e7f --- /dev/null +++ b/.devcontainer/lifecycle/30-on-container-create/10-vscode-integration.zsh @@ -0,0 +1,3 @@ +#!/usr/bin/env zsh + +echo '[[ "$TERM_PROGRAM" == "vscode" ]] && . "$(code --locate-shell-integration-path zsh)"' >> ~/.zshrc diff --git a/.devcontainer/lifecycle/30-on-container-create/15-setup-docker-host.zsh b/.devcontainer/lifecycle/30-on-container-create/15-setup-docker-host.zsh new file mode 100644 index 0000000..3e3c5ef --- /dev/null +++ b/.devcontainer/lifecycle/30-on-container-create/15-setup-docker-host.zsh @@ -0,0 +1,14 @@ +#!/usr/bin/env zsh +# +# This script configures Docker contexts for dev container environments +# supporting both Docker-in-Docker (DinD) and Docker-outside-Docker patterns. +# +# NOTES: +# - Part 2/2 of the Docker host setup. Part 1 is in `00-on-dockerfile/15-docker-host.zsh`. +# + +# Setup Docker context for docker-outside-docker +docker context create docker-host --docker "host=unix:///var/run/docker-host.sock" + +# "default" context uses DinD +docker context use default diff --git a/.devcontainer/lifecycle/30-on-container-create/34-install-python-venv.zsh b/.devcontainer/lifecycle/30-on-container-create/34-install-python-venv.zsh new file mode 100644 index 0000000..de503bd --- /dev/null +++ b/.devcontainer/lifecycle/30-on-container-create/34-install-python-venv.zsh @@ -0,0 +1,4 @@ +#!/usr/bin/zsh + +# Install virtual environment +(cd $WORKSPACE_DIR && uv sync --frozen) diff --git a/.devcontainer/lifecycle/30-on-container-create/35-install-omz-plugins.zsh b/.devcontainer/lifecycle/30-on-container-create/35-install-omz-plugins.zsh new file mode 100644 index 0000000..bc372c1 --- /dev/null +++ b/.devcontainer/lifecycle/30-on-container-create/35-install-omz-plugins.zsh @@ -0,0 +1,9 @@ +#!/usr/bin/env zsh + +# ohmyzsh plugins from GitHub +setup-omz-plugins \ + zsh-users/zsh-autosuggestions \ + zsh-users/zsh-syntax-highlighting \ + zsh-users/zsh-completions \ + zsh-users/zsh-history-substring-search \ + matthiasha/zsh-uv-env diff --git a/.devcontainer/lifecycle/30-on-container-create/40-enable-config-dirs.zsh b/.devcontainer/lifecycle/30-on-container-create/40-enable-config-dirs.zsh new file mode 100644 index 0000000..0b3177b --- /dev/null +++ b/.devcontainer/lifecycle/30-on-container-create/40-enable-config-dirs.zsh @@ -0,0 +1,5 @@ +# Configure alias files loading +enable-config-dir "${WORKSPACE_DIR}/.devcontainer/config/aliases" + +# Configure config files loading +enable-config-dir "${WORKSPACE_DIR}/.devcontainer/config/custom" diff --git a/.devcontainer/lifecycle/30-on-container-create/50-install-asdf.zsh b/.devcontainer/lifecycle/30-on-container-create/50-install-asdf.zsh new file mode 100755 index 0000000..9cbde57 --- /dev/null +++ b/.devcontainer/lifecycle/30-on-container-create/50-install-asdf.zsh @@ -0,0 +1,367 @@ +#!/usr/bin/env zsh +# Download and install latest asdf release from GitHub +# This script uses a hybrid approach: GitHub API first, Git tags as fallback + +set -euo pipefail + +# Configuration +ASDF_DIR="${ASDF_DIR:-$HOME/.asdf}" +ASDF_REPO="https://github.com/asdf-vm/asdf" +API_URL="https://api.github.com/repos/asdf-vm/asdf/releases/latest" +TIMEOUT_SECONDS=10 +MAX_RETRIES=3 + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Logging functions +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" >&2 +} + +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" >&2 +} + +log_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" >&2 +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" >&2 +} + +# Check prerequisites +check_prerequisites() { + local missing_tools=() + + for tool in curl git jq; do + if ! command -v "$tool" >/dev/null 2>&1; then + missing_tools+=("$tool") + fi + done + + if [[ ${#missing_tools[@]} -gt 0 ]]; then + log_error "Missing required tools: ${missing_tools[*]}" + log_info "Installing missing tools..." + + # Install missing tools using apt (since we're in Ubuntu dev container) + sudo apt-get update -qq + for tool in "${missing_tools[@]}"; do + sudo apt-get install -y "$tool" + done + + log_success "Required tools installed" + fi +} + +# Get latest release using GitHub API with retry logic +get_latest_version_api() { + local retry_count=0 + local retry_delay=2 + + while [[ $retry_count -lt $MAX_RETRIES ]]; do + local response + if response=$(curl -sfS --connect-timeout "$TIMEOUT_SECONDS" "$API_URL" 2>/dev/null); then + local tag_name + if tag_name=$(echo "$response" | jq -r '.tag_name' 2>/dev/null) && [[ "$tag_name" != "null" ]] && [[ -n "$tag_name" ]]; then + echo "$tag_name" + return 0 + fi + fi + + retry_count=$((retry_count + 1)) + if [[ $retry_count -lt $MAX_RETRIES ]]; then + sleep "$retry_delay" + retry_delay=$((retry_delay * 2)) + fi + done + + return 1 +} + +# Fallback: Get latest release using Git tags +get_latest_version_git() { + local latest_tag + if latest_tag=$(git ls-remote --tags --sort=-v:refname "$ASDF_REPO" 2>/dev/null | + grep -oP 'refs/tags/\Kv.*' | + grep -v '\^' | + head -1); then + echo "$latest_tag" + return 0 + fi + + return 1 +} + +# Get the latest version using hybrid approach +get_latest_version() { + local version + + log_info "Attempting to fetch latest version from GitHub API..." + # Try API first + if version=$(get_latest_version_api); then + log_success "Retrieved latest version from GitHub API: $version" + echo "$version" + return 0 + fi + + log_warning "GitHub API failed, falling back to Git tags method..." + # Fallback to Git tags + if version=$(get_latest_version_git); then + log_success "Retrieved latest version from Git tags: $version" + echo "$version" + return 0 + fi + + log_error "Failed to retrieve latest version using both methods" + return 1 +} + +# Check if asdf is already installed and up to date +check_existing_installation() { + if [[ -d "$ASDF_DIR" ]] && [[ -f "$ASDF_DIR/bin/asdf" ]]; then + local current_version + if current_version=$("$ASDF_DIR/bin/asdf" version 2>/dev/null | cut -d' ' -f1); then + log_info "Found existing asdf installation: $current_version" + + local latest_version + if latest_version=$(get_latest_version); then + # Remove 'v' prefix for comparison + local current_clean="${current_version#v}" + local latest_clean="${latest_version#v}" + + if [[ "$current_clean" == "$latest_clean" ]]; then + log_success "asdf is already up to date ($current_version)" + return 0 + else + log_info "Update available: $current_version -> $latest_version" + return 1 + fi + fi + fi + fi + + return 1 +} + +# Download and install asdf +install_asdf() { + local version="$1" + + log_info "Installing asdf $version" + + # Remove existing installation if present + if [[ -d "$ASDF_DIR" ]]; then + log_info "Removing existing asdf installation at $ASDF_DIR" + rm -rf "$ASDF_DIR" + fi + + # Check if this is a newer version (0.16+) that uses Go binary + local version_number="${version#v}" + local major_version="${version_number%%.*}" + local minor_version="${version_number#*.}" + minor_version="${minor_version%%.*}" + + if [[ "$major_version" -gt 0 ]] || [[ "$major_version" -eq 0 && "$minor_version" -ge 16 ]]; then + log_info "Version $version is 0.16+ (Go-based), attempting binary download..." + + # Try to download pre-built binary for newer versions + local arch=$(uname -m) + local os=$(uname -s | tr '[:upper:]' '[:lower:]') + + # Map common architecture names + case "$arch" in + x86_64) arch="amd64" ;; + aarch64 | arm64) arch="arm64" ;; + *) log_warning "Unsupported architecture: $arch, falling back to source install" ;; + esac + + local binary_url="https://github.com/asdf-vm/asdf/releases/download/${version}/asdf-${version}-${os}-${arch}.tar.gz" # Try to download binary + log_info "Attempting to download binary from: $binary_url" + local temp_dir=$(mktemp -d) + if curl -sfL "$binary_url" -o "$temp_dir/asdf.tar.gz" 2>/dev/null; then + mkdir -p "$ASDF_DIR/bin" + # Extract the binary directly to the bin directory + if tar -xzf "$temp_dir/asdf.tar.gz" -C "$ASDF_DIR/bin" 2>/dev/null; then + rm -rf "$temp_dir" + + # Make sure the binary is executable + chmod +x "$ASDF_DIR/bin/asdf" + + # Verify installation + if [[ -f "$ASDF_DIR/bin/asdf" ]]; then + local installed_version + if installed_version=$("$ASDF_DIR/bin/asdf" version 2>/dev/null | head -1); then + log_success "Successfully installed asdf binary $version" + log_success "Binary installation verified: $installed_version" + return 0 + fi + fi + fi + fi + + rm -rf "$temp_dir" + log_warning "Binary download failed, falling back to Git clone method" + fi + + # Clone the repository (fallback or for older versions) + log_info "Cloning asdf repository..." + if ! git clone "$ASDF_REPO" "$ASDF_DIR" --quiet; then + log_error "Failed to clone asdf repository" + return 1 + fi + + # Checkout the specific version + log_info "Checking out version $version..." + if ! (cd "$ASDF_DIR" && git checkout "$version" --quiet); then + log_error "Failed to checkout version $version" + return 1 + fi + + # Verify installation + if [[ -f "$ASDF_DIR/bin/asdf" ]]; then + local installed_version + if installed_version=$("$ASDF_DIR/bin/asdf" version 2>/dev/null | head -1); then + log_success "Successfully installed asdf $installed_version" + return 0 + fi + fi + + log_error "Installation verification failed" + return 1 +} + +# Configure shell integration (for zsh) +configure_shell() { + local shell_config="$HOME/.zshrc" + + # Check if asdf is already configured + if grep -q "asdf.sh\|\.asdf/bin" "$shell_config" 2>/dev/null; then + log_info "asdf shell integration already configured" + return 0 + fi + + log_info "Configuring asdf shell integration for zsh" + + # Backup existing config + if [[ -f "$shell_config" ]]; then + cp "$shell_config" "${shell_config}.backup.$(date +%Y%m%d_%H%M%S)" + fi + + # Determine which asdf files exist for shell integration + local asdf_init_line="" + local asdf_completion_line="" + + if [[ -f "$ASDF_DIR/asdf.sh" ]]; then + asdf_init_line=". \"\$HOME/.asdf/asdf.sh\"" + elif [[ -f "$ASDF_DIR/bin/asdf" ]]; then + # For newer versions, add to PATH + asdf_init_line="export PATH=\"\$HOME/.asdf/bin:\$PATH\"" + fi + + if [[ -f "$ASDF_DIR/completions/asdf.bash" ]]; then + asdf_completion_line=". \"\$HOME/.asdf/completions/asdf.bash\"" + fi + + # Add asdf configuration + { + echo "" + echo "# asdf version manager" + [[ -n "$asdf_init_line" ]] && echo "$asdf_init_line" + [[ -n "$asdf_completion_line" ]] && echo "$asdf_completion_line" + } >>"$shell_config" + + log_success "Shell integration configured. Please restart your shell or run: source $shell_config" +} + +# Validate installation +validate_installation() { + log_info "Validating asdf installation..." + + # Try to source asdf for current session + if [[ -f "$ASDF_DIR/asdf.sh" ]]; then + # shellcheck source=/dev/null + source "$ASDF_DIR/asdf.sh" + elif [[ -f "$ASDF_DIR/bin/asdf" ]]; then + # For newer versions, add to PATH + export PATH="$ASDF_DIR/bin:$PATH" + fi + + # Test asdf command + if command -v asdf >/dev/null 2>&1; then + local version + if version=$(asdf version 2>/dev/null); then + log_success "asdf is working correctly: $(echo "$version" | head -1)" + + # Test plugin listing (this works for both old and new versions) + if asdf plugin list >/dev/null 2>&1; then + log_success "asdf plugin system is functional" + return 0 + else + log_info "Plugin system test completed (empty plugin list is normal)" + return 0 + fi + fi + fi + + log_warning "asdf validation failed. You may need to restart your shell." + return 1 +} + +# Main execution +main() { + log_info "Starting asdf installation script" + + # Check prerequisites + check_prerequisites + + # Get latest version + local latest_version + if ! latest_version=$(get_latest_version); then + log_error "Could not determine latest asdf version" + return 1 + fi + + # Install asdf + if ! install_asdf "$latest_version"; then + log_error "Installation failed" + return 1 + fi + + # Configure shell integration + configure_shell + + # Validate installation + validate_installation + + log_success "asdf installation completed successfully!" + log_info "To start using asdf, restart your shell or run: source ~/.zshrc" +} + +# Run main function +main "$@" + +# Add shims directory to path +cat >>"$HOME/.zshrc" <<'EOF' +export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH" +EOF + +# Set up shell completions +mkdir -p "${ASDF_DATA_DIR:-$HOME/.asdf}/completions" +asdf completion zsh >"${ASDF_DATA_DIR:-$HOME/.asdf}/completions/_asdf" + +# Add asdf completion setup to .zshrc +cat >>"$HOME/.zshrc" <<'EOF' +# append completions to fpath +fpath=(${ASDF_DATA_DIR:-$HOME/.asdf}/completions $fpath) + +# initialise completions with ZSH's compinit +autoload -Uz compinit && compinit +EOF + +# vim: set ft=sh: diff --git a/.devcontainer/lifecycle/30-on-container-create/51-install-claude-cli.zsh b/.devcontainer/lifecycle/30-on-container-create/51-install-claude-cli.zsh new file mode 100644 index 0000000..a2fb408 --- /dev/null +++ b/.devcontainer/lifecycle/30-on-container-create/51-install-claude-cli.zsh @@ -0,0 +1,12 @@ +#!/usr/bin/env zsh +# This script installs Claude CLI + +set -euo pipefail + +# npx @anthropic-ai/claude-code install --force +curl -fsSL https://claude.ai/install.sh | bash + +# Tool needed for some MCP servers +# npm install -g mcp-remote + +exit 0 diff --git a/.devcontainer/lifecycle/30-on-container-create/99-enable-git-indicator.zsh b/.devcontainer/lifecycle/30-on-container-create/99-enable-git-indicator.zsh new file mode 100644 index 0000000..b015199 --- /dev/null +++ b/.devcontainer/lifecycle/30-on-container-create/99-enable-git-indicator.zsh @@ -0,0 +1,2 @@ +# Enable git dirty state indicator in prompt +git config --global devcontainers-theme.show-dirty 1 diff --git a/.devcontainer/lifecycle/40-on-container-created/10-enable-omz-plugins.zsh b/.devcontainer/lifecycle/40-on-container-created/10-enable-omz-plugins.zsh new file mode 100644 index 0000000..faa32f0 --- /dev/null +++ b/.devcontainer/lifecycle/40-on-container-created/10-enable-omz-plugins.zsh @@ -0,0 +1,19 @@ +#!/usr/bin/env zsh +# vim: set ft=zsh: + +# +# Setup Oh My Zsh plugins +# Enables commonly used Oh My Zsh plugins for development workflow. +# + + +# Source rc for `omz` command +# shellcheck source=/dev/null +source "${HOME}/.zshrc" + +# Enable OMZ plugins +omz plugin enable asdf +omz plugin enable docker +omz plugin enable docker-compose + +exit 0 diff --git a/.devcontainer/lifecycle/60-on-container-start/35-set-docker-hostnames.zsh b/.devcontainer/lifecycle/60-on-container-start/35-set-docker-hostnames.zsh new file mode 100644 index 0000000..a392d21 --- /dev/null +++ b/.devcontainer/lifecycle/60-on-container-start/35-set-docker-hostnames.zsh @@ -0,0 +1,12 @@ +#!/usr/bin/env zsh + +# Wait for Docker to be ready +while ! docker info >/dev/null 2>&1; do + echo "Waiting for Docker to be ready..." + sleep 1 +done + +# Set container hostnames in /etc/hosts +sudo $WORKSPACE_DIR/.devcontainer/tools/set-docker-subhosts/run.zsh + +exit 0 diff --git a/.devcontainer/lifecycle/_lib/loaders.zsh b/.devcontainer/lifecycle/_lib/loaders.zsh new file mode 100644 index 0000000..4de87cb --- /dev/null +++ b/.devcontainer/lifecycle/_lib/loaders.zsh @@ -0,0 +1,81 @@ +#!/usr/bin/env zsh +# Functions for loading scripts + +## +# Get list of executable script files from directory +# +# @param {string} dir_path - Directory to search for scripts +# @return {array} List of script files, or empty array if dir_path is invalid +# +# NOTES: +# - Only searches for files with .sh, .zsh, or .bash extensions +## +get_script_files() { + setopt local_options null_glob + local dir_path="$1" + + # Check if "dir_path" is not empty and the directory exists + if [[ -z ${dir_path} ]] || [[ ! -d ${dir_path} ]]; then + return + fi + + # Find all scripts with .sh, .zsh, or .bash extensions in the directory + local files=("${dir_path}/"*.{sh,zsh,bash}) + + # If no files found, return + if [[ ! -e ${files[1]} ]]; then + return + fi + + # Return the files array + echo "${files[@]}" +} + +## +# Execute scripts from the specified directory +# +# @param {string} dir_path - Directory containing scripts to execute +## +execute_dir() { + local dir_path="$1" + + # Get list of script files from directory + local files=($(get_script_files "${dir_path}")) + + # If no files found, return + if [[ ${#files[@]} -eq 0 ]]; then + return + fi + + # Loop through each file and execute it if it exists and is readable + for file in "${files[@]}"; do + if [[ -e ${file} ]] && [[ -r ${file} ]]; then + # shellcheck source=/dev/null + zsh "${file}" + fi + done +} + +## +# Source scripts from the specified directory +# +# @param {string} dir_path - Directory to source scripts from +## +source_dir() { + local dir_path="$1" + + # Get list of script files from directory + local files=($(get_script_files "${dir_path}")) + + # If no files found, return + if [[ ${#files[@]} -eq 0 ]]; then + return + fi + + for file in "${files[@]}"; do + if [[ -e ${file} ]] && [[ -r ${file} ]]; then + # shellcheck source=/dev/null + source "${file}" + fi + done +} diff --git a/.devcontainer/lifecycle/_loaders/00-loader-on-dockerfile.zsh b/.devcontainer/lifecycle/_loaders/00-loader-on-dockerfile.zsh new file mode 100755 index 0000000..7361584 --- /dev/null +++ b/.devcontainer/lifecycle/_loaders/00-loader-on-dockerfile.zsh @@ -0,0 +1,19 @@ +#!/usr/bin/env zsh +# vim: set ft=zsh: +# +# Executes scripts from "00-on-dockerfile" directory +# +# This script loads and executes all shell scripts (.sh, .zsh, .bash) +# from the 00-on-dockerfile directory during Dockerfile build process. +# + +# Globals +DIR_PATH="${WORKSPACE_DIR}/.devcontainer/lifecycle/00-on-dockerfile" + +# Libraries +source "${WORKSPACE_DIR}/.devcontainer/lifecycle/_lib/loaders.zsh" + +# Main logic +execute_dir "${DIR_PATH}" + +exit 0 diff --git a/.devcontainer/lifecycle/_loaders/30-loader-on-container-create.zsh b/.devcontainer/lifecycle/_loaders/30-loader-on-container-create.zsh new file mode 100755 index 0000000..c198252 --- /dev/null +++ b/.devcontainer/lifecycle/_loaders/30-loader-on-container-create.zsh @@ -0,0 +1,19 @@ +#!/usr/bin/env zsh +# vim: set ft=zsh: +# +# Executes scripts from "30-on-container-create" directory +# +# This script loads and executes all shell scripts (.sh, .zsh, .bash) +# from the 30-on-container-create directory during container creation. +# + +# Libraries +source "${WORKSPACE_DIR}/.devcontainer/lifecycle/_lib/loaders.zsh" + +# Globals +DIR_PATH="${WORKSPACE_DIR}/.devcontainer/lifecycle/30-on-container-create" + +# Main logic +execute_dir "${DIR_PATH}" + +exit 0 diff --git a/.devcontainer/lifecycle/_loaders/40-loader-on-container-created.zsh b/.devcontainer/lifecycle/_loaders/40-loader-on-container-created.zsh new file mode 100755 index 0000000..4d6a8be --- /dev/null +++ b/.devcontainer/lifecycle/_loaders/40-loader-on-container-created.zsh @@ -0,0 +1,19 @@ +#!/usr/bin/env zsh +# vim: set ft=zsh: +# +# Executes scripts from "40-on-container-created" directory +# +# This script loads and executes all shell scripts (.sh, .zsh, .bash) +# from the 40-on-container-created directory after container creation. +# + +# Libraries +source "${WORKSPACE_DIR}/.devcontainer/lifecycle/_lib/loaders.zsh" + +# Globals +DIR_PATH="${WORKSPACE_DIR}/.devcontainer/lifecycle/40-on-container-created" + +# Main logic +execute_dir "${DIR_PATH}" + +exit 0 \ No newline at end of file diff --git a/.devcontainer/lifecycle/_loaders/60-loader-on-container-start.zsh b/.devcontainer/lifecycle/_loaders/60-loader-on-container-start.zsh new file mode 100755 index 0000000..c7d2984 --- /dev/null +++ b/.devcontainer/lifecycle/_loaders/60-loader-on-container-start.zsh @@ -0,0 +1,19 @@ +#!/usr/bin/env zsh +# vim: set ft=zsh: +# +# Executes scripts from "60-on-container-start" directory +# +# This script loads and executes all shell scripts (.sh, .zsh, .bash) +# from the 60-on-container-start directory when the container starts. +# + +# Libraries +source "${WORKSPACE_DIR}/.devcontainer/lifecycle/_lib/loaders.zsh" + +# Globals +DIR_PATH="${WORKSPACE_DIR}/.devcontainer/lifecycle/60-on-container-start" + +# Main logic +execute_dir "${DIR_PATH}" + +exit 0 \ No newline at end of file diff --git a/.devcontainer/scripts/post-create.sh b/.devcontainer/scripts/post-create.sh deleted file mode 100755 index b5de963..0000000 --- a/.devcontainer/scripts/post-create.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/zsh - -# Set WORKSPACE_DIR -export WORKSPACE_DIR="$PWD" -echo "export WORKSPACE_DIR='$WORKSPACE_DIR'" >> $HOME/.zshrc - -# Install virtual environment -export UV_CACHE_DIR="$PWD/.uv_cache" -uv sync --frozen - -# Show a "dirty" indicator in the prompt if the workspace is dirty -git config devcontainers-theme.show-dirty 1 - -# UV/UVX auto-completion -echo 'eval "$(uv generate-shell-completion bash)"' >> ~/.bashrc -echo 'eval "$(uv generate-shell-completion zsh)"' >> ~/.zshrc -echo 'eval "$(uvx --generate-shell-completion bash)"' >> ~/.bashrc -echo 'eval "$(uvx --generate-shell-completion zsh)"' >> ~/.zshrc diff --git a/.devcontainer/tools/enable-config-dir/SPECIFICATION.md b/.devcontainer/tools/enable-config-dir/SPECIFICATION.md new file mode 100644 index 0000000..b2e4a9c --- /dev/null +++ b/.devcontainer/tools/enable-config-dir/SPECIFICATION.md @@ -0,0 +1,296 @@ +# enable-config-dir Tool + +## Overview + +The `enable-config-dir` tool transforms any user directory into a system-like configuration directory that automatically loads on new shell sessions. Instead of cramming everything into your `.zshrc` file, this tool lets you choose any directory (or multiple directories) to become modular configuration sources - just like having multiple `.zshrc` files organized in directories. + +## Purpose + +- **Primary Function**: Transform ordinary directories into configuration directories that auto-load on shell startup +- **Secondary Function**: Enable modular shell configuration using directories instead of monolithic files +- **User Benefit**: Choose your own directory structure for shell configuration - personal dotfiles, project configs, team shared settings +- **Target Audience**: Developers using Oh My Zsh who want to organize shell configuration in directories rather than single files + +## Usage + +### Installation + +Run the installation script to create a symlink in your PATH: + +```bash +./install.zsh +``` + +This creates a symlink from `run.zsh` to a directory in your `$PATH`, renaming it to `enable-config-dir` during the process. After installation, the tool will be available system-wide as `enable-config-dir`. + +#### Installation Options + +```bash +./install.zsh [OPTIONS] +``` + +**Options:** + +- `--prefix `: Install to specified directory (default: `~/.local/bin`) +- `--create-dirs`: Create installation directory if it doesn't exist + +**Examples:** + +```bash +# Default installation to ~/.local/bin +./install.zsh + +# Install to custom directory +./install.zsh --prefix /usr/local/bin + +# Install to custom directory, creating it if needed +./install.zsh --prefix ~/mytools/bin --create-dirs +``` + +### Basic Syntax + +```bash +enable-config-dir +``` + +### Arguments + +- ``: Required. Directory path containing custom shell scripts to be auto-loaded (positional argument) + +### Examples + +```bash +# Transform your personal dotfiles directory into a config directory +enable-config-dir ~/.config/shell + +# Make your project workspace auto-configure shells +enable-config-dir /workspace/custom-scripts + +# Enable team shared configuration directory +enable-config-dir /shared/team-configs +``` + +**Result**: Any `.sh`, `.zsh`, or `.bash` files in these directories will automatically load in new shell sessions, just like they were part of your `.zshrc`. + +## Script Format Support + +### What Gets Auto-Loaded + +Once you transform a directory into a configuration directory, any script files placed in it will automatically load on new shell sessions: + +- **Shell Scripts**: `.sh` files +- **Zsh Scripts**: `.zsh` files +- **Bash Scripts**: `.bash` files +- **Discovery Pattern**: All files matching `"${custom_dir}/"*.{sh,zsh,bash}` + +### User Workflow + +1. **Install the tool**: Run `./install.zsh` (with optional `--prefix` and `--create-dirs` options) to create a system-wide symlink +2. **Choose any directory** for your shell configurations +3. **Run enable-config-dir** to transform it: `enable-config-dir /path/to/your/directory` +4. **Add shell scripts** to that directory (aliases, functions, exports, etc.) +5. **Open new shells** - your configurations automatically load + +## Technical Implementation + +### Dependencies + +- **Required**: `envsubst`, `zsh` +- **Validation**: Tool exits with error if dependencies are missing or environment is invalid +- **Environment Requirements**: + - `$ZSH_CUSTOM` environment variable must be set by Oh My Zsh + - Oh My Zsh must be installed and configured + +### Installation Process + +1. **Validation Phase**: + - Validates command line arguments (path argument required) + - Checks for required dependencies (`envsubst`) + - Verifies `$ZSH_CUSTOM` environment variable is set + +2. **Template Processing Phase**: + - Generates directory-specific hash using MD5 of absolute path + - Sets `CUSTOM_DIR` template variable from user argument + - Processes `loader.zsh.template` with `envsubst` + - Creates final autoloader script with unique filename + +3. **Installation Phase**: + - Outputs processed template to `${ZSH_CUSTOM}/custom-config-loader_${hash}.zsh` + - Enables automatic loading on next shell session + +### Error Handling + +- **Batch Processing**: Individual script failures don't prevent loading remaining scripts +- **Argument Validation**: Displays usage message for missing or incorrect arguments +- **Dependency Checks**: Validates `envsubst` availability and template file existence +- **Silent Failures**: Missing target directories don't generate errors during runtime +- **Graceful Degradation**: File permission issues and syntax errors handled gracefully + +## File System Behavior + +### Autoloader Storage Location + +```bash +${ZSH_CUSTOM}/custom-config-loader_${hash}.zsh +``` + +- Uses Oh My Zsh's `$ZSH_CUSTOM` directory for autoloader placement +- Hash-based naming prevents conflicts between multiple custom directories +- Each unique directory gets its own dedicated autoloader file + +### Configuration Directory Location + +```bash +${CUSTOM_DIR} +``` + +- User-specified directory containing custom shell scripts +- Supports absolute and relative paths (resolved to absolute during processing) +- Multiple directories can be configured with separate autoloaders + +### Custom Script Discovery + +```bash +"${custom_dir}/"*.{sh,zsh,bash} +``` + +- Searches for shell scripts in user-specified directory +- Supports `.sh`, `.zsh`, and `.bash` file extensions +- Uses glob patterns with `null_glob` option for safe empty directory handling + +## Integration Points + +### Oh My Zsh Ecosystem + +- **Directory Convention**: Implements system-like configuration directories (similar to `/etc/profile.d/`) within Oh My Zsh +- **Automatic Discovery**: Oh My Zsh automatically sources all `.zsh` files in `$ZSH_CUSTOM` directory +- **Multiple Config Dirs**: Transform multiple directories - each gets its own autoloader, no conflicts +- **Load Order**: Depends on Oh My Zsh's file discovery order (typically alphabetical) +- **User Choice**: You decide which directories become configuration sources + +### Template Processing Strategy + +- **Rationale**: External template file maintains separation of concerns and improves maintainability +- **Benefit**: Clean substitution of user-provided directory paths using `envsubst` +- **Variables**: `${CUSTOM_DIR}` substituted with absolute path from positional argument + +### Filename Generation Algorithm + +- **Method**: MD5 hash of absolute directory path (via `realpath`) +- **Truncation**: Last 9 characters of MD5 hash for filename suffix +- **Collision Resistance**: 36^9 possible combinations provide sufficient uniqueness +- **Deterministic**: Same directory always generates same loader filename, enabling safe re-installation + +## Output and Logging + +### File Generation + +- **Template Source**: `loader.zsh.template` +- **Main Script**: `run.zsh` (symlinked as `enable-config-dir`) +- **Output Location**: `${ZSH_CUSTOM}/custom-config-loader_${hash}.zsh` +- **Processing**: `envsubst` variable substitution + +### Runtime Behavior + +- **Silent Operation**: No output during normal autoloader execution +- **Error Suppression**: Missing directories and unreadable files fail silently +- **Graceful Handling**: Individual script failures don't prevent loading remaining scripts + +### Installation Feedback + +- **Success Indication**: Successful autoloader creation and installation +- **Error Messages**: Clear indication of validation failures and missing dependencies +- **Path Information**: Display of target directory and generated autoloader location + +## Configuration Processing + +### Template Variables + +- **CUSTOM_DIR**: User-provided directory path from positional argument +- **Substitution Method**: `envsubst` command processes template file +- **Output Generation**: Creates Oh My Zsh-compatible autoloader script + +### File Discovery Logic + +- **Core Function**: `load_custom_dir()` in generated autoloader +- **Safety Checks**: Directory existence and readability validation before processing +- **Glob Pattern**: `"${custom_dir}/"*.{sh,zsh,bash}` with `null_glob` option +- **Processing**: Source each readable file found in directory + +## Error Conditions + +### Pre-execution Validation + +- Missing path argument +- Missing `envsubst` utility +- Undefined `$ZSH_CUSTOM` environment variable +- Missing `loader.zsh.template` file + +### Runtime Errors + +- Invalid directory path provided as argument +- File permission issues during autoloader creation +- Template processing failures +- Syntax errors in template file + +## Shell Script Architecture + +### Source Files + +- **run.zsh**: Main installation script with argument parsing and template processing +- **install.zsh**: Installation script with `--prefix` and `--create-dirs` options for flexible installation to user-specified directories +- **loader.zsh.template**: Template for runtime autoloader with `${CUSTOM_DIR}` placeholder + +### Generated Components + +- **custom-config-loader_${hash}.zsh**: Final autoloader script in Oh My Zsh custom directory +- **load_custom_dir()**: Core function that handles directory scanning and script sourcing + +### Function Organization + +- **Template Processing**: Main setup script with argument parsing and validation +- **File Generation**: Template variable substitution and autoloader creation +- **Path Utilities**: Directory resolution and hash generation functions +- **Validation**: Dependency checks and environment validation +- **Installation Management**: Symlink creation and PATH integration via `install.zsh` + +### Script Options + +```bash +set -euo pipefail +``` + +- **`-e`**: Exit on any command failure +- **`-u`**: Exit on undefined variable usage +- **`-o pipefail`**: Exit on pipeline failures + +## Use Cases for AI Assistants + +### Implementation Assistance + +- Understanding the template processing workflow +- Extending functionality for additional file types or processing rules +- Debugging installation or runtime failures +- Adding validation for custom directory contents + +### User Support + +- Troubleshooting autoloader installation issues +- Explaining the hash-based naming system +- Guiding users through custom script organization +- Helping with Oh My Zsh integration concepts + +### Automation Integration + +- Incorporating into dotfiles management systems +- Setting up team-wide custom configuration standards +- Integration with development environment automation +- CI/CD pipeline usage for consistent shell environments + +## Limitations and Considerations + +- **Oh My Zsh Dependency**: Requires Oh My Zsh installation and `$ZSH_CUSTOM` environment variable +- **Template Dependency**: Assumes `loader.zsh.template` file exists alongside setup script +- **No Validation**: Does not validate contents of custom directory or individual scripts +- **Silent Failures**: Missing directories and script errors fail silently during runtime +- **No Uninstall**: Tool only handles installation, not removal of autoloaders diff --git a/.devcontainer/tools/enable-config-dir/install.zsh b/.devcontainer/tools/enable-config-dir/install.zsh new file mode 100755 index 0000000..82b48cf --- /dev/null +++ b/.devcontainer/tools/enable-config-dir/install.zsh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +# +# Installs the enable-config-dir tool by creating a symlink from run.zsh to +# a directory in the user's PATH. This makes the tool available system-wide +# without requiring manual alias configuration. +# +# Usage: +# ./install.zsh [OPTIONS] +# ./install.zsh --prefix ~/.local/bin +# ./install.zsh --prefix /usr/local/bin --create-dirs +# +# Options: +# --prefix +# Install to specified directory (default: ~/.local/bin) +# --create-dirs +# Create installation directory if it doesn't exist +# +# Notes: +# - Overwrites existing installation if present +# - Requires installation directory to be in user's PATH for system-wide access +# - Creates symlink preserving original script location + +set -euo pipefail + +# Global variables +SELF_DIR="$(cd -- "$(dirname -- "$0")" && pwd)" + +SRC_SCRIPT_NAME="run.zsh" +DEST_SCRIPT_NAME="enable-config-dir" +DEFAULT_DEST_DIR="${HOME}/.local/bin" +SRC_SCRIPT_PATH="${SELF_DIR}/${SRC_SCRIPT_NAME}" + +parse_arguments() { + local dest_dir + local create_dirs + + # Default values + dest_dir="${DEFAULT_DEST_DIR}" + create_dirs="false" + + while [[ $# -gt 0 ]]; do + case "$1" in + --prefix) + if [[ -n "${2:-}" ]]; then + dest_dir="$2" + shift 2 + else + echo "Error: --prefix requires a path argument" >&2 + exit 2 + fi + ;; + --create-dirs) + create_dirs="true" + shift + ;; + -*) + echo "Error: Unknown option: $1" >&2 + exit 1 + ;; + *) + break + ;; + esac + done + + echo "${dest_dir} ${create_dirs}" +} + +check_environment() { + if [[ ! -f "${SRC_SCRIPT_PATH}" ]]; then + echo "Error: ${SRC_SCRIPT_PATH} not found" >&2 + exit 1 + fi +} + +# @param $1 string $dest_dir. The destination directory where the script will be installed +# @param $2 string $create_dirs. If "true", create the directory if it doesn't exist +# @return void +# @exits 1 if the directory does not exist and create_dirs is false +# 2 if the directory is not writable +# 3 if the directory cannot be created +ensure_dest_dir() { + local dest_dir="$1" + local create_dirs="$2" + + if [[ ! -d "${dest_dir}" ]]; then + if [[ "${create_dirs}" == "true" ]]; then + echo "Creating destination directory: ${dest_dir}" + if ! mkdir -p "${dest_dir}"; then + echo "Error: Failed to create directory ${dest_dir}" >&2 + exit 3 + fi + else + echo "Error: Directory ${dest_dir} does not exist. Use --create-dirs to create it automatically." >&2 + exit 1 + fi + fi + + if [[ ! -w "${dest_dir}" ]]; then + echo "Error: Destination directory ${dest_dir} is not writable." >&2 + exit 2 + fi +} + +# @param $1 string $src_path. The source script path to symlink +# @param $2 string $dest_path. The destination path where the symlink will be created +# @return void +# @exits 1 if the symlink creation fails +tool::install() { + local src_path="$1" + local dest_path="$2" + + if [[ -e "${dest_path}" ]]; then + echo "Warning: ${dest_path} already exists. Overwriting..." + fi + + if ! ln -sf "${src_path}" "${dest_path}"; then + echo "Error: Failed to create symlink from ${src_path} to ${dest_path}" >&2 + exit 1 + fi +} + +main() { + # Parse arguments and assign to variables + local dest_dir + local create_dirs + read -r dest_dir create_dirs < <(parse_arguments "$@") + + local dest_script_path + dest_script_path="${dest_dir}/${DEST_SCRIPT_NAME}" + + check_environment + + ensure_dest_dir "${dest_dir}" "${create_dirs}" + + tool::install "${SRC_SCRIPT_PATH}" "${dest_script_path}" + + echo "Installed ${DEST_SCRIPT_NAME} to ${dest_script_path}" +} + +main "$@" diff --git a/.devcontainer/tools/enable-config-dir/loader.zsh.template b/.devcontainer/tools/enable-config-dir/loader.zsh.template new file mode 100644 index 0000000..8e28f7b --- /dev/null +++ b/.devcontainer/tools/enable-config-dir/loader.zsh.template @@ -0,0 +1,33 @@ +#!/usr/bin/env zsh +# shellcheck shell=bash +# +# Load custom scripts from a specified directory +# +# Notice: +# - Auto-generated by install-custom-config tool. +## + +load_custom_dir() +{ + setopt local_options null_glob + local custom_dir="${1}" + + if [[ ! -d ${custom_dir} ]] || [[ -z ${custom_dir} ]]; then + return + fi + + local files=("${custom_dir}/"*.{sh,zsh,bash}) + if [[ ! -e ${files[1]} ]]; then + return + fi + + for file in "${files[@]}"; do + if [[ -e ${file} ]] && [[ -r ${file} ]]; then + # shellcheck source=/dev/null + source "${file}" + fi + done +} + +# shellcheck disable=SC2153 +load_custom_dir "${CUSTOM_DIR}" diff --git a/.devcontainer/tools/enable-config-dir/run.zsh b/.devcontainer/tools/enable-config-dir/run.zsh new file mode 100755 index 0000000..4e60be1 --- /dev/null +++ b/.devcontainer/tools/enable-config-dir/run.zsh @@ -0,0 +1,142 @@ +#!/usr/bin/env zsh +# +# Sets up a custom configuration loader for oh-my-zsh that automatically +# sources shell scripts from a specified directory on every new shell session. +# This provides the same effect as sourcing scripts directly in ~/.zshrc but +# allows for easier management of custom configurations. +# +# Usage: +# ./run.zsh +# +# Notes: +# - Requires oh-my-zsh and $ZSH_CUSTOM environment variable +# - Generated loader persists across shell sessions +# - Uses MD5 hash of directory path to prevent duplicate loaders +# - Re-running for same directory overwrites existing loader safely + +set -euo pipefail + +# Global variables +SELF_PATH="$(readlink -f -- "${(%):-%N}")" +readonly SELF_PATH + +SELF_DIR="$(cd -- "$(dirname -- "${SELF_PATH}")" && pwd)" +readonly SELF_DIR + +ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}" +readonly ZSH_CUSTOM + + +{ # Colors + NC=$'\033[0m' + BOLD_RED=$'\033[1;31m' + BOLD_GREEN=$'\033[1;32m' + BOLD_YELLOW=$'\033[1;33m' + BOLD_BLUE=$'\033[1;34m' +} + +{ # Logging functions + log::info() { + echo -e "${BOLD_BLUE}[INFO]${NC} $*" >&2 + } + + log::success() { + echo -e "${BOLD_GREEN}[SUCCESS]${NC} $*" >&2 + } + + log::warning() { + echo -e "${BOLD_YELLOW}[WARNING]${NC} $*" >&2 + } + + log::error() { + echo -e "${BOLD_RED}[ERROR]${NC} $*" >&2 + } +} + +show_environment() { + log::info "About to install loader on ${ZSH_CUSTOM} with args:\n" \ + "$*" +} + +check_dependencies() { + if ! command -v envsubst > /dev/null 2>&1; then + log::error "envsubst is required to generate the loader script." + exit 1 + fi + + if ! command -v md5sum > /dev/null 2>&1; then + log::error "md5sum is required to generate the loader filename." + exit 1 + fi +} + +check_environment() { + if [[ -z "${ZSH_CUSTOM:-}" ]]; then + log::error "ZSH_CUSTOM environment variable is not set. Please ensure oh-my-zsh is installed." + exit 1 + fi + + if [[ ! -d "${ZSH_CUSTOM}" ]]; then + log::error "ZSH_CUSTOM directory does not exist: ${ZSH_CUSTOM}" + exit 1 + fi +} + +parse_arguments() { + if [[ $# -ne 1 ]]; then + log::error "Usage: $0 " + exit 1 + fi + + local custom_dir="$1" + + echo "${custom_dir}" +} + +loader::_generate_filename() { + local custom_dir="$1" + + # Use md5sum to hash the custom_dir path and extract the last 12 chars + local hash + hash=$(echo -n "$custom_dir" | md5sum | awk '{print $1}' | tail -c 10) + + echo "custom-config-loader_${hash}.zsh" +} + +loader::install() { + local custom_dir="$1" + custom_dir=$(realpath "$custom_dir") + + local loader_filename + loader_filename=$(loader::_generate_filename "$custom_dir") + + # Template variables + export CUSTOM_DIR="${custom_dir}" + + # shellcheck disable=SC2016 + envsubst \ + '${CUSTOM_DIR}' \ + < "${SELF_DIR}/loader.zsh.template" \ + > "${ZSH_CUSTOM}/${loader_filename}" + + # Return + echo "${ZSH_CUSTOM}/${loader_filename}" +} + +main() { + show_environment "$@" + + check_dependencies + + check_environment + + local custom_dir + custom_dir=$(parse_arguments "$@") + + local result + result=$(loader::install "${custom_dir}") + + log::success "Custom config loader installed: ${result}" +} + +main "$@" diff --git a/.devcontainer/tools/set-docker-subhosts/run.zsh b/.devcontainer/tools/set-docker-subhosts/run.zsh new file mode 100755 index 0000000..774c8b7 --- /dev/null +++ b/.devcontainer/tools/set-docker-subhosts/run.zsh @@ -0,0 +1,148 @@ +#!/usr/bin/env zsh + +# Script to update /etc/hosts with running Docker container IP addresses +# This script maintains a section in /etc/hosts between markers for Docker containers + +set -e # Exit on any error + +# Marker lines for /etc/hosts section +BEGIN_MARKER="# BEGIN DOCKER HOSTS" +END_MARKER="# END DOCKER HOSTS" + +# Function to log messages +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" +} + +# Function to check if Docker is running +check_docker() { + if ! docker info >/dev/null 2>&1; then + log "ERROR: Docker daemon is not running or not accessible" + return 1 + fi + return 0 +} + +# Function to get container mappings in /etc/hosts format +get_container_mappings() { + local mappings="" + + # Get running containers and their IP addresses + docker ps --format "table {{.Names}}" | tail -n +2 | while read container_name; do + if [[ -n "$container_name" ]]; then + # Get first IP address (primary network) + ip_address=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{break}}{{end}}' "$container_name" 2>/dev/null) + if [[ -n "$ip_address" && "$ip_address" != "" ]]; then + echo "$ip_address $container_name" + fi + fi + done +} + +# Function to update /etc/hosts file +update_hosts_file() { + local container_mappings="$1" + local hosts_file="/etc/hosts" + local temp_file="/tmp/hosts.tmp.$$" + local backup_file="/etc/hosts.backup.$(date +%s)" + + # Check if we have sudo access + if [[ $EUID -ne 0 ]]; then + log "ERROR: This script needs to be run with sudo privileges to modify /etc/hosts" + return 1 + fi + + # Create backup + cp "$hosts_file" "$backup_file" + log "Created backup: $backup_file" + + # Check if markers exist in the file + if ! grep -q "$BEGIN_MARKER" "$hosts_file" || ! grep -q "$END_MARKER" "$hosts_file"; then + log "Markers not found in $hosts_file. Adding Docker hosts section..." + # Add markers and content at the end of the file + { + cat "$hosts_file" + echo "" + echo "$BEGIN_MARKER" + if [[ -n "$container_mappings" ]]; then + echo "$container_mappings" + fi + echo "$END_MARKER" + } > "$temp_file" + else + # Replace content between markers + log "Updating existing Docker hosts section..." + awk -v begin="$BEGIN_MARKER" -v end="$END_MARKER" -v mappings="$container_mappings" ' + BEGIN { in_section = 0 } + $0 == begin { + print $0 + if (mappings != "") print mappings + in_section = 1 + next + } + $0 == end { + print $0 + in_section = 0 + next + } + !in_section { print $0 } + ' "$hosts_file" > "$temp_file" + fi + + # Validate the temporary file + if [[ ! -s "$temp_file" ]]; then + log "ERROR: Generated hosts file is empty. Aborting update." + rm -f "$temp_file" + return 1 + fi # Copy content to hosts file (safer for mounted files) + cat "$temp_file" > "$hosts_file" + + # Clean up temporary file + rm -f "$temp_file" + + # Preserve original permissions + chmod 644 "$hosts_file" + chown root:root "$hosts_file" + + log "Successfully updated $hosts_file" + return 0 +} + +# Main execution +main() { + log "Starting Docker hosts update..." + + # Check if Docker is available + if ! check_docker; then + log "Docker is not available. Skipping hosts update." + return 0 + fi + + # Get container mappings + log "Retrieving container IP mappings..." + local container_mappings + container_mappings=$(get_container_mappings) + + if [[ -z "$container_mappings" ]]; then + log "No running containers with IP addresses found." + container_mappings="" + else + log "Found container mappings:" + echo "$container_mappings" | while read line; do + log " $line" + done + fi + + # Update /etc/hosts + if update_hosts_file "$container_mappings"; then + log "Docker hosts update completed successfully" + else + log "ERROR: Failed to update hosts file" + return 1 + fi +} + +# Run main function if script is executed directly +if [[ "${BASH_SOURCE[0]}" == "${0}" ]] || [[ "${(%):-%N}" == "${0}" ]]; then + main "$@" +fi diff --git a/.devcontainer/tools/setup-omz-plugins/SPECIFICATION.md b/.devcontainer/tools/setup-omz-plugins/SPECIFICATION.md new file mode 100644 index 0000000..3ade42f --- /dev/null +++ b/.devcontainer/tools/setup-omz-plugins/SPECIFICATION.md @@ -0,0 +1,271 @@ +# OMZ Plugin Setup Tool Specification + +## Overview + +The OMZ Plugin Setup Tool is a general-purpose command-line tool that automates the installation and activation of Oh My Zsh plugins from GitHub repositories or custom Git URIs. The tool downloads plugins as Git submodules and automatically enables them in the user's `.zshrc` configuration. + +## Purpose + +- **Primary Function**: Install Oh My Zsh plugins from GitHub or custom Git repositories +- **Secondary Function**: Automatically enable installed plugins in the user's zsh configuration +- **Target Audience**: Developers using Oh My Zsh who want to streamline plugin installation + +## Usage + +### Installation + +Run the installation script to create a symlink in your PATH: + +```bash +./install.zsh +``` + +This creates a symlink from `run.zsh` to a directory in your `$PATH`, renaming it to `setup-omz-plugins` during the process. After installation, the tool will be available system-wide as `setup-omz-plugins`. + +#### Installation Options + +```bash +./install.zsh [OPTIONS] +``` + +**Options:** + +- `--prefix `: Install to specified directory (default: `~/.local/bin`) +- `--create-dirs`: Create installation directory if it doesn't exist + +**Examples:** + +```bash +# Default installation to ~/.local/bin +./install.zsh + +# Install to custom directory +./install.zsh --prefix /usr/local/bin + +# Install to custom directory, creating it if needed +./install.zsh --prefix ~/mytools/bin --create-dirs +``` + +### Basic Syntax + +```bash +setup-omz-plugins [--no-enable] [--from-string ] [ ...] +``` + +### Arguments + +- `--no-enable`: Skip enabling plugins in `.zshrc` after installation (download only) +- `--from-string `: Accept plugins from a space-separated string (useful for automation and environment variables) + +### Examples + +```bash +# Install single plugin using GitHub shorthand +setup-omz-plugins zsh-users/zsh-autosuggestions + +# Install multiple plugins +setup-omz-plugins zsh-users/zsh-autosuggestions \ + zsh-users/zsh-syntax-highlighting + +# Install from custom Git URI +setup-omz-plugins https://gitlab.com/user/custom-plugin.git + +# Install plugins from string (useful for automation) +setup-omz-plugins --from-string "zsh-users/zsh-autosuggestions zsh-users/zsh-syntax-highlighting" + +# Install from environment variable +setup-omz-plugins --from-string "${PLUGINS_LIST}" + +# Download plugins without enabling them +setup-omz-plugins --no-enable zsh-users/zsh-autosuggestions \ + zsh-users/zsh-syntax-highlighting + +# Download from string without enabling +setup-omz-plugins --no-enable --from-string "${PLUGINS_LIST}" + +# Development usage (before installation) +./run.zsh zsh-users/zsh-autosuggestions +``` + +## Plugin Format Support + +### GitHub Shorthand Format + +- **Pattern**: `/` +- **Example**: `zsh-users/zsh-autosuggestions` +- **Resolves to**: `https://github.com/zsh-users/zsh-autosuggestions` + +### Full URI Format + +- **HTTP/HTTPS**: `https://github.com/user/repo.git` +- **SSH**: `git@gitlab.com:user/repo.git` +- **Use Case**: Non-GitHub repositories (GitLab, Bitbucket, etc.) + +## Technical Implementation + +### Dependencies + +- **Required**: `git`, `zsh` +- **Validation**: Tool exits with error code 1 if dependencies are missing +- **Environment Requirements**: + - `$ZSH_CUSTOM/plugins` directory must exist + - `.zshrc` file must exist and contain a `plugins=()` line + +### Installation Process + +1. **Download Phase**: + - Changes directory to `$ZSH_CUSTOM/plugins` + - Executes `git submodule add -f ` + - Plugin name extracted from repository path (everything after last `/`) + +2. **Activation Phase** (skipped if `--no-enable` flag is used): + - Parses existing `plugins=()` line from `.zshrc` + - Appends plugin name to plugins array + - Updates `.zshrc` with modified plugins line + - Creates backup file (`.zshrc.bak`) during modification + +### Error Handling + +- **Batch Processing**: If one plugin fails, continues with remaining plugins +- **Logging**: Colored output with different log levels (INFO, SUCCESS, WARNING, ERROR) +- **Graceful Degradation**: Shows specific error messages and continues processing + +## File System Behavior + +### Plugin Storage Location + +```bash +${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins +``` + +- Uses `$ZSH_CUSTOM` if set, otherwise defaults to `$HOME/.oh-my-zsh/custom` +- Each plugin installed as a subdirectory named after the repository + +### Configuration File Modification + +```bash +${ZDOTDIR:-$HOME}/.zshrc +``` + +- Uses `$ZDOTDIR/.zshrc` if set, otherwise `$HOME/.zshrc` +- Modifies the `plugins=()` line using regex pattern matching +- Creates backup before modification + +## Integration Points + +### Oh My Zsh Ecosystem + +- **Plugin Discovery**: Installed plugins appear in `omz plugin list` +- **Manual Management**: Plugins can be managed with `omz plugin enable/disable ` +- **Standard Location**: Uses Oh My Zsh's standard plugin directory structure + +### Git Submodule Strategy + +- **Rationale**: Avoids conflicts when `$ZSH_CUSTOM` is already a Git repository +- **Benefit**: Maintains proper Git history and enables easy updates +- **Command**: `git submodule add -f ` + +## Output and Logging + +### Log Levels + +- **INFO** (Blue): General operation information +- **SUCCESS** (Green): Successful plugin installation +- **WARNING** (Yellow): Non-critical issues (duplicate plugins, failures) +- **ERROR** (Red): Critical failures requiring user attention + +### Color Codes + +```bash +BOLD_RED=$'\033[1;31m' +BOLD_GREEN=$'\033[1;32m' +BOLD_YELLOW=$'\033[1;33m' +BOLD_BLUE=$'\033[1;34m' +NC=$'\033[0m' # No Color +``` + +## Configuration Parsing + +### Plugin Line Format + +- **Expected Pattern**: `^plugins=\(.*\)$` +- **Example**: `plugins=(git docker zsh-autosuggestions)` +- **Modification Strategy**: String replacement using `sed` + +### Array Manipulation + +- **Serialization**: Converts zsh array to space-separated string in parentheses +- **Deserialization**: Parses parenthesized string back to array elements +- **Append Logic**: Adds new plugin name to existing array + +## Error Conditions + +### Pre-execution Validation + +- Missing `git` command +- Missing `zsh` command +- Non-existent `$ZSH_CUSTOM/plugins` directory +- Non-existent `.zshrc` file + +### Runtime Errors + +- Invalid repository URI +- Network connectivity issues during `git submodule add` +- Missing `plugins=()` line in `.zshrc` +- File permission issues during `.zshrc` modification + +## Shell Script Architecture + +### Source Files + +- **run.zsh**: Main script with argument parsing, validation, and plugin installation logic +- **install.zsh**: Installation script with `--prefix` and `--create-dirs` options for flexible installation to user-specified directories + +### Function Organization + +- **Logging**: `log::info`, `log::success`, `log::warning`, `log::error` +- **Validation**: `check_dependencies`, `show_environment` +- **Plugin Operations**: `plugins::*` namespace functions +- **Configuration**: `zshrc::*` namespace functions +- **Utilities**: `array::*` namespace functions + +### Script Options + +```bash +set -euo pipefail +``` + +- **`-e`**: Exit on any command failure +- **`-u`**: Exit on undefined variable usage +- **`-o pipefail`**: Exit on pipeline failures + +## Use Cases for AI Assistants + +### Implementation Assistance + +- Understanding the modular function architecture +- Extending functionality (e.g., plugin removal, updates) +- Debugging installation failures +- Adding support for additional Git hosting services + +### User Support + +- Troubleshooting installation errors +- Explaining plugin activation process +- Guiding users through manual `.zshrc` fixes +- Recommending popular plugins for installation + +### Automation Integration + +- Incorporating into development environment setup scripts +- Batch installation for team standardization +- Integration with dotfiles management systems +- CI/CD pipeline usage for consistent environments + +## Limitations and Considerations + +- **Single Plugin Line**: Assumes `.zshrc` has exactly one `plugins=()` line +- **Bash Arrays**: Uses zsh-specific array syntax for plugin list manipulation +- **No Conflict Resolution**: Does not handle plugin name conflicts +- **No Version Management**: Always installs latest version from default branch +- **No Uninstall**: Tool only handles installation, not removal diff --git a/.devcontainer/tools/setup-omz-plugins/install.zsh b/.devcontainer/tools/setup-omz-plugins/install.zsh new file mode 100755 index 0000000..e135ada --- /dev/null +++ b/.devcontainer/tools/setup-omz-plugins/install.zsh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +# +# Installs the setup-omz-plugins tool by creating a symlink from run.zsh to +# a directory in the user's PATH. This makes the tool available system-wide +# without requiring manual alias configuration. +# +# Usage: +# ./install.zsh [OPTIONS] +# ./install.zsh --prefix ~/.local/bin +# ./install.zsh --prefix /usr/local/bin --create-dirs +# +# Options: +# --prefix +# Install to specified directory (default: ~/.local/bin) +# --create-dirs +# Create installation directory if it doesn't exist +# +# Notes: +# - Overwrites existing installation if present +# - Requires installation directory to be in user's PATH for system-wide access +# - Creates symlink preserving original script location + +set -euo pipefail + +# Global variables +SELF_DIR="$(cd -- "$(dirname -- "$0")" && pwd)" + +SRC_SCRIPT_NAME="run.zsh" +DEST_SCRIPT_NAME="setup-omz-plugins" +DEFAULT_DEST_DIR="${HOME}/.local/bin" +SRC_SCRIPT_PATH="${SELF_DIR}/${SRC_SCRIPT_NAME}" + +parse_arguments() { + local dest_dir + local create_dirs + + # Default values + dest_dir="${DEFAULT_DEST_DIR}" + create_dirs="false" + + while [[ $# -gt 0 ]]; do + case "$1" in + --prefix) + if [[ -n "${2:-}" ]]; then + dest_dir="$2" + shift 2 + else + echo "Error: --prefix requires a path argument" >&2 + exit 2 + fi + ;; + --create-dirs) + create_dirs="true" + shift + ;; + -*) + echo "Error: Unknown option: $1" >&2 + exit 1 + ;; + *) + break + ;; + esac + done + + echo "${dest_dir} ${create_dirs}" +} + +check_environment() { + if [[ ! -f "${SRC_SCRIPT_PATH}" ]]; then + echo "Error: ${SRC_SCRIPT_PATH} not found" >&2 + exit 1 + fi +} + +# @param $1 string $dest_dir. The destination directory where the script will be installed +# @param $2 string $create_dirs. If "true", create the directory if it doesn't exist +# @return void +# @exits 1 if the directory does not exist and create_dirs is false +# 2 if the directory is not writable +# 3 if the directory cannot be created +ensure_dest_dir() { + local dest_dir="$1" + local create_dirs="$2" + + if [[ ! -d "${dest_dir}" ]]; then + if [[ "${create_dirs}" == "true" ]]; then + echo "Creating destination directory: ${dest_dir}" + if ! mkdir -p "${dest_dir}"; then + echo "Error: Failed to create directory ${dest_dir}" >&2 + exit 3 + fi + else + echo "Error: Directory ${dest_dir} does not exist. Use --create-dirs to create it automatically." >&2 + exit 1 + fi + fi + + if [[ ! -w "${dest_dir}" ]]; then + echo "Error: Destination directory ${dest_dir} is not writable." >&2 + exit 2 + fi +} + +# @param $1 string $src_path. The source script path to symlink +# @param $2 string $dest_path. The destination path where the symlink will be created +# @return void +# @exits 1 if the symlink creation fails +tool::install() { + local src_path="$1" + local dest_path="$2" + + if [[ -e "${dest_path}" ]]; then + echo "Warning: ${dest_path} already exists. Overwriting..." + fi + + if ! ln -sf "${src_path}" "${dest_path}"; then + echo "Error: Failed to create symlink from ${src_path} to ${dest_path}" >&2 + exit 1 + fi +} + +main() { + # Parse arguments and assign to variables + local dest_dir + local create_dirs + read -r dest_dir create_dirs < <(parse_arguments "$@") + + local dest_script_path + dest_script_path="${dest_dir}/${DEST_SCRIPT_NAME}" + + check_environment + + ensure_dest_dir "${dest_dir}" "${create_dirs}" + + tool::install "${SRC_SCRIPT_PATH}" "${dest_script_path}" + + echo "Installed ${DEST_SCRIPT_NAME} to ${dest_script_path}" +} + +main "$@" diff --git a/.devcontainer/tools/setup-omz-plugins/run.zsh b/.devcontainer/tools/setup-omz-plugins/run.zsh new file mode 100755 index 0000000..17cdca5 --- /dev/null +++ b/.devcontainer/tools/setup-omz-plugins/run.zsh @@ -0,0 +1,326 @@ +#!/usr/bin/env zsh +# Oh My Zsh plugin setup tool that downloads plugins from GitHub or custom Git +# repositories and automatically enables them in .zshrc configuration. +# +# Usage: +# ./run.zsh [--no-enable] [--from-string ] [ ...] +# ./run.zsh zsh-users/zsh-autosuggestions \ +# zsh-users/zsh-syntax-highlighting +# ./run.zsh --from-string "zsh-users/zsh-autosuggestions zsh-users/zsh-syntax-highlighting" +# ./run.zsh --from-string "${PLUGINS_LIST}" +# ./run.zsh --no-enable https://gitlab.com/user/custom-plugin.git +# +# Options: +# --no-enable +# Skip enabling plugins in .zshrc after installation (download only) +# --from-string +# Accept plugins from a space-separated string (useful for automation) +# +# Notes: +# - Supports GitHub shorthand format (org/repo) or full Git URIs +# - Downloads plugins as Git submodules to avoid conflicts +# - Automatically appends plugins to existing plugins=() line in .zshrc +# - Creates .zshrc.bak backup before making changes +# - Continues processing remaining plugins if one fails + +set -euo pipefail + +# Global variables +PLUGIN_DIRS="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins" +readonly PLUGIN_DIRS + +ZSHRC="${ZDOTDIR:-$HOME}/.zshrc" +readonly ZSHRC + + +{ # Colors + BOLD_RED=$'\033[1;31m' + BOLD_GREEN=$'\033[1;32m' + BOLD_YELLOW=$'\033[1;33m' + BOLD_BLUE=$'\033[1;34m' + NC=$'\033[0m' +} + +{ # Logging functions + log::info() { + echo -e "${BOLD_BLUE}[INFO]${NC} $*" >&2 + } + + log::success() { + echo -e "${BOLD_GREEN}[SUCCESS]${NC} $*" >&2 + } + + log::warning() { + echo -e "${BOLD_YELLOW}[WARNING]${NC} $*" >&2 + } + + log::error() { + echo -e "${BOLD_RED}[ERROR]${NC} $*" >&2 + } +} + +# @param $@ string[] $args +show_environment() { + log::info "About to setup zsh plugins on ${PLUGIN_DIRS} with args:\n" \ + "$*" +} + +# @param $@ string[] $args +# @return string[] $plugins (remaining arguments after flags) +parse_arguments() { + local plugins=() + local enable_plugins="true" + local from_string="" + + while [[ $# -gt 0 ]]; do + case "$1" in + --no-enable) + enable_plugins="false" + shift 1 + ;; + --from-string) + from_string="$2" + shift 2 + ;; + -* ) + log::error "Unknown option: $1" + exit 1 + ;; + *) + plugins+=("$1") + shift 1 + ;; + esac + done + + if [[ -n "$from_string" ]]; then + local from_string_plugins=( ${(z)from_string} ) + plugins+=("${from_string_plugins[@]}") + fi + + # Print enable_plugins and plugins as a single line, plugins space-separated + printf '%s ' "$enable_plugins" + printf '%s ' "${plugins[@]}" + printf '\n' +} + +check_dependencies() { + if ! command -v git > /dev/null 2>&1; then + log::error "git is required to setup omz plugins." + exit 1 + fi + + if ! command -v zsh > /dev/null 2>&1; then + log::error "zsh is required to setup omz plugins." + exit 1 + fi +} + +check_environment() { + if [[ ! -d "${PLUGIN_DIRS}" ]]; then + log::error "PLUGIN_DIRS directory does not exist: ${PLUGIN_DIRS}" + exit 1 + fi + + if [[ ! -f "${ZSHRC}" ]]; then + log::error "ZSHRC file does not exist: ${ZSHRC}" + exit 1 + fi +} + +# @param $1 string $serialized_list, e.g. "plugins=(plugin1 plugin2)" +# @param $2 string $item, e.g. "new_plugin" +# @return string serialized list with item appended, +# e.g. "plugins=(plugin1 plugin2 new_plugin)" +array::append_item_to_serialized_list() { + local item="$1" + local serialized_list="$2" + + local list_name + local new_list + local new_serialized + + # Extract the list name (everything before the '=') + list_name="${serialized_list%%=*}" + + # Unserialize by removing the list name and parenthesis + new_list=("${(s: :)${serialized_list#*=\(}}") # Split by spaces, removing the 'var=(' part + new_list=("${new_list[@]%)}") # Remove trailing parenthesis + + # Append new item + new_list=("${new_list[@]}" "$item") + + # Serialize back to line using the extracted list name + new_serialized="${list_name}=(${(j: :)new_list})" + + echo "$new_serialized" +} + +# @param $1 string $zshrc_path, e.g. "$HOME/.zshrc" +# @return string The plugins line/block, e.g. "plugins=(plugin1 plugin2)" +# @exits 1 if no plugins line found +zshrc::extract_plugins_line() { + local zshrc_path="$1" + + local plugins_line + plugins_line=$(grep -E '^plugins=\(' "$zshrc_path" || true) + + if [[ -z "$plugins_line" ]]; then + return 1 + fi + + echo "$plugins_line" +} + +# @param $1 string $plugins_line, e.g. "plugins=(plugin1 plugin2)" +# @param $2 string $zshrc_path, e.g. "$HOME/.zshrc" +# @exits 1 if plugins line format is invalid +# 2 if update failed +zshrc::update_plugins_line() { + local plugins_line="$1" + local zshrc_path="$2" + + # Ensure the plugins line is properly formatted + if [[ ! "$plugins_line" =~ ^plugins=\(.*\)$ ]]; then + log::error "Invalid plugins line format: $plugins_line" + return 1 + fi + + # Replace the existing plugins line in .zshrc + if ! sed -i.bak "s/^plugins=.*/$plugins_line/" "$zshrc_path"; then + return 2 + fi +} + +# @param $1 string $plugin +# @param $2 string $zshrc_path, e.g. "$HOME/.zshrc" +# @exits 1 if no plugins line found +# 2 if update failed +zshrc::enable_plugin() { + local plugin="$1" + local zshrc_path="$2" + + local plugin_name + plugin_name="${plugin##*/}" + + log::info "Enabling plugin '$plugin_name' in .zshrc" + + local plugins_line + if ! plugins_line=$(zshrc::extract_plugins_line "$zshrc_path"); then + log::error "No plugins line found in .zshrc. Please add 'plugins=(...)' to your .zshrc file." + return 1 + fi + + if [[ "$plugins_line" =~ $plugin_name ]]; then + log::warning "Plugin '$plugin_name' is already enabled in .zshrc." + return 0 + fi + + plugins_line=$(array::append_item_to_serialized_list "$plugin_name" "$plugins_line") + + if ! $(zshrc::update_plugins_line "$plugins_line" "$zshrc_path"); then + log::error "Failed to update .zshrc with plugin '$plugin_name'." + return 2 + fi +} + +# @param $1 string $plugin +# @exit 0 if plugin is a URI, 1 otherwise +plugins::is_uri() { + local plugin="$1" + [[ "$plugin" =~ ^https?:// ]] || [[ "$plugin" =~ ^git@ ]] +} + +# @param $1 string $plugin +# @return string repository URL +plugins::get_repo_uri() { + local plugin="$1" + + if plugins::is_uri "$plugin"; then + echo "$plugin" + else + echo "https://github.com/$plugin" + fi +} + +# @param $1 string $plugin +# @exits 1 if plugin couldn't be downloaded +plugins::download() { + local plugin="$1" + + local plugin_name + plugin_name="${plugin##*/}" + + local repo_uri + repo_uri=$(plugins::get_repo_uri "${plugin}") + + log::info "Downloading plugin: ${repo_uri}" + + cd "$PLUGIN_DIRS" + + if ! git submodule add -f "${repo_uri}"; then + log::error "Failed to download plugin: $plugin" + fi +} + +# @param $1 string enable_plugins. If "true", enable the plugin in .zshrc +# @param $2 string plugin. The plugin name or repository URL +# @exits 1 if plugin couldn't be downloaded +plugins::install_single() { + local enable_plugins="$1" + local plugin="$2" + + if ! plugins::download "${plugin}"; then + return 1 + fi + + if [[ "$enable_plugins" == "true" ]]; then + zshrc::enable_plugin "${plugin}" "${ZSHRC}" + fi +} + +# @param $1 string enable_plugins +# @param $@ string[] plugins +plugins::install_list() { + local enable_plugins="$1" + shift 1 + local plugins=("$@") + + if [[ ${#plugins[@]} -eq 0 ]]; then + log::warning "No plugins specified for installation." + return 0 + fi + + for plugin in "${plugins[@]}"; do + log::info "Setting up plugin: ${plugin}" + + if plugins::install_single "$enable_plugins" "${plugin}"; then + log::success "Installed: ${plugin}" + else + log::warning "Failed to install: ${plugin}" + fi + done +} + +# @param $@ string[] $args +main() { + # Parse command line arguments + local enable_plugins + local plugins_str + local plugins + + read -r enable_plugins plugins_str < <(parse_arguments "$@") + plugins=(${(z)plugins_str}) + + show_environment "$@" + + check_dependencies + + check_environment + + plugins::install_list "${enable_plugins}" "${plugins[@]}" + + log::success "All specified plugins have been processed." +} + +main $@ diff --git a/.devcontainer/tools/switch-apt-mirror/SPECIFICATION.md b/.devcontainer/tools/switch-apt-mirror/SPECIFICATION.md new file mode 100644 index 0000000..d7bd396 --- /dev/null +++ b/.devcontainer/tools/switch-apt-mirror/SPECIFICATION.md @@ -0,0 +1,236 @@ +# switch-apt-mirror Tool Specification + +## Overview + +A bash utility for safely switching APT repository mirrors in Debian-based systems. The tool replaces repository URLs while preserving all other source configuration details, providing automatic backup functionality, and automatically updating package lists after switching mirrors. + +## Purpose + +- **Primary Function**: Replace the URI component of APT source entries while maintaining all other repository metadata (type, options, distribution, suite, components) +- **Secondary Function**: Automatically update package lists and create backups for safe mirror switching +- **Target Audience**: System administrators and developers working with Debian-based systems who need to change APT mirrors efficiently + +## Usage + +### Installation + +Run the installation script to create a symlink in your PATH: + +```bash +./install.bash +``` + +This creates a symlink from `run.bash` to `~/.local/bin/switch-apt-mirror`. After installation, the tool will be available system-wide as `switch-apt-mirror` (assuming `~/.local/bin` is in your PATH). + +#### Installation Options + +```bash +./install.bash [OPTIONS] +``` + +**Options:** + +- `--prefix `: Install to specified directory (default: `~/.local/bin`) +- `--create-dirs`: Create installation directory if it doesn't exist + +**Examples:** + +```bash +# Default installation to ~/.local/bin +./install.bash + +# Install to custom directory +./install.bash --prefix /usr/local/bin + +# Install to custom directory, creating it if needed +./install.bash --prefix ~/mytools/bin --create-dirs +``` + +### Basic Syntax + +```bash +switch-apt-mirror [OPTIONS] +``` + +### Arguments + +- ``: Required. The new repository mirror URL (e.g., `mirrors.kernel.org`) + +### Options + +- `--type [deb|deb-src|all]`: Filter by repository type (default: `all`) +- `--suite [updates|backports|security|main|all]`: Filter by distribution suite (default: `all`) +- `--no-backup`: Skip backup creation +- `--no-update`: Skip running 'apt update' after switching mirrors + +### Examples + +```bash +# Basic mirror change +sudo switch-apt-mirror mirrors.kernel.org + +# Target only binary packages +sudo switch-apt-mirror --type deb mirrors.kernel.org + +# Update only security repositories +sudo switch-apt-mirror --suite security security.ubuntu.com + +# Skip backup for testing +sudo switch-apt-mirror --no-backup test-mirror.example.com + +# Skip automatic apt update +sudo switch-apt-mirror --no-update mirrors.kernel.org + +# Development usage (before installation) +sudo ./run.bash mirrors.kernel.org +``` + +## Repository Entry Format Support + +APT source entries follow this structure: + +```text + [] [-] [component2] ... +``` + +### Field Definitions + +- ``: `deb` (binary packages) or `deb-src` (source packages) +- `[]`: Optional parameters in square brackets (e.g., `[arch=amd64 signed-by=/path/to/key]`) +- ``: Repository URL (the field this tool modifies) +- ``: Distribution codename (e.g., `focal`, `jammy`) +- ``: Optional suite suffix (`-updates`, `-backports`, `-security`) +- ``: Repository components (`main`, `universe`, `restricted`, `multiverse`) + +### Filtering Logic + +**Type Filtering**: + +- `deb`: Match only binary package repositories +- `deb-src`: Match only source package repositories +- `all`: Match both types + +**Suite Filtering**: + +- `updates`: Match distributions ending with `-updates` +- `backports`: Match distributions ending with `-backports` +- `security`: Match distributions ending with `-security` +- `main`: Match distributions without suite suffix (base distribution) +- `all`: Match any distribution/suite combination + +## Technical Implementation + +### Dependencies + +- **Required**: `awk`, `sudo` (root privileges) +- **Validation**: Tool exits with error code 1 if dependencies are missing +- **Environment Requirements**: + - `/etc/apt/sources.list` file must exist and be readable + - Root/sudo privileges required for modifying `/etc/apt/` files + +### Processing Pipeline + +1. **Validation Phase**: + - Check for required dependencies (`awk`) + - Verify root/sudo privileges + - Validate command line arguments + +2. **Backup Phase** (skipped if `--no-backup`): + - Create timestamped backup: `/etc/apt/sources.list.backup.YYYYMMDD_HHMMSS` + - Create convenience symlink: `/etc/apt/sources.list.backup` → most recent backup + +3. **Processing Phase**: + - Use AWK-based text processing for reliable field parsing + - Apply type and suite filters to target specific repositories + - Replace URI field while preserving all other metadata + - Handle only active (uncommented) repository entries + +4. **Update Phase** (skipped if `--no-update`): + - Execute `apt-get update` to refresh package lists + - Verify mirror connectivity automatically + +### Error Handling + +- **Batch Processing**: Process all matching entries, continue on individual failures +- **Logging**: Colored output with different log levels (INFO, SUCCESS, WARNING, ERROR) +- **Graceful Degradation**: Atomic operations with backup → modify → verify workflow + +## Error Conditions + +### Pre-execution Validation + +- Missing `awk` command +- Missing root/sudo privileges +- Non-existent `/etc/apt/sources.list` file +- Invalid command line arguments + +### Runtime Errors + +- File permission issues during backup creation +- Backup creation failures (aborts operation unless `--no-backup`) +- Malformed source entries in `/etc/apt/sources.list` +- Network connectivity issues during `apt update` +- Processing failures during URI replacement + +### Input Validation + +- Accept any string values for `--type` and `--suite` options (no hardcoded validation) +- Allow flexibility for custom repository types and suites beyond standard values +- Only validate that required parameters are provided + +## Shell Script Architecture + +### Source Files + +- **run.bash**: Main script with argument parsing, validation, and mirror switching logic +- **install.bash**: Installation script with `--prefix` and `--create-dirs` options for flexible installation to user-specified directories +- **replace_entry_uri.awk**: AWK script for URI replacement in source entries + +### Function Organization + +- **Logging**: `log::info`, `log::success`, `log::warning`, `log::error` +- **Validation**: `check_dependencies`, `show_environment` +- **File Operations**: `sources_file::*` namespace functions +- **Package Management**: `apt::update` function +- **Argument Processing**: `parse_args` function + +### Script Options + +```bash +set -euo pipefail +``` + +- **`-e`**: Exit on any command failure +- **`-u`**: Exit on undefined variable usage +- **`-o pipefail`**: Exit on pipeline failures + +## Use Cases for AI Assistants + +### Implementation Assistance + +- Understanding the AWK-based text processing workflow +- Extending functionality for additional file types (e.g., sources.list.d support) +- Debugging mirror switching failures +- Adding support for additional repository validation + +### User Support + +- Troubleshooting mirror switching issues +- Explaining the backup and restore process +- Guiding users through manual recovery procedures +- Recommending appropriate mirror URLs for different regions + +### Automation Integration + +- Incorporating into system setup and provisioning scripts +- Setting up automated mirror switching for different environments +- Integration with configuration management systems +- CI/CD pipeline usage for consistent package sources + +## Limitations and Considerations + +- **Single File Target**: Processes `/etc/apt/sources.list` only, not files in `sources.list.d/` +- **Root Privileges**: Requires sudo/root access for system file modifications +- **No Rollback**: Tool only handles forward migration, manual backup restoration needed for rollback +- **No Mirror Validation**: Does not validate mirror URL accessibility before switching +- **Atomic Operations**: Ensures backup → modify → verify workflow but no transaction rollback on failure diff --git a/.devcontainer/tools/switch-apt-mirror/install.zsh b/.devcontainer/tools/switch-apt-mirror/install.zsh new file mode 100755 index 0000000..e3d20fb --- /dev/null +++ b/.devcontainer/tools/switch-apt-mirror/install.zsh @@ -0,0 +1,141 @@ +#!/usr/bin/env zsh +# +# Installs the switch-apt-mirror tool by creating a symlink from run.zsh to +# a directory in the user's PATH. This makes the tool available system-wide +# without requiring manual alias configuration. +# +# Usage: +# ./install.zsh [OPTIONS] +# ./install.zsh --prefix ~/.local/bin +# ./install.zsh --prefix /usr/local/bin --create-dirs +# +# Options: +# --prefix +# Install to specified directory (default: ~/.local/bin) +# --create-dirs +# Create installation directory if it doesn't exist +# +# Notes: +# - Overwrites existing installation if present +# - Requires installation directory to be in user's PATH for system-wide access +# - Creates symlink preserving original script location + +set -euo pipefail + +# Global variables +SELF_DIR="$(cd -- "$(dirname -- "$0")" && pwd)" + +SRC_SCRIPT_NAME="run.zsh" +DEST_SCRIPT_NAME="switch-apt-mirror" +DEFAULT_DEST_DIR="${HOME}/.local/bin" +SRC_SCRIPT_PATH="${SELF_DIR}/${SRC_SCRIPT_NAME}" + +parse_arguments() { + local dest_dir + local create_dirs + + # Default values + dest_dir="${DEFAULT_DEST_DIR}" + create_dirs="false" + + while [[ $# -gt 0 ]]; do + case "$1" in + --prefix) + if [[ -n "${2:-}" ]]; then + dest_dir="$2" + shift 2 + else + echo "Error: --prefix requires a path argument" >&2 + exit 2 + fi + ;; + --create-dirs) + create_dirs="true" + shift + ;; + -*) + echo "Error: Unknown option: $1" >&2 + exit 1 + ;; + *) + break + ;; + esac + done + + echo "${dest_dir} ${create_dirs}" +} + +check_environment() { + if [[ ! -f "${SRC_SCRIPT_PATH}" ]]; then + echo "Error: ${SRC_SCRIPT_PATH} not found" >&2 + exit 1 + fi +} + +# @param $1 string $dest_dir. The destination directory where the script will be installed +# @param $2 string $create_dirs. If "true", create the directory if it doesn't exist +# @return void +# @exits 1 if the directory does not exist and create_dirs is false +# 2 if the directory is not writable +# 3 if the directory cannot be created +ensure_dest_dir() { + local dest_dir="$1" + local create_dirs="$2" + + if [[ ! -d "${dest_dir}" ]]; then + if [[ "${create_dirs}" == "true" ]]; then + echo "Creating destination directory: ${dest_dir}" + if ! mkdir -p "${dest_dir}"; then + echo "Error: Failed to create directory ${dest_dir}" >&2 + exit 3 + fi + else + echo "Error: Directory ${dest_dir} does not exist. Use --create-dirs to create it automatically." >&2 + exit 1 + fi + fi + + if [[ ! -w "${dest_dir}" ]]; then + echo "Error: Destination directory ${dest_dir} is not writable." >&2 + exit 2 + fi +} + +# @param $1 string $src_path. The source script path to symlink +# @param $2 string $dest_path. The destination path where the symlink will be created +# @return void +# @exits 1 if the symlink creation fails +tool::install() { + local src_path="$1" + local dest_path="$2" + + if [[ -e "${dest_path}" ]]; then + echo "Warning: ${dest_path} already exists. Overwriting..." + fi + + if ! ln -sf "${src_path}" "${dest_path}"; then + echo "Error: Failed to create symlink from ${src_path} to ${dest_path}" >&2 + exit 1 + fi +} + +main() { + # Parse arguments and assign to variables + local dest_dir + local create_dirs + read -r dest_dir create_dirs < <(parse_arguments "$@") + + local dest_script_path + dest_script_path="${dest_dir}/${DEST_SCRIPT_NAME}" + + check_environment + + ensure_dest_dir "${dest_dir}" "${create_dirs}" + + tool::install "${SRC_SCRIPT_PATH}" "${dest_script_path}" + + echo "Installed ${DEST_SCRIPT_NAME} to ${dest_script_path}" +} + +main "$@" diff --git a/.devcontainer/tools/switch-apt-mirror/replace_entry_uri.awk b/.devcontainer/tools/switch-apt-mirror/replace_entry_uri.awk new file mode 100644 index 0000000..86fc2db --- /dev/null +++ b/.devcontainer/tools/switch-apt-mirror/replace_entry_uri.awk @@ -0,0 +1,52 @@ +# Usage: awk -v type_match=TYPE -v suite_match=SUITE -v new_uri=URI -f replace_entry_uri.awk + +function has_suite(dist) { + return (dist ~ /-(updates|backports|security)$/) +} +{ + # Skip empty lines + if (NF == 0) { print; next } + + # Skip commented lines + if ($0 ~ /^#/) { print; next } + + # Parse type (field 1) + entry_type = $1 + + # Handle optional [options] in field 2 + if ($2 ~ /^\[/) { + entry_options = $2 + entry_uri = $3 + entry_dist = $4 + } else { + entry_options = "" + entry_uri = $2 + entry_dist = $3 + } + + # Type match logic + type_ok = (type_match == "all" || entry_type == type_match) + + # Suite match logic + suite_ok = 0 + if (suite_match == "all") { + suite_ok = 1 + } else if (has_suite(entry_dist)) { + split(entry_dist, arr, "-") + suite_ok = (arr[2] == suite_match) + } else if (suite_match == "main") { + suite_ok = !has_suite(entry_dist) + } + + # If both match, replace URI + if (type_ok && suite_ok) { + if (entry_options != "") { + $3 = new_uri + } else { + $2 = new_uri + } + } + + # Print the modified or unmodified line + print +} diff --git a/.devcontainer/tools/switch-apt-mirror/run.zsh b/.devcontainer/tools/switch-apt-mirror/run.zsh new file mode 100755 index 0000000..76407c9 --- /dev/null +++ b/.devcontainer/tools/switch-apt-mirror/run.zsh @@ -0,0 +1,202 @@ +#!/usr/bin/env zsh +# +# Switch APT repository mirrors in Debian-based systems. +# +# Usage: +# sudo ./run.zsh [OPTIONS] +# sudo ./run.zsh --type deb mirrors.kernel.org +# sudo ./run.zsh --suite security security.ubuntu.com +# sudo ./run.zsh --no-backup test-mirror.example.com +# +# Options: +# --type [deb|deb-src|all] +# Filter by repository type (default: all) +# --suite [updates|backports|security|main|all] +# Filter by distribution suite (default: all) +# --no-backup +# Skip backup creation +# --no-update +# Skip running 'apt update' after switching mirrors +# +# Notes: +# - Replaces mirror URLs while preserving all other repository metadata. +# - Processes /etc/apt/sources.list only (not sources.list.d files). +# - Creates timestamped backups by default unless --no-backup is specified. +# - Script must be run with sudo privileges. +# + +set -euo pipefail + +# Global variables +SELF_PATH="$(readlink -f -- "${(%):-%N}")" +readonly SELF_PATH + +SELF_DIR="$(cd -- "$(dirname -- "${SELF_PATH}")" && pwd)" +readonly SELF_DIR + + +{ # Colors + BOLD_RED=$'\033[1;31m' + BOLD_GREEN=$'\033[1;32m' + BOLD_YELLOW=$'\033[1;33m' + BOLD_BLUE=$'\033[1;34m' + NC=$'\033[0m' +} + +{ # Logging functions + log::info() { + echo -e "${BOLD_BLUE}[INFO]${NC} $*" >&2 + } + + log::success() { + echo -e "${BOLD_GREEN}[SUCCESS]${NC} $*" >&2 + } + + log::warning() { + echo -e "${BOLD_YELLOW}[WARNING]${NC} $*" >&2 + } + + log::error() { + echo -e "${BOLD_RED}[ERROR]${NC} $*" >&2 + } +} + +show_environment() { + log::info "About to switch APT repository mirrors with args:\n" \ + "$*" +} + +check_dependencies() { + if ! command -v awk > /dev/null 2>&1; then + log::error "awk is required to process sources.list." + exit 1 + fi +} + +check_environment() { + if [[ "$EUID" -ne 0 ]]; then + log::error "Please run the script with sudo." + exit 1 + fi +} + +parse_arguments() { + local type="all" + local suite="all" + local no_backup=0 + local no_update=0 + + while [[ $# -gt 0 ]]; do + case "$1" in + --type) + type="$2" + shift 2 + ;; + --suite) + suite="$2" + shift 2 + ;; + --no-backup) + no_backup=1 + shift + ;; + --no-update) + no_update=1 + shift + ;; + -*) + log::error "Unknown option: $1" + exit 1 + ;; + *) + new_provider="$1" + shift + ;; + esac + done + + if [[ -z "${new_provider:-}" ]]; then + log::error " is required." + exit 1 + fi + + echo "$type" "$suite" "$no_backup" "$no_update" "$new_provider" +} + +sources_file::backup() { + local src="/etc/apt/sources.list" + local symlink="/etc/apt/sources.list.backup" + + local backup_file + backup_file="/etc/apt/sources.list.backup.$(date +%Y%m%d_%H%M%S)" + + if ! cp --preserve=all "${src}" "${backup_file}"; then + log::error "Failed to create backup at ${backup_file}" + exit 1 + fi + + ln -sf "${backup_file}" "${symlink}" +} + +sources_file::replace_entry_uri() { + local type="$1" + local suite="$2" + local new_uri="$3" + + awk -v type_match="$type" -v suite_match="$suite" -v new_uri="$new_uri" \ + -f "${SELF_DIR}/replace_entry_uri.awk" +} + +sources_file::process() { + local type="$1" + local suite="$2" + local new_provider="$3" + local src="/etc/apt/sources.list" + + local tmp + tmp="$(mktemp "${src}.XXXXXX")" + + if ! sources_file::replace_entry_uri "${type}" "${suite}" "${new_provider}" < "${src}" > "${tmp}"; then + log::error "Failed to process ${src}." + rm -f "${tmp}" + exit 1 + fi + + if ! mv "${tmp}" "${src}"; then + log::error "Failed to update ${src}." + rm -f "${tmp}" + exit 1 + fi +} + +apt::update() { + if ! apt-get update; then + log::error "Failed to run 'apt update'. Please check your sources.list." + exit 1 + fi +} + +main() { + show_environment "$@" + + check_dependencies + + check_environment + + # Parse arguments and assign to variables + read -r type suite no_backup no_update new_provider < <(parse_arguments "$@") + + if [[ "${no_backup}" -eq 0 ]]; then + sources_file::backup + fi + + sources_file::process "${type}" "${suite}" "${new_provider}" + + if [[ "${no_update}" -eq 0 ]]; then + apt::update + fi + + log::success "Successfully switched APT repository mirrors to ${new_provider}." +} + +main "$@" diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..95fab5a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,64 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": true, + "cwd": "${workspaceFolder}" + }, + { + "name": "Python: Debug Tests", + "type": "debugpy", + "request": "launch", + "module": "pytest", + "args": [ + "-v", + "--tb=short" + ], + "console": "integratedTerminal", + "justMyCode": false, + "cwd": "${workspaceFolder}" + }, + { + "name": "Python: Debug Current Test File", + "type": "debugpy", + "request": "launch", + "module": "pytest", + "args": [ + "${file}", + "-v", + "--tb=short" + ], + "console": "integratedTerminal", + "justMyCode": false, + "cwd": "${workspaceFolder}" + }, + { + "name": "Python: Debug Specific Test", + "type": "debugpy", + "request": "launch", + "module": "pytest", + "args": [ + "${file}::${selectedText}", + "-v", + "--tb=short" + ], + "console": "integratedTerminal", + "justMyCode": false, + "cwd": "${workspaceFolder}" + }, + { + "name": "Python: Module", + "type": "debugpy", + "request": "launch", + "module": "thecodecrate_pipeline", + "console": "integratedTerminal", + "justMyCode": true, + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..bcd85bb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,19 @@ +{ + "python.testing.pytestEnabled": true, + "python.testing.unittestEnabled": false, + "python.testing.pytestArgs": [ + "tests" + ], + "python.analysis.typeCheckingMode": "strict", + "python.analysis.autoImportCompletions": true, + "python.languageServer": "Pylance", + "[python]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.codeActionsOnSave": { + "source.fixAll": "explicit", + "source.organizeImports": "explicit" + } + }, + "python.terminal.activateEnvironment": false +} diff --git a/jupyter/01-playground.ipynb b/jupyter/01-playground.ipynb index 5f8a9c4..8b99906 100644 --- a/jupyter/01-playground.ipynb +++ b/jupyter/01-playground.ipynb @@ -187,15 +187,10 @@ "## of the processing queue\n", "###\n", "from abc import abstractmethod\n", - "from typing import Awaitable, Callable, Concatenate, cast\n", + "from typing import Any, Awaitable, Callable, Concatenate, cast\n", "\n", - "from thecodecrate_pipeline import (\n", - " Processor,\n", - " Stage,\n", - " T_in,\n", - " T_out,\n", - " StageInstanceCollection,\n", - ")\n", + "from thecodecrate_pipeline import Processor, Stage\n", + "from thecodecrate_pipeline.types import T_in, T_out, StageDefinitionCollection\n", "\n", "\n", "class IndexedStage(Stage[T_in, T_out]):\n", @@ -220,24 +215,26 @@ " async def process(\n", " self,\n", " payload: T_in,\n", - " stages: StageInstanceCollection,\n", + " stages: StageDefinitionCollection,\n", " ) -> T_out:\n", " index = 0\n", "\n", + " payload_out: Any = payload\n", + "\n", " for stage in stages:\n", - " payload = await self._call(\n", + " payload_out = await self._call(\n", " callable=stage,\n", - " payload=payload,\n", + " payload=payload_out,\n", " index=index,\n", " )\n", "\n", " index += 1\n", "\n", - " return cast(T_out, payload)\n", + " return cast(T_out, payload_out)\n", "\n", "\n", "class IndexedPipeline(Pipeline[T_in, T_out]):\n", - " processor_class = IndexedProcessor\n", + " processor = IndexedProcessor\n", "\n", "\n", "###\n", @@ -263,7 +260,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -272,17 +269,17 @@ "12" ] }, - "execution_count": 7, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "from thecodecrate_pipeline import InterruptiblePipeline\n", + "from thecodecrate_pipeline.processors import InterruptiblePipeline\n", "\n", "\n", "def continues_when_less_than_ten(payload: int) -> bool:\n", - " return payload < 10\n", + " return payload > 10\n", "\n", "\n", "pipeline = (\n", @@ -301,7 +298,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "thecodecrate-pipeline", "language": "python", "name": "python3" }, @@ -315,7 +312,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.2" + "version": "3.13.8" } }, "nbformat": 4, diff --git a/project.code-workspace b/project.code-workspace new file mode 100644 index 0000000..c097e67 --- /dev/null +++ b/project.code-workspace @@ -0,0 +1,20 @@ +{ + "folders": [ + { + "name": "jupyter", + "path": "jupyter" + }, + { + "name": "src", + "path": "src" + }, + { + "name": "python-pipeline", + "path": "." + } + ], + "settings": { + "python.terminal.activateEnvironment": false, + "python.analysis.typeCheckingMode": "strict" + } +} diff --git a/pyproject.toml b/pyproject.toml index 7f3fa34..a11437a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,20 +24,20 @@ documentation = "https://thecodecrate.github.io/python-pipeline/" [dependency-groups] dev = [ - "pytest-asyncio>=0.24.0", - "pytest>=8.3.4", - "pytest-cov>=6.0.0", - "bumpver>=2024.1130", - "ruff>=0.8.2", - "ipykernel>=6.29.5", - "debugpy>=1.8.9", - "mkdocstrings[python]>=0.27.0", - "mkdocs-material>=9.5.48", + "black>=25.9.0", + "bumpver>=2025.1131", + "debugpy>=1.8.17", + "ipykernel>=6.30.1", + "mkdocs-autorefs>=1.4.3", "mkdocs-gen-files>=0.5.0", - "mkdocs-autorefs>=1.2.0", - "mkdocs-git-revision-date-localized-plugin>=1.3.0", + "mkdocs-git-revision-date-localized-plugin>=1.4.7", + "mkdocs-material>=9.6.21", "mkdocs-minify-plugin>=0.8.0", - "black>=24.10.0", + "mkdocstrings-python>=1.18.2", + "pytest>=8.4.2", + "pytest-asyncio>=1.2.0", + "pytest-cov>=7.0.0", + "ruff>=0.14.0", ] [build-system] diff --git a/src/_api/__init__.py b/src/_api/__init__.py deleted file mode 100644 index 821ab8b..0000000 --- a/src/_api/__init__.py +++ /dev/null @@ -1,35 +0,0 @@ -# Version of the package -# DO NOT MODIFY MANUALLY -# This will be updated by `bumpver` command. -# - Make sure to commit all changes first before running `bumpver`. -# - Run `bumpver update --[minor|major|patch]` -__version__ = "1.23.0" - -# Re-exporting symbols -from .core import Pipeline as Pipeline -from .core import PipelineFactory as PipelineFactory -from .core import PipelineFactoryInterface as PipelineFactoryInterface -from .core import PipelineInterface as PipelineInterface -from .core import Processor as Processor -from .core import ProcessorInterface as ProcessorInterface -from .core import Stage as Stage -from .core import StageCallable as StageCallable -from .core import StageClassOrInstance as StageClassOrInstance -from .core import StageCollection as StageCollection -from .core import StageInstance as StageInstance -from .core import StageInstanceCollection as StageInstanceCollection -from .core import StageInterface as StageInterface -from .core import T_in as T_in -from .core import T_out as T_out -from .core import __all__ as _core_all -from .processors import ChainedPipeline as ChainedPipeline -from .processors import ChainedProcessor as ChainedProcessor -from .processors import InterruptiblePipeline as InterruptiblePipeline -from .processors import InterruptibleProcessor as InterruptibleProcessor -from .processors import __all__ as _processor_all - -# pyright: reportUnsupportedDunderAll=false -__all__ = ( - *_core_all, - *_processor_all, -) diff --git a/src/_api/core/__init__.py b/src/_api/core/__init__.py deleted file mode 100644 index 2500dec..0000000 --- a/src/_api/core/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# Re-exporting symbols -from .final import ChainedProcessor as ChainedProcessor -from .final import Pipeline as Pipeline -from .final import PipelineFactory as PipelineFactory -from .final import PipelineFactoryInterface as PipelineFactoryInterface -from .final import PipelineInterface as PipelineInterface -from .final import Processor as Processor -from .final import ProcessorInterface as ProcessorInterface -from .final import Stage as Stage -from .final import StageCallable as StageCallable -from .final import StageClassOrInstance as StageClassOrInstance -from .final import StageCollection as StageCollection -from .final import StageInstance as StageInstance -from .final import StageInstanceCollection as StageInstanceCollection -from .final import StageInterface as StageInterface -from .final import T_in as T_in -from .final import T_out as T_out -from .final import __all__ as _final_all - -# pyright: reportUnsupportedDunderAll=false -__all__ = (*_final_all,) diff --git a/src/_api/core/_app.toml b/src/_api/core/_app.toml deleted file mode 100644 index b19ce4b..0000000 --- a/src/_api/core/_app.toml +++ /dev/null @@ -1,11 +0,0 @@ -name = "core" -plugins = [ - "_01_with_base", - "_02_with_pipeline_as_list", - "_03_with_stage_as_callable", - "_04_with_pipeline_declared_stages", - "_05_with_pipeline_factory", - "_06_with_pipeline_processor", - "_08_with_pipeline_as_stage", - "_99_with_pipeline_default_processor", -] diff --git a/src/_api/core/final/pipeline.py b/src/_api/core/final/pipeline.py deleted file mode 100644 index b51adc7..0000000 --- a/src/_api/core/final/pipeline.py +++ /dev/null @@ -1,42 +0,0 @@ -from typing import Generic - -# extends: outside base -from ..plugins._01_with_base import Pipeline as PipelineBase - -# extends: outside mixins -from ..plugins._02_with_pipeline_as_list import ( - PipelineMixin as _02_WithPipelineAsList, -) -from ..plugins._04_with_pipeline_declared_stages import ( - PipelineMixin as _04_WithPipelineDeclaredStages, -) -from ..plugins._06_with_pipeline_processor import ( - PipelineMixin as _06_WithPipelineProcessor, -) -from ..plugins._08_with_pipeline_as_stage import ( - PipelineMixin as _08_WithPipelineAsStage, -) -from ..plugins._99_with_pipeline_default_processor import ( - PipelineMixin as _99_WithPipelineDefaultProcessor, -) - -# implements: self-interface -from .pipeline_interface import PipelineInterface as ImplementsInterface - -# uses: bridge interface -from .types import T_in, T_out - - -class Pipeline( - _99_WithPipelineDefaultProcessor[T_in, T_out], - _08_WithPipelineAsStage[T_in, T_out], - _06_WithPipelineProcessor[T_in, T_out], - _04_WithPipelineDeclaredStages, - _02_WithPipelineAsList, - PipelineBase, - ImplementsInterface[T_in, T_out], - Generic[T_in, T_out], -): - """Pipeline Class""" - - pass diff --git a/src/_api/core/final/pipeline_factory.py b/src/_api/core/final/pipeline_factory.py deleted file mode 100644 index 2a48718..0000000 --- a/src/_api/core/final/pipeline_factory.py +++ /dev/null @@ -1,29 +0,0 @@ -from typing import Generic - -# extends: outside base -from ..plugins._05_with_pipeline_factory import PipelineFactory as PipelineFactoryBase - -# extends: outside mixins -from ..plugins._06_with_pipeline_processor import ( - PipelineFactoryMixin as _06_WithPipelineProcessor, -) -from ..plugins._99_with_pipeline_default_processor import ( - PipelineFactoryMixin as _99_WithPipelineDefaultProcessor, -) - -# implements: self-interface -from .pipeline_factory_interface import PipelineFactoryInterface as ImplementsInterface - -# uses: bridge interface -from .pipeline_interface import PipelineInterface -from .types import T_in, T_out - - -class PipelineFactory( - _99_WithPipelineDefaultProcessor[T_in, T_out], - _06_WithPipelineProcessor[T_in, T_out], - PipelineFactoryBase[PipelineInterface[T_in, T_out]], - ImplementsInterface[T_in, T_out], - Generic[T_in, T_out], -): - pass diff --git a/src/_api/core/final/pipeline_factory_interface.py b/src/_api/core/final/pipeline_factory_interface.py deleted file mode 100644 index 39a0b8e..0000000 --- a/src/_api/core/final/pipeline_factory_interface.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..plugins._05_with_pipeline_factory import ( - PipelineFactoryInterface as PipelineFactoryBaseInterface, -) - -# extends: outside mixins -from ..plugins._06_with_pipeline_processor import ( - PipelineFactoryInterfaceMixin as _06_WithPipelineProcessorInterface, -) -from ..plugins._99_with_pipeline_default_processor import ( - PipelineFactoryInterfaceMixin as _99_WithPipelineDefaultProcessorInterface, -) - -# uses: bridge interface -from .pipeline_interface import PipelineInterface -from .types import T_in, T_out - - -class PipelineFactoryInterface( - _99_WithPipelineDefaultProcessorInterface[T_in, T_out], - _06_WithPipelineProcessorInterface[T_in, T_out], - PipelineFactoryBaseInterface[PipelineInterface[T_in, T_out]], - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/final/pipeline_interface.py b/src/_api/core/final/pipeline_interface.py deleted file mode 100644 index c96f1ea..0000000 --- a/src/_api/core/final/pipeline_interface.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Protocol, TypeVar - -# extends: outside base -from ..plugins._01_with_base import PipelineInterface as PipelineBaseInterface - -# extends: outside mixins -from ..plugins._02_with_pipeline_as_list import ( - PipelineInterfaceMixin as _02_WithPipelineAsListInterface, -) -from ..plugins._04_with_pipeline_declared_stages import ( - PipelineInterfaceMixin as _04_WithPipelineDeclaredStagesInterface, -) -from ..plugins._06_with_pipeline_processor import ( - PipelineInterfaceMixin as _06_WithPipelineProcessorInterface, -) -from ..plugins._08_with_pipeline_as_stage import ( - PipelineInterfaceMixin as _08_WithPipelineAsStageInterface, -) -from ..plugins._99_with_pipeline_default_processor import ( - PipelineInterfaceMixin as _99_WithPipelineDefaultProcessorInterface, -) - -# uses: bridge interface -from .types import T_in, T_out - - -class PipelineInterface( - _99_WithPipelineDefaultProcessorInterface[T_in, T_out], - _08_WithPipelineAsStageInterface[T_in, T_out], - _06_WithPipelineProcessorInterface[T_in, T_out], - _04_WithPipelineDeclaredStagesInterface, - _02_WithPipelineAsListInterface, - PipelineBaseInterface, - Protocol[T_in, T_out], -): - pass - - -TPipeline = TypeVar("TPipeline", bound=PipelineInterface, infer_variance=True) diff --git a/src/_api/core/final/processor.py b/src/_api/core/final/processor.py deleted file mode 100644 index 1222781..0000000 --- a/src/_api/core/final/processor.py +++ /dev/null @@ -1,20 +0,0 @@ -from abc import ABC - -# extends: outside base -from ..plugins._06_with_pipeline_processor import Processor as ProcessorBase - -# implements: self-interface -from .processor_interface import ProcessorInterface as ImplementsInterface - -# uses: bridge interface -from .types import T_in, T_out - - -class Processor( - ProcessorBase[T_in, T_out], - ImplementsInterface[T_in, T_out], - ABC, -): - """Processor Class""" - - pass diff --git a/src/_api/core/final/processor_interface.py b/src/_api/core/final/processor_interface.py deleted file mode 100644 index e22976c..0000000 --- a/src/_api/core/final/processor_interface.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..plugins._06_with_pipeline_processor import ( - ProcessorInterface as ProcessorBaseInterface, -) - -# uses: bridge interface -from .types import T_in, T_out - - -class ProcessorInterface( - ProcessorBaseInterface[T_in, T_out], - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/final/processors/chained_processor.py b/src/_api/core/final/processors/chained_processor.py deleted file mode 100644 index 84e19f7..0000000 --- a/src/_api/core/final/processors/chained_processor.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import Generic - -# extends: outside base -from ...plugins._99_with_pipeline_default_processor import ( - ChainedProcessor as ChainedProcessorBase, -) - -# uses: bridge interface -from ..types import T_in, T_out - - -class ChainedProcessor( - ChainedProcessorBase[T_in, T_out], - Generic[T_in, T_out], -): - pass diff --git a/src/_api/core/final/processors/chained_processor_interface.py b/src/_api/core/final/processors/chained_processor_interface.py deleted file mode 100644 index 095bf2c..0000000 --- a/src/_api/core/final/processors/chained_processor_interface.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ...plugins._99_with_pipeline_default_processor import ( - ChainedProcessorInterface as ChainedProcessorBaseInterface, -) - -# uses: final interface -from ..types import T_in, T_out - - -class ChainedProcessorInterface( - ChainedProcessorBaseInterface[T_in, T_out], - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/final/stage.py b/src/_api/core/final/stage.py deleted file mode 100644 index 9050987..0000000 --- a/src/_api/core/final/stage.py +++ /dev/null @@ -1,21 +0,0 @@ -# extends: outside base -from ..plugins._01_with_base import Stage as StageBase - -# extends: outside mixins -from ..plugins._03_with_stage_as_callable import ( - StageMixin as _03_WithStageAsCallable, -) - -# implements: self-interface -from .stage_interface import StageInterface as ImplementsInterface - -# uses: bridge -from .types import T_in, T_out - - -class Stage( - _03_WithStageAsCallable[T_in, T_out], - StageBase, - ImplementsInterface[T_in, T_out], -): - pass diff --git a/src/_api/core/final/stage_callable.py b/src/_api/core/final/stage_callable.py deleted file mode 100644 index 2f623ae..0000000 --- a/src/_api/core/final/stage_callable.py +++ /dev/null @@ -1,29 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..plugins._01_with_base import StageCallable as StageCallableBase -from ..plugins._01_with_base import ( - StageClassOrInstance, - StageCollection, - StageInstance, - StageInstanceCollection, -) - -# uses: bridge interface -from .types import T_in, T_out - - -class StageCallable( - StageCallableBase[T_in, T_out], - Protocol[T_in, T_out], -): - pass - - -__all__ = ( - "StageCallable", - "StageInstance", - "StageInstanceCollection", - "StageClassOrInstance", - "StageCollection", -) diff --git a/src/_api/core/final/stage_interface.py b/src/_api/core/final/stage_interface.py deleted file mode 100644 index e45e142..0000000 --- a/src/_api/core/final/stage_interface.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..plugins._01_with_base import StageInterface as StageBaseInterface - -# extends: outside mixins -from ..plugins._03_with_stage_as_callable import ( - StageInterfaceMixin as _03_WithStageAsCallableInterface, -) - -# uses: bridge interface -from .types import T_in, T_out - - -class StageInterface( - _03_WithStageAsCallableInterface[T_in, T_out], - StageBaseInterface, - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/final/types.py b/src/_api/core/final/types.py deleted file mode 100644 index 405bde4..0000000 --- a/src/_api/core/final/types.py +++ /dev/null @@ -1,7 +0,0 @@ -# extends: outside base -from ..plugins._01_with_base import T_in, T_out - -__all__ = ( - "T_in", - "T_out", -) diff --git a/src/_api/core/plugins/_01_with_base/__init__.py b/src/_api/core/plugins/_01_with_base/__init__.py deleted file mode 100644 index 0ef40d6..0000000 --- a/src/_api/core/plugins/_01_with_base/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -from .bases.pipeline import Pipeline -from .bases.pipeline_interface import PipelineInterface, TPipeline -from .bases.stage import Stage -from .bases.stage_callable import ( - StageCallable, - StageClassOrInstance, - StageCollection, - StageInstance, - StageInstanceCollection, -) -from .bases.stage_interface import StageInterface -from .bases.types import T_in, T_out - -__all__ = ( - "Pipeline", - "PipelineInterface", - "Stage", - "StageInterface", - "StageCallable", - "StageClassOrInstance", - "StageCollection", - "StageInstance", - "StageInstanceCollection", - "T_in", - "T_out", - "TPipeline", -) diff --git a/src/_api/core/plugins/_01_with_base/_plugin.toml b/src/_api/core/plugins/_01_with_base/_plugin.toml deleted file mode 100644 index ec7174e..0000000 --- a/src/_api/core/plugins/_01_with_base/_plugin.toml +++ /dev/null @@ -1,2 +0,0 @@ -name = "_01_with_base" -dependencies = [] diff --git a/src/_api/core/plugins/_01_with_base/bases/pipeline.py b/src/_api/core/plugins/_01_with_base/bases/pipeline.py deleted file mode 100644 index e86eff9..0000000 --- a/src/_api/core/plugins/_01_with_base/bases/pipeline.py +++ /dev/null @@ -1,15 +0,0 @@ -from typing import Any - -# extends: 3rd-party concrete -from ....support.clonable import Clonable - -# implements: self-interface -from .pipeline_interface import PipelineInterface as ImplementsInterface - - -class Pipeline( - Clonable, - ImplementsInterface, -): - def __init__(self, *args: Any, **kwds: Any) -> None: - pass diff --git a/src/_api/core/plugins/_01_with_base/bases/pipeline_interface.py b/src/_api/core/plugins/_01_with_base/bases/pipeline_interface.py deleted file mode 100644 index 702057b..0000000 --- a/src/_api/core/plugins/_01_with_base/bases/pipeline_interface.py +++ /dev/null @@ -1,14 +0,0 @@ -from typing import Any, Protocol, TypeVar - -# extend: 3rd-party interface -from ....support.clonable import ClonableInterface - - -class PipelineInterface( - ClonableInterface, - Protocol, -): - def __init__(self, *args: Any, **kwds: Any) -> None: ... - - -TPipeline = TypeVar("TPipeline", bound=PipelineInterface, infer_variance=True) diff --git a/src/_api/core/plugins/_01_with_base/bases/stage.py b/src/_api/core/plugins/_01_with_base/bases/stage.py deleted file mode 100644 index 5fc63b4..0000000 --- a/src/_api/core/plugins/_01_with_base/bases/stage.py +++ /dev/null @@ -1,8 +0,0 @@ -# implements: self-interface -from .stage_interface import StageInterface as ImplementsInterface - - -class Stage( - ImplementsInterface, -): - pass diff --git a/src/_api/core/plugins/_01_with_base/bases/stage_callable.py b/src/_api/core/plugins/_01_with_base/bases/stage_callable.py deleted file mode 100644 index 1951e87..0000000 --- a/src/_api/core/plugins/_01_with_base/bases/stage_callable.py +++ /dev/null @@ -1,30 +0,0 @@ -from typing import Any, Awaitable, Protocol - -from .types import T_in, T_out - - -class StageCallable( - Protocol[T_in, T_out], -): - """Callable object used in the pipeline""" - - def __call__( - self, - payload: T_in, - /, # Make 'payload' a positional-only parameter - *args: Any, - **kwds: Any, - ) -> T_out | Awaitable[T_out]: ... - - -StageInstance = StageCallable -"""Stage object""" - -StageInstanceCollection = tuple[StageInstance, ...] -"""Collection of Stage objects""" - -StageClassOrInstance = StageInstance | type[StageInstance] -"""Stage class or object""" - -StageCollection = tuple[StageClassOrInstance, ...] -"""Collection of Stage classes or objects""" diff --git a/src/_api/core/plugins/_01_with_base/bases/stage_interface.py b/src/_api/core/plugins/_01_with_base/bases/stage_interface.py deleted file mode 100644 index 89afb39..0000000 --- a/src/_api/core/plugins/_01_with_base/bases/stage_interface.py +++ /dev/null @@ -1,7 +0,0 @@ -from typing import Protocol - - -class StageInterface( - Protocol, -): - pass diff --git a/src/_api/core/plugins/_02_with_pipeline_as_list/__init__.py b/src/_api/core/plugins/_02_with_pipeline_as_list/__init__.py deleted file mode 100644 index c86d4eb..0000000 --- a/src/_api/core/plugins/_02_with_pipeline_as_list/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .mixins.pipeline_interface_mixin import PipelineInterfaceMixin -from .mixins.pipeline_mixin import PipelineMixin - -__all__ = ( - "PipelineMixin", - "PipelineInterfaceMixin", -) diff --git a/src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/pipeline_interface.py b/src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/pipeline_interface.py deleted file mode 100644 index f61f075..0000000 --- a/src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/pipeline_interface.py +++ /dev/null @@ -1,14 +0,0 @@ -from typing import Protocol, TypeVar - -# extends: outside base -from ..._01_with_base import PipelineInterface as PipelineBaseInterface - - -class PipelineInterface( - PipelineBaseInterface, - Protocol, -): - pass - - -TPipeline = TypeVar("TPipeline", bound=PipelineInterface, infer_variance=True) diff --git a/src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/stage_callable.py b/src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/stage_callable.py deleted file mode 100644 index 425be68..0000000 --- a/src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/stage_callable.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..._01_with_base import StageCallable as StageCallableBase - -# uses: local bridge -from .types import T_in, T_out - - -class StageCallable( - StageCallableBase[T_in, T_out], - Protocol[T_in, T_out], -): - pass - - -StageInstance = StageCallable - -StageInstanceCollection = tuple[StageInstance, ...] - -StageClassOrInstance = StageInstance | type[StageInstance] - -StageCollection = tuple[StageClassOrInstance, ...] diff --git a/src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/types.py b/src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/types.py deleted file mode 100644 index 8205cc8..0000000 --- a/src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/types.py +++ /dev/null @@ -1,7 +0,0 @@ -# extends: outside base -from ..._01_with_base import T_in, T_out - -__all__ = ( - "T_in", - "T_out", -) diff --git a/src/_api/core/plugins/_02_with_pipeline_as_list/_plugin.toml b/src/_api/core/plugins/_02_with_pipeline_as_list/_plugin.toml deleted file mode 100644 index 6c0709e..0000000 --- a/src/_api/core/plugins/_02_with_pipeline_as_list/_plugin.toml +++ /dev/null @@ -1,2 +0,0 @@ -name = "_02_with_pipeline_as_list" -dependencies = ["_01_with_base"] diff --git a/src/_api/core/plugins/_02_with_pipeline_as_list/mixins/__init__.py b/src/_api/core/plugins/_02_with_pipeline_as_list/mixins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_02_with_pipeline_as_list/mixins/pipeline_interface_mixin.py b/src/_api/core/plugins/_02_with_pipeline_as_list/mixins/pipeline_interface_mixin.py deleted file mode 100644 index 0626abd..0000000 --- a/src/_api/core/plugins/_02_with_pipeline_as_list/mixins/pipeline_interface_mixin.py +++ /dev/null @@ -1,28 +0,0 @@ -from typing import Any, Optional, Protocol, Self - -# extends: 3rd-party interface -from ....support.act_as_list import ActAsListInterface - -# extends: self-bridge -from .._bridges.pipeline_interface import PipelineInterface - -# uses: bridge interface -from .._bridges.stage_callable import ( - StageInstance, - StageInstanceCollection, -) - - -class PipelineInterfaceMixin( - ActAsListInterface[StageInstance, StageInstanceCollection], - PipelineInterface, - Protocol, -): - def __init__( - self, - stage_instances: Optional[StageInstanceCollection] = None, - *args: Any, - **kwds: Any, - ) -> None: ... - - def pipe(self, stage: StageInstance) -> Self: ... diff --git a/src/_api/core/plugins/_02_with_pipeline_as_list/mixins/pipeline_mixin.py b/src/_api/core/plugins/_02_with_pipeline_as_list/mixins/pipeline_mixin.py deleted file mode 100644 index e37e751..0000000 --- a/src/_api/core/plugins/_02_with_pipeline_as_list/mixins/pipeline_mixin.py +++ /dev/null @@ -1,50 +0,0 @@ -from abc import ABC -from typing import Any, Optional, Self - -# extends: 3rd-party concrete -from ....support.act_as_list import ActAsList - -# uses: bridge interfaces -from .._bridges.stage_callable import StageInstance, StageInstanceCollection - -# implements: self-interface -from .pipeline_interface_mixin import PipelineInterfaceMixin as ImplementsInterface - - -class PipelineMixin( - ActAsList[StageInstance, StageInstanceCollection], - ImplementsInterface, - ABC, -): - stage_instances: StageInstanceCollection - - def __init__( - self, - stage_instances: Optional[StageInstanceCollection] = None, - *args: Any, - **kwds: Any, - ) -> None: - super().__init__(*args, **kwds) # type: ignore - - if not hasattr(self, "stage_instances"): - self.stage_instances = tuple() - - if stage_instances: - self.stage_instances = stage_instances - - def _get_items(self) -> StageInstanceCollection: - return self.stage_instances - - def _set_items(self, items: StageInstanceCollection) -> Self: - self.stage_instances = items - - return self - - def _add_item(self, item: StageInstance) -> Self: - return self.clone({"stage_instances": tuple([*self.stage_instances, item])}) - - def pipe(self, stage: StageInstance) -> Self: - """ - Adds a single stage to the pipeline. - """ - return self._add_item(stage) diff --git a/src/_api/core/plugins/_03_with_stage_as_callable/__init__.py b/src/_api/core/plugins/_03_with_stage_as_callable/__init__.py deleted file mode 100644 index 3d8e34d..0000000 --- a/src/_api/core/plugins/_03_with_stage_as_callable/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .mixins.stage_interface_mixin import StageInterfaceMixin -from .mixins.stage_mixin import StageMixin - -__all__ = ( - "StageMixin", - "StageInterfaceMixin", -) diff --git a/src/_api/core/plugins/_03_with_stage_as_callable/_bridges/__init__.py b/src/_api/core/plugins/_03_with_stage_as_callable/_bridges/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_03_with_stage_as_callable/_bridges/stage_interface.py b/src/_api/core/plugins/_03_with_stage_as_callable/_bridges/stage_interface.py deleted file mode 100644 index cdb2282..0000000 --- a/src/_api/core/plugins/_03_with_stage_as_callable/_bridges/stage_interface.py +++ /dev/null @@ -1,11 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..._01_with_base import StageInterface as StageBaseInterface - - -class StageInterface( - StageBaseInterface, - Protocol, -): - pass diff --git a/src/_api/core/plugins/_03_with_stage_as_callable/_bridges/types.py b/src/_api/core/plugins/_03_with_stage_as_callable/_bridges/types.py deleted file mode 100644 index 8205cc8..0000000 --- a/src/_api/core/plugins/_03_with_stage_as_callable/_bridges/types.py +++ /dev/null @@ -1,7 +0,0 @@ -# extends: outside base -from ..._01_with_base import T_in, T_out - -__all__ = ( - "T_in", - "T_out", -) diff --git a/src/_api/core/plugins/_03_with_stage_as_callable/_plugin.toml b/src/_api/core/plugins/_03_with_stage_as_callable/_plugin.toml deleted file mode 100644 index d54c3b2..0000000 --- a/src/_api/core/plugins/_03_with_stage_as_callable/_plugin.toml +++ /dev/null @@ -1,2 +0,0 @@ -name = "_03_with_stage_as_callable" -dependencies = ["_01_with_base"] diff --git a/src/_api/core/plugins/_03_with_stage_as_callable/mixins/__init__.py b/src/_api/core/plugins/_03_with_stage_as_callable/mixins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_04_with_pipeline_declared_stages/__init__.py b/src/_api/core/plugins/_04_with_pipeline_declared_stages/__init__.py deleted file mode 100644 index c86d4eb..0000000 --- a/src/_api/core/plugins/_04_with_pipeline_declared_stages/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .mixins.pipeline_interface_mixin import PipelineInterfaceMixin -from .mixins.pipeline_mixin import PipelineMixin - -__all__ = ( - "PipelineMixin", - "PipelineInterfaceMixin", -) diff --git a/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/__init__.py b/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/pipeline_interface.py b/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/pipeline_interface.py deleted file mode 100644 index 0b1527c..0000000 --- a/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/pipeline_interface.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Protocol, TypeVar - -# extends: outside base -from ..._01_with_base import PipelineInterface as PipelineBaseInterface - -# extends: outside mixins -from ..._02_with_pipeline_as_list import ( - PipelineInterfaceMixin as _02_WithPipelineAsListInterface, -) - - -class PipelineInterface( - _02_WithPipelineAsListInterface, - PipelineBaseInterface, - Protocol, -): - pass - - -TPipeline = TypeVar("TPipeline", bound=PipelineInterface, infer_variance=True) diff --git a/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/stage_callable.py b/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/stage_callable.py deleted file mode 100644 index 425be68..0000000 --- a/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/stage_callable.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..._01_with_base import StageCallable as StageCallableBase - -# uses: local bridge -from .types import T_in, T_out - - -class StageCallable( - StageCallableBase[T_in, T_out], - Protocol[T_in, T_out], -): - pass - - -StageInstance = StageCallable - -StageInstanceCollection = tuple[StageInstance, ...] - -StageClassOrInstance = StageInstance | type[StageInstance] - -StageCollection = tuple[StageClassOrInstance, ...] diff --git a/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/types.py b/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/types.py deleted file mode 100644 index 605f696..0000000 --- a/src/_api/core/plugins/_04_with_pipeline_declared_stages/_bridges/types.py +++ /dev/null @@ -1,7 +0,0 @@ -# extends: outside base interface -from ..._01_with_base import T_in, T_out - -__all__ = ( - "T_in", - "T_out", -) diff --git a/src/_api/core/plugins/_04_with_pipeline_declared_stages/_plugin.toml b/src/_api/core/plugins/_04_with_pipeline_declared_stages/_plugin.toml deleted file mode 100644 index f162c24..0000000 --- a/src/_api/core/plugins/_04_with_pipeline_declared_stages/_plugin.toml +++ /dev/null @@ -1,2 +0,0 @@ -name = "_04_with_pipeline_declared_stages" -dependencies = ["_01_with_base", "_02_with_pipeline_as_list"] diff --git a/src/_api/core/plugins/_04_with_pipeline_declared_stages/mixins/__init__.py b/src/_api/core/plugins/_04_with_pipeline_declared_stages/mixins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_04_with_pipeline_declared_stages/mixins/pipeline_interface_mixin.py b/src/_api/core/plugins/_04_with_pipeline_declared_stages/mixins/pipeline_interface_mixin.py deleted file mode 100644 index fbd1957..0000000 --- a/src/_api/core/plugins/_04_with_pipeline_declared_stages/mixins/pipeline_interface_mixin.py +++ /dev/null @@ -1,25 +0,0 @@ -from typing import Any, Optional, Protocol, Self - -# extends: self-bridge -from .._bridges.pipeline_interface import PipelineInterface - -# uses: bridge interface -from .._bridges.stage_callable import StageCollection - - -class PipelineInterfaceMixin( - PipelineInterface, - Protocol, -): - def __init__( - self, - stages: Optional[StageCollection] = None, - *args: Any, - **kwds: Any, - ) -> None: ... - - def _should_instantiate_stages(self) -> bool: ... - - def _instantiate_stages(self) -> Self: ... - - def with_stages(self, stages: StageCollection) -> Self: ... diff --git a/src/_api/core/plugins/_04_with_pipeline_declared_stages/mixins/pipeline_mixin.py b/src/_api/core/plugins/_04_with_pipeline_declared_stages/mixins/pipeline_mixin.py deleted file mode 100644 index 9569de3..0000000 --- a/src/_api/core/plugins/_04_with_pipeline_declared_stages/mixins/pipeline_mixin.py +++ /dev/null @@ -1,50 +0,0 @@ -from abc import ABC -from typing import Any, Optional, Self - -# uses: bridge interface -from .._bridges.stage_callable import StageCollection - -# implements: self-interface -from .pipeline_interface_mixin import PipelineInterfaceMixin as ImplementsInterface - - -class PipelineMixin( - ImplementsInterface, - ABC, -): - stages: StageCollection - - def __init__( - self, - stages: Optional[StageCollection] = None, - *args: Any, - **kwds: Any, - ) -> None: - super().__init__(*args, **kwds) # type: ignore - - if not hasattr(self, "stages"): - self.stages = tuple() - - if stages: - self.stages = stages - - if self._should_instantiate_stages(): - self._instantiate_stages() - - def _should_instantiate_stages(self) -> bool: - return len(self._get_items()) == 0 and len(self.stages) > 0 - - def _instantiate_stages(self) -> Self: - instances = tuple( - stage() if isinstance(stage, type) else stage for stage in self.stages - ) - - return self._set_items(instances) - - def with_stages(self, stages: StageCollection) -> Self: - """ - Adds a collection of stages to the pipeline. - """ - cloned = self.clone({"stages": stages, "stage_instances": []}) - - return cloned._instantiate_stages() diff --git a/src/_api/core/plugins/_05_with_pipeline_factory/__init__.py b/src/_api/core/plugins/_05_with_pipeline_factory/__init__.py deleted file mode 100644 index 364687b..0000000 --- a/src/_api/core/plugins/_05_with_pipeline_factory/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .bases.pipeline_factory import PipelineFactory -from .bases.pipeline_factory_interface import PipelineFactoryInterface - -__all__ = ( - "PipelineFactory", - "PipelineFactoryInterface", -) diff --git a/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/__init__.py b/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/pipeline_interface.py b/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/pipeline_interface.py deleted file mode 100644 index f61f075..0000000 --- a/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/pipeline_interface.py +++ /dev/null @@ -1,14 +0,0 @@ -from typing import Protocol, TypeVar - -# extends: outside base -from ..._01_with_base import PipelineInterface as PipelineBaseInterface - - -class PipelineInterface( - PipelineBaseInterface, - Protocol, -): - pass - - -TPipeline = TypeVar("TPipeline", bound=PipelineInterface, infer_variance=True) diff --git a/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/stage_callable.py b/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/stage_callable.py deleted file mode 100644 index 425be68..0000000 --- a/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/stage_callable.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..._01_with_base import StageCallable as StageCallableBase - -# uses: local bridge -from .types import T_in, T_out - - -class StageCallable( - StageCallableBase[T_in, T_out], - Protocol[T_in, T_out], -): - pass - - -StageInstance = StageCallable - -StageInstanceCollection = tuple[StageInstance, ...] - -StageClassOrInstance = StageInstance | type[StageInstance] - -StageCollection = tuple[StageClassOrInstance, ...] diff --git a/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/types.py b/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/types.py deleted file mode 100644 index 605f696..0000000 --- a/src/_api/core/plugins/_05_with_pipeline_factory/_bridges/types.py +++ /dev/null @@ -1,7 +0,0 @@ -# extends: outside base interface -from ..._01_with_base import T_in, T_out - -__all__ = ( - "T_in", - "T_out", -) diff --git a/src/_api/core/plugins/_05_with_pipeline_factory/_plugin.toml b/src/_api/core/plugins/_05_with_pipeline_factory/_plugin.toml deleted file mode 100644 index eb3997c..0000000 --- a/src/_api/core/plugins/_05_with_pipeline_factory/_plugin.toml +++ /dev/null @@ -1,2 +0,0 @@ -name = "_05_with_pipeline_factory" -dependencies = ["_01_with_base"] diff --git a/src/_api/core/plugins/_05_with_pipeline_factory/bases/__init__.py b/src/_api/core/plugins/_05_with_pipeline_factory/bases/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_05_with_pipeline_factory/bases/pipeline_factory.py b/src/_api/core/plugins/_05_with_pipeline_factory/bases/pipeline_factory.py deleted file mode 100644 index 51ae2b4..0000000 --- a/src/_api/core/plugins/_05_with_pipeline_factory/bases/pipeline_factory.py +++ /dev/null @@ -1,82 +0,0 @@ -from typing import Any, Optional, Self - -# extends: 3rd-party concrete -from ....support.act_as_factory import ActAsFactory -from ....support.act_as_list import ActAsList -from .._bridges.pipeline_interface import TPipeline - -# uses: bridge interfaces -from .._bridges.stage_callable import StageClassOrInstance, StageCollection - -# implements: self-interface -from .pipeline_factory_interface import PipelineFactoryInterface as ImplementsInterface - - -class PipelineFactory( - ActAsFactory[TPipeline], - ActAsList[StageClassOrInstance, StageCollection], - ImplementsInterface[TPipeline], -): - stages: StageCollection # ActAsList - pipeline_class: Optional[type[TPipeline]] - - def __init__( - self, - stages: Optional[StageCollection] = None, - pipeline_class: Optional[type[TPipeline]] = None, - *args: Any, - **kwds: Any, - ) -> None: - if not hasattr(self, "stages"): - self.stages = tuple() - - if not hasattr(self, "pipeline_class"): - self.pipeline_class = self._get_default_pipeline_class() - - if stages: - self.stages = stages - - if pipeline_class: - self.pipeline_class = pipeline_class - - # ActAsList - def _get_items(self) -> StageCollection: - return self.stages - - # ActAsList - def _set_items(self, items: StageCollection) -> Self: - self.stages = items - - return self - - # ActAsList - def _add_item(self, item: StageClassOrInstance) -> Self: - return self._set_items(self.stages + (item,)) - - # ActAsFactory - def _get_target_class(self) -> type[TPipeline]: - if self.pipeline_class is None: - raise ValueError("Pipeline class not set in factory.") - - return self.pipeline_class - - # ActAsFactory - def _definition(self) -> dict[str, Any]: - return {"stages": self._get_items()} - - # public API: factory configuration - def add_stage(self, stage: StageClassOrInstance) -> Self: - """ - Adds a single stage to the pipeline. - """ - return self._add_item(stage) - - # public API: factory configuration - def with_stages(self, stages: StageCollection) -> Self: - """ - Adds a collection of stages to the pipeline. - """ - return self._set_items(stages) - - def _get_default_pipeline_class(self) -> Optional[type[TPipeline]]: - return None diff --git a/src/_api/core/plugins/_05_with_pipeline_factory/bases/pipeline_factory_interface.py b/src/_api/core/plugins/_05_with_pipeline_factory/bases/pipeline_factory_interface.py deleted file mode 100644 index c2e40ba..0000000 --- a/src/_api/core/plugins/_05_with_pipeline_factory/bases/pipeline_factory_interface.py +++ /dev/null @@ -1,29 +0,0 @@ -from typing import Any, Optional, Protocol, Self - -# extends: 3rd-party interface -from ....support.act_as_factory import ActAsFactoryInterface -from ....support.act_as_list import ActAsListInterface - -# uses: bridge interface -from .._bridges.pipeline_interface import TPipeline -from .._bridges.stage_callable import StageClassOrInstance, StageCollection - - -class PipelineFactoryInterface( - ActAsFactoryInterface[TPipeline], - ActAsListInterface[StageClassOrInstance, StageCollection], - Protocol[TPipeline], -): - def __init__( - self, - stages: Optional[StageCollection] = None, - pipeline_class: Optional[type[TPipeline]] = None, - *args: Any, - **kwds: Any, - ) -> None: ... - - def add_stage(self, stage: StageClassOrInstance) -> Self: ... - - def with_stages(self, stages: StageCollection) -> Self: ... - - def _get_default_pipeline_class(self) -> Optional[type[TPipeline]]: ... diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/__init__.py b/src/_api/core/plugins/_06_with_pipeline_processor/__init__.py deleted file mode 100644 index 531bac0..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -from .bases.processor import Processor -from .bases.processor_interface import ProcessorInterface -from .mixins.pipeline_factory_interface_mixin import PipelineFactoryInterfaceMixin -from .mixins.pipeline_factory_mixin import PipelineFactoryMixin -from .mixins.pipeline_interface_mixin import PipelineInterfaceMixin -from .mixins.pipeline_mixin import PipelineMixin - -__all__ = ( - "PipelineMixin", - "PipelineInterfaceMixin", - "PipelineFactoryMixin", - "PipelineFactoryInterfaceMixin", - "Processor", - "ProcessorInterface", -) diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/__init__.py b/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/pipeline_factory_interface.py b/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/pipeline_factory_interface.py deleted file mode 100644 index 7242e29..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/pipeline_factory_interface.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..._05_with_pipeline_factory import ( - PipelineFactoryInterface as PipelineFactoryBaseInterface, -) -from .._bridges.pipeline_interface import PipelineInterface - -# uses: bridge interface -from .._bridges.types import T_in, T_out - - -class PipelineFactoryInterface( - PipelineFactoryBaseInterface[PipelineInterface], - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/pipeline_interface.py b/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/pipeline_interface.py deleted file mode 100644 index 0b1527c..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/pipeline_interface.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Protocol, TypeVar - -# extends: outside base -from ..._01_with_base import PipelineInterface as PipelineBaseInterface - -# extends: outside mixins -from ..._02_with_pipeline_as_list import ( - PipelineInterfaceMixin as _02_WithPipelineAsListInterface, -) - - -class PipelineInterface( - _02_WithPipelineAsListInterface, - PipelineBaseInterface, - Protocol, -): - pass - - -TPipeline = TypeVar("TPipeline", bound=PipelineInterface, infer_variance=True) diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/stage_callable.py b/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/stage_callable.py deleted file mode 100644 index 425be68..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/stage_callable.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..._01_with_base import StageCallable as StageCallableBase - -# uses: local bridge -from .types import T_in, T_out - - -class StageCallable( - StageCallableBase[T_in, T_out], - Protocol[T_in, T_out], -): - pass - - -StageInstance = StageCallable - -StageInstanceCollection = tuple[StageInstance, ...] - -StageClassOrInstance = StageInstance | type[StageInstance] - -StageCollection = tuple[StageClassOrInstance, ...] diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/types.py b/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/types.py deleted file mode 100644 index 605f696..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/_bridges/types.py +++ /dev/null @@ -1,7 +0,0 @@ -# extends: outside base interface -from ..._01_with_base import T_in, T_out - -__all__ = ( - "T_in", - "T_out", -) diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/_plugin.toml b/src/_api/core/plugins/_06_with_pipeline_processor/_plugin.toml deleted file mode 100644 index d919f09..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/_plugin.toml +++ /dev/null @@ -1,6 +0,0 @@ -name = "_06_with_pipeline_processor" -dependencies = [ - "_01_with_base", - "_02_with_pipeline_as_list", - "_05_with_pipeline_factory", -] diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/bases/__init__.py b/src/_api/core/plugins/_06_with_pipeline_processor/bases/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/bases/processor_interface.py b/src/_api/core/plugins/_06_with_pipeline_processor/bases/processor_interface.py deleted file mode 100644 index a1df16b..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/bases/processor_interface.py +++ /dev/null @@ -1,39 +0,0 @@ -from abc import abstractmethod -from typing import Any, Protocol, TypeVar - -# extends: 3rd-party interface -from ....support.clonable import ClonableInterface -from ....support.has_call_async import HasCallAsyncInterface - -# uses: bridge interface -from .._bridges.stage_callable import StageInstance, StageInstanceCollection -from .._bridges.types import T_in, T_out - - -class ProcessorInterface( - HasCallAsyncInterface, - ClonableInterface, - Protocol[T_in, T_out], -): - def __init__(self, *args: Any, **kwds: Any) -> None: ... - - @abstractmethod - async def process( - self, - payload: T_in, - stages: StageInstanceCollection, - *args: Any, - **kwds: Any, - ) -> T_out: ... - - # HasCallAsync: include callable type and `payload` in the signature - async def _call( - self, - callable: StageInstance, - payload: T_in, - *args: Any, - **kwds: Any, - ) -> Any: ... - - -TProcessor = TypeVar("TProcessor", bound=ProcessorInterface, infer_variance=True) diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/mixins/__init__.py b/src/_api/core/plugins/_06_with_pipeline_processor/mixins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_factory_interface_mixin.py b/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_factory_interface_mixin.py deleted file mode 100644 index 2887c0c..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_factory_interface_mixin.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Any, Optional, Protocol, Self - -# extends: self-bridge -from .._bridges.pipeline_factory_interface import PipelineFactoryInterface - -# uses: bridge interface -from .._bridges.types import T_in, T_out - -# uses: local base -from ..bases.processor_interface import ProcessorInterface - - -class PipelineFactoryInterfaceMixin( - PipelineFactoryInterface[T_in, T_out], - Protocol[T_in, T_out], -): - def __init__( - self, - processor_class: Optional[type[ProcessorInterface]] = None, - processor_instance: Optional[ProcessorInterface] = None, - processor: Optional[type[ProcessorInterface] | ProcessorInterface] = None, - *args: Any, - **kwds: Any, - ) -> None: ... - - def with_processor( - self, processor: type[ProcessorInterface] | ProcessorInterface - ) -> Self: ... - - def with_processor_instance( - self, processor_instance: ProcessorInterface - ) -> Self: ... - - def with_processor_class( - self, processor_class: type[ProcessorInterface] - ) -> Self: ... - - # ActAsFactory - def _definition(self) -> dict[str, Any]: ... diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_factory_mixin.py b/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_factory_mixin.py deleted file mode 100644 index 8a2a722..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_factory_mixin.py +++ /dev/null @@ -1,76 +0,0 @@ -from typing import Any, Generic, Optional, Self - -# uses: bridge interface -from .._bridges.types import T_in, T_out - -# uses: local base -from ..bases.processor_interface import ProcessorInterface - -# implements: self-interface -from .pipeline_factory_interface_mixin import ( - PipelineFactoryInterfaceMixin as ImplementsInterface, -) - - -class PipelineFactoryMixin( - ImplementsInterface[T_in, T_out], - Generic[T_in, T_out], -): - processor_class: Optional[type[ProcessorInterface[T_in, T_out]]] = None - processor_instance: Optional[ProcessorInterface[T_in, T_out]] = None - - def __init__( - self, - processor_class: Optional[type[ProcessorInterface]] = None, - processor_instance: Optional[ProcessorInterface] = None, - processor: Optional[type[ProcessorInterface] | ProcessorInterface] = None, - *args: Any, - **kwds: Any, - ) -> None: - super().__init__(*args, **kwds) # type: ignore - - if not self.processor_class: - self.processor_class = processor_class or None - - if not self.processor_instance: - self.processor_instance = processor_instance or None - - if processor: - self.with_processor(processor) - - def with_processor( - self, processor: type[ProcessorInterface] | ProcessorInterface - ) -> Self: - """ - Attachs a processor (class or instance) to the pipeline factory. - """ - if isinstance(processor, type): - return self.with_processor_class(processor) - - return self.with_processor_instance(processor) - - def with_processor_instance(self, processor_instance: ProcessorInterface) -> Self: - """ - Attachs a processor instance to the pipeline factory. - """ - self.processor_class = processor_instance.__class__ - - self.processor_instance = processor_instance - - return self - - def with_processor_class(self, processor_class: type[ProcessorInterface]) -> Self: - """ - Attachs a processor class to the pipeline factory. - """ - self.processor_class = processor_class - - return self - - # ActAsFactory - def _definition(self) -> dict[str, Any]: - return { - **super()._definition(), # type: ignore - "processor_class": self.processor_class, - "processor_instance": self.processor_instance, - } diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_interface_mixin.py b/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_interface_mixin.py deleted file mode 100644 index 8a776e4..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_interface_mixin.py +++ /dev/null @@ -1,46 +0,0 @@ -from typing import Any, Optional, Protocol, Self - -# extends: self-bridge -from .._bridges.pipeline_interface import PipelineInterface - -# uses: bridge interface -from .._bridges.types import T_in, T_out - -# uses: local base -from ..bases.processor_interface import ProcessorInterface - - -class PipelineInterfaceMixin( - PipelineInterface, - Protocol[T_in, T_out], -): - def __init__( - self, - processor_class: Optional[type[ProcessorInterface]] = None, - processor_instance: Optional[ProcessorInterface] = None, - processor: Optional[type[ProcessorInterface] | ProcessorInterface] = None, - *args: Any, - **kwds: Any, - ) -> None: ... - - def with_processor( - self, processor: type[ProcessorInterface] | ProcessorInterface - ) -> Self: ... - - def with_processor_instance( - self, processor_instance: ProcessorInterface - ) -> Self: ... - - def with_processor_class( - self, processor_class: type[ProcessorInterface] - ) -> Self: ... - - def _make_processor(self) -> ProcessorInterface: ... - - async def process(self, payload: T_in, *args: Any, **kwds: Any) -> T_out: ... - - def get_processor_instance(self) -> Optional[ProcessorInterface]: ... - - def get_processor_class(self) -> Optional[type[ProcessorInterface]]: ... - - def _get_default_processor_class(self) -> Optional[type[ProcessorInterface]]: ... diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_mixin.py b/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_mixin.py deleted file mode 100644 index 78342b2..0000000 --- a/src/_api/core/plugins/_06_with_pipeline_processor/mixins/pipeline_mixin.py +++ /dev/null @@ -1,104 +0,0 @@ -from typing import Any, Generic, Optional, Self - -# uses: bridge interface -from .._bridges.types import T_in, T_out - -# uses: local base -from ..bases.processor_interface import ProcessorInterface - -# implements: self-interface -from .pipeline_interface_mixin import PipelineInterfaceMixin as ImplementsInterface - - -class PipelineMixin( - ImplementsInterface[T_in, T_out], - Generic[T_in, T_out], -): - processor_class: Optional[type[ProcessorInterface[T_in, T_out]]] - processor_instance: Optional[ProcessorInterface[T_in, T_out]] - - def __init__( - self, - processor_class: Optional[type[ProcessorInterface]] = None, - processor_instance: Optional[ProcessorInterface] = None, - processor: Optional[type[ProcessorInterface] | ProcessorInterface] = None, - *args: Any, - **kwds: Any, - ) -> None: - super().__init__(*args, **kwds) # type: ignore - - if not hasattr(self, "processor_class"): - self.processor_class = self._get_default_processor_class() - - if not hasattr(self, "processor_instance"): - self.processor_instance = None - - if processor_class: - self.processor_class = processor_class - - if processor_instance: - self.processor_instance = processor_instance - - if processor: - cloned = self.with_processor(processor) - - self.processor_class = cloned.processor_class - - self.processor_instance = cloned.processor_instance - - if not self.processor_instance: - self.processor_instance = self._make_processor() - - def with_processor( - self, processor: type[ProcessorInterface] | ProcessorInterface - ) -> Self: - """ - Attachs a processor (class or instance) to the pipeline. - """ - if isinstance(processor, type): - return self.with_processor_class(processor) - - return self.with_processor_instance(processor) - - def with_processor_instance(self, processor_instance: ProcessorInterface) -> Self: - """ - Attachs a processor instance to the pipeline. - """ - return self.clone( - { - "processor_class": processor_instance.__class__, - "processor_instance": processor_instance, - } - ) - - def with_processor_class(self, processor_class: type[ProcessorInterface]) -> Self: - """ - Attachs a processor class to the pipeline. - """ - return self.clone({"processor_class": processor_class}) - - def _make_processor(self) -> ProcessorInterface: - if self.processor_class is None: - raise ValueError("Processor class not set") - - return self.processor_class() - - async def process(self, payload: T_in, *args: Any, **kwds: Any) -> T_out: - """ - Process the given payload through the pipeline. - """ - if self.processor_instance is None: - raise ValueError("Processor not set") - - return await self.processor_instance.process( - payload=payload, stages=self._get_items(), *args, **kwds - ) - - def _get_default_processor_class(self) -> Optional[type[ProcessorInterface]]: - return None - - def get_processor_instance(self) -> Optional[ProcessorInterface]: - return self.processor_instance - - def get_processor_class(self) -> Optional[type[ProcessorInterface]]: - return self.processor_class diff --git a/src/_api/core/plugins/_08_with_pipeline_as_stage/__init__.py b/src/_api/core/plugins/_08_with_pipeline_as_stage/__init__.py deleted file mode 100644 index c86d4eb..0000000 --- a/src/_api/core/plugins/_08_with_pipeline_as_stage/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .mixins.pipeline_interface_mixin import PipelineInterfaceMixin -from .mixins.pipeline_mixin import PipelineMixin - -__all__ = ( - "PipelineMixin", - "PipelineInterfaceMixin", -) diff --git a/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/__init__.py b/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/pipeline_interface.py b/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/pipeline_interface.py deleted file mode 100644 index e215dcb..0000000 --- a/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/pipeline_interface.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Protocol, TypeVar - -# extends: outside base -from ..._01_with_base import PipelineInterface as PipelineBaseInterface - -# extends: outside mixins -from ..._02_with_pipeline_as_list import ( - PipelineInterfaceMixin as _02_WithPipelineAsListInterface, -) -from ..._06_with_pipeline_processor import ( - PipelineInterfaceMixin as _06_WithPipelineProcessorInterface, -) - -# uses: bridge interface -from .types import T_in, T_out - - -class PipelineInterface( - _06_WithPipelineProcessorInterface[T_in, T_out], - _02_WithPipelineAsListInterface, - PipelineBaseInterface, - Protocol[T_in, T_out], -): - pass - - -TPipeline = TypeVar("TPipeline", bound=PipelineInterface, infer_variance=True) diff --git a/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/stage_interface.py b/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/stage_interface.py deleted file mode 100644 index bdc3caf..0000000 --- a/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/stage_interface.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..._01_with_base import StageInterface as StageBaseInterface - -# extends: outside mixins -from ..._03_with_stage_as_callable import ( - StageInterfaceMixin as _03_WithStageAsCallableInterface, -) - -# uses: bridge interface -from .types import T_in, T_out - - -class StageInterface( - _03_WithStageAsCallableInterface[T_in, T_out], - StageBaseInterface, - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/types.py b/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/types.py deleted file mode 100644 index 605f696..0000000 --- a/src/_api/core/plugins/_08_with_pipeline_as_stage/_bridges/types.py +++ /dev/null @@ -1,7 +0,0 @@ -# extends: outside base interface -from ..._01_with_base import T_in, T_out - -__all__ = ( - "T_in", - "T_out", -) diff --git a/src/_api/core/plugins/_08_with_pipeline_as_stage/_plugin.toml b/src/_api/core/plugins/_08_with_pipeline_as_stage/_plugin.toml deleted file mode 100644 index db59ffa..0000000 --- a/src/_api/core/plugins/_08_with_pipeline_as_stage/_plugin.toml +++ /dev/null @@ -1,7 +0,0 @@ -name = "_08_with_pipeline_as_stage" -dependencies = [ - "_01_with_base", - "_02_with_pipeline_as_list", - "_03_with_stage_as_callable", - "_06_with_pipeline_processor", -] diff --git a/src/_api/core/plugins/_08_with_pipeline_as_stage/mixins/__init__.py b/src/_api/core/plugins/_08_with_pipeline_as_stage/mixins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_08_with_pipeline_as_stage/mixins/pipeline_interface_mixin.py b/src/_api/core/plugins/_08_with_pipeline_as_stage/mixins/pipeline_interface_mixin.py deleted file mode 100644 index c76b4d3..0000000 --- a/src/_api/core/plugins/_08_with_pipeline_as_stage/mixins/pipeline_interface_mixin.py +++ /dev/null @@ -1,18 +0,0 @@ -from typing import Protocol - -# extends: self-bridge -from .._bridges.pipeline_interface import PipelineInterface - -# extends: bridge interface -from .._bridges.stage_interface import StageInterface - -# uses: bridge interface -from .._bridges.types import T_in, T_out - - -class PipelineInterfaceMixin( - StageInterface[T_in, T_out], - PipelineInterface[T_in, T_out], - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/plugins/_08_with_pipeline_as_stage/mixins/pipeline_mixin.py b/src/_api/core/plugins/_08_with_pipeline_as_stage/mixins/pipeline_mixin.py deleted file mode 100644 index ae4a1ec..0000000 --- a/src/_api/core/plugins/_08_with_pipeline_as_stage/mixins/pipeline_mixin.py +++ /dev/null @@ -1,25 +0,0 @@ -from abc import ABC -from typing import Any - -# uses: bridge interface -from .._bridges.types import T_in, T_out - -# implements: self-interface -from .pipeline_interface_mixin import PipelineInterfaceMixin as ImplementsInterface - - -class PipelineMixin( - ImplementsInterface[T_in, T_out], - ABC, -): - async def __call__( - self, - payload: T_in, - /, - *args: Any, - **kwds: Any, - ) -> T_out: - """ - Processes the payload through the pipeline. - """ - return await self.process(payload, *args, **kwds) diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/__init__.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/__init__.py deleted file mode 100644 index c82b958..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -from .bases.processors.chained_processor import ChainedProcessor -from .bases.processors.chained_processor_interface import ChainedProcessorInterface -from .mixins.pipeline_factory_interface_mixin import PipelineFactoryInterfaceMixin -from .mixins.pipeline_factory_mixin import PipelineFactoryMixin -from .mixins.pipeline_interface_mixin import PipelineInterfaceMixin -from .mixins.pipeline_mixin import PipelineMixin - -__all__ = ( - "ChainedProcessorInterface", - "ChainedProcessor", - "PipelineMixin", - "PipelineInterfaceMixin", - "PipelineFactoryMixin", - "PipelineFactoryInterfaceMixin", -) diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/__init__.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/pipeline.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/pipeline.py deleted file mode 100644 index d925368..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/pipeline.py +++ /dev/null @@ -1,36 +0,0 @@ -from typing import Generic - -# extends: outside base -from ..._01_with_base import Pipeline as PipelineBase - -# extends: outside mixins -from ..._02_with_pipeline_as_list import ( - PipelineMixin as _02_WithPipelineAsList, -) -from ..._04_with_pipeline_declared_stages import ( - PipelineMixin as _04_WithPipelineDeclaredStages, -) -from ..._06_with_pipeline_processor import ( - PipelineMixin as _06_WithPipelineProcessor, -) -from ..._08_with_pipeline_as_stage import ( - PipelineMixin as _08_WithPipelineAsStage, -) - -# implements: self-interface -from .pipeline_interface import PipelineInterface as ImplementsInterface - -# uses: bridge interface -from .types import T_in, T_out - - -class Pipeline( - _08_WithPipelineAsStage[T_in, T_out], - _06_WithPipelineProcessor[T_in, T_out], - _04_WithPipelineDeclaredStages, - _02_WithPipelineAsList, - PipelineBase, - ImplementsInterface[T_in, T_out], - Generic[T_in, T_out], -): - pass diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/pipeline_factory_interface.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/pipeline_factory_interface.py deleted file mode 100644 index d9db374..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/pipeline_factory_interface.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..._05_with_pipeline_factory import ( - PipelineFactoryInterface as PipelineFactoryBaseInterface, -) - -# extends: outside mixins -from ..._06_with_pipeline_processor import ( - PipelineFactoryInterfaceMixin as _06_WithPipelineProcessorInterface, -) - -# uses: bridge interface -from .pipeline_interface import PipelineInterface -from .types import T_in, T_out - - -class PipelineFactoryInterface( - _06_WithPipelineProcessorInterface[T_in, T_out], - PipelineFactoryBaseInterface[PipelineInterface[T_in, T_out]], - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/pipeline_interface.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/pipeline_interface.py deleted file mode 100644 index 6f45f88..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/pipeline_interface.py +++ /dev/null @@ -1,35 +0,0 @@ -from typing import Protocol, TypeVar - -# extends: outside base -from ..._01_with_base import PipelineInterface as PipelineBaseInterface - -# extends: outside mixins -from ..._02_with_pipeline_as_list import ( - PipelineInterfaceMixin as _02_WithPipelineAsListInterface, -) -from ..._04_with_pipeline_declared_stages import ( - PipelineInterfaceMixin as _04_WithPipelineDeclaredStagesInterface, -) -from ..._06_with_pipeline_processor import ( - PipelineInterfaceMixin as _06_WithPipelineProcessorInterface, -) -from ..._08_with_pipeline_as_stage import ( - PipelineInterfaceMixin as _08_WithPipelineAsStageInterface, -) - -# uses: bridge interface -from .types import T_in, T_out - - -class PipelineInterface( - _08_WithPipelineAsStageInterface[T_in, T_out], - _06_WithPipelineProcessorInterface[T_in, T_out], - _04_WithPipelineDeclaredStagesInterface, - _02_WithPipelineAsListInterface, - PipelineBaseInterface, - Protocol[T_in, T_out], -): - pass - - -TPipeline = TypeVar("TPipeline", bound=PipelineInterface, infer_variance=True) diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/processor.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/processor.py deleted file mode 100644 index ef159b5..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/processor.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Generic - -# extends: outside base -from ..._06_with_pipeline_processor import ( - Processor as ProcessorBase, -) - -# implements: self-interface -from .processor_interface import ProcessorInterface as ImplementsInterface - -# uses: bridge interface -from .types import T_in, T_out - - -class Processor( - ProcessorBase[T_in, T_out], - ImplementsInterface[T_in, T_out], - Generic[T_in, T_out], -): - pass diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/processor_interface.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/processor_interface.py deleted file mode 100644 index b7b36c4..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/processor_interface.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..._06_with_pipeline_processor import ( - ProcessorInterface as ProcessorBaseInterface, -) - -# uses: bridge interface -from .types import T_in, T_out - - -class ProcessorInterface( - ProcessorBaseInterface, - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/stage_callable.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/stage_callable.py deleted file mode 100644 index 425be68..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/stage_callable.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Protocol - -# extends: outside base -from ..._01_with_base import StageCallable as StageCallableBase - -# uses: local bridge -from .types import T_in, T_out - - -class StageCallable( - StageCallableBase[T_in, T_out], - Protocol[T_in, T_out], -): - pass - - -StageInstance = StageCallable - -StageInstanceCollection = tuple[StageInstance, ...] - -StageClassOrInstance = StageInstance | type[StageInstance] - -StageCollection = tuple[StageClassOrInstance, ...] diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/types.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/types.py deleted file mode 100644 index 605f696..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/_bridges/types.py +++ /dev/null @@ -1,7 +0,0 @@ -# extends: outside base interface -from ..._01_with_base import T_in, T_out - -__all__ = ( - "T_in", - "T_out", -) diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/_plugin.toml b/src/_api/core/plugins/_99_with_pipeline_default_processor/_plugin.toml deleted file mode 100644 index a7d9720..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/_plugin.toml +++ /dev/null @@ -1,9 +0,0 @@ -name = "_99_with_pipeline_default_processor" -dependencies = [ - "_01_with_base", - "_02_with_pipeline_as_list", - "_04_with_pipeline_declared_stages", - "_05_with_pipeline_factory", - "_06_with_pipeline_processor", - "_08_with_pipeline_as_stage", -] diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/bases/__init__.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/bases/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/bases/processors/__init__.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/bases/processors/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/__init__.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_factory_interface_mixin.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_factory_interface_mixin.py deleted file mode 100644 index 9ee6ac5..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_factory_interface_mixin.py +++ /dev/null @@ -1,14 +0,0 @@ -from typing import Protocol - -# extends: self-bridge -from .._bridges.pipeline_factory_interface import PipelineFactoryInterface - -# uses: bridge interface -from .._bridges.types import T_in, T_out - - -class PipelineFactoryInterfaceMixin( - PipelineFactoryInterface[T_in, T_out], - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_factory_mixin.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_factory_mixin.py deleted file mode 100644 index e1e282a..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_factory_mixin.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Generic - -# uses: bridge interface -from .._bridges.types import T_in, T_out - -# implements: self-interface -from .pipeline_factory_interface_mixin import ( - PipelineFactoryInterfaceMixin as ImplementsInterface, -) - -# uses: mixin-bridge concrete -from .pipeline_mixin import PipelineMixin as Pipeline - - -class PipelineFactoryMixin( - ImplementsInterface[T_in, T_out], - Generic[T_in, T_out], -): - def _get_default_pipeline_class(self) -> type[Pipeline[T_in, T_out]]: - return Pipeline[T_in, T_out] diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_interface_mixin.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_interface_mixin.py deleted file mode 100644 index 54d9668..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_interface_mixin.py +++ /dev/null @@ -1,14 +0,0 @@ -from typing import Protocol - -# extends: self-bridge -from .._bridges.pipeline_interface import PipelineInterface - -# uses: bridge interface -from .._bridges.types import T_in, T_out - - -class PipelineInterfaceMixin( - PipelineInterface, - Protocol[T_in, T_out], -): - pass diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_mixin.py b/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_mixin.py deleted file mode 100644 index b9d1394..0000000 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/mixins/pipeline_mixin.py +++ /dev/null @@ -1,22 +0,0 @@ -from abc import ABC - -# extends: self-bridge concrete -from .._bridges.pipeline import Pipeline - -# uses: bridge interface -from .._bridges.types import T_in, T_out - -# uses: base concrete -from ..bases.processors.chained_processor import ChainedProcessor - -# implements: self-interface -from .pipeline_interface_mixin import PipelineInterfaceMixin as ImplementsInterface - - -class PipelineMixin( - Pipeline[T_in, T_out], - ImplementsInterface[T_in, T_out], - ABC, -): - def _get_default_processor_class(self) -> type[ChainedProcessor[T_in, T_out]]: - return ChainedProcessor[T_in, T_out] diff --git a/src/_api/core/plugins/__init__.py b/src/_api/core/plugins/__init__.py deleted file mode 100644 index da233fd..0000000 --- a/src/_api/core/plugins/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -from ._01_with_base import __all__ as _01_with_base -from ._02_with_pipeline_as_list import __all__ as _02_with_pipeline_as_list -from ._03_with_stage_as_callable import __all__ as _03_with_stage_as_callable -from ._04_with_pipeline_declared_stages import ( - __all__ as _04_with_pipeline_declared_stages, -) -from ._05_with_pipeline_factory import __all__ as _05_with_pipeline_factory -from ._06_with_pipeline_processor import __all__ as _06_with_pipeline_processor -from ._08_with_pipeline_as_stage import __all__ as _08_with_pipeline_as_stage -from ._99_with_pipeline_default_processor import ( - __all__ as _99_with_pipeline_default_processor, -) - -# pyright: reportUnsupportedDunderAll=false -__all__ = ( - *_01_with_base, - *_02_with_pipeline_as_list, - *_03_with_stage_as_callable, - *_04_with_pipeline_declared_stages, - *_05_with_pipeline_factory, - *_06_with_pipeline_processor, - *_08_with_pipeline_as_stage, - *_99_with_pipeline_default_processor, -) diff --git a/src/_api/core/support/__init__.py b/src/_api/core/support/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/_api/core/support/act_as_list/__init__.py b/src/_api/core/support/act_as_list/__init__.py deleted file mode 100644 index a3f2644..0000000 --- a/src/_api/core/support/act_as_list/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -from .act_as_list import ActAsList -from .act_as_list_interface import ActAsListInterface -from .types import TCollection, TItem - -__all__ = ( - # main - "ActAsList", - "ActAsListInterface", - # types - "TItem", - "TCollection", -) diff --git a/src/_api/core/support/act_as_list/act_as_list.py b/src/_api/core/support/act_as_list/act_as_list.py deleted file mode 100644 index 87d3939..0000000 --- a/src/_api/core/support/act_as_list/act_as_list.py +++ /dev/null @@ -1,22 +0,0 @@ -from abc import abstractmethod -from typing import Protocol, Self - -from .types import TItem, TCollection -from .act_as_list_interface import ActAsListInterface - - -class ActAsList( - ActAsListInterface[TItem, TCollection], - Protocol[TItem, TCollection], -): - @abstractmethod - def _get_items(self) -> TCollection: - pass - - @abstractmethod - def _set_items(self, items: TCollection) -> Self: - pass - - @abstractmethod - def _add_item(self, item: TItem) -> Self: - pass diff --git a/src/_api/core/support/act_as_list/act_as_list_interface.py b/src/_api/core/support/act_as_list/act_as_list_interface.py deleted file mode 100644 index b3b0884..0000000 --- a/src/_api/core/support/act_as_list/act_as_list_interface.py +++ /dev/null @@ -1,13 +0,0 @@ -from typing import Protocol, Self - -from .types import TItem, TCollection - - -class ActAsListInterface( - Protocol[TItem, TCollection], -): - def _get_items(self) -> TCollection: ... - - def _set_items(self, items: TCollection) -> Self: ... - - def _add_item(self, item: TItem) -> Self: ... diff --git a/src/_api/core/support/act_as_list/types.py b/src/_api/core/support/act_as_list/types.py deleted file mode 100644 index 7e53219..0000000 --- a/src/_api/core/support/act_as_list/types.py +++ /dev/null @@ -1,5 +0,0 @@ -from typing import Any, Sequence, TypeVar - -TItem = TypeVar("TItem", infer_variance=True) - -TCollection = TypeVar("TCollection", infer_variance=True, bound=Sequence[Any]) diff --git a/src/_api/core/support/has_call_async/__init__.py b/src/_api/core/support/has_call_async/__init__.py deleted file mode 100644 index 79fafd7..0000000 --- a/src/_api/core/support/has_call_async/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .has_call_async import HasCallAsync -from .has_call_async_interface import HasCallAsyncInterface - -__all__ = ( - "HasCallAsync", - "HasCallAsyncInterface", -) diff --git a/src/_api/core/support/has_call_async/has_call_async.py b/src/_api/core/support/has_call_async/has_call_async.py deleted file mode 100644 index 3ea2a24..0000000 --- a/src/_api/core/support/has_call_async/has_call_async.py +++ /dev/null @@ -1,19 +0,0 @@ -import inspect -from typing import Any, Awaitable, Callable, Protocol - -from .has_call_async_interface import HasCallAsyncInterface, TCallableReturn - - -class HasCallAsync(HasCallAsyncInterface, Protocol): - async def _call( - self, - callable: Callable[..., TCallableReturn | Awaitable[TCallableReturn]], - *args: Any, - **kwds: Any, - ) -> TCallableReturn: - result = callable(*args, **kwds) - - if inspect.isawaitable(result): - return await result - - return result diff --git a/src/_api/core/support/has_call_async/has_call_async_interface.py b/src/_api/core/support/has_call_async/has_call_async_interface.py deleted file mode 100644 index 1e79c17..0000000 --- a/src/_api/core/support/has_call_async/has_call_async_interface.py +++ /dev/null @@ -1,12 +0,0 @@ -from typing import Any, Awaitable, Callable, Protocol, TypeVar - -TCallableReturn = TypeVar("TCallableReturn", infer_variance=True) - - -class HasCallAsyncInterface(Protocol): - async def _call( - self, - callable: Callable[..., TCallableReturn | Awaitable[TCallableReturn]], - *args: Any, - **kwds: Any, - ) -> TCallableReturn: ... diff --git a/src/_lib/__init__.py b/src/_lib/__init__.py new file mode 100644 index 0000000..af488b1 --- /dev/null +++ b/src/_lib/__init__.py @@ -0,0 +1,34 @@ +# Version of the package +# DO NOT MODIFY MANUALLY +# This will be updated by `bumpver` command. +# - Make sure to commit all changes first before running `bumpver`. +# - Run `bumpver update --[minor|major|patch]` +__version__ = "1.26.0" + +# Re-exporting symbols +from .pipeline import CallableCollection as CallableCollection +from .pipeline import CallableType as CallableType +from .pipeline import Pipeline as Pipeline +from .pipeline import PipelineFactory as PipelineFactory +from .pipeline import PipelineFactoryInterface as PipelineFactoryInterface +from .pipeline import PipelineInterface as PipelineInterface +from .pipeline import Processor as Processor +from .pipeline import ProcessorInterface as ProcessorInterface +from .pipeline import Stage as Stage +from .pipeline import StageDefinition as StageDefinition +from .pipeline import StageDefinitionCollection as StageDefinitionCollection +from .pipeline import StageInterface as StageInterface +from .pipeline import T_in as T_in +from .pipeline import T_out as T_out +from .pipeline import __all__ as _pipeline_all +from .processors import ChainedPipeline as ChainedPipeline +from .processors import ChainedProcessor as ChainedProcessor +from .processors import InterruptiblePipeline as InterruptiblePipeline +from .processors import InterruptibleProcessor as InterruptibleProcessor +from .processors import __all__ as _processor_all + +# pyright: reportUnsupportedDunderAll=false +__all__ = ( + *_pipeline_all, + *_processor_all, +) diff --git a/src/_api/core/final/__init__.py b/src/_lib/pipeline/__init__.py similarity index 74% rename from src/_api/core/final/__init__.py rename to src/_lib/pipeline/__init__.py index 2a867f7..ac6778e 100644 --- a/src/_api/core/final/__init__.py +++ b/src/_lib/pipeline/__init__.py @@ -1,3 +1,9 @@ +from .callable_type import ( + CallableCollection, + CallableType, + StageDefinition, + StageDefinitionCollection, +) from .pipeline import Pipeline from .pipeline_factory import PipelineFactory from .pipeline_factory_interface import PipelineFactoryInterface @@ -7,13 +13,6 @@ from .processors.chained_processor import ChainedProcessor from .processors.chained_processor_interface import ChainedProcessorInterface from .stage import Stage -from .stage_callable import ( - StageCallable, - StageClassOrInstance, - StageCollection, - StageInstance, - StageInstanceCollection, -) from .stage_interface import StageInterface from .types import T_in, T_out @@ -28,11 +27,10 @@ "PipelineFactoryInterface", "T_in", "T_out", - "StageCallable", - "StageInstance", - "StageInstanceCollection", - "StageClassOrInstance", - "StageCollection", + "CallableType", + "CallableCollection", + "StageDefinition", + "StageDefinitionCollection", "ChainedProcessor", "ChainedProcessorInterface", ) diff --git a/src/_lib/pipeline/callable_type.py b/src/_lib/pipeline/callable_type.py new file mode 100644 index 0000000..cd62f1c --- /dev/null +++ b/src/_lib/pipeline/callable_type.py @@ -0,0 +1,27 @@ +from typing import Any, Awaitable, Protocol + +from .types import T_in, T_out + + +class CallableType( + Protocol[T_in, T_out], +): + """Protocol for callable stages that process data in a pipeline.""" + + def __call__( + self, + payload: T_in, + /, # Make 'payload' a positional-only parameter + *args: Any, + **kwds: Any, + ) -> T_out | Awaitable[T_out]: ... + + +CallableCollection = tuple[CallableType, ...] +"""Collection of objects or functions used as stages in the pipeline""" + +StageDefinition = CallableType | type[CallableType] +"""A Stage class, object or function""" + +StageDefinitionCollection = tuple[StageDefinition, ...] +"""Collection of Stage classes, objects or functions used to define stages in the pipeline""" diff --git a/src/_lib/pipeline/pipeline.py b/src/_lib/pipeline/pipeline.py new file mode 100644 index 0000000..d418d46 --- /dev/null +++ b/src/_lib/pipeline/pipeline.py @@ -0,0 +1,140 @@ +from typing import Any, Optional, Self + +from .callable_type import CallableCollection, CallableType, StageDefinitionCollection +from .pipeline_interface import PipelineInterface as ImplementsInterface +from .processor_interface import ProcessorInterface +from .processors.chained_processor import ChainedProcessor +from .traits.clonable import Clonable +from .types import T_in, T_out + + +class Pipeline( + Clonable, + ImplementsInterface[T_in, T_out], +): + stages: StageDefinitionCollection + stage_instances: CallableCollection + processor: Optional[type[ProcessorInterface] | ProcessorInterface] + processor_instance: Optional[ProcessorInterface] + + def __init__( + self, + stages: Optional[StageDefinitionCollection] = None, + stage_instances: Optional[CallableCollection] = None, + processor: Optional[type[ProcessorInterface] | ProcessorInterface] = None, + processor_instance: Optional[ProcessorInterface] = None, + *args: Any, + **kwds: Any, + ) -> None: + if not hasattr(self, "stages"): + self.stages = tuple() + + if not hasattr(self, "stage_instances"): + self.stage_instances = tuple() + + if not hasattr(self, "processor"): + self.processor = self._get_default_processor() + + if not hasattr(self, "processor_instance"): + self.processor_instance = None + + if stages: + self.stages = stages + + if stage_instances: + self.stage_instances = stage_instances + + if self._should_instantiate_stages(): + self._instantiate_stages() + + if processor: + self.processor = processor + + if processor_instance: + self.processor_instance = processor_instance + + if self._should_instantiate_processor(): + self._instantiate_processor() + + async def process(self, payload: T_in, *args: Any, **kwds: Any) -> T_out: + """ + Process the given payload through the pipeline. + """ + if self.processor_instance is None: + raise ValueError("Processor not set") + + return await self.processor_instance.process( + payload=payload, stages=self.stage_instances, *args, **kwds + ) + + def pipe(self, stage: CallableType) -> Self: + """ + Adds a single stage to the pipeline. + """ + return self.clone({"stage_instances": tuple([*self.stage_instances, stage])}) + + async def __call__( + self, + payload: T_in, + /, # Make 'payload' a positional-only parameter + *args: Any, + **kwds: Any, + ) -> T_out: + """ + Processes payload through the pipeline. + """ + return await self.process(payload, *args, **kwds) + + def with_processor( + self, processor: type[ProcessorInterface] | ProcessorInterface + ) -> Self: + """ + Attachs a processor (class or instance) to the pipeline. + """ + cloned = self.clone({"processor": processor, "processor_instance": None}) + + return cloned._instantiate_processor() + + def with_stages(self, stages: StageDefinitionCollection) -> Self: + """ + Adds a collection of stages to the pipeline. + """ + cloned = self.clone({"stages": stages, "stage_instances": []}) + + return cloned._instantiate_stages() + + def get_processor_instance(self) -> Optional[ProcessorInterface]: + return self.processor_instance + + def get_stages(self) -> StageDefinitionCollection: + return self.stages + + def _get_default_processor(self) -> type[ChainedProcessor[T_in, T_out]]: + return ChainedProcessor + + def _should_instantiate_processor(self) -> bool: + return self.processor_instance is None + + def _instantiate_processor(self) -> Self: + if self.processor is None: + raise ValueError("Processor class not set") + + if isinstance(self.processor, type): + self.processor_instance = self.processor() + else: + self.processor_instance = self.processor + + if isinstance(self.processor_instance, type): + raise ValueError("Processor instance could not be created") + + return self + + def _should_instantiate_stages(self) -> bool: + return len(self.stage_instances) == 0 and len(self.stages) > 0 + + def _instantiate_stages(self) -> Self: + self.stage_instances = tuple( + stage() if isinstance(stage, type) else stage for stage in self.stages + ) + + return self diff --git a/src/_lib/pipeline/pipeline_factory.py b/src/_lib/pipeline/pipeline_factory.py new file mode 100644 index 0000000..40dddb2 --- /dev/null +++ b/src/_lib/pipeline/pipeline_factory.py @@ -0,0 +1,89 @@ +from typing import Any, Optional, Self + +from .callable_type import StageDefinition, StageDefinitionCollection +from .pipeline import Pipeline +from .pipeline_factory_interface import PipelineFactoryInterface as ImplementsInterface +from .pipeline_interface import PipelineInterface +from .processor_interface import ProcessorInterface +from .traits.act_as_factory.act_as_factory import ActAsFactory +from .types import T_in, T_out + + +class PipelineFactory( + ActAsFactory[PipelineInterface[T_in, T_out]], + ImplementsInterface[T_in, T_out], +): + stages: StageDefinitionCollection + processor: Optional[type[ProcessorInterface[T_in, T_out]] | ProcessorInterface] + pipeline_class: Optional[type[PipelineInterface[T_in, T_out]]] + + def __init__( + self, + stages: Optional[StageDefinitionCollection] = None, + processor: Optional[type[ProcessorInterface] | ProcessorInterface] = None, + pipeline_class: Optional[type[PipelineInterface[T_in, T_out]]] = None, + *args: Any, + **kwds: Any, + ) -> None: + if not hasattr(self, "stages"): + self.stages = tuple() + + if not hasattr(self, "processor"): + self.processor = None + + if not hasattr(self, "pipeline_class"): + self.pipeline_class = self._get_default_pipeline_class() + + if stages: + self.stages = stages + + if processor: + self.with_processor(processor) + + if pipeline_class: + self.pipeline_class = pipeline_class + + def add_stage(self, stage: StageDefinition) -> Self: + """ + Adds a single stage to the pipeline. + """ + self.stages = self.stages + (stage,) + + return self + + def with_stages(self, stages: StageDefinitionCollection) -> Self: + """ + Adds a collection of stages to the pipeline. + """ + self.stages = stages + + return self + + def with_processor( + self, processor: type[ProcessorInterface] | ProcessorInterface + ) -> Self: + """ + Attachs a processor (class or instance) to the pipeline factory. + """ + self.processor = processor + + return self + + def _get_default_pipeline_class( + self, + ) -> Optional[type[PipelineInterface[T_in, T_out]]]: + return Pipeline + + # ActAsFactory + def _definition(self) -> dict[str, Any]: + return { + "stages": self.stages, + "processor": self.processor, + } + + # ActAsFactory + def _get_target_class(self) -> type[PipelineInterface[T_in, T_out]]: + if self.pipeline_class is None: + raise ValueError("Pipeline class not set in factory.") + + return self.pipeline_class diff --git a/src/_lib/pipeline/pipeline_factory_interface.py b/src/_lib/pipeline/pipeline_factory_interface.py new file mode 100644 index 0000000..6fc594e --- /dev/null +++ b/src/_lib/pipeline/pipeline_factory_interface.py @@ -0,0 +1,23 @@ +from typing import Any, Optional, Protocol, Self + +from .callable_type import StageDefinition, StageDefinitionCollection +from .pipeline_interface import PipelineInterface +from .traits.act_as_factory.act_as_factory_interface import ActAsFactoryInterface +from .types import T_in, T_out + + +class PipelineFactoryInterface( + ActAsFactoryInterface[PipelineInterface[T_in, T_out]], + Protocol[T_in, T_out], +): + def __init__( + self, + stages: Optional[StageDefinitionCollection] = None, + pipeline_class: Optional[type[PipelineInterface[T_in, T_out]]] = None, + *args: Any, + **kwds: Any, + ) -> None: ... + + def add_stage(self, stage: StageDefinition) -> Self: ... + + def with_stages(self, stages: StageDefinitionCollection) -> Self: ... diff --git a/src/_lib/pipeline/pipeline_interface.py b/src/_lib/pipeline/pipeline_interface.py new file mode 100644 index 0000000..977e599 --- /dev/null +++ b/src/_lib/pipeline/pipeline_interface.py @@ -0,0 +1,46 @@ +from typing import Any, Optional, Protocol, Self, TypeVar + +from .callable_type import CallableCollection, CallableType, StageDefinitionCollection +from .processor_interface import ProcessorInterface +from .traits.clonable import ClonableInterface +from .types import T_in, T_out + + +class PipelineInterface( + ClonableInterface, + Protocol[T_in, T_out], +): + def __init__( + self, + stages: Optional[StageDefinitionCollection] = None, + stage_instances: Optional[CallableCollection] = None, + processor: Optional[type[ProcessorInterface] | ProcessorInterface] = None, + processor_instance: Optional[ProcessorInterface] = None, + *args: Any, + **kwds: Any, + ) -> None: ... + + async def process(self, payload: T_in, *args: Any, **kwds: Any) -> T_out: ... + + def pipe(self, stage: CallableType) -> Self: ... + + async def __call__( + self, + payload: T_in, + /, # Make 'payload' a positional-only parameter + *args: Any, + **kwds: Any, + ) -> T_out: ... + + def with_processor( + self, processor: type[ProcessorInterface] | ProcessorInterface + ) -> Self: ... + + def with_stages(self, stages: StageDefinitionCollection) -> Self: ... + + def get_processor_instance(self) -> Optional[ProcessorInterface]: ... + + def get_stages(self) -> StageDefinitionCollection: ... + + +TPipeline = TypeVar("TPipeline", bound=PipelineInterface, infer_variance=True) diff --git a/src/_api/core/plugins/_06_with_pipeline_processor/bases/processor.py b/src/_lib/pipeline/processor.py similarity index 51% rename from src/_api/core/plugins/_06_with_pipeline_processor/bases/processor.py rename to src/_lib/pipeline/processor.py index ae415ed..8099f92 100644 --- a/src/_api/core/plugins/_06_with_pipeline_processor/bases/processor.py +++ b/src/_lib/pipeline/processor.py @@ -1,32 +1,22 @@ +import inspect from abc import abstractmethod from typing import Any -# extends: 3rd-party concrete -from ....support.clonable import Clonable -from ....support.has_call_async import HasCallAsync - -# uses: bridge interface -from .._bridges.stage_callable import StageInstance, StageInstanceCollection -from .._bridges.types import T_in, T_out - -# implements: self-interface +from .callable_type import CallableCollection, CallableType from .processor_interface import ProcessorInterface as ImplementsInterface +from .traits.clonable import Clonable +from .types import T_in, T_out class Processor( - HasCallAsync, Clonable, ImplementsInterface[T_in, T_out], ): - def __init__(self, *args: Any, **kwds: Any) -> None: - """Constructor.""" - pass - @abstractmethod async def process( self, payload: T_in, - stages: StageInstanceCollection, + stages: CallableCollection, *args: Any, **kwds: Any, ) -> T_out: @@ -35,7 +25,7 @@ async def process( Args: payload (T_in): The input payload to process. - stages (StageInstanceCollection): The collection of stages to process the payload through. + stages (CallableCollection): The collection of stages to process the payload through. *args (Any): Additional positional arguments. **kwds (Any): Additional keyword arguments. @@ -44,15 +34,19 @@ async def process( """ pass - # HasCallAsync: include callable type and `payload` in the signature async def _call( self, - callable: StageInstance, + callable: CallableType[T_in, T_out], payload: T_in, *args: Any, **kwds: Any, - ) -> Any: + ) -> T_out: """ - Alias to `process` method. + Process the given payload. """ - return await super()._call(callable, payload, *args, **kwds) + result = callable(payload, *args, **kwds) + + if inspect.isawaitable(result): + return await result + + return result diff --git a/src/_lib/pipeline/processor_interface.py b/src/_lib/pipeline/processor_interface.py new file mode 100644 index 0000000..a71a401 --- /dev/null +++ b/src/_lib/pipeline/processor_interface.py @@ -0,0 +1,28 @@ +from abc import abstractmethod +from typing import Any, Awaitable, Protocol + +from .callable_type import CallableCollection, CallableType +from .traits.clonable import ClonableInterface +from .types import T_in, T_out + + +class ProcessorInterface( + ClonableInterface, + Protocol[T_in, T_out], +): + @abstractmethod + async def process( + self, + payload: T_in, + stages: CallableCollection, + *args: Any, + **kwds: Any, + ) -> T_out: ... + + async def _call( + self, + callable: CallableType[T_in, T_out | Awaitable[T_out]], + payload: T_in, + *args: Any, + **kwds: Any, + ) -> T_out: ... diff --git a/src/_api/core/plugins/_01_with_base/bases/__init__.py b/src/_lib/pipeline/processors/__init__.py similarity index 100% rename from src/_api/core/plugins/_01_with_base/bases/__init__.py rename to src/_lib/pipeline/processors/__init__.py diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/bases/processors/chained_processor.py b/src/_lib/pipeline/processors/chained_processor.py similarity index 58% rename from src/_api/core/plugins/_99_with_pipeline_default_processor/bases/processors/chained_processor.py rename to src/_lib/pipeline/processors/chained_processor.py index ade10dc..3abc1f3 100644 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/bases/processors/chained_processor.py +++ b/src/_lib/pipeline/processors/chained_processor.py @@ -1,13 +1,8 @@ from typing import Any, cast -# extends: "3rd-party" concrete -from ..._bridges.processor import Processor - -# uses: bridge interface -from ..._bridges.stage_callable import StageInstanceCollection -from ..._bridges.types import T_in, T_out - -# implements: self-interface +from ..callable_type import CallableCollection +from ..processor import Processor +from ..types import T_in, T_out from .chained_processor_interface import ( ChainedProcessorInterface as ImplementsInterface, ) @@ -20,7 +15,7 @@ class ChainedProcessor( async def process( self, payload: T_in, - stages: StageInstanceCollection, + stages: CallableCollection, *args: Any, **kwds: Any, ) -> T_out: @@ -29,14 +24,18 @@ async def process( Args: payload (T_in): The input payload to process. - stages (StageInstanceCollection): The collection of stages to process the payload through. + stages (CallableCollection): The collection of stages to process the payload through. *args (Any): Additional positional arguments. **kwds (Any): Additional keyword arguments. Returns: T_out: The processed output. """ + payload_out: Any = payload + for stage in stages: - payload = await self._call(callable=stage, payload=payload, *args, **kwds) + payload_out = await self._call( + callable=stage, payload=payload_out, *args, **kwds + ) - return cast(T_out, payload) + return cast(T_out, payload_out) diff --git a/src/_api/core/plugins/_99_with_pipeline_default_processor/bases/processors/chained_processor_interface.py b/src/_lib/pipeline/processors/chained_processor_interface.py similarity index 56% rename from src/_api/core/plugins/_99_with_pipeline_default_processor/bases/processors/chained_processor_interface.py rename to src/_lib/pipeline/processors/chained_processor_interface.py index ffb6f0e..7bdd36a 100644 --- a/src/_api/core/plugins/_99_with_pipeline_default_processor/bases/processors/chained_processor_interface.py +++ b/src/_lib/pipeline/processors/chained_processor_interface.py @@ -1,11 +1,8 @@ from typing import Any, Protocol -# extends: "3rd-party" interface -from ..._bridges.processor_interface import ProcessorInterface - -# uses: bridge interface -from ..._bridges.stage_callable import StageInstanceCollection -from ..._bridges.types import T_in, T_out +from ..callable_type import CallableCollection +from ..processor_interface import ProcessorInterface +from ..types import T_in, T_out class ChainedProcessorInterface( @@ -19,7 +16,7 @@ class ChainedProcessorInterface( async def process( self, payload: T_in, - stages: StageInstanceCollection, + stages: CallableCollection, *args: Any, **kwds: Any, ) -> T_out: ... diff --git a/src/_api/core/plugins/_03_with_stage_as_callable/mixins/stage_mixin.py b/src/_lib/pipeline/stage.py similarity index 58% rename from src/_api/core/plugins/_03_with_stage_as_callable/mixins/stage_mixin.py rename to src/_lib/pipeline/stage.py index da29515..f1c24f5 100644 --- a/src/_api/core/plugins/_03_with_stage_as_callable/mixins/stage_mixin.py +++ b/src/_lib/pipeline/stage.py @@ -1,16 +1,12 @@ -from abc import ABC, abstractmethod +from abc import abstractmethod from typing import Any -# uses: bridge -from .._bridges.types import T_in, T_out +from .stage_interface import StageInterface as ImplementsInterface +from .types import T_in, T_out -# implements: self-interface -from .stage_interface_mixin import StageInterfaceMixin as ImplementsInterface - -class StageMixin( +class Stage( ImplementsInterface[T_in, T_out], - ABC, ): @abstractmethod async def __call__( diff --git a/src/_api/core/plugins/_03_with_stage_as_callable/mixins/stage_interface_mixin.py b/src/_lib/pipeline/stage_interface.py similarity index 62% rename from src/_api/core/plugins/_03_with_stage_as_callable/mixins/stage_interface_mixin.py rename to src/_lib/pipeline/stage_interface.py index 2e2ac59..eac9a9f 100644 --- a/src/_api/core/plugins/_03_with_stage_as_callable/mixins/stage_interface_mixin.py +++ b/src/_lib/pipeline/stage_interface.py @@ -1,15 +1,10 @@ from abc import abstractmethod from typing import Any, Protocol -# extends: self-bridge -from .._bridges.stage_interface import StageInterface +from .types import T_in, T_out -# uses: bridge -from .._bridges.types import T_in, T_out - -class StageInterfaceMixin( - StageInterface, +class StageInterface( Protocol[T_in, T_out], ): @abstractmethod diff --git a/src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/__init__.py b/src/_lib/pipeline/traits/__init__.py similarity index 100% rename from src/_api/core/plugins/_02_with_pipeline_as_list/_bridges/__init__.py rename to src/_lib/pipeline/traits/__init__.py diff --git a/src/_api/core/support/act_as_factory/__init__.py b/src/_lib/pipeline/traits/act_as_factory/__init__.py similarity index 100% rename from src/_api/core/support/act_as_factory/__init__.py rename to src/_lib/pipeline/traits/act_as_factory/__init__.py diff --git a/src/_api/core/support/act_as_factory/act_as_factory.py b/src/_lib/pipeline/traits/act_as_factory/act_as_factory.py similarity index 100% rename from src/_api/core/support/act_as_factory/act_as_factory.py rename to src/_lib/pipeline/traits/act_as_factory/act_as_factory.py diff --git a/src/_api/core/support/act_as_factory/act_as_factory_interface.py b/src/_lib/pipeline/traits/act_as_factory/act_as_factory_interface.py similarity index 100% rename from src/_api/core/support/act_as_factory/act_as_factory_interface.py rename to src/_lib/pipeline/traits/act_as_factory/act_as_factory_interface.py diff --git a/src/_api/core/support/clonable/__init__.py b/src/_lib/pipeline/traits/clonable/__init__.py similarity index 100% rename from src/_api/core/support/clonable/__init__.py rename to src/_lib/pipeline/traits/clonable/__init__.py diff --git a/src/_api/core/support/clonable/clonable.py b/src/_lib/pipeline/traits/clonable/clonable.py similarity index 100% rename from src/_api/core/support/clonable/clonable.py rename to src/_lib/pipeline/traits/clonable/clonable.py diff --git a/src/_api/core/support/clonable/clonable_interface.py b/src/_lib/pipeline/traits/clonable/clonable_interface.py similarity index 100% rename from src/_api/core/support/clonable/clonable_interface.py rename to src/_lib/pipeline/traits/clonable/clonable_interface.py diff --git a/src/_api/core/plugins/_01_with_base/bases/types.py b/src/_lib/pipeline/types.py similarity index 100% rename from src/_api/core/plugins/_01_with_base/bases/types.py rename to src/_lib/pipeline/types.py diff --git a/src/_api/processors/__init__.py b/src/_lib/processors/__init__.py similarity index 100% rename from src/_api/processors/__init__.py rename to src/_lib/processors/__init__.py diff --git a/src/_api/processors/chained_processor/__init__.py b/src/_lib/processors/chained_processor/__init__.py similarity index 100% rename from src/_api/processors/chained_processor/__init__.py rename to src/_lib/processors/chained_processor/__init__.py diff --git a/src/_api/processors/chained_processor/chained_pipeline.py b/src/_lib/processors/chained_processor/chained_pipeline.py similarity index 94% rename from src/_api/processors/chained_processor/chained_pipeline.py rename to src/_lib/processors/chained_processor/chained_pipeline.py index c1463b1..79d995c 100644 --- a/src/_api/processors/chained_processor/chained_pipeline.py +++ b/src/_lib/processors/chained_processor/chained_pipeline.py @@ -1,6 +1,6 @@ from typing import Any -from ...core import Pipeline, T_in, T_out +from ...pipeline import Pipeline, T_in, T_out from .chained_processor import ChainedProcessor diff --git a/src/_api/processors/chained_processor/chained_processor.py b/src/_lib/processors/chained_processor/chained_processor.py similarity index 84% rename from src/_api/processors/chained_processor/chained_processor.py rename to src/_lib/processors/chained_processor/chained_processor.py index fb60b62..0bf73f4 100644 --- a/src/_api/processors/chained_processor/chained_processor.py +++ b/src/_lib/processors/chained_processor/chained_processor.py @@ -1,5 +1,5 @@ -from ...core import ChainedProcessor as ChainedProcessorBase -from ...core import T_in, T_out +from ...pipeline import ChainedProcessor as ChainedProcessorBase +from ...pipeline import T_in, T_out class ChainedProcessor(ChainedProcessorBase[T_in, T_out]): diff --git a/src/_api/processors/interruptible_processor/__init__.py b/src/_lib/processors/interruptible_processor/__init__.py similarity index 100% rename from src/_api/processors/interruptible_processor/__init__.py rename to src/_lib/processors/interruptible_processor/__init__.py diff --git a/src/_api/processors/interruptible_processor/interruptible_pipeline.py b/src/_lib/processors/interruptible_processor/interruptible_pipeline.py similarity index 95% rename from src/_api/processors/interruptible_processor/interruptible_pipeline.py rename to src/_lib/processors/interruptible_processor/interruptible_pipeline.py index 2cd1f4a..0812110 100644 --- a/src/_api/processors/interruptible_processor/interruptible_pipeline.py +++ b/src/_lib/processors/interruptible_processor/interruptible_pipeline.py @@ -1,6 +1,6 @@ from typing import Any -from ...core import Pipeline, T_in, T_out +from ...pipeline import Pipeline, T_in, T_out from .interruptible_processor import CheckCallable, InterruptibleProcessor diff --git a/src/_api/processors/interruptible_processor/interruptible_processor.py b/src/_lib/processors/interruptible_processor/interruptible_processor.py similarity index 79% rename from src/_api/processors/interruptible_processor/interruptible_processor.py rename to src/_lib/processors/interruptible_processor/interruptible_processor.py index b1b33f0..269191c 100644 --- a/src/_api/processors/interruptible_processor/interruptible_processor.py +++ b/src/_lib/processors/interruptible_processor/interruptible_processor.py @@ -1,7 +1,7 @@ import inspect from typing import Any, Awaitable, Callable, cast -from ...core import Processor, StageInstanceCollection, T_in, T_out +from ...pipeline import CallableCollection, Processor, T_in, T_out CheckCallable = Callable[[T_in], bool | Awaitable[bool]] @@ -46,17 +46,21 @@ def check_value(payload: int) -> bool: async def process( self, payload: T_in, - stages: StageInstanceCollection, + stages: CallableCollection, *args: Any, **kwds: Any, ) -> T_out: + payload_out: Any = payload + for stage in stages: - payload = await self._call(callable=stage, payload=payload, *args, **kwds) + payload_out = await self._call( + callable=stage, payload=payload_out, *args, **kwds + ) - if await self._call_check(payload): - return cast(T_out, payload) + if await self._call_check(payload_out): + return cast(T_out, payload_out) - return cast(T_out, payload) + return cast(T_out, payload_out) async def _call_check(self, payload: T_in) -> bool: result = self.check(payload) diff --git a/src/_api/py.typed b/src/_lib/py.typed similarity index 100% rename from src/_api/py.typed rename to src/_lib/py.typed diff --git a/src/thecodecrate_pipeline/__init__.py b/src/thecodecrate_pipeline/__init__.py index 4d5339c..a083f6b 100644 --- a/src/thecodecrate_pipeline/__init__.py +++ b/src/thecodecrate_pipeline/__init__.py @@ -6,15 +6,14 @@ __version__ = "1.26.0" # Re-exporting symbols -from _api.core import Pipeline as Pipeline -from _api.core import PipelineFactory as PipelineFactory -from _api.core import PipelineFactoryInterface as PipelineFactoryInterface -from _api.core import PipelineInterface as PipelineInterface -from _api.core import Processor as Processor -from _api.core import ProcessorInterface as ProcessorInterface -from _api.core import Stage as Stage -from _api.core import StageCallable as StageCallable -from _api.core import StageInterface as StageInterface +from _lib import Pipeline as Pipeline +from _lib import PipelineFactory as PipelineFactory +from _lib import PipelineFactoryInterface as PipelineFactoryInterface +from _lib import PipelineInterface as PipelineInterface +from _lib import Processor as Processor +from _lib import ProcessorInterface as ProcessorInterface +from _lib import Stage as Stage +from _lib import StageInterface as StageInterface # pyright: reportUnsupportedDunderAll=false __all__ = ( @@ -25,6 +24,5 @@ "Processor", "ProcessorInterface", "Stage", - "StageCallable", "StageInterface", ) diff --git a/src/thecodecrate_pipeline/processors/__init__.py b/src/thecodecrate_pipeline/processors/__init__.py index 47ba3f5..0625641 100644 --- a/src/thecodecrate_pipeline/processors/__init__.py +++ b/src/thecodecrate_pipeline/processors/__init__.py @@ -1,11 +1,11 @@ """A collection of processors and their pipelines""" # Re-exporting symbols -from _api.processors import ChainedPipeline as ChainedPipeline -from _api.processors import ChainedProcessor as ChainedProcessor -from _api.processors import InterruptiblePipeline as InterruptiblePipeline -from _api.processors import InterruptibleProcessor as InterruptibleProcessor -from _api.processors import __all__ as _processors_all +from _lib.processors import ChainedPipeline as ChainedPipeline +from _lib.processors import ChainedProcessor as ChainedProcessor +from _lib.processors import InterruptiblePipeline as InterruptiblePipeline +from _lib.processors import InterruptibleProcessor as InterruptibleProcessor +from _lib.processors import __all__ as _processors_all # pyright: reportUnsupportedDunderAll=false __all__ = (*_processors_all,) diff --git a/src/thecodecrate_pipeline/types/__init__.py b/src/thecodecrate_pipeline/types/__init__.py index 876ce6a..1640622 100644 --- a/src/thecodecrate_pipeline/types/__init__.py +++ b/src/thecodecrate_pipeline/types/__init__.py @@ -1,19 +1,19 @@ """Library's public types""" # Re-exporting symbols -from _api.core import StageClassOrInstance as StageClassOrInstance -from _api.core import StageCollection as StageCollection -from _api.core import StageInstance as StageInstance -from _api.core import StageInstanceCollection as StageInstanceCollection -from _api.core import T_in as T_in -from _api.core import T_out as T_out +from _lib import CallableCollection as CallableCollection +from _lib import CallableType as CallableType +from _lib import StageDefinition as StageDefinition +from _lib import StageDefinitionCollection as StageDefinitionCollection +from _lib import T_in as T_in +from _lib import T_out as T_out # pyright: reportUnsupportedDunderAll=false __all__ = ( - "StageClassOrInstance", - "StageCollection", - "StageInstance", - "StageInstanceCollection", + "CallableType", + "CallableCollection", + "StageDefinition", + "StageDefinitionCollection", "T_in", "T_out", ) diff --git a/tests/stubs/stub_processor.py b/tests/stubs/stub_processor.py index 16b0e77..e04300c 100644 --- a/tests/stubs/stub_processor.py +++ b/tests/stubs/stub_processor.py @@ -1,12 +1,12 @@ from thecodecrate_pipeline import Processor -from thecodecrate_pipeline.types import StageInstanceCollection +from thecodecrate_pipeline.types import CallableCollection class StubProcessor(Processor[int]): async def process( self, payload: int, - stages: StageInstanceCollection, + stages: CallableCollection, ) -> int: for stage in stages: payload = await self._call(callable=stage, payload=payload) diff --git a/tests/stubs/stub_stage_with_custom_args.py b/tests/stubs/stub_stage_with_custom_args.py index 8e5d80c..eea25b9 100644 --- a/tests/stubs/stub_stage_with_custom_args.py +++ b/tests/stubs/stub_stage_with_custom_args.py @@ -1,8 +1,8 @@ from abc import abstractmethod -from typing import Awaitable, Callable, Concatenate, cast +from typing import Any, Awaitable, Callable, Concatenate, cast from thecodecrate_pipeline import Pipeline, Processor, Stage -from thecodecrate_pipeline.types import StageInstanceCollection, T_in, T_out +from thecodecrate_pipeline.types import CallableCollection, T_in, T_out class IndexedStage(Stage[T_in, T_out]): @@ -27,17 +27,21 @@ class IndexedProcessor(Processor[T_in, T_out]): async def process( self, payload: T_in, - stages: StageInstanceCollection, + stages: CallableCollection, ) -> T_out: index = 0 + payload_out: Any = payload + for stage in stages: - payload = await self._call(callable=stage, payload=payload, index=index) + payload_out = await self._call( + callable=stage, payload=payload_out, index=index + ) index += 1 - return cast(T_out, payload) + return cast(T_out, payload_out) class IndexedPipeline(Pipeline[T_in]): - processor_class = IndexedProcessor + processor = IndexedProcessor diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py index f1f5550..9f57021 100644 --- a/tests/test_pipeline.py +++ b/tests/test_pipeline.py @@ -1,7 +1,7 @@ import pytest from thecodecrate_pipeline import Pipeline -from thecodecrate_pipeline.types import StageCollection, StageInstanceCollection +from thecodecrate_pipeline.types import CallableCollection, StageDefinitionCollection from .stubs.stub_processor import StubProcessor from .stubs.stub_stage import StubStage @@ -144,7 +144,7 @@ class MyPipeline(Pipeline[int]): @pytest.mark.asyncio async def test_declarative_stages_with_processor(): class MyPipeline(Pipeline[int]): - processor_class = StubProcessor + processor = StubProcessor stages = ( TimesTwoStage, TimesThreeStage, @@ -177,7 +177,7 @@ class MyPipeline(Pipeline[int]): sub_three_async, # async function ) - stage_instances: StageInstanceCollection = ( + stage_instances: CallableCollection = ( add_seven, # function sub_three_async, # async function ) @@ -194,7 +194,7 @@ def add_seven(payload: int) -> int: async def sub_three_async(payload: int) -> int: return payload - 3 - stage_instances: StageInstanceCollection = ( + stage_instances: CallableCollection = ( add_seven, # function sub_three_async, # async function ) @@ -217,12 +217,12 @@ class MyPipeline(Pipeline[int]): TimesThreeStage(), # stage instance ) - stages: StageCollection = ( + stages: StageDefinitionCollection = ( AddOneStage, # stage class TimesTwoStage(), # stage instance ) - stage_instances: StageInstanceCollection = ( + stage_instances: CallableCollection = ( AddOneStage(), # only instances can be added TimesTwoStage(), # only instances can be added ) @@ -250,7 +250,7 @@ async def __call__(self, payload: str, index: int) -> str: async def test_method__with_stages(): pipeline = Pipeline() - stages: StageCollection = ( + stages: StageDefinitionCollection = ( AddOneStage, # stage class TimesTwoStage(), # stage instance ) @@ -267,7 +267,7 @@ async def test_method__with_stages(): async def test_method__with_stages__override_current_instances(): pipeline = Pipeline().pipe(AddOneStage()) - stages: StageCollection = ( + stages: StageDefinitionCollection = ( TimesTwoStage, # stage class TimesThreeStage(), # stage instance ) diff --git a/tests/test_pipeline_factory.py b/tests/test_pipeline_factory.py index 967d796..90d5c12 100644 --- a/tests/test_pipeline_factory.py +++ b/tests/test_pipeline_factory.py @@ -2,13 +2,13 @@ from thecodecrate_pipeline import PipelineFactory, Stage from thecodecrate_pipeline.processors import ChainedProcessor -from thecodecrate_pipeline.types import StageCollection +from thecodecrate_pipeline.types import StageDefinitionCollection from .stubs.stub_stages_int import ( AddOneStage, ) -some_stages: StageCollection = ( +some_stages: StageDefinitionCollection = ( AddOneStage, (lambda x: x + 1), (lambda x: f"result is {x}"), @@ -105,27 +105,6 @@ class MyProcessor(ChainedProcessor): assert pipeline.get_processor_instance().__class__ == MyProcessor -@pytest.mark.asyncio -async def test_with_processor_class(): - class MyProcessor(ChainedProcessor): - pass - - # create factory with a processor - pipeline_factory = ( - (PipelineFactory[int, str]()) - .with_stages(some_stages) - .with_processor_class(MyProcessor) - ) - - # create and process - pipeline = pipeline_factory.make() - result = await pipeline.process(10) - assert result == "result is 12" - - # check the processor - assert pipeline.get_processor_instance().__class__ == MyProcessor - - @pytest.mark.asyncio async def test_with_class_stages(): class MyStage(Stage[int, str]): diff --git a/uv.lock b/uv.lock index 453a888..f75f07e 100644 --- a/uv.lock +++ b/uv.lock @@ -1,36 +1,51 @@ version = 1 +revision = 3 requires-python = ">=3.13" [[package]] name = "appnope" version = "0.1.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170 } +sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload-time = "2024-02-06T09:43:11.258Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 }, + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" }, ] [[package]] name = "asttokens" version = "3.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978 } +sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload-time = "2024-11-30T04:30:14.439Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918 }, + { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload-time = "2024-11-30T04:30:10.946Z" }, ] [[package]] name = "babel" -version = "2.16.0" +version = "2.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, +] + +[[package]] +name = "backrefs" +version = "5.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/a7/312f673df6a79003279e1f55619abbe7daebbb87c17c976ddc0345c04c7b/backrefs-5.9.tar.gz", hash = "sha256:808548cb708d66b82ee231f962cb36faaf4f2baab032f2fbb783e9c2fdddaa59", size = 5765857, upload-time = "2025-06-22T19:34:13.97Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/4d/798dc1f30468134906575156c089c492cf79b5a5fd373f07fe26c4d046bf/backrefs-5.9-py310-none-any.whl", hash = "sha256:db8e8ba0e9de81fcd635f440deab5ae5f2591b54ac1ebe0550a2ca063488cd9f", size = 380267, upload-time = "2025-06-22T19:34:05.252Z" }, + { url = "https://files.pythonhosted.org/packages/55/07/f0b3375bf0d06014e9787797e6b7cc02b38ac9ff9726ccfe834d94e9991e/backrefs-5.9-py311-none-any.whl", hash = "sha256:6907635edebbe9b2dc3de3a2befff44d74f30a4562adbb8b36f21252ea19c5cf", size = 392072, upload-time = "2025-06-22T19:34:06.743Z" }, + { url = "https://files.pythonhosted.org/packages/9d/12/4f345407259dd60a0997107758ba3f221cf89a9b5a0f8ed5b961aef97253/backrefs-5.9-py312-none-any.whl", hash = "sha256:7fdf9771f63e6028d7fee7e0c497c81abda597ea45d6b8f89e8ad76994f5befa", size = 397947, upload-time = "2025-06-22T19:34:08.172Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/fa31834dc27a7f05e5290eae47c82690edc3a7b37d58f7fb35a1bdbf355b/backrefs-5.9-py313-none-any.whl", hash = "sha256:cc37b19fa219e93ff825ed1fed8879e47b4d89aa7a1884860e2db64ccd7c676b", size = 399843, upload-time = "2025-06-22T19:34:09.68Z" }, + { url = "https://files.pythonhosted.org/packages/fc/24/b29af34b2c9c41645a9f4ff117bae860291780d73880f449e0b5d948c070/backrefs-5.9-py314-none-any.whl", hash = "sha256:df5e169836cc8acb5e440ebae9aad4bf9d15e226d3bad049cf3f6a5c20cc8dc9", size = 411762, upload-time = "2025-06-22T19:34:11.037Z" }, + { url = "https://files.pythonhosted.org/packages/41/ff/392bff89415399a979be4a65357a41d92729ae8580a66073d8ec8d810f98/backrefs-5.9-py39-none-any.whl", hash = "sha256:f48ee18f6252b8f5777a22a00a09a85de0ca931658f1dd96d4406a34f3748c60", size = 380265, upload-time = "2025-06-22T19:34:12.405Z" }, ] [[package]] name = "black" -version = "24.10.0" +version = "25.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -38,19 +53,20 @@ dependencies = [ { name = "packaging" }, { name = "pathspec" }, { name = "platformdirs" }, + { name = "pytokens" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/0d/cc2fb42b8c50d80143221515dd7e4766995bd07c56c9a3ed30baf080b6dc/black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875", size = 645813 } +sdist = { url = "https://files.pythonhosted.org/packages/4b/43/20b5c90612d7bdb2bdbcceeb53d588acca3bb8f0e4c5d5c751a2c8fdd55a/black-25.9.0.tar.gz", hash = "sha256:0474bca9a0dd1b51791fcc507a4e02078a1c63f6d4e4ae5544b9848c7adfb619", size = 648393, upload-time = "2025-09-19T00:27:37.758Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/a0/a993f58d4ecfba035e61fca4e9f64a2ecae838fc9f33ab798c62173ed75c/black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981", size = 1643986 }, - { url = "https://files.pythonhosted.org/packages/37/d5/602d0ef5dfcace3fb4f79c436762f130abd9ee8d950fa2abdbf8bbc555e0/black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b", size = 1448085 }, - { url = "https://files.pythonhosted.org/packages/47/6d/a3a239e938960df1a662b93d6230d4f3e9b4a22982d060fc38c42f45a56b/black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2", size = 1760928 }, - { url = "https://files.pythonhosted.org/packages/dd/cf/af018e13b0eddfb434df4d9cd1b2b7892bab119f7a20123e93f6910982e8/black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b", size = 1436875 }, - { url = "https://files.pythonhosted.org/packages/8d/a7/4b27c50537ebca8bec139b872861f9d2bf501c5ec51fcf897cb924d9e264/black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d", size = 206898 }, + { url = "https://files.pythonhosted.org/packages/48/99/3acfea65f5e79f45472c45f87ec13037b506522719cd9d4ac86484ff51ac/black-25.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0172a012f725b792c358d57fe7b6b6e8e67375dd157f64fa7a3097b3ed3e2175", size = 1742165, upload-time = "2025-09-19T00:34:10.402Z" }, + { url = "https://files.pythonhosted.org/packages/3a/18/799285282c8236a79f25d590f0222dbd6850e14b060dfaa3e720241fd772/black-25.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3bec74ee60f8dfef564b573a96b8930f7b6a538e846123d5ad77ba14a8d7a64f", size = 1581259, upload-time = "2025-09-19T00:32:49.685Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ce/883ec4b6303acdeca93ee06b7622f1fa383c6b3765294824165d49b1a86b/black-25.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b756fc75871cb1bcac5499552d771822fd9db5a2bb8db2a7247936ca48f39831", size = 1655583, upload-time = "2025-09-19T00:30:44.505Z" }, + { url = "https://files.pythonhosted.org/packages/21/17/5c253aa80a0639ccc427a5c7144534b661505ae2b5a10b77ebe13fa25334/black-25.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:846d58e3ce7879ec1ffe816bb9df6d006cd9590515ed5d17db14e17666b2b357", size = 1343428, upload-time = "2025-09-19T00:32:13.839Z" }, + { url = "https://files.pythonhosted.org/packages/1b/46/863c90dcd3f9d41b109b7f19032ae0db021f0b2a81482ba0a1e28c84de86/black-25.9.0-py3-none-any.whl", hash = "sha256:474b34c1342cdc157d307b56c4c65bce916480c4a8f6551fdc6bf9b486a7c4ae", size = 203363, upload-time = "2025-09-19T00:27:35.724Z" }, ] [[package]] name = "bumpver" -version = "2024.1130" +version = "2025.1131" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -58,162 +74,226 @@ dependencies = [ { name = "lexid" }, { name = "toml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/a9/becf78cc86211bd2287114c4f990a3bed450816696f14810cc59d7815bb5/bumpver-2024.1130.tar.gz", hash = "sha256:74f7ebc294b2240f346e99748cc6f238e57b050999d7428db75d76baf2bf1437", size = 115102 } +sdist = { url = "https://files.pythonhosted.org/packages/8f/8a/cc13e816e9f0849dce423b904b06fd91b5444cba6df3200d512a702f2e95/bumpver-2025.1131.tar.gz", hash = "sha256:a35fd2d43a5f65f014035c094866bd3bd6c739606f29fd41246d6ec6e839d3f9", size = 115372, upload-time = "2025-07-02T20:36:11.982Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/09/34/57d038ae30374976ce4ec57db9dea95bf55d1b5543b35e77aa9ce3543198/bumpver-2024.1130-py2.py3-none-any.whl", hash = "sha256:8e54220aefe7db25148622f45959f7beb6b8513af0b0429b38b9072566665a49", size = 65273 }, + { url = "https://files.pythonhosted.org/packages/1d/5b/2d5ea6802495ee4506721977be522804314aa66ad629d9356e3c7e5af4a6/bumpver-2025.1131-py2.py3-none-any.whl", hash = "sha256:c02527f6ed7887afbc06c07630047b24a9f9d02d544a65639e99bf8b92aaa674", size = 65361, upload-time = "2025-07-02T20:36:10.103Z" }, ] [[package]] name = "certifi" -version = "2024.12.14" +version = "2025.10.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } +sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, + { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, ] [[package]] name = "cffi" -version = "1.17.1" +version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pycparser" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, - { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, - { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, - { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, - { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, - { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, - { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, - { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, - { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, ] [[package]] name = "charset-normalizer" -version = "3.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/89/68a4c86f1a0002810a27f12e9a7b22feb198c59b2f05231349fbce5c06f4/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", size = 194617 }, - { url = "https://files.pythonhosted.org/packages/4f/cd/8947fe425e2ab0aa57aceb7807af13a0e4162cd21eee42ef5b053447edf5/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", size = 125310 }, - { url = "https://files.pythonhosted.org/packages/5b/f0/b5263e8668a4ee9becc2b451ed909e9c27058337fda5b8c49588183c267a/charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", size = 119126 }, - { url = "https://files.pythonhosted.org/packages/ff/6e/e445afe4f7fda27a533f3234b627b3e515a1b9429bc981c9a5e2aa5d97b6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", size = 139342 }, - { url = "https://files.pythonhosted.org/packages/a1/b2/4af9993b532d93270538ad4926c8e37dc29f2111c36f9c629840c57cd9b3/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", size = 149383 }, - { url = "https://files.pythonhosted.org/packages/fb/6f/4e78c3b97686b871db9be6f31d64e9264e889f8c9d7ab33c771f847f79b7/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", size = 142214 }, - { url = "https://files.pythonhosted.org/packages/2b/c9/1c8fe3ce05d30c87eff498592c89015b19fade13df42850aafae09e94f35/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", size = 144104 }, - { url = "https://files.pythonhosted.org/packages/ee/68/efad5dcb306bf37db7db338338e7bb8ebd8cf38ee5bbd5ceaaaa46f257e6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", size = 146255 }, - { url = "https://files.pythonhosted.org/packages/0c/75/1ed813c3ffd200b1f3e71121c95da3f79e6d2a96120163443b3ad1057505/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", size = 140251 }, - { url = "https://files.pythonhosted.org/packages/7d/0d/6f32255c1979653b448d3c709583557a4d24ff97ac4f3a5be156b2e6a210/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", size = 148474 }, - { url = "https://files.pythonhosted.org/packages/ac/a0/c1b5298de4670d997101fef95b97ac440e8c8d8b4efa5a4d1ef44af82f0d/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", size = 151849 }, - { url = "https://files.pythonhosted.org/packages/04/4f/b3961ba0c664989ba63e30595a3ed0875d6790ff26671e2aae2fdc28a399/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", size = 149781 }, - { url = "https://files.pythonhosted.org/packages/d8/90/6af4cd042066a4adad58ae25648a12c09c879efa4849c705719ba1b23d8c/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482", size = 144970 }, - { url = "https://files.pythonhosted.org/packages/cc/67/e5e7e0cbfefc4ca79025238b43cdf8a2037854195b37d6417f3d0895c4c2/charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", size = 94973 }, - { url = "https://files.pythonhosted.org/packages/65/97/fc9bbc54ee13d33dc54a7fcf17b26368b18505500fc01e228c27b5222d80/charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", size = 102308 }, - { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 }, +version = "3.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, + { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, + { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, + { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, + { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, + { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, + { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, + { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, + { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload-time = "2025-08-09T07:56:38.687Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload-time = "2025-08-09T07:56:40.048Z" }, + { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload-time = "2025-08-09T07:56:41.311Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload-time = "2025-08-09T07:56:43.195Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload-time = "2025-08-09T07:56:44.819Z" }, + { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload-time = "2025-08-09T07:56:46.684Z" }, + { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload-time = "2025-08-09T07:56:47.941Z" }, + { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload-time = "2025-08-09T07:56:49.756Z" }, + { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, ] [[package]] name = "click" -version = "8.1.7" +version = "8.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } +sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, + { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "comm" -version = "0.2.2" +version = "0.2.3" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e9/a8/fb783cb0abe2b5fded9f55e5703015cdf1c9c85b3669087c538dd15a6a86/comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e", size = 6210 } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/75/49e5bfe642f71f272236b5b2d2691cf915a7283cc0ceda56357b61daa538/comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3", size = 7180 }, + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, ] [[package]] name = "coverage" -version = "7.6.9" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5b/d2/c25011f4d036cf7e8acbbee07a8e09e9018390aee25ba085596c4b83d510/coverage-7.6.9.tar.gz", hash = "sha256:4a8d8977b0c6ef5aeadcb644da9e69ae0dcfe66ec7f368c89c72e058bd71164d", size = 801710 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/35/26/9abab6539d2191dbda2ce8c97b67d74cbfc966cc5b25abb880ffc7c459bc/coverage-7.6.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:899b8cd4781c400454f2f64f7776a5d87bbd7b3e7f7bda0cb18f857bb1334664", size = 207356 }, - { url = "https://files.pythonhosted.org/packages/44/da/d49f19402240c93453f606e660a6676a2a1fbbaa6870cc23207790aa9697/coverage-7.6.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:61f70dc68bd36810972e55bbbe83674ea073dd1dcc121040a08cdf3416c5349c", size = 207614 }, - { url = "https://files.pythonhosted.org/packages/da/e6/93bb9bf85497816082ec8da6124c25efa2052bd4c887dd3b317b91990c9e/coverage-7.6.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a289d23d4c46f1a82d5db4abeb40b9b5be91731ee19a379d15790e53031c014", size = 240129 }, - { url = "https://files.pythonhosted.org/packages/df/65/6a824b9406fe066835c1274a9949e06f084d3e605eb1a602727a27ec2fe3/coverage-7.6.9-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e216d8044a356fc0337c7a2a0536d6de07888d7bcda76febcb8adc50bdbbd00", size = 237276 }, - { url = "https://files.pythonhosted.org/packages/9f/79/6c7a800913a9dd23ac8c8da133ebb556771a5a3d4df36b46767b1baffd35/coverage-7.6.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c026eb44f744acaa2bda7493dad903aa5bf5fc4f2554293a798d5606710055d", size = 239267 }, - { url = "https://files.pythonhosted.org/packages/57/e7/834d530293fdc8a63ba8ff70033d5182022e569eceb9aec7fc716b678a39/coverage-7.6.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e77363e8425325384f9d49272c54045bbed2f478e9dd698dbc65dbc37860eb0a", size = 238887 }, - { url = "https://files.pythonhosted.org/packages/15/05/ec9d6080852984f7163c96984444e7cd98b338fd045b191064f943ee1c08/coverage-7.6.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:777abfab476cf83b5177b84d7486497e034eb9eaea0d746ce0c1268c71652077", size = 236970 }, - { url = "https://files.pythonhosted.org/packages/0a/d8/775937670b93156aec29f694ce37f56214ed7597e1a75b4083ee4c32121c/coverage-7.6.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:447af20e25fdbe16f26e84eb714ba21d98868705cb138252d28bc400381f6ffb", size = 238831 }, - { url = "https://files.pythonhosted.org/packages/f4/58/88551cb7fdd5ec98cb6044e8814e38583436b14040a5ece15349c44c8f7c/coverage-7.6.9-cp313-cp313-win32.whl", hash = "sha256:d872ec5aeb086cbea771c573600d47944eea2dcba8be5f3ee649bfe3cb8dc9ba", size = 210000 }, - { url = "https://files.pythonhosted.org/packages/b7/12/cfbf49b95120872785ff8d56ab1c7fe3970a65e35010c311d7dd35c5fd00/coverage-7.6.9-cp313-cp313-win_amd64.whl", hash = "sha256:fd1213c86e48dfdc5a0cc676551db467495a95a662d2396ecd58e719191446e1", size = 210753 }, - { url = "https://files.pythonhosted.org/packages/7c/68/c1cb31445599b04bde21cbbaa6d21b47c5823cdfef99eae470dfce49c35a/coverage-7.6.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9e7484d286cd5a43744e5f47b0b3fb457865baf07bafc6bee91896364e1419", size = 208091 }, - { url = "https://files.pythonhosted.org/packages/11/73/84b02c6b19c4a11eb2d5b5eabe926fb26c21c080e0852f5e5a4f01165f9e/coverage-7.6.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e5ea1cf0872ee455c03e5674b5bca5e3e68e159379c1af0903e89f5eba9ccc3a", size = 208369 }, - { url = "https://files.pythonhosted.org/packages/de/e0/ae5d878b72ff26df2e994a5c5b1c1f6a7507d976b23beecb1ed4c85411ef/coverage-7.6.9-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d10e07aa2b91835d6abec555ec8b2733347956991901eea6ffac295f83a30e4", size = 251089 }, - { url = "https://files.pythonhosted.org/packages/ab/9c/0aaac011aef95a93ef3cb2fba3fde30bc7e68a6635199ed469b1f5ea355a/coverage-7.6.9-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13a9e2d3ee855db3dd6ea1ba5203316a1b1fd8eaeffc37c5b54987e61e4194ae", size = 246806 }, - { url = "https://files.pythonhosted.org/packages/f8/19/4d5d3ae66938a7dcb2f58cef3fa5386f838f469575b0bb568c8cc9e3a33d/coverage-7.6.9-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c38bf15a40ccf5619fa2fe8f26106c7e8e080d7760aeccb3722664c8656b030", size = 249164 }, - { url = "https://files.pythonhosted.org/packages/b3/0b/4ee8a7821f682af9ad440ae3c1e379da89a998883271f088102d7ca2473d/coverage-7.6.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d5275455b3e4627c8e7154feaf7ee0743c2e7af82f6e3b561967b1cca755a0be", size = 248642 }, - { url = "https://files.pythonhosted.org/packages/8a/12/36ff1d52be18a16b4700f561852e7afd8df56363a5edcfb04cf26a0e19e0/coverage-7.6.9-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8f8770dfc6e2c6a2d4569f411015c8d751c980d17a14b0530da2d7f27ffdd88e", size = 246516 }, - { url = "https://files.pythonhosted.org/packages/43/d0/8e258f6c3a527c1655602f4f576215e055ac704de2d101710a71a2affac2/coverage-7.6.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8d2dfa71665a29b153a9681edb1c8d9c1ea50dfc2375fb4dac99ea7e21a0bcd9", size = 247783 }, - { url = "https://files.pythonhosted.org/packages/a9/0d/1e4a48d289429d38aae3babdfcadbf35ca36bdcf3efc8f09b550a845bdb5/coverage-7.6.9-cp313-cp313t-win32.whl", hash = "sha256:5e6b86b5847a016d0fbd31ffe1001b63355ed309651851295315031ea7eb5a9b", size = 210646 }, - { url = "https://files.pythonhosted.org/packages/26/74/b0729f196f328ac55e42b1e22ec2f16d8bcafe4b8158a26ec9f1cdd1d93e/coverage-7.6.9-cp313-cp313t-win_amd64.whl", hash = "sha256:97ddc94d46088304772d21b060041c97fc16bdda13c6c7f9d8fcd8d5ae0d8611", size = 211815 }, +version = "7.10.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/26/d22c300112504f5f9a9fd2297ce33c35f3d353e4aeb987c8419453b2a7c2/coverage-7.10.7.tar.gz", hash = "sha256:f4ab143ab113be368a3e9b795f9cd7906c5ef407d6173fe9675a902e1fffc239", size = 827704, upload-time = "2025-09-21T20:03:56.815Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/94/b765c1abcb613d103b64fcf10395f54d69b0ef8be6a0dd9c524384892cc7/coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:981a651f543f2854abd3b5fcb3263aac581b18209be49863ba575de6edf4c14d", size = 218320, upload-time = "2025-09-21T20:01:56.629Z" }, + { url = "https://files.pythonhosted.org/packages/72/4f/732fff31c119bb73b35236dd333030f32c4bfe909f445b423e6c7594f9a2/coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:73ab1601f84dc804f7812dc297e93cd99381162da39c47040a827d4e8dafe63b", size = 218575, upload-time = "2025-09-21T20:01:58.203Z" }, + { url = "https://files.pythonhosted.org/packages/87/02/ae7e0af4b674be47566707777db1aa375474f02a1d64b9323e5813a6cdd5/coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a8b6f03672aa6734e700bbcd65ff050fd19cddfec4b031cc8cf1c6967de5a68e", size = 249568, upload-time = "2025-09-21T20:01:59.748Z" }, + { url = "https://files.pythonhosted.org/packages/a2/77/8c6d22bf61921a59bce5471c2f1f7ac30cd4ac50aadde72b8c48d5727902/coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10b6ba00ab1132a0ce4428ff68cf50a25efd6840a42cdf4239c9b99aad83be8b", size = 252174, upload-time = "2025-09-21T20:02:01.192Z" }, + { url = "https://files.pythonhosted.org/packages/b1/20/b6ea4f69bbb52dac0aebd62157ba6a9dddbfe664f5af8122dac296c3ee15/coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c79124f70465a150e89340de5963f936ee97097d2ef76c869708c4248c63ca49", size = 253447, upload-time = "2025-09-21T20:02:02.701Z" }, + { url = "https://files.pythonhosted.org/packages/f9/28/4831523ba483a7f90f7b259d2018fef02cb4d5b90bc7c1505d6e5a84883c/coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:69212fbccdbd5b0e39eac4067e20a4a5256609e209547d86f740d68ad4f04911", size = 249779, upload-time = "2025-09-21T20:02:04.185Z" }, + { url = "https://files.pythonhosted.org/packages/a7/9f/4331142bc98c10ca6436d2d620c3e165f31e6c58d43479985afce6f3191c/coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7ea7c6c9d0d286d04ed3541747e6597cbe4971f22648b68248f7ddcd329207f0", size = 251604, upload-time = "2025-09-21T20:02:06.034Z" }, + { url = "https://files.pythonhosted.org/packages/ce/60/bda83b96602036b77ecf34e6393a3836365481b69f7ed7079ab85048202b/coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b9be91986841a75042b3e3243d0b3cb0b2434252b977baaf0cd56e960fe1e46f", size = 249497, upload-time = "2025-09-21T20:02:07.619Z" }, + { url = "https://files.pythonhosted.org/packages/5f/af/152633ff35b2af63977edd835d8e6430f0caef27d171edf2fc76c270ef31/coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b281d5eca50189325cfe1f365fafade89b14b4a78d9b40b05ddd1fc7d2a10a9c", size = 249350, upload-time = "2025-09-21T20:02:10.34Z" }, + { url = "https://files.pythonhosted.org/packages/9d/71/d92105d122bd21cebba877228990e1646d862e34a98bb3374d3fece5a794/coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:99e4aa63097ab1118e75a848a28e40d68b08a5e19ce587891ab7fd04475e780f", size = 251111, upload-time = "2025-09-21T20:02:12.122Z" }, + { url = "https://files.pythonhosted.org/packages/a2/9e/9fdb08f4bf476c912f0c3ca292e019aab6712c93c9344a1653986c3fd305/coverage-7.10.7-cp313-cp313-win32.whl", hash = "sha256:dc7c389dce432500273eaf48f410b37886be9208b2dd5710aaf7c57fd442c698", size = 220746, upload-time = "2025-09-21T20:02:13.919Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b1/a75fd25df44eab52d1931e89980d1ada46824c7a3210be0d3c88a44aaa99/coverage-7.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:cac0fdca17b036af3881a9d2729a850b76553f3f716ccb0360ad4dbc06b3b843", size = 221541, upload-time = "2025-09-21T20:02:15.57Z" }, + { url = "https://files.pythonhosted.org/packages/14/3a/d720d7c989562a6e9a14b2c9f5f2876bdb38e9367126d118495b89c99c37/coverage-7.10.7-cp313-cp313-win_arm64.whl", hash = "sha256:4b6f236edf6e2f9ae8fcd1332da4e791c1b6ba0dc16a2dc94590ceccb482e546", size = 220170, upload-time = "2025-09-21T20:02:17.395Z" }, + { url = "https://files.pythonhosted.org/packages/bb/22/e04514bf2a735d8b0add31d2b4ab636fc02370730787c576bb995390d2d5/coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a0ec07fd264d0745ee396b666d47cef20875f4ff2375d7c4f58235886cc1ef0c", size = 219029, upload-time = "2025-09-21T20:02:18.936Z" }, + { url = "https://files.pythonhosted.org/packages/11/0b/91128e099035ece15da3445d9015e4b4153a6059403452d324cbb0a575fa/coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd5e856ebb7bfb7672b0086846db5afb4567a7b9714b8a0ebafd211ec7ce6a15", size = 219259, upload-time = "2025-09-21T20:02:20.44Z" }, + { url = "https://files.pythonhosted.org/packages/8b/51/66420081e72801536a091a0c8f8c1f88a5c4bf7b9b1bdc6222c7afe6dc9b/coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f57b2a3c8353d3e04acf75b3fed57ba41f5c0646bbf1d10c7c282291c97936b4", size = 260592, upload-time = "2025-09-21T20:02:22.313Z" }, + { url = "https://files.pythonhosted.org/packages/5d/22/9b8d458c2881b22df3db5bb3e7369e63d527d986decb6c11a591ba2364f7/coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ef2319dd15a0b009667301a3f84452a4dc6fddfd06b0c5c53ea472d3989fbf0", size = 262768, upload-time = "2025-09-21T20:02:24.287Z" }, + { url = "https://files.pythonhosted.org/packages/f7/08/16bee2c433e60913c610ea200b276e8eeef084b0d200bdcff69920bd5828/coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83082a57783239717ceb0ad584de3c69cf581b2a95ed6bf81ea66034f00401c0", size = 264995, upload-time = "2025-09-21T20:02:26.133Z" }, + { url = "https://files.pythonhosted.org/packages/20/9d/e53eb9771d154859b084b90201e5221bca7674ba449a17c101a5031d4054/coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:50aa94fb1fb9a397eaa19c0d5ec15a5edd03a47bf1a3a6111a16b36e190cff65", size = 259546, upload-time = "2025-09-21T20:02:27.716Z" }, + { url = "https://files.pythonhosted.org/packages/ad/b0/69bc7050f8d4e56a89fb550a1577d5d0d1db2278106f6f626464067b3817/coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2120043f147bebb41c85b97ac45dd173595ff14f2a584f2963891cbcc3091541", size = 262544, upload-time = "2025-09-21T20:02:29.216Z" }, + { url = "https://files.pythonhosted.org/packages/ef/4b/2514b060dbd1bc0aaf23b852c14bb5818f244c664cb16517feff6bb3a5ab/coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2fafd773231dd0378fdba66d339f84904a8e57a262f583530f4f156ab83863e6", size = 260308, upload-time = "2025-09-21T20:02:31.226Z" }, + { url = "https://files.pythonhosted.org/packages/54/78/7ba2175007c246d75e496f64c06e94122bdb914790a1285d627a918bd271/coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:0b944ee8459f515f28b851728ad224fa2d068f1513ef6b7ff1efafeb2185f999", size = 258920, upload-time = "2025-09-21T20:02:32.823Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/fac9f7abbc841409b9a410309d73bfa6cfb2e51c3fada738cb607ce174f8/coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4b583b97ab2e3efe1b3e75248a9b333bd3f8b0b1b8e5b45578e05e5850dfb2c2", size = 261434, upload-time = "2025-09-21T20:02:34.86Z" }, + { url = "https://files.pythonhosted.org/packages/ee/51/a03bec00d37faaa891b3ff7387192cef20f01604e5283a5fabc95346befa/coverage-7.10.7-cp313-cp313t-win32.whl", hash = "sha256:2a78cd46550081a7909b3329e2266204d584866e8d97b898cd7fb5ac8d888b1a", size = 221403, upload-time = "2025-09-21T20:02:37.034Z" }, + { url = "https://files.pythonhosted.org/packages/53/22/3cf25d614e64bf6d8e59c7c669b20d6d940bb337bdee5900b9ca41c820bb/coverage-7.10.7-cp313-cp313t-win_amd64.whl", hash = "sha256:33a5e6396ab684cb43dc7befa386258acb2d7fae7f67330ebb85ba4ea27938eb", size = 222469, upload-time = "2025-09-21T20:02:39.011Z" }, + { url = "https://files.pythonhosted.org/packages/49/a1/00164f6d30d8a01c3c9c48418a7a5be394de5349b421b9ee019f380df2a0/coverage-7.10.7-cp313-cp313t-win_arm64.whl", hash = "sha256:86b0e7308289ddde73d863b7683f596d8d21c7d8664ce1dee061d0bcf3fbb4bb", size = 220731, upload-time = "2025-09-21T20:02:40.939Z" }, + { url = "https://files.pythonhosted.org/packages/23/9c/5844ab4ca6a4dd97a1850e030a15ec7d292b5c5cb93082979225126e35dd/coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b06f260b16ead11643a5a9f955bd4b5fd76c1a4c6796aeade8520095b75de520", size = 218302, upload-time = "2025-09-21T20:02:42.527Z" }, + { url = "https://files.pythonhosted.org/packages/f0/89/673f6514b0961d1f0e20ddc242e9342f6da21eaba3489901b565c0689f34/coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:212f8f2e0612778f09c55dd4872cb1f64a1f2b074393d139278ce902064d5b32", size = 218578, upload-time = "2025-09-21T20:02:44.468Z" }, + { url = "https://files.pythonhosted.org/packages/05/e8/261cae479e85232828fb17ad536765c88dd818c8470aca690b0ac6feeaa3/coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3445258bcded7d4aa630ab8296dea4d3f15a255588dd535f980c193ab6b95f3f", size = 249629, upload-time = "2025-09-21T20:02:46.503Z" }, + { url = "https://files.pythonhosted.org/packages/82/62/14ed6546d0207e6eda876434e3e8475a3e9adbe32110ce896c9e0c06bb9a/coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb45474711ba385c46a0bfe696c695a929ae69ac636cda8f532be9e8c93d720a", size = 252162, upload-time = "2025-09-21T20:02:48.689Z" }, + { url = "https://files.pythonhosted.org/packages/ff/49/07f00db9ac6478e4358165a08fb41b469a1b053212e8a00cb02f0d27a05f/coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:813922f35bd800dca9994c5971883cbc0d291128a5de6b167c7aa697fcf59360", size = 253517, upload-time = "2025-09-21T20:02:50.31Z" }, + { url = "https://files.pythonhosted.org/packages/a2/59/c5201c62dbf165dfbc91460f6dbbaa85a8b82cfa6131ac45d6c1bfb52deb/coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:93c1b03552081b2a4423091d6fb3787265b8f86af404cff98d1b5342713bdd69", size = 249632, upload-time = "2025-09-21T20:02:51.971Z" }, + { url = "https://files.pythonhosted.org/packages/07/ae/5920097195291a51fb00b3a70b9bbd2edbfe3c84876a1762bd1ef1565ebc/coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:cc87dd1b6eaf0b848eebb1c86469b9f72a1891cb42ac7adcfbce75eadb13dd14", size = 251520, upload-time = "2025-09-21T20:02:53.858Z" }, + { url = "https://files.pythonhosted.org/packages/b9/3c/a815dde77a2981f5743a60b63df31cb322c944843e57dbd579326625a413/coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:39508ffda4f343c35f3236fe8d1a6634a51f4581226a1262769d7f970e73bffe", size = 249455, upload-time = "2025-09-21T20:02:55.807Z" }, + { url = "https://files.pythonhosted.org/packages/aa/99/f5cdd8421ea656abefb6c0ce92556709db2265c41e8f9fc6c8ae0f7824c9/coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:925a1edf3d810537c5a3abe78ec5530160c5f9a26b1f4270b40e62cc79304a1e", size = 249287, upload-time = "2025-09-21T20:02:57.784Z" }, + { url = "https://files.pythonhosted.org/packages/c3/7a/e9a2da6a1fc5d007dd51fca083a663ab930a8c4d149c087732a5dbaa0029/coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2c8b9a0636f94c43cd3576811e05b89aa9bc2d0a85137affc544ae5cb0e4bfbd", size = 250946, upload-time = "2025-09-21T20:02:59.431Z" }, + { url = "https://files.pythonhosted.org/packages/ef/5b/0b5799aa30380a949005a353715095d6d1da81927d6dbed5def2200a4e25/coverage-7.10.7-cp314-cp314-win32.whl", hash = "sha256:b7b8288eb7cdd268b0304632da8cb0bb93fadcfec2fe5712f7b9cc8f4d487be2", size = 221009, upload-time = "2025-09-21T20:03:01.324Z" }, + { url = "https://files.pythonhosted.org/packages/da/b0/e802fbb6eb746de006490abc9bb554b708918b6774b722bb3a0e6aa1b7de/coverage-7.10.7-cp314-cp314-win_amd64.whl", hash = "sha256:1ca6db7c8807fb9e755d0379ccc39017ce0a84dcd26d14b5a03b78563776f681", size = 221804, upload-time = "2025-09-21T20:03:03.4Z" }, + { url = "https://files.pythonhosted.org/packages/9e/e8/71d0c8e374e31f39e3389bb0bd19e527d46f00ea8571ec7ec8fd261d8b44/coverage-7.10.7-cp314-cp314-win_arm64.whl", hash = "sha256:097c1591f5af4496226d5783d036bf6fd6cd0cbc132e071b33861de756efb880", size = 220384, upload-time = "2025-09-21T20:03:05.111Z" }, + { url = "https://files.pythonhosted.org/packages/62/09/9a5608d319fa3eba7a2019addeacb8c746fb50872b57a724c9f79f146969/coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:a62c6ef0d50e6de320c270ff91d9dd0a05e7250cac2a800b7784bae474506e63", size = 219047, upload-time = "2025-09-21T20:03:06.795Z" }, + { url = "https://files.pythonhosted.org/packages/f5/6f/f58d46f33db9f2e3647b2d0764704548c184e6f5e014bef528b7f979ef84/coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9fa6e4dd51fe15d8738708a973470f67a855ca50002294852e9571cdbd9433f2", size = 219266, upload-time = "2025-09-21T20:03:08.495Z" }, + { url = "https://files.pythonhosted.org/packages/74/5c/183ffc817ba68e0b443b8c934c8795553eb0c14573813415bd59941ee165/coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8fb190658865565c549b6b4706856d6a7b09302c797eb2cf8e7fe9dabb043f0d", size = 260767, upload-time = "2025-09-21T20:03:10.172Z" }, + { url = "https://files.pythonhosted.org/packages/0f/48/71a8abe9c1ad7e97548835e3cc1adbf361e743e9d60310c5f75c9e7bf847/coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:affef7c76a9ef259187ef31599a9260330e0335a3011732c4b9effa01e1cd6e0", size = 262931, upload-time = "2025-09-21T20:03:11.861Z" }, + { url = "https://files.pythonhosted.org/packages/84/fd/193a8fb132acfc0a901f72020e54be5e48021e1575bb327d8ee1097a28fd/coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e16e07d85ca0cf8bafe5f5d23a0b850064e8e945d5677492b06bbe6f09cc699", size = 265186, upload-time = "2025-09-21T20:03:13.539Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8f/74ecc30607dd95ad50e3034221113ccb1c6d4e8085cc761134782995daae/coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:03ffc58aacdf65d2a82bbeb1ffe4d01ead4017a21bfd0454983b88ca73af94b9", size = 259470, upload-time = "2025-09-21T20:03:15.584Z" }, + { url = "https://files.pythonhosted.org/packages/0f/55/79ff53a769f20d71b07023ea115c9167c0bb56f281320520cf64c5298a96/coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1b4fd784344d4e52647fd7857b2af5b3fbe6c239b0b5fa63e94eb67320770e0f", size = 262626, upload-time = "2025-09-21T20:03:17.673Z" }, + { url = "https://files.pythonhosted.org/packages/88/e2/dac66c140009b61ac3fc13af673a574b00c16efdf04f9b5c740703e953c0/coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0ebbaddb2c19b71912c6f2518e791aa8b9f054985a0769bdb3a53ebbc765c6a1", size = 260386, upload-time = "2025-09-21T20:03:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/a2/f1/f48f645e3f33bb9ca8a496bc4a9671b52f2f353146233ebd7c1df6160440/coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a2d9a3b260cc1d1dbdb1c582e63ddcf5363426a1a68faa0f5da28d8ee3c722a0", size = 258852, upload-time = "2025-09-21T20:03:21.007Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3b/8442618972c51a7affeead957995cfa8323c0c9bcf8fa5a027421f720ff4/coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a3cc8638b2480865eaa3926d192e64ce6c51e3d29c849e09d5b4ad95efae5399", size = 261534, upload-time = "2025-09-21T20:03:23.12Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dc/101f3fa3a45146db0cb03f5b4376e24c0aac818309da23e2de0c75295a91/coverage-7.10.7-cp314-cp314t-win32.whl", hash = "sha256:67f8c5cbcd3deb7a60b3345dffc89a961a484ed0af1f6f73de91705cc6e31235", size = 221784, upload-time = "2025-09-21T20:03:24.769Z" }, + { url = "https://files.pythonhosted.org/packages/4c/a1/74c51803fc70a8a40d7346660379e144be772bab4ac7bb6e6b905152345c/coverage-7.10.7-cp314-cp314t-win_amd64.whl", hash = "sha256:e1ed71194ef6dea7ed2d5cb5f7243d4bcd334bfb63e59878519be558078f848d", size = 222905, upload-time = "2025-09-21T20:03:26.93Z" }, + { url = "https://files.pythonhosted.org/packages/12/65/f116a6d2127df30bcafbceef0302d8a64ba87488bf6f73a6d8eebf060873/coverage-7.10.7-cp314-cp314t-win_arm64.whl", hash = "sha256:7fe650342addd8524ca63d77b2362b02345e5f1a093266787d210c70a50b471a", size = 220922, upload-time = "2025-09-21T20:03:28.672Z" }, + { url = "https://files.pythonhosted.org/packages/ec/16/114df1c291c22cac3b0c127a73e0af5c12ed7bbb6558d310429a0ae24023/coverage-7.10.7-py3-none-any.whl", hash = "sha256:f7941f6f2fe6dd6807a1208737b8a0cbcf1cc6d7b07d24998ad2d63590868260", size = 209952, upload-time = "2025-09-21T20:03:53.918Z" }, ] [[package]] name = "csscompressor" version = "0.9.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/2a/8c3ac3d8bc94e6de8d7ae270bb5bc437b210bb9d6d9e46630c98f4abd20c/csscompressor-0.9.5.tar.gz", hash = "sha256:afa22badbcf3120a4f392e4d22f9fff485c044a1feda4a950ecc5eba9dd31a05", size = 237808 } +sdist = { url = "https://files.pythonhosted.org/packages/f1/2a/8c3ac3d8bc94e6de8d7ae270bb5bc437b210bb9d6d9e46630c98f4abd20c/csscompressor-0.9.5.tar.gz", hash = "sha256:afa22badbcf3120a4f392e4d22f9fff485c044a1feda4a950ecc5eba9dd31a05", size = 237808, upload-time = "2017-11-26T21:13:08.238Z" } [[package]] name = "debugpy" -version = "1.8.9" +version = "1.8.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/92/15b454c516c4c53cc8c03967e4be12b65a1ea36db3bb4513a7453f75c8d8/debugpy-1.8.9.zip", hash = "sha256:1339e14c7d980407248f09824d1b25ff5c5616651689f1e0f0e51bdead3ea13e", size = 4921695 } +sdist = { url = "https://files.pythonhosted.org/packages/15/ad/71e708ff4ca377c4230530d6a7aa7992592648c122a2cd2b321cf8b35a76/debugpy-1.8.17.tar.gz", hash = "sha256:fd723b47a8c08892b1a16b2c6239a8b96637c62a59b94bb5dab4bac592a58a8e", size = 1644129, upload-time = "2025-09-17T16:33:20.633Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/8d/eb12dcb977a2d166aac6614e60daddd1eef72881a0343717d7deb0d4868c/debugpy-1.8.9-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:957ecffff80d47cafa9b6545de9e016ae8c9547c98a538ee96ab5947115fb3dd", size = 2489077 }, - { url = "https://files.pythonhosted.org/packages/87/2b/3b7a00d8d2bb891cfa33240575c2d5fc3fa6e0bc75567f4ece59b9d3d6ea/debugpy-1.8.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1efbb3ff61487e2c16b3e033bc8595aea578222c08aaf3c4bf0f93fadbd662ee", size = 4219198 }, - { url = "https://files.pythonhosted.org/packages/5f/a1/f489026a65fabfff8c73bd51b880c130d636e02b1847564141fe3957d94f/debugpy-1.8.9-cp313-cp313-win32.whl", hash = "sha256:7c4d65d03bee875bcb211c76c1d8f10f600c305dbd734beaed4077e902606fee", size = 5163014 }, - { url = "https://files.pythonhosted.org/packages/e6/84/6070908dd163121358eb9d76fcc94f05bc99d2f89a85fe1b86167bc34ec6/debugpy-1.8.9-cp313-cp313-win_amd64.whl", hash = "sha256:e46b420dc1bea64e5bbedd678148be512442bc589b0111bd799367cde051e71a", size = 5203529 }, - { url = "https://files.pythonhosted.org/packages/2d/23/3f5804202da11c950dc0caae4a62d0c9aadabdb2daeb5f7aa09838647b5d/debugpy-1.8.9-py2.py3-none-any.whl", hash = "sha256:cc37a6c9987ad743d9c3a14fa1b1a14b7e4e6041f9dd0c8abf8895fe7a97b899", size = 5166094 }, + { url = "https://files.pythonhosted.org/packages/50/76/597e5cb97d026274ba297af8d89138dfd9e695767ba0e0895edb20963f40/debugpy-1.8.17-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:857c1dd5d70042502aef1c6d1c2801211f3ea7e56f75e9c335f434afb403e464", size = 2538386, upload-time = "2025-09-17T16:33:54.594Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/ce5c34fcdfec493701f9d1532dba95b21b2f6394147234dce21160bd923f/debugpy-1.8.17-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:3bea3b0b12f3946e098cce9b43c3c46e317b567f79570c3f43f0b96d00788088", size = 4292100, upload-time = "2025-09-17T16:33:56.353Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/7873cf2146577ef71d2a20bf553f12df865922a6f87b9e8ee1df04f01785/debugpy-1.8.17-cp313-cp313-win32.whl", hash = "sha256:e34ee844c2f17b18556b5bbe59e1e2ff4e86a00282d2a46edab73fd7f18f4a83", size = 5277002, upload-time = "2025-09-17T16:33:58.231Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/18c79a1cee5ff539a94ec4aa290c1c069a5580fd5cfd2fb2e282f8e905da/debugpy-1.8.17-cp313-cp313-win_amd64.whl", hash = "sha256:6c5cd6f009ad4fca8e33e5238210dc1e5f42db07d4b6ab21ac7ffa904a196420", size = 5319047, upload-time = "2025-09-17T16:34:00.586Z" }, + { url = "https://files.pythonhosted.org/packages/de/45/115d55b2a9da6de812696064ceb505c31e952c5d89c4ed1d9bb983deec34/debugpy-1.8.17-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:045290c010bcd2d82bc97aa2daf6837443cd52f6328592698809b4549babcee1", size = 2536899, upload-time = "2025-09-17T16:34:02.657Z" }, + { url = "https://files.pythonhosted.org/packages/5a/73/2aa00c7f1f06e997ef57dc9b23d61a92120bec1437a012afb6d176585197/debugpy-1.8.17-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:b69b6bd9dba6a03632534cdf67c760625760a215ae289f7489a452af1031fe1f", size = 4268254, upload-time = "2025-09-17T16:34:04.486Z" }, + { url = "https://files.pythonhosted.org/packages/86/b5/ed3e65c63c68a6634e3ba04bd10255c8e46ec16ebed7d1c79e4816d8a760/debugpy-1.8.17-cp314-cp314-win32.whl", hash = "sha256:5c59b74aa5630f3a5194467100c3b3d1c77898f9ab27e3f7dc5d40fc2f122670", size = 5277203, upload-time = "2025-09-17T16:34:06.65Z" }, + { url = "https://files.pythonhosted.org/packages/b0/26/394276b71c7538445f29e792f589ab7379ae70fd26ff5577dfde71158e96/debugpy-1.8.17-cp314-cp314-win_amd64.whl", hash = "sha256:893cba7bb0f55161de4365584b025f7064e1f88913551bcd23be3260b231429c", size = 5318493, upload-time = "2025-09-17T16:34:08.483Z" }, + { url = "https://files.pythonhosted.org/packages/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-py2.py3-none-any.whl", hash = "sha256:60c7dca6571efe660ccb7a9508d73ca14b8796c4ed484c2002abba714226cfef", size = 5283210, upload-time = "2025-09-17T16:34:25.835Z" }, ] [[package]] name = "decorator" -version = "5.1.1" +version = "5.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/66/0c/8d907af351aa16b42caae42f9d6aa37b900c67308052d10fdce809f8d952/decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", size = 35016 } +sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 }, + { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, ] [[package]] name = "executing" -version = "2.1.0" +version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/e3/7d45f492c2c4a0e8e0fad57d081a7c8a0286cdd86372b070cca1ec0caa1e/executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab", size = 977485 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/fd/afcd0496feca3276f509df3dbd5dae726fcc756f1a08d9e25abe1733f962/executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf", size = 25805 }, + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, ] [[package]] @@ -223,45 +303,45 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943 } +sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943, upload-time = "2022-05-02T15:47:16.11Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034 }, + { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, ] [[package]] name = "gitdb" -version = "4.0.11" +version = "4.0.12" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "smmap" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/19/0d/bbb5b5ee188dec84647a4664f3e11b06ade2bde568dbd489d9d64adef8ed/gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b", size = 394469 } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/5b/8f0c4a5bb9fd491c277c21eff7ccae71b47d43c4446c9d0c6cff2fe8c2c4/gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", size = 62721 }, + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, ] [[package]] name = "gitpython" -version = "3.1.43" +version = "3.1.45" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b6/a1/106fd9fa2dd989b6fb36e5893961f82992cf676381707253e0bf93eb1662/GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c", size = 214149 } +sdist = { url = "https://files.pythonhosted.org/packages/9a/c8/dd58967d119baab745caec2f9d853297cec1989ec1d63f677d3880632b88/gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c", size = 215076, upload-time = "2025-07-24T03:45:54.871Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/bd/cc3a402a6439c15c3d4294333e13042b915bbeab54edc457c723931fed3f/GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff", size = 207337 }, + { url = "https://files.pythonhosted.org/packages/01/61/d4b89fec821f72385526e1b9d9a3a0385dda4a72b206d28049e2c7cd39b8/gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77", size = 208168, upload-time = "2025-07-24T03:45:52.517Z" }, ] [[package]] name = "griffe" -version = "1.5.1" +version = "1.14.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d4/c9/8167810358ca129839156dc002526e7398b5fad4a9d7b6e88b875e802d0d/griffe-1.5.1.tar.gz", hash = "sha256:72964f93e08c553257706d6cd2c42d1c172213feb48b2be386f243380b405d4b", size = 384113 } +sdist = { url = "https://files.pythonhosted.org/packages/ec/d7/6c09dd7ce4c7837e4cdb11dce980cb45ae3cd87677298dc3b781b6bce7d3/griffe-1.14.0.tar.gz", hash = "sha256:9d2a15c1eca966d68e00517de5d69dd1bc5c9f2335ef6c1775362ba5b8651a13", size = 424684, upload-time = "2025-09-05T15:02:29.167Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/00/e693a155da0a2a72fd2df75b8fe338146cae59d590ad6f56800adde90cb5/griffe-1.5.1-py3-none-any.whl", hash = "sha256:ad6a7980f8c424c9102160aafa3bcdf799df0e75f7829d75af9ee5aef656f860", size = 127132 }, + { url = "https://files.pythonhosted.org/packages/2a/b1/9ff6578d789a89812ff21e4e0f80ffae20a65d5dd84e7a17873fe3b365be/griffe-1.14.0-py3-none-any.whl", hash = "sha256:0e9d52832cccf0f7188cfe585ba962d2674b241c01916d780925df34873bceb0", size = 144439, upload-time = "2025-09-05T15:02:27.511Z" }, ] [[package]] @@ -269,33 +349,33 @@ name = "htmlmin2" version = "0.1.13" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/be/31/a76f4bfa885f93b8167cb4c85cf32b54d1f64384d0b897d45bc6d19b7b45/htmlmin2-0.1.13-py3-none-any.whl", hash = "sha256:75609f2a42e64f7ce57dbff28a39890363bde9e7e5885db633317efbdf8c79a2", size = 34486 }, + { url = "https://files.pythonhosted.org/packages/be/31/a76f4bfa885f93b8167cb4c85cf32b54d1f64384d0b897d45bc6d19b7b45/htmlmin2-0.1.13-py3-none-any.whl", hash = "sha256:75609f2a42e64f7ce57dbff28a39890363bde9e7e5885db633317efbdf8c79a2", size = 34486, upload-time = "2023-03-14T21:28:30.388Z" }, ] [[package]] name = "idna" -version = "3.10" +version = "3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] [[package]] name = "iniconfig" -version = "2.0.0" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] [[package]] name = "ipykernel" -version = "6.29.5" +version = "6.30.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "appnope", marker = "platform_system == 'Darwin'" }, + { name = "appnope", marker = "sys_platform == 'darwin'" }, { name = "comm" }, { name = "debugpy" }, { name = "ipython" }, @@ -309,18 +389,19 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/5c/67594cb0c7055dc50814b21731c22a601101ea3b1b50a9a1b090e11f5d0f/ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215", size = 163367 } +sdist = { url = "https://files.pythonhosted.org/packages/bb/76/11082e338e0daadc89c8ff866185de11daf67d181901038f9e139d109761/ipykernel-6.30.1.tar.gz", hash = "sha256:6abb270161896402e76b91394fcdce5d1be5d45f456671e5080572f8505be39b", size = 166260, upload-time = "2025-08-04T15:47:35.018Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/5c/368ae6c01c7628438358e6d337c19b05425727fbb221d2a3c4303c372f42/ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5", size = 117173 }, + { url = "https://files.pythonhosted.org/packages/fc/c7/b445faca8deb954fe536abebff4ece5b097b923de482b26e78448c89d1dd/ipykernel-6.30.1-py3-none-any.whl", hash = "sha256:aa6b9fb93dca949069d8b85b6c79b2518e32ac583ae9c7d37c51d119e18b3fb4", size = 117484, upload-time = "2025-08-04T15:47:32.622Z" }, ] [[package]] name = "ipython" -version = "8.30.0" +version = "9.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "decorator" }, + { name = "ipython-pygments-lexers" }, { name = "jedi" }, { name = "matplotlib-inline" }, { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, @@ -329,9 +410,21 @@ dependencies = [ { name = "stack-data" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/8b/710af065ab8ed05649afa5bd1e07401637c9ec9fb7cfda9eac7e91e9fbd4/ipython-8.30.0.tar.gz", hash = "sha256:cb0a405a306d2995a5cbb9901894d240784a9f341394c6ba3f4fe8c6eb89ff6e", size = 5592205 } +sdist = { url = "https://files.pythonhosted.org/packages/2a/34/29b18c62e39ee2f7a6a3bba7efd952729d8aadd45ca17efc34453b717665/ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731", size = 4396932, upload-time = "2025-09-29T10:55:53.948Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/c5/d5e07995077e48220269c28a221e168c91123ad5ceee44d548f54a057fc0/ipython-9.6.0-py3-none-any.whl", hash = "sha256:5f77efafc886d2f023442479b8149e7d86547ad0a979e9da9f045d252f648196", size = 616170, upload-time = "2025-09-29T10:55:47.676Z" }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/f3/1332ba2f682b07b304ad34cad2f003adcfeb349486103f4b632335074a7c/ipython-8.30.0-py3-none-any.whl", hash = "sha256:85ec56a7e20f6c38fce7727dcca699ae4ffc85985aa7b23635a8008f918ae321", size = 820765 }, + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, ] [[package]] @@ -341,28 +434,28 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "parso" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287 } +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, ] [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 } +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] [[package]] name = "jsmin" version = "3.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5e/73/e01e4c5e11ad0494f4407a3f623ad4d87714909f50b17a06ed121034ff6e/jsmin-3.0.1.tar.gz", hash = "sha256:c0959a121ef94542e807a674142606f7e90214a2b3d1eb17300244bbb5cc2bfc", size = 13925 } +sdist = { url = "https://files.pythonhosted.org/packages/5e/73/e01e4c5e11ad0494f4407a3f623ad4d87714909f50b17a06ed121034ff6e/jsmin-3.0.1.tar.gz", hash = "sha256:c0959a121ef94542e807a674142606f7e90214a2b3d1eb17300244bbb5cc2bfc", size = 13925, upload-time = "2022-01-16T20:35:59.13Z" } [[package]] name = "jupyter-client" @@ -375,69 +468,93 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019 } +sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019, upload-time = "2024-09-17T10:44:17.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105 }, + { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105, upload-time = "2024-09-17T10:44:15.218Z" }, ] [[package]] name = "jupyter-core" -version = "5.7.2" +version = "5.8.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "platformdirs" }, { name = "pywin32", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'win32'" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/11/b56381fa6c3f4cc5d2cf54a7dbf98ad9aa0b339ef7a601d6053538b079a7/jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9", size = 87629 } +sdist = { url = "https://files.pythonhosted.org/packages/99/1b/72906d554acfeb588332eaaa6f61577705e9ec752ddb486f302dafa292d9/jupyter_core-5.8.1.tar.gz", hash = "sha256:0a5f9706f70e64786b75acba995988915ebd4601c8a52e534a40b51c95f59941", size = 88923, upload-time = "2025-05-27T07:38:16.655Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/fb/108ecd1fe961941959ad0ee4e12ee7b8b1477247f30b1fdfd83ceaf017f0/jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", size = 28965 }, + { url = "https://files.pythonhosted.org/packages/2f/57/6bffd4b20b88da3800c5d691e0337761576ee688eb01299eae865689d2df/jupyter_core-5.8.1-py3-none-any.whl", hash = "sha256:c28d268fc90fb53f1338ded2eb410704c5449a358406e8a948b75706e24863d0", size = 28880, upload-time = "2025-05-27T07:38:15.137Z" }, ] [[package]] name = "lexid" version = "2021.1006" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/60/0b/28a3f9abc75abbf1fa996eb2dd77e1e33a5d1aac62566e3f60a8ec8b8a22/lexid-2021.1006.tar.gz", hash = "sha256:509a3a4cc926d3dbf22b203b18a4c66c25e6473fb7c0e0d30374533ac28bafe5", size = 11525 } +sdist = { url = "https://files.pythonhosted.org/packages/60/0b/28a3f9abc75abbf1fa996eb2dd77e1e33a5d1aac62566e3f60a8ec8b8a22/lexid-2021.1006.tar.gz", hash = "sha256:509a3a4cc926d3dbf22b203b18a4c66c25e6473fb7c0e0d30374533ac28bafe5", size = 11525, upload-time = "2021-04-02T20:18:34.668Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/e3/35764404a4b7e2021be1f88f42264c2e92e0c4720273559a62461ce64a47/lexid-2021.1006-py2.py3-none-any.whl", hash = "sha256:5526bb5606fd74c7add23320da5f02805bddd7c77916f2dc1943e6bada8605ed", size = 7587 }, + { url = "https://files.pythonhosted.org/packages/cf/e3/35764404a4b7e2021be1f88f42264c2e92e0c4720273559a62461ce64a47/lexid-2021.1006-py2.py3-none-any.whl", hash = "sha256:5526bb5606fd74c7add23320da5f02805bddd7c77916f2dc1943e6bada8605ed", size = 7587, upload-time = "2021-04-02T20:18:33.129Z" }, ] [[package]] name = "markdown" -version = "3.7" +version = "3.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/28/3af612670f82f4c056911fbbbb42760255801b3068c48de792d354ff4472/markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", size = 357086 } +sdist = { url = "https://files.pythonhosted.org/packages/8d/37/02347f6d6d8279247a5837082ebc26fc0d5aaeaf75aa013fcbb433c777ab/markdown-3.9.tar.gz", hash = "sha256:d2900fe1782bd33bdbbd56859defef70c2e78fc46668f8eb9df3128138f2cb6a", size = 364585, upload-time = "2025-09-04T20:25:22.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/08/83871f3c50fc983b88547c196d11cf8c3340e37c32d2e9d6152abe2c61f7/Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803", size = 106349 }, + { url = "https://files.pythonhosted.org/packages/70/ae/44c4a6a4cbb496d93c6257954260fe3a6e91b7bed2240e5dad2a717f5111/markdown-3.9-py3-none-any.whl", hash = "sha256:9f4d91ed810864ea88a6f32c07ba8bee1346c0cc1f6b1f9f6c822f2a9667d280", size = 107441, upload-time = "2025-09-04T20:25:21.784Z" }, ] [[package]] name = "markupsafe" -version = "3.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] [[package]] @@ -447,18 +564,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159 } +sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload-time = "2024-04-15T13:44:44.803Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899 }, + { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, ] [[package]] name = "mergedeep" version = "1.3.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661 } +sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354 }, + { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, ] [[package]] @@ -467,7 +584,7 @@ version = "1.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, - { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "ghp-import" }, { name = "jinja2" }, { name = "markdown" }, @@ -480,23 +597,23 @@ dependencies = [ { name = "pyyaml-env-tag" }, { name = "watchdog" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159 } +sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451 }, + { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, ] [[package]] name = "mkdocs-autorefs" -version = "1.2.0" +version = "1.4.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "markupsafe" }, { name = "mkdocs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/ae/0f1154c614d6a8b8a36fff084e5b82af3a15f7d2060cf0dcdb1c53297a71/mkdocs_autorefs-1.2.0.tar.gz", hash = "sha256:a86b93abff653521bda71cf3fc5596342b7a23982093915cb74273f67522190f", size = 40262 } +sdist = { url = "https://files.pythonhosted.org/packages/51/fa/9124cd63d822e2bcbea1450ae68cdc3faf3655c69b455f3a7ed36ce6c628/mkdocs_autorefs-1.4.3.tar.gz", hash = "sha256:beee715b254455c4aa93b6ef3c67579c399ca092259cc41b7d9342573ff1fc75", size = 55425, upload-time = "2025-08-26T14:23:17.223Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/26/4d39d52ea2219604053a4d05b98e90d6a335511cc01806436ec4886b1028/mkdocs_autorefs-1.2.0-py3-none-any.whl", hash = "sha256:d588754ae89bd0ced0c70c06f58566a4ee43471eeeee5202427da7de9ef85a2f", size = 16522 }, + { url = "https://files.pythonhosted.org/packages/9f/4d/7123b6fa2278000688ebd338e2a06d16870aaf9eceae6ba047ea05f92df1/mkdocs_autorefs-1.4.3-py3-none-any.whl", hash = "sha256:469d85eb3114801d08e9cc55d102b3ba65917a869b893403b8987b601cf55dc9", size = 25034, upload-time = "2025-08-26T14:23:15.906Z" }, ] [[package]] @@ -506,9 +623,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mkdocs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/48/85/2d634462fd59136197d3126ca431ffb666f412e3db38fd5ce3a60566303e/mkdocs_gen_files-0.5.0.tar.gz", hash = "sha256:4c7cf256b5d67062a788f6b1d035e157fc1a9498c2399be9af5257d4ff4d19bc", size = 7539 } +sdist = { url = "https://files.pythonhosted.org/packages/48/85/2d634462fd59136197d3126ca431ffb666f412e3db38fd5ce3a60566303e/mkdocs_gen_files-0.5.0.tar.gz", hash = "sha256:4c7cf256b5d67062a788f6b1d035e157fc1a9498c2399be9af5257d4ff4d19bc", size = 7539, upload-time = "2023-04-27T19:48:04.894Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/0f/1e55b3fd490ad2cecb6e7b31892d27cb9fc4218ec1dab780440ba8579e74/mkdocs_gen_files-0.5.0-py3-none-any.whl", hash = "sha256:7ac060096f3f40bd19039e7277dd3050be9a453c8ac578645844d4d91d7978ea", size = 8380 }, + { url = "https://files.pythonhosted.org/packages/e7/0f/1e55b3fd490ad2cecb6e7b31892d27cb9fc4218ec1dab780440ba8579e74/mkdocs_gen_files-0.5.0-py3-none-any.whl", hash = "sha256:7ac060096f3f40bd19039e7277dd3050be9a453c8ac578645844d4d91d7978ea", size = 8380, upload-time = "2023-04-27T19:48:07.059Z" }, ] [[package]] @@ -520,14 +637,14 @@ dependencies = [ { name = "platformdirs" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239 } +sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239, upload-time = "2023-11-20T17:51:09.981Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521 }, + { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521, upload-time = "2023-11-20T17:51:08.587Z" }, ] [[package]] name = "mkdocs-git-revision-date-localized-plugin" -version = "1.3.0" +version = "1.4.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "babel" }, @@ -535,17 +652,18 @@ dependencies = [ { name = "mkdocs" }, { name = "pytz" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/73/85/6dc9d4eca486ed5734a05f7fd5c612a8e60a35e65610dad6aa9c58118c3f/mkdocs_git_revision_date_localized_plugin-1.3.0.tar.gz", hash = "sha256:439e2f14582204050a664c258861c325064d97cdc848c541e48bb034a6c4d0cb", size = 384797 } +sdist = { url = "https://files.pythonhosted.org/packages/5e/f8/a17ec39a4fc314d40cc96afdc1d401e393ebd4f42309d454cc940a2cf38a/mkdocs_git_revision_date_localized_plugin-1.4.7.tar.gz", hash = "sha256:10a49eff1e1c3cb766e054b9d8360c904ce4fe8c33ac3f6cc083ac6459c91953", size = 450473, upload-time = "2025-05-28T18:26:20.697Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/67/e5/ffeb92db53af8c3aa2d92e21a3cf6b5f83eee7e03b9cf9234ef6b30230d5/mkdocs_git_revision_date_localized_plugin-1.3.0-py3-none-any.whl", hash = "sha256:c99377ee119372d57a9e47cff4e68f04cce634a74831c06bc89b33e456e840a1", size = 22549 }, + { url = "https://files.pythonhosted.org/packages/53/b6/106fcc15287e7228658fbd0ad9e8b0d775becced0a089cc39984641f4a0f/mkdocs_git_revision_date_localized_plugin-1.4.7-py3-none-any.whl", hash = "sha256:056c0a90242409148f1dc94d5c9d2c25b5b8ddd8de45489fa38f7fa7ccad2bc4", size = 25382, upload-time = "2025-05-28T18:26:18.907Z" }, ] [[package]] name = "mkdocs-material" -version = "9.5.48" +version = "9.6.21" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "babel" }, + { name = "backrefs" }, { name = "colorama" }, { name = "jinja2" }, { name = "markdown" }, @@ -554,21 +672,20 @@ dependencies = [ { name = "paginate" }, { name = "pygments" }, { name = "pymdown-extensions" }, - { name = "regex" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/73/e3/925e4c619c03cd538b77d329479f64d75ed9ae35f5d936a19023204de6eb/mkdocs_material-9.5.48.tar.gz", hash = "sha256:a582531e8b34f4c7ed38c29d5c44763053832cf2a32f7409567e0c74749a47db", size = 3936033 } +sdist = { url = "https://files.pythonhosted.org/packages/ff/d5/ab83ca9aa314954b0a9e8849780bdd01866a3cfcb15ffb7e3a61ca06ff0b/mkdocs_material-9.6.21.tar.gz", hash = "sha256:b01aa6d2731322438056f360f0e623d3faae981f8f2d8c68b1b973f4f2657870", size = 4043097, upload-time = "2025-09-30T19:11:27.517Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/c2/5cb2482c12d3473c00b6a8b8fe7305613142d418d87871edb83a9eb89981/mkdocs_material-9.5.48-py3-none-any.whl", hash = "sha256:b695c998f4b939ce748adbc0d3bff73fa886a670ece948cf27818fa115dc16f8", size = 8666114 }, + { url = "https://files.pythonhosted.org/packages/cf/4f/98681c2030375fe9b057dbfb9008b68f46c07dddf583f4df09bf8075e37f/mkdocs_material-9.6.21-py3-none-any.whl", hash = "sha256:aa6a5ab6fb4f6d381588ac51da8782a4d3757cb3d1b174f81a2ec126e1f22c92", size = 9203097, upload-time = "2025-09-30T19:11:24.063Z" }, ] [[package]] name = "mkdocs-material-extensions" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847 } +sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847, upload-time = "2023-11-22T19:09:45.208Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728 }, + { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728, upload-time = "2023-11-22T19:09:43.465Z" }, ] [[package]] @@ -581,101 +698,94 @@ dependencies = [ { name = "jsmin" }, { name = "mkdocs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/52/67/fe4b77e7a8ae7628392e28b14122588beaf6078b53eb91c7ed000fd158ac/mkdocs-minify-plugin-0.8.0.tar.gz", hash = "sha256:bc11b78b8120d79e817308e2b11539d790d21445eb63df831e393f76e52e753d", size = 8366 } +sdist = { url = "https://files.pythonhosted.org/packages/52/67/fe4b77e7a8ae7628392e28b14122588beaf6078b53eb91c7ed000fd158ac/mkdocs-minify-plugin-0.8.0.tar.gz", hash = "sha256:bc11b78b8120d79e817308e2b11539d790d21445eb63df831e393f76e52e753d", size = 8366, upload-time = "2024-01-29T16:11:32.982Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1b/cd/2e8d0d92421916e2ea4ff97f10a544a9bd5588eb747556701c983581df13/mkdocs_minify_plugin-0.8.0-py3-none-any.whl", hash = "sha256:5fba1a3f7bd9a2142c9954a6559a57e946587b21f133165ece30ea145c66aee6", size = 6723 }, + { url = "https://files.pythonhosted.org/packages/1b/cd/2e8d0d92421916e2ea4ff97f10a544a9bd5588eb747556701c983581df13/mkdocs_minify_plugin-0.8.0-py3-none-any.whl", hash = "sha256:5fba1a3f7bd9a2142c9954a6559a57e946587b21f133165ece30ea145c66aee6", size = 6723, upload-time = "2024-01-29T16:11:31.851Z" }, ] [[package]] name = "mkdocstrings" -version = "0.27.0" +version = "0.30.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click" }, { name = "jinja2" }, { name = "markdown" }, { name = "markupsafe" }, { name = "mkdocs" }, { name = "mkdocs-autorefs" }, - { name = "platformdirs" }, { name = "pymdown-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e2/5a/5de70538c2cefae7ac3a15b5601e306ef3717290cb2aab11d51cbbc2d1c0/mkdocstrings-0.27.0.tar.gz", hash = "sha256:16adca6d6b0a1f9e0c07ff0b02ced8e16f228a9d65a37c063ec4c14d7b76a657", size = 94830 } +sdist = { url = "https://files.pythonhosted.org/packages/c5/33/2fa3243439f794e685d3e694590d28469a9b8ea733af4b48c250a3ffc9a0/mkdocstrings-0.30.1.tar.gz", hash = "sha256:84a007aae9b707fb0aebfc9da23db4b26fc9ab562eb56e335e9ec480cb19744f", size = 106350, upload-time = "2025-09-19T10:49:26.446Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cd/10/4c27c3063c2b3681a4b7942f8dbdeb4fa34fecb2c19b594e7345ebf4f86f/mkdocstrings-0.27.0-py3-none-any.whl", hash = "sha256:6ceaa7ea830770959b55a16203ac63da24badd71325b96af950e59fd37366332", size = 30658 }, -] - -[package.optional-dependencies] -python = [ - { name = "mkdocstrings-python" }, + { url = "https://files.pythonhosted.org/packages/7b/2c/f0dc4e1ee7f618f5bff7e05898d20bf8b6e7fa612038f768bfa295f136a4/mkdocstrings-0.30.1-py3-none-any.whl", hash = "sha256:41bd71f284ca4d44a668816193e4025c950b002252081e387433656ae9a70a82", size = 36704, upload-time = "2025-09-19T10:49:24.805Z" }, ] [[package]] name = "mkdocstrings-python" -version = "1.12.2" +version = "1.18.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "griffe" }, { name = "mkdocs-autorefs" }, { name = "mkdocstrings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/23/ec/cb6debe2db77f1ef42b25b21d93b5021474de3037cd82385e586aee72545/mkdocstrings_python-1.12.2.tar.gz", hash = "sha256:7a1760941c0b52a2cd87b960a9e21112ffe52e7df9d0b9583d04d47ed2e186f3", size = 168207 } +sdist = { url = "https://files.pythonhosted.org/packages/95/ae/58ab2bfbee2792e92a98b97e872f7c003deb903071f75d8d83aa55db28fa/mkdocstrings_python-1.18.2.tar.gz", hash = "sha256:4ad536920a07b6336f50d4c6d5603316fafb1172c5c882370cbbc954770ad323", size = 207972, upload-time = "2025-08-28T16:11:19.847Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/c1/ac524e1026d9580cbc654b5d19f5843c8b364a66d30f956372cd09fd2f92/mkdocstrings_python-1.12.2-py3-none-any.whl", hash = "sha256:7f7d40d6db3cb1f5d19dbcd80e3efe4d0ba32b073272c0c0de9de2e604eda62a", size = 111759 }, + { url = "https://files.pythonhosted.org/packages/d5/8f/ce008599d9adebf33ed144e7736914385e8537f5fc686fdb7cceb8c22431/mkdocstrings_python-1.18.2-py3-none-any.whl", hash = "sha256:944fe6deb8f08f33fa936d538233c4036e9f53e840994f6146e8e94eb71b600d", size = 138215, upload-time = "2025-08-28T16:11:18.176Z" }, ] [[package]] name = "mypy-extensions" -version = "1.0.0" +version = "1.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] [[package]] name = "nest-asyncio" version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418 } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195 }, + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, ] [[package]] name = "packaging" -version = "24.2" +version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "paginate" version = "0.5.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252 } +sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252, upload-time = "2024-08-25T14:17:24.139Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746 }, + { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, ] [[package]] name = "parso" -version = "0.8.4" +version = "0.8.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609 } +sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205, upload-time = "2025-08-23T15:15:28.028Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650 }, + { url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668, upload-time = "2025-08-23T15:15:25.663Z" }, ] [[package]] name = "pathspec" version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] [[package]] @@ -685,143 +795,146 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ptyprocess" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450 } +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772 }, + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, ] [[package]] name = "platformdirs" -version = "4.3.6" +version = "4.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, + { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, ] [[package]] name = "pluggy" -version = "1.5.0" +version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] name = "prompt-toolkit" -version = "3.0.48" +version = "3.0.52" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wcwidth" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2d/4f/feb5e137aff82f7c7f3248267b97451da3644f6cdc218edfe549fb354127/prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90", size = 424684 } +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/6a/fd08d94654f7e67c52ca30523a178b3f8ccc4237fce4be90d39c938a831a/prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e", size = 386595 }, + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, ] [[package]] name = "psutil" -version = "6.1.0" +version = "7.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/10/2a30b13c61e7cf937f4adf90710776b7918ed0a9c434e2c38224732af310/psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a", size = 508565 } +sdist = { url = "https://files.pythonhosted.org/packages/b3/31/4723d756b59344b643542936e37a31d1d3204bcdc42a7daa8ee9eb06fb50/psutil-7.1.0.tar.gz", hash = "sha256:655708b3c069387c8b77b072fc429a57d0e214221d01c0a772df7dfedcb3bcd2", size = 497660, upload-time = "2025-09-17T20:14:52.902Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/9e/8be43078a171381953cfee33c07c0d628594b5dbfc5157847b85022c2c1b/psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688", size = 247762 }, - { url = "https://files.pythonhosted.org/packages/1d/cb/313e80644ea407f04f6602a9e23096540d9dc1878755f3952ea8d3d104be/psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e", size = 248777 }, - { url = "https://files.pythonhosted.org/packages/65/8e/bcbe2025c587b5d703369b6a75b65d41d1367553da6e3f788aff91eaf5bd/psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38", size = 284259 }, - { url = "https://files.pythonhosted.org/packages/58/4d/8245e6f76a93c98aab285a43ea71ff1b171bcd90c9d238bf81f7021fb233/psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b", size = 287255 }, - { url = "https://files.pythonhosted.org/packages/27/c2/d034856ac47e3b3cdfa9720d0e113902e615f4190d5d1bdb8df4b2015fb2/psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a", size = 288804 }, - { url = "https://files.pythonhosted.org/packages/ea/55/5389ed243c878725feffc0d6a3bc5ef6764312b6fc7c081faaa2cfa7ef37/psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e", size = 250386 }, - { url = "https://files.pythonhosted.org/packages/11/91/87fa6f060e649b1e1a7b19a4f5869709fbf750b7c8c262ee776ec32f3028/psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be", size = 254228 }, + { url = "https://files.pythonhosted.org/packages/46/62/ce4051019ee20ce0ed74432dd73a5bb087a6704284a470bb8adff69a0932/psutil-7.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:76168cef4397494250e9f4e73eb3752b146de1dd950040b29186d0cce1d5ca13", size = 245242, upload-time = "2025-09-17T20:14:56.126Z" }, + { url = "https://files.pythonhosted.org/packages/38/61/f76959fba841bf5b61123fbf4b650886dc4094c6858008b5bf73d9057216/psutil-7.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:5d007560c8c372efdff9e4579c2846d71de737e4605f611437255e81efcca2c5", size = 246682, upload-time = "2025-09-17T20:14:58.25Z" }, + { url = "https://files.pythonhosted.org/packages/88/7a/37c99d2e77ec30d63398ffa6a660450b8a62517cabe44b3e9bae97696e8d/psutil-7.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22e4454970b32472ce7deaa45d045b34d3648ce478e26a04c7e858a0a6e75ff3", size = 287994, upload-time = "2025-09-17T20:14:59.901Z" }, + { url = "https://files.pythonhosted.org/packages/9d/de/04c8c61232f7244aa0a4b9a9fbd63a89d5aeaf94b2fc9d1d16e2faa5cbb0/psutil-7.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c70e113920d51e89f212dd7be06219a9b88014e63a4cec69b684c327bc474e3", size = 291163, upload-time = "2025-09-17T20:15:01.481Z" }, + { url = "https://files.pythonhosted.org/packages/f4/58/c4f976234bf6d4737bc8c02a81192f045c307b72cf39c9e5c5a2d78927f6/psutil-7.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d4a113425c037300de3ac8b331637293da9be9713855c4fc9d2d97436d7259d", size = 293625, upload-time = "2025-09-17T20:15:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/79/87/157c8e7959ec39ced1b11cc93c730c4fb7f9d408569a6c59dbd92ceb35db/psutil-7.1.0-cp37-abi3-win32.whl", hash = "sha256:09ad740870c8d219ed8daae0ad3b726d3bf9a028a198e7f3080f6a1888b99bca", size = 244812, upload-time = "2025-09-17T20:15:07.462Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e9/b44c4f697276a7a95b8e94d0e320a7bf7f3318521b23de69035540b39838/psutil-7.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:57f5e987c36d3146c0dd2528cd42151cf96cd359b9d67cfff836995cc5df9a3d", size = 247965, upload-time = "2025-09-17T20:15:09.673Z" }, + { url = "https://files.pythonhosted.org/packages/26/65/1070a6e3c036f39142c2820c4b52e9243246fcfc3f96239ac84472ba361e/psutil-7.1.0-cp37-abi3-win_arm64.whl", hash = "sha256:6937cb68133e7c97b6cc9649a570c9a18ba0efebed46d8c5dae4c07fa1b67a07", size = 244971, upload-time = "2025-09-17T20:15:12.262Z" }, ] [[package]] name = "ptyprocess" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762 } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993 }, + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, ] [[package]] name = "pure-eval" version = "0.2.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752 } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842 }, + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, ] [[package]] name = "pycparser" -version = "2.22" +version = "2.23" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, ] [[package]] name = "pygments" -version = "2.18.0" +version = "2.19.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] [[package]] name = "pymdown-extensions" -version = "10.12" +version = "10.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/0b/32f05854cfd432e9286bb41a870e0d1a926b72df5f5cdb6dec962b2e369e/pymdown_extensions-10.12.tar.gz", hash = "sha256:b0ee1e0b2bef1071a47891ab17003bfe5bf824a398e13f49f8ed653b699369a7", size = 840790 } +sdist = { url = "https://files.pythonhosted.org/packages/55/b3/6d2b3f149bc5413b0a29761c2c5832d8ce904a1d7f621e86616d96f505cc/pymdown_extensions-10.16.1.tar.gz", hash = "sha256:aace82bcccba3efc03e25d584e6a22d27a8e17caa3f4dd9f207e49b787aa9a91", size = 853277, upload-time = "2025-07-28T16:19:34.167Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/32/95a164ddf533bd676cbbe878e36e89b4ade3efde8dd61d0148c90cbbe57e/pymdown_extensions-10.12-py3-none-any.whl", hash = "sha256:49f81412242d3527b8b4967b990df395c89563043bc51a3d2d7d500e52123b77", size = 263448 }, + { url = "https://files.pythonhosted.org/packages/e4/06/43084e6cbd4b3bc0e80f6be743b2e79fbc6eed8de9ad8c629939fa55d972/pymdown_extensions-10.16.1-py3-none-any.whl", hash = "sha256:d6ba157a6c03146a7fb122b2b9a121300056384eafeec9c9f9e584adfdb2a32d", size = 266178, upload-time = "2025-07-28T16:19:31.401Z" }, ] [[package]] name = "pytest" -version = "8.3.4" +version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, + { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, ] [[package]] name = "pytest-asyncio" -version = "0.24.0" +version = "1.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/52/6d/c6cf50ce320cf8611df7a1254d86233b3df7cc07f9b5f5cbcb82e08aa534/pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276", size = 49855 } +sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119, upload-time = "2025-09-12T07:33:53.816Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/96/31/6607dab48616902f76885dfcf62c08d929796fc3b2d2318faf9fd54dbed9/pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b", size = 18024 }, + { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095, upload-time = "2025-09-12T07:33:52.639Z" }, ] [[package]] name = "pytest-cov" -version = "6.0.0" +version = "7.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage" }, + { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945 } +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, ] [[package]] @@ -831,117 +944,136 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "pytokens" +version = "0.1.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/5f/e959a442435e24f6fb5a01aec6c657079ceaca1b3baf18561c3728d681da/pytokens-0.1.10.tar.gz", hash = "sha256:c9a4bfa0be1d26aebce03e6884ba454e842f186a59ea43a6d3b25af58223c044", size = 12171, upload-time = "2025-02-19T14:51:22.001Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/e5/63bed382f6a7a5ba70e7e132b8b7b8abbcf4888ffa6be4877698dcfbed7d/pytokens-0.1.10-py3-none-any.whl", hash = "sha256:db7b72284e480e69fb085d9f251f66b3d2df8b7166059261258ff35f50fb711b", size = 12046, upload-time = "2025-02-19T14:51:18.694Z" }, ] [[package]] name = "pytz" -version = "2024.2" +version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, ] [[package]] name = "pywin32" -version = "308" +version = "311" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/a4/aa562d8935e3df5e49c161b427a3a2efad2ed4e9cf81c3de636f1fdddfd0/pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed", size = 5938579 }, - { url = "https://files.pythonhosted.org/packages/c7/50/b0efb8bb66210da67a53ab95fd7a98826a97ee21f1d22949863e6d588b22/pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4", size = 6542056 }, - { url = "https://files.pythonhosted.org/packages/26/df/2b63e3e4f2df0224f8aaf6d131f54fe4e8c96400eb9df563e2aae2e1a1f9/pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd", size = 7974986 }, + { url = "https://files.pythonhosted.org/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700, upload-time = "2025-07-14T20:13:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700, upload-time = "2025-07-14T20:13:28.243Z" }, + { url = "https://files.pythonhosted.org/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318, upload-time = "2025-07-14T20:13:30.348Z" }, + { url = "https://files.pythonhosted.org/packages/c9/31/097f2e132c4f16d99a22bfb777e0fd88bd8e1c634304e102f313af69ace5/pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee", size = 8840714, upload-time = "2025-07-14T20:13:32.449Z" }, + { url = "https://files.pythonhosted.org/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87", size = 9656800, upload-time = "2025-07-14T20:13:34.312Z" }, + { url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540, upload-time = "2025-07-14T20:13:36.379Z" }, ] [[package]] name = "pyyaml" -version = "6.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] name = "pyyaml-env-tag" -version = "0.1" +version = "1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/8e/da1c6c58f751b70f8ceb1eb25bc25d524e8f14fe16edcce3f4e3ba08629c/pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", size = 5631 } +sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/66/bbb1dd374f5c870f59c5bb1db0e18cbe7fa739415a24cbd95b2d1f5ae0c4/pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069", size = 3911 }, + { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, ] [[package]] name = "pyzmq" -version = "26.2.0" +version = "27.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "implementation_name == 'pypy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fd/05/bed626b9f7bb2322cdbbf7b4bd8f54b1b617b0d2ab2d3547d6e39428a48e/pyzmq-26.2.0.tar.gz", hash = "sha256:070672c258581c8e4f640b5159297580a9974b026043bd4ab0470be9ed324f1f", size = 271975 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/a7/0f7e2f6c126fe6e62dbae0bc93b1bd3f1099cf7fea47a5468defebe3f39d/pyzmq-26.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9dd8cd1aeb00775f527ec60022004d030ddc51d783d056e3e23e74e623e33726", size = 1006564 }, - { url = "https://files.pythonhosted.org/packages/31/b6/a187165c852c5d49f826a690857684333a6a4a065af0a6015572d2284f6a/pyzmq-26.2.0-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:28c812d9757fe8acecc910c9ac9dafd2ce968c00f9e619db09e9f8f54c3a68a3", size = 1340447 }, - { url = "https://files.pythonhosted.org/packages/68/ba/f4280c58ff71f321602a6e24fd19879b7e79793fb8ab14027027c0fb58ef/pyzmq-26.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d80b1dd99c1942f74ed608ddb38b181b87476c6a966a88a950c7dee118fdf50", size = 665485 }, - { url = "https://files.pythonhosted.org/packages/77/b5/c987a5c53c7d8704216f29fc3d810b32f156bcea488a940e330e1bcbb88d/pyzmq-26.2.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c997098cc65e3208eca09303630e84d42718620e83b733d0fd69543a9cab9cb", size = 903484 }, - { url = "https://files.pythonhosted.org/packages/29/c9/07da157d2db18c72a7eccef8e684cefc155b712a88e3d479d930aa9eceba/pyzmq-26.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ad1bc8d1b7a18497dda9600b12dc193c577beb391beae5cd2349184db40f187", size = 859981 }, - { url = "https://files.pythonhosted.org/packages/43/09/e12501bd0b8394b7d02c41efd35c537a1988da67fc9c745cae9c6c776d31/pyzmq-26.2.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:bea2acdd8ea4275e1278350ced63da0b166421928276c7c8e3f9729d7402a57b", size = 860334 }, - { url = "https://files.pythonhosted.org/packages/eb/ff/f5ec1d455f8f7385cc0a8b2acd8c807d7fade875c14c44b85c1bddabae21/pyzmq-26.2.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:23f4aad749d13698f3f7b64aad34f5fc02d6f20f05999eebc96b89b01262fb18", size = 1196179 }, - { url = "https://files.pythonhosted.org/packages/ec/8a/bb2ac43295b1950fe436a81fc5b298be0b96ac76fb029b514d3ed58f7b27/pyzmq-26.2.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:a4f96f0d88accc3dbe4a9025f785ba830f968e21e3e2c6321ccdfc9aef755115", size = 1507668 }, - { url = "https://files.pythonhosted.org/packages/a9/49/dbc284ebcfd2dca23f6349227ff1616a7ee2c4a35fe0a5d6c3deff2b4fed/pyzmq-26.2.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ced65e5a985398827cc9276b93ef6dfabe0273c23de8c7931339d7e141c2818e", size = 1406539 }, - { url = "https://files.pythonhosted.org/packages/00/68/093cdce3fe31e30a341d8e52a1ad86392e13c57970d722c1f62a1d1a54b6/pyzmq-26.2.0-cp313-cp313-win32.whl", hash = "sha256:31507f7b47cc1ead1f6e86927f8ebb196a0bab043f6345ce070f412a59bf87b5", size = 575567 }, - { url = "https://files.pythonhosted.org/packages/92/ae/6cc4657148143412b5819b05e362ae7dd09fb9fe76e2a539dcff3d0386bc/pyzmq-26.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:70fc7fcf0410d16ebdda9b26cbd8bf8d803d220a7f3522e060a69a9c87bf7bad", size = 637551 }, - { url = "https://files.pythonhosted.org/packages/6c/67/fbff102e201688f97c8092e4c3445d1c1068c2f27bbd45a578df97ed5f94/pyzmq-26.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:c3789bd5768ab5618ebf09cef6ec2b35fed88709b104351748a63045f0ff9797", size = 540378 }, - { url = "https://files.pythonhosted.org/packages/3f/fe/2d998380b6e0122c6c4bdf9b6caf490831e5f5e2d08a203b5adff060c226/pyzmq-26.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:034da5fc55d9f8da09015d368f519478a52675e558c989bfcb5cf6d4e16a7d2a", size = 1007378 }, - { url = "https://files.pythonhosted.org/packages/4a/f4/30d6e7157f12b3a0390bde94d6a8567cdb88846ed068a6e17238a4ccf600/pyzmq-26.2.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:c92d73464b886931308ccc45b2744e5968cbaade0b1d6aeb40d8ab537765f5bc", size = 1329532 }, - { url = "https://files.pythonhosted.org/packages/82/86/3fe917870e15ee1c3ad48229a2a64458e36036e64b4afa9659045d82bfa8/pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:794a4562dcb374f7dbbfb3f51d28fb40123b5a2abadee7b4091f93054909add5", size = 653242 }, - { url = "https://files.pythonhosted.org/packages/50/2d/242e7e6ef6c8c19e6cb52d095834508cd581ffb925699fd3c640cdc758f1/pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aee22939bb6075e7afededabad1a56a905da0b3c4e3e0c45e75810ebe3a52672", size = 888404 }, - { url = "https://files.pythonhosted.org/packages/ac/11/7270566e1f31e4ea73c81ec821a4b1688fd551009a3d2bab11ec66cb1e8f/pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ae90ff9dad33a1cfe947d2c40cb9cb5e600d759ac4f0fd22616ce6540f72797", size = 845858 }, - { url = "https://files.pythonhosted.org/packages/91/d5/72b38fbc69867795c8711bdd735312f9fef1e3d9204e2f63ab57085434b9/pyzmq-26.2.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:43a47408ac52647dfabbc66a25b05b6a61700b5165807e3fbd40063fcaf46386", size = 847375 }, - { url = "https://files.pythonhosted.org/packages/dd/9a/10ed3c7f72b4c24e719c59359fbadd1a27556a28b36cdf1cd9e4fb7845d5/pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:25bf2374a2a8433633c65ccb9553350d5e17e60c8eb4de4d92cc6bd60f01d306", size = 1183489 }, - { url = "https://files.pythonhosted.org/packages/72/2d/8660892543fabf1fe41861efa222455811adac9f3c0818d6c3170a1153e3/pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:007137c9ac9ad5ea21e6ad97d3489af654381324d5d3ba614c323f60dab8fae6", size = 1492932 }, - { url = "https://files.pythonhosted.org/packages/7b/d6/32fd69744afb53995619bc5effa2a405ae0d343cd3e747d0fbc43fe894ee/pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:470d4a4f6d48fb34e92d768b4e8a5cc3780db0d69107abf1cd7ff734b9766eb0", size = 1392485 }, -] - -[[package]] -name = "regex" -version = "2024.11.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525 }, - { url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324 }, - { url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617 }, - { url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023 }, - { url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072 }, - { url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130 }, - { url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857 }, - { url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006 }, - { url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650 }, - { url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545 }, - { url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045 }, - { url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182 }, - { url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733 }, - { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122 }, - { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545 }, +sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, + { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, + { url = "https://files.pythonhosted.org/packages/60/cb/84a13459c51da6cec1b7b1dc1a47e6db6da50b77ad7fd9c145842750a011/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5", size = 1122436, upload-time = "2025-09-08T23:08:20.801Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b6/94414759a69a26c3dd674570a81813c46a078767d931a6c70ad29fc585cb/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6", size = 1156301, upload-time = "2025-09-08T23:08:22.47Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7", size = 1341197, upload-time = "2025-09-08T23:08:24.286Z" }, + { url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275, upload-time = "2025-09-08T23:08:26.063Z" }, + { url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469, upload-time = "2025-09-08T23:08:27.623Z" }, + { url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961, upload-time = "2025-09-08T23:08:29.672Z" }, + { url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282, upload-time = "2025-09-08T23:08:31.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468, upload-time = "2025-09-08T23:08:33.543Z" }, + { url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394, upload-time = "2025-09-08T23:08:35.51Z" }, + { url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964, upload-time = "2025-09-08T23:08:37.178Z" }, + { url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029, upload-time = "2025-09-08T23:08:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541, upload-time = "2025-09-08T23:08:42.668Z" }, + { url = "https://files.pythonhosted.org/packages/87/45/19efbb3000956e82d0331bafca5d9ac19ea2857722fa2caacefb6042f39d/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a", size = 1341197, upload-time = "2025-09-08T23:08:44.973Z" }, + { url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea", size = 897175, upload-time = "2025-09-08T23:08:46.601Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96", size = 660427, upload-time = "2025-09-08T23:08:48.187Z" }, + { url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d", size = 847929, upload-time = "2025-09-08T23:08:49.76Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146", size = 1650193, upload-time = "2025-09-08T23:08:51.7Z" }, + { url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd", size = 2024388, upload-time = "2025-09-08T23:08:53.393Z" }, + { url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a", size = 1885316, upload-time = "2025-09-08T23:08:55.702Z" }, + { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" }, + { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" }, + { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" }, ] [[package]] name = "requests" -version = "2.32.3" +version = "2.32.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -949,52 +1081,53 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[package]] name = "ruff" -version = "0.8.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5e/2b/01245f4f3a727d60bebeacd7ee6d22586c7f62380a2597ddb22c2f45d018/ruff-0.8.2.tar.gz", hash = "sha256:b84f4f414dda8ac7f75075c1fa0b905ac0ff25361f42e6d5da681a465e0f78e5", size = 3349020 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/91/29/366be70216dba1731a00a41f2f030822b0c96c7c4f3b2c0cdce15cbace74/ruff-0.8.2-py3-none-linux_armv6l.whl", hash = "sha256:c49ab4da37e7c457105aadfd2725e24305ff9bc908487a9bf8d548c6dad8bb3d", size = 10530649 }, - { url = "https://files.pythonhosted.org/packages/63/82/a733956540bb388f00df5a3e6a02467b16c0e529132625fe44ce4c5fb9c7/ruff-0.8.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ec016beb69ac16be416c435828be702ee694c0d722505f9c1f35e1b9c0cc1bf5", size = 10274069 }, - { url = "https://files.pythonhosted.org/packages/3d/12/0b3aa14d1d71546c988a28e1b412981c1b80c8a1072e977a2f30c595cc4a/ruff-0.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f05cdf8d050b30e2ba55c9b09330b51f9f97d36d4673213679b965d25a785f3c", size = 9909400 }, - { url = "https://files.pythonhosted.org/packages/23/08/f9f08cefb7921784c891c4151cce6ed357ff49e84b84978440cffbc87408/ruff-0.8.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f578c11feb1d3d257b2fb043ddb47501ab4816e7e221fbb0077f0d5d4e7b6f", size = 10766782 }, - { url = "https://files.pythonhosted.org/packages/e4/71/bf50c321ec179aa420c8ec40adac5ae9cc408d4d37283a485b19a2331ceb/ruff-0.8.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbd5cf9b0ae8f30eebc7b360171bd50f59ab29d39f06a670b3e4501a36ba5897", size = 10286316 }, - { url = "https://files.pythonhosted.org/packages/f2/83/c82688a2a6117539aea0ce63fdf6c08e60fe0202779361223bcd7f40bd74/ruff-0.8.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b402ddee3d777683de60ff76da801fa7e5e8a71038f57ee53e903afbcefdaa58", size = 11338270 }, - { url = "https://files.pythonhosted.org/packages/7f/d7/bc6a45e5a22e627640388e703160afb1d77c572b1d0fda8b4349f334fc66/ruff-0.8.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:705832cd7d85605cb7858d8a13d75993c8f3ef1397b0831289109e953d833d29", size = 12058579 }, - { url = "https://files.pythonhosted.org/packages/da/3b/64150c93946ec851e6f1707ff586bb460ca671581380c919698d6a9267dc/ruff-0.8.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32096b41aaf7a5cc095fa45b4167b890e4c8d3fd217603f3634c92a541de7248", size = 11615172 }, - { url = "https://files.pythonhosted.org/packages/e4/9e/cf12b697ea83cfe92ec4509ae414dc4c9b38179cc681a497031f0d0d9a8e/ruff-0.8.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e769083da9439508833cfc7c23e351e1809e67f47c50248250ce1ac52c21fb93", size = 12882398 }, - { url = "https://files.pythonhosted.org/packages/a9/27/96d10863accf76a9c97baceac30b0a52d917eb985a8ac058bd4636aeede0/ruff-0.8.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fe716592ae8a376c2673fdfc1f5c0c193a6d0411f90a496863c99cd9e2ae25d", size = 11176094 }, - { url = "https://files.pythonhosted.org/packages/eb/10/cd2fd77d4a4e7f03c29351be0f53278a393186b540b99df68beb5304fddd/ruff-0.8.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:81c148825277e737493242b44c5388a300584d73d5774defa9245aaef55448b0", size = 10771884 }, - { url = "https://files.pythonhosted.org/packages/71/5d/beabb2ff18870fc4add05fa3a69a4cb1b1d2d6f83f3cf3ae5ab0d52f455d/ruff-0.8.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d261d7850c8367704874847d95febc698a950bf061c9475d4a8b7689adc4f7fa", size = 10382535 }, - { url = "https://files.pythonhosted.org/packages/ae/29/6b3fdf3ad3e35b28d87c25a9ff4c8222ad72485ab783936b2b267250d7a7/ruff-0.8.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1ca4e3a87496dc07d2427b7dd7ffa88a1e597c28dad65ae6433ecb9f2e4f022f", size = 10886995 }, - { url = "https://files.pythonhosted.org/packages/e9/dc/859d889b4d9356a1a2cdbc1e4a0dda94052bc5b5300098647e51a58c430b/ruff-0.8.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:729850feed82ef2440aa27946ab39c18cb4a8889c1128a6d589ffa028ddcfc22", size = 11220750 }, - { url = "https://files.pythonhosted.org/packages/0b/08/e8f519f61f1d624264bfd6b8829e4c5f31c3c61193bc3cff1f19dbe7626a/ruff-0.8.2-py3-none-win32.whl", hash = "sha256:ac42caaa0411d6a7d9594363294416e0e48fc1279e1b0e948391695db2b3d5b1", size = 8729396 }, - { url = "https://files.pythonhosted.org/packages/f8/d4/ba1c7ab72aba37a2b71fe48ab95b80546dbad7a7f35ea28cf66fc5cea5f6/ruff-0.8.2-py3-none-win_amd64.whl", hash = "sha256:2aae99ec70abf43372612a838d97bfe77d45146254568d94926e8ed5bbb409ea", size = 9594729 }, - { url = "https://files.pythonhosted.org/packages/23/34/db20e12d3db11b8a2a8874258f0f6d96a9a4d631659d54575840557164c8/ruff-0.8.2-py3-none-win_arm64.whl", hash = "sha256:fb88e2a506b70cfbc2de6fae6681c4f944f7dd5f2fe87233a7233d888bad73e8", size = 9035131 }, +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/41/b9/9bd84453ed6dd04688de9b3f3a4146a1698e8faae2ceeccce4e14c67ae17/ruff-0.14.0.tar.gz", hash = "sha256:62ec8969b7510f77945df916de15da55311fade8d6050995ff7f680afe582c57", size = 5452071, upload-time = "2025-10-07T18:21:55.763Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/4e/79d463a5f80654e93fa653ebfb98e0becc3f0e7cf6219c9ddedf1e197072/ruff-0.14.0-py3-none-linux_armv6l.whl", hash = "sha256:58e15bffa7054299becf4bab8a1187062c6f8cafbe9f6e39e0d5aface455d6b3", size = 12494532, upload-time = "2025-10-07T18:21:00.373Z" }, + { url = "https://files.pythonhosted.org/packages/ee/40/e2392f445ed8e02aa6105d49db4bfff01957379064c30f4811c3bf38aece/ruff-0.14.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:838d1b065f4df676b7c9957992f2304e41ead7a50a568185efd404297d5701e8", size = 13160768, upload-time = "2025-10-07T18:21:04.73Z" }, + { url = "https://files.pythonhosted.org/packages/75/da/2a656ea7c6b9bd14c7209918268dd40e1e6cea65f4bb9880eaaa43b055cd/ruff-0.14.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:703799d059ba50f745605b04638fa7e9682cc3da084b2092feee63500ff3d9b8", size = 12363376, upload-time = "2025-10-07T18:21:07.833Z" }, + { url = "https://files.pythonhosted.org/packages/42/e2/1ffef5a1875add82416ff388fcb7ea8b22a53be67a638487937aea81af27/ruff-0.14.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ba9a8925e90f861502f7d974cc60e18ca29c72bb0ee8bfeabb6ade35a3abde7", size = 12608055, upload-time = "2025-10-07T18:21:10.72Z" }, + { url = "https://files.pythonhosted.org/packages/4a/32/986725199d7cee510d9f1dfdf95bf1efc5fa9dd714d0d85c1fb1f6be3bc3/ruff-0.14.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e41f785498bd200ffc276eb9e1570c019c1d907b07cfb081092c8ad51975bbe7", size = 12318544, upload-time = "2025-10-07T18:21:13.741Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ed/4969cefd53315164c94eaf4da7cfba1f267dc275b0abdd593d11c90829a3/ruff-0.14.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30a58c087aef4584c193aebf2700f0fbcfc1e77b89c7385e3139956fa90434e2", size = 14001280, upload-time = "2025-10-07T18:21:16.411Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ad/96c1fc9f8854c37681c9613d825925c7f24ca1acfc62a4eb3896b50bacd2/ruff-0.14.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f8d07350bc7af0a5ce8812b7d5c1a7293cf02476752f23fdfc500d24b79b783c", size = 15027286, upload-time = "2025-10-07T18:21:19.577Z" }, + { url = "https://files.pythonhosted.org/packages/b3/00/1426978f97df4fe331074baf69615f579dc4e7c37bb4c6f57c2aad80c87f/ruff-0.14.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eec3bbbf3a7d5482b5c1f42d5fc972774d71d107d447919fca620b0be3e3b75e", size = 14451506, upload-time = "2025-10-07T18:21:22.779Z" }, + { url = "https://files.pythonhosted.org/packages/58/d5/9c1cea6e493c0cf0647674cca26b579ea9d2a213b74b5c195fbeb9678e15/ruff-0.14.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16b68e183a0e28e5c176d51004aaa40559e8f90065a10a559176713fcf435206", size = 13437384, upload-time = "2025-10-07T18:21:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/29/b4/4cd6a4331e999fc05d9d77729c95503f99eae3ba1160469f2b64866964e3/ruff-0.14.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb732d17db2e945cfcbbc52af0143eda1da36ca8ae25083dd4f66f1542fdf82e", size = 13447976, upload-time = "2025-10-07T18:21:28.83Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c0/ac42f546d07e4f49f62332576cb845d45c67cf5610d1851254e341d563b6/ruff-0.14.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:c958f66ab884b7873e72df38dcabee03d556a8f2ee1b8538ee1c2bbd619883dd", size = 13682850, upload-time = "2025-10-07T18:21:31.842Z" }, + { url = "https://files.pythonhosted.org/packages/5f/c4/4b0c9bcadd45b4c29fe1af9c5d1dc0ca87b4021665dfbe1c4688d407aa20/ruff-0.14.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7eb0499a2e01f6e0c285afc5bac43ab380cbfc17cd43a2e1dd10ec97d6f2c42d", size = 12449825, upload-time = "2025-10-07T18:21:35.074Z" }, + { url = "https://files.pythonhosted.org/packages/4b/a8/e2e76288e6c16540fa820d148d83e55f15e994d852485f221b9524514730/ruff-0.14.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4c63b2d99fafa05efca0ab198fd48fa6030d57e4423df3f18e03aa62518c565f", size = 12272599, upload-time = "2025-10-07T18:21:38.08Z" }, + { url = "https://files.pythonhosted.org/packages/18/14/e2815d8eff847391af632b22422b8207704222ff575dec8d044f9ab779b2/ruff-0.14.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:668fce701b7a222f3f5327f86909db2bbe99c30877c8001ff934c5413812ac02", size = 13193828, upload-time = "2025-10-07T18:21:41.216Z" }, + { url = "https://files.pythonhosted.org/packages/44/c6/61ccc2987cf0aecc588ff8f3212dea64840770e60d78f5606cd7dc34de32/ruff-0.14.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a86bf575e05cb68dcb34e4c7dfe1064d44d3f0c04bbc0491949092192b515296", size = 13628617, upload-time = "2025-10-07T18:21:44.04Z" }, + { url = "https://files.pythonhosted.org/packages/73/e6/03b882225a1b0627e75339b420883dc3c90707a8917d2284abef7a58d317/ruff-0.14.0-py3-none-win32.whl", hash = "sha256:7450a243d7125d1c032cb4b93d9625dea46c8c42b4f06c6b709baac168e10543", size = 12367872, upload-time = "2025-10-07T18:21:46.67Z" }, + { url = "https://files.pythonhosted.org/packages/41/77/56cf9cf01ea0bfcc662de72540812e5ba8e9563f33ef3d37ab2174892c47/ruff-0.14.0-py3-none-win_amd64.whl", hash = "sha256:ea95da28cd874c4d9c922b39381cbd69cb7e7b49c21b8152b014bd4f52acddc2", size = 13464628, upload-time = "2025-10-07T18:21:50.318Z" }, + { url = "https://files.pythonhosted.org/packages/c6/2a/65880dfd0e13f7f13a775998f34703674a4554906167dce02daf7865b954/ruff-0.14.0-py3-none-win_arm64.whl", hash = "sha256:f42c9495f5c13ff841b1da4cb3c2a42075409592825dada7c5885c2c844ac730", size = 12565142, upload-time = "2025-10-07T18:21:53.577Z" }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "smmap" -version = "5.0.1" +version = "5.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/04/b5bf6d21dc4041000ccba7eb17dd3055feb237e7ffc2c20d3fae3af62baa/smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", size = 22291 } +sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329, upload-time = "2025-01-02T07:14:40.909Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/a5/10f97f73544edcdef54409f1d839f6049a0d79df68adbc1ceb24d1aaca42/smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da", size = 24282 }, + { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" }, ] [[package]] @@ -1006,14 +1139,14 @@ dependencies = [ { name = "executing" }, { name = "pure-eval" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707 } +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 }, + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, ] [[package]] name = "thecodecrate-pipeline" -version = "1.23.0" +version = "1.26.0" source = { editable = "." } [package.dev-dependencies] @@ -1027,7 +1160,7 @@ dev = [ { name = "mkdocs-git-revision-date-localized-plugin" }, { name = "mkdocs-material" }, { name = "mkdocs-minify-plugin" }, - { name = "mkdocstrings", extra = ["python"] }, + { name = "mkdocstrings-python" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, @@ -1038,93 +1171,94 @@ dev = [ [package.metadata.requires-dev] dev = [ - { name = "black", specifier = ">=24.10.0" }, - { name = "bumpver", specifier = ">=2024.1130" }, - { name = "debugpy", specifier = ">=1.8.9" }, - { name = "ipykernel", specifier = ">=6.29.5" }, - { name = "mkdocs-autorefs", specifier = ">=1.2.0" }, + { name = "black", specifier = ">=25.9.0" }, + { name = "bumpver", specifier = ">=2025.1131" }, + { name = "debugpy", specifier = ">=1.8.17" }, + { name = "ipykernel", specifier = ">=6.30.1" }, + { name = "mkdocs-autorefs", specifier = ">=1.4.3" }, { name = "mkdocs-gen-files", specifier = ">=0.5.0" }, - { name = "mkdocs-git-revision-date-localized-plugin", specifier = ">=1.3.0" }, - { name = "mkdocs-material", specifier = ">=9.5.48" }, + { name = "mkdocs-git-revision-date-localized-plugin", specifier = ">=1.4.7" }, + { name = "mkdocs-material", specifier = ">=9.6.21" }, { name = "mkdocs-minify-plugin", specifier = ">=0.8.0" }, - { name = "mkdocstrings", extras = ["python"], specifier = ">=0.27.0" }, - { name = "pytest", specifier = ">=8.3.4" }, - { name = "pytest-asyncio", specifier = ">=0.24.0" }, - { name = "pytest-cov", specifier = ">=6.0.0" }, - { name = "ruff", specifier = ">=0.8.2" }, + { name = "mkdocstrings-python", specifier = ">=1.18.2" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "pytest-asyncio", specifier = ">=1.2.0" }, + { name = "pytest-cov", specifier = ">=7.0.0" }, + { name = "ruff", specifier = ">=0.14.0" }, ] [[package]] name = "toml" version = "0.10.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253 } +sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588 }, + { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, ] [[package]] name = "tornado" -version = "6.4.2" +version = "6.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/59/45/a0daf161f7d6f36c3ea5fc0c2de619746cc3dd4c76402e9db545bd920f63/tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b", size = 501135 } +sdist = { url = "https://files.pythonhosted.org/packages/09/ce/1eb500eae19f4648281bb2186927bb062d2438c2e5093d1360391afd2f90/tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0", size = 510821, upload-time = "2025-08-08T18:27:00.78Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/7e/71f604d8cea1b58f82ba3590290b66da1e72d840aeb37e0d5f7291bd30db/tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1", size = 436299 }, - { url = "https://files.pythonhosted.org/packages/96/44/87543a3b99016d0bf54fdaab30d24bf0af2e848f1d13d34a3a5380aabe16/tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803", size = 434253 }, - { url = "https://files.pythonhosted.org/packages/cb/fb/fdf679b4ce51bcb7210801ef4f11fdac96e9885daa402861751353beea6e/tornado-6.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec", size = 437602 }, - { url = "https://files.pythonhosted.org/packages/4f/3b/e31aeffffc22b475a64dbeb273026a21b5b566f74dee48742817626c47dc/tornado-6.4.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946", size = 436972 }, - { url = "https://files.pythonhosted.org/packages/22/55/b78a464de78051a30599ceb6983b01d8f732e6f69bf37b4ed07f642ac0fc/tornado-6.4.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca9eb02196e789c9cb5c3c7c0f04fb447dc2adffd95265b2c7223a8a615ccbf", size = 437173 }, - { url = "https://files.pythonhosted.org/packages/79/5e/be4fb0d1684eb822c9a62fb18a3e44a06188f78aa466b2ad991d2ee31104/tornado-6.4.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634", size = 437892 }, - { url = "https://files.pythonhosted.org/packages/f5/33/4f91fdd94ea36e1d796147003b490fe60a0215ac5737b6f9c65e160d4fe0/tornado-6.4.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73", size = 437334 }, - { url = "https://files.pythonhosted.org/packages/2b/ae/c1b22d4524b0e10da2f29a176fb2890386f7bd1f63aacf186444873a88a0/tornado-6.4.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c", size = 437261 }, - { url = "https://files.pythonhosted.org/packages/b5/25/36dbd49ab6d179bcfc4c6c093a51795a4f3bed380543a8242ac3517a1751/tornado-6.4.2-cp38-abi3-win32.whl", hash = "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482", size = 438463 }, - { url = "https://files.pythonhosted.org/packages/61/cc/58b1adeb1bb46228442081e746fcdbc4540905c87e8add7c277540934edb/tornado-6.4.2-cp38-abi3-win_amd64.whl", hash = "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38", size = 438907 }, + { url = "https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6", size = 442563, upload-time = "2025-08-08T18:26:42.945Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef", size = 440729, upload-time = "2025-08-08T18:26:44.473Z" }, + { url = "https://files.pythonhosted.org/packages/1b/4e/619174f52b120efcf23633c817fd3fed867c30bff785e2cd5a53a70e483c/tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e", size = 444295, upload-time = "2025-08-08T18:26:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/95/fa/87b41709552bbd393c85dd18e4e3499dcd8983f66e7972926db8d96aa065/tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882", size = 443644, upload-time = "2025-08-08T18:26:47.625Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/fb15f06e33d7430ca89420283a8762a4e6b8025b800ea51796ab5e6d9559/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108", size = 443878, upload-time = "2025-08-08T18:26:50.599Z" }, + { url = "https://files.pythonhosted.org/packages/11/92/fe6d57da897776ad2e01e279170ea8ae726755b045fe5ac73b75357a5a3f/tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c", size = 444549, upload-time = "2025-08-08T18:26:51.864Z" }, + { url = "https://files.pythonhosted.org/packages/9b/02/c8f4f6c9204526daf3d760f4aa555a7a33ad0e60843eac025ccfd6ff4a93/tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4", size = 443973, upload-time = "2025-08-08T18:26:53.625Z" }, + { url = "https://files.pythonhosted.org/packages/ae/2d/f5f5707b655ce2317190183868cd0f6822a1121b4baeae509ceb9590d0bd/tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04", size = 443954, upload-time = "2025-08-08T18:26:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/e8/59/593bd0f40f7355806bf6573b47b8c22f8e1374c9b6fd03114bd6b7a3dcfd/tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0", size = 445023, upload-time = "2025-08-08T18:26:56.677Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/f609b420c2f564a748a2d80ebfb2ee02a73ca80223af712fca591386cafb/tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f", size = 445427, upload-time = "2025-08-08T18:26:57.91Z" }, + { url = "https://files.pythonhosted.org/packages/5e/4f/e1f65e8f8c76d73658b33d33b81eed4322fb5085350e4328d5c956f0c8f9/tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af", size = 444456, upload-time = "2025-08-08T18:26:59.207Z" }, ] [[package]] name = "traitlets" version = "5.14.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621 } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359 }, + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, ] [[package]] name = "urllib3" -version = "2.2.3" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] name = "watchdog" version = "6.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220 } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480 }, - { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451 }, - { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057 }, - { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079 }, - { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078 }, - { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076 }, - { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077 }, - { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078 }, - { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077 }, - { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078 }, - { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065 }, - { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070 }, - { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067 }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, ] [[package]] name = "wcwidth" -version = "0.2.13" +version = "0.2.14" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301 } +sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, + { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, ]