diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4154a19e..603061a1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -46,7 +46,7 @@ jobs:
github_workflows: ${{ steps.changes.outputs.github_workflows }}
steps:
- name: "Check out repository code"
- uses: "actions/checkout@v5"
+ uses: "actions/checkout@v6"
- name: Check for file changes
uses: dorny/paths-filter@v3
id: changes
@@ -63,7 +63,7 @@ jobs:
timeout-minutes: 5
steps:
- name: "Check out repository code"
- uses: "actions/checkout@v5"
+ uses: "actions/checkout@v6"
- name: "Setup environment"
run: "pip install yamllint==1.35.1"
- name: "Linting: yamllint"
@@ -71,18 +71,26 @@ jobs:
python-lint:
if: needs.files-changed.outputs.python == 'true'
- needs: ["files-changed"]
+ needs: ["files-changed", "prepare-environment"]
runs-on: "ubuntu-latest"
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v5"
- - name: "Setup environment"
- run: "pip install ruff==0.11.0"
+ - name: Set up Python
+ uses: actions/setup-python@v6
+ with:
+ python-version: "3.12"
+ - name: Install UV
+ uses: astral-sh/setup-uv@v7
+ with:
+ version: "${{ needs.prepare-environment.outputs.UV_VERSION }}"
+ - name: Install dependencies
+ run: uv sync --group lint
- name: "Linting: ruff check"
- run: "ruff check ."
+ run: "uv run ruff check ."
- name: "Linting: ruff format"
- run: "ruff format --check --diff ."
+ run: "uv run ruff format --check --diff ."
markdown-lint:
@@ -94,9 +102,9 @@ jobs:
timeout-minutes: 5
steps:
- name: "Check out repository code"
- uses: "actions/checkout@v5"
+ uses: "actions/checkout@v6"
- name: "Linting: markdownlint"
- uses: DavidAnson/markdownlint-cli2-action@v20
+ uses: DavidAnson/markdownlint-cli2-action@v21
with:
config: .markdownlint.yaml
globs: |
@@ -110,7 +118,7 @@ jobs:
timeout-minutes: 5
steps:
- name: "Check out repository code"
- uses: "actions/checkout@v5"
+ uses: "actions/checkout@v6"
- name: Check workflow files
run: |
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
@@ -156,7 +164,7 @@ jobs:
timeout-minutes: 5
steps:
- name: "Check out repository code"
- uses: "actions/checkout@v5"
+ uses: "actions/checkout@v6"
with:
submodules: true
- name: Install NodeJS
@@ -172,7 +180,7 @@ jobs:
with:
python-version: "3.12"
- name: Install UV
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v7
with:
version: "${{ needs.prepare-environment.outputs.UV_VERSION }}"
- name: Install dependencies
@@ -191,7 +199,7 @@ jobs:
timeout-minutes: 5
steps:
- name: "Check out repository code"
- uses: "actions/checkout@v5"
+ uses: "actions/checkout@v6"
with:
submodules: true
- name: Set up Python
@@ -199,7 +207,7 @@ jobs:
with:
python-version: "3.12"
- name: Install UV
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v7
with:
version: "${{ needs.prepare-environment.outputs.UV_VERSION }}"
- name: Install dependencies
@@ -217,7 +225,7 @@ jobs:
timeout-minutes: 5
steps:
- name: "Check out repository code"
- uses: "actions/checkout@v5"
+ uses: "actions/checkout@v6"
with:
submodules: true
@@ -239,7 +247,6 @@ jobs:
strategy:
matrix:
python-version:
- - "3.9"
- "3.10"
- "3.11"
- "3.12"
@@ -254,15 +261,16 @@ jobs:
timeout-minutes: 30
steps:
- name: "Check out repository code"
- uses: "actions/checkout@v5"
+ uses: "actions/checkout@v6"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v7
with:
version: "${{ needs.prepare-environment.outputs.UV_VERSION }}"
+ python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --all-groups --all-extras
- name: Mypy Tests
@@ -301,7 +309,7 @@ jobs:
timeout-minutes: 30
steps:
- name: "Check out repository code"
- uses: "actions/checkout@v5"
+ uses: "actions/checkout@v6"
- name: Set up Python
uses: actions/setup-python@v6
with:
@@ -311,7 +319,7 @@ jobs:
RUNNER_NAME=$(echo "${{ runner.name }}" | grep -o 'ghrunner[0-9]\+' | sed 's/ghrunner\([0-9]\+\)/ghrunner_\1/')
echo "PYTEST_DEBUG_TEMPROOT=/var/lib/github/${RUNNER_NAME}/_temp" >> $GITHUB_ENV
- name: Install UV
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v7
with:
version: "${{ needs.prepare-environment.outputs.UV_VERSION }}"
- name: Install dependencies
@@ -339,14 +347,14 @@ jobs:
# timeout-minutes: 30
# steps:
# - name: "Check out repository code"
- # uses: "actions/checkout@v5"
+ # uses: "actions/checkout@v6"
# - name: "Extract target branch name"
# id: extract_branch
# run: echo "TARGET_BRANCH=${{ github.base_ref }}" >> $GITHUB_ENV
# - name: "Checkout infrahub repository"
- # uses: "actions/checkout@v5"
+ # uses: "actions/checkout@v6"
# with:
# repository: "opsmill/infrahub"
# path: "infrahub-server"
diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml
index aa7c4002..9d558080 100644
--- a/.github/workflows/labels.yml
+++ b/.github/workflows/labels.yml
@@ -17,7 +17,7 @@ jobs:
steps:
-
name: Checkout
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
-
name: Run Labeler
uses: crazy-max/ghaction-github-labeler@v5
diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml
index 2c838d3c..96bb84a7 100644
--- a/.github/workflows/publish-pypi.yml
+++ b/.github/workflows/publish-pypi.yml
@@ -46,8 +46,8 @@ jobs:
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- - name: Check out repository code
- uses: "actions/checkout@v5"
+ - name: "Check out repository code"
+ uses: "actions/checkout@v6"
with:
submodules: true
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b9384541..1f0a088b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -21,7 +21,7 @@ jobs:
latest_tag: ${{ steps.release.outputs.latest_tag }}
steps:
- name: "Check out repository code"
- uses: "actions/checkout@v5"
+ uses: "actions/checkout@v6"
with:
submodules: true
diff --git a/.github/workflows/repository-dispatch.yml b/.github/workflows/repository-dispatch.yml
index 33f9eaee..261429df 100644
--- a/.github/workflows/repository-dispatch.yml
+++ b/.github/workflows/repository-dispatch.yml
@@ -42,7 +42,7 @@ jobs:
steps:
- name: Checkout code
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v4
diff --git a/.github/workflows/sync-docs.yml b/.github/workflows/sync-docs.yml
index 6ed64d59..65574ce7 100644
--- a/.github/workflows/sync-docs.yml
+++ b/.github/workflows/sync-docs.yml
@@ -16,12 +16,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout source repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
path: source-repo
- name: Checkout target repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
repository: opsmill/infrahub-docs
token: ${{ secrets.PAT_TOKEN }}
diff --git a/.github/workflows/update-submodule.yml b/.github/workflows/update-submodule.yml
index 314a6ac7..726201cd 100644
--- a/.github/workflows/update-submodule.yml
+++ b/.github/workflows/update-submodule.yml
@@ -33,7 +33,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
- name: Trigger submodule update
run: |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1988a9e4..f66416f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,22 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang
+## [1.16.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.16.0) - 2025-12-01
+
+### Added
+
+- Added infrahubctl branch report command to help with cleaning up branches in Infrahub.
+
+### Changed
+
+- Updated behaviour for recursive lookups for the conversion of nested relationships. Note that this change could cause issues in transforms or generators that use the convert_query_response feature if "id" or "__typename" isn't requested for nested related objects. ([#389](https://github.com/opsmill/infrahub-sdk-python/issues/389))
+- The project now uses `uv` instead of `poetry` for package and dependency management.
+
+### Removed
+
+- Remove `is_visible` property from infrahub
+- Removed support for Python 3.9 (end of life)
+
## [1.15.1](https://github.com/opsmill/infrahub-sdk-python/tree/v1.15.1) - 2025-11-13
### Fixed
diff --git a/docs/_templates/sdk_template_reference.j2 b/docs/_templates/sdk_template_reference.j2
index 7b7148db..b8a89c90 100644
--- a/docs/_templates/sdk_template_reference.j2
+++ b/docs/_templates/sdk_template_reference.j2
@@ -9,7 +9,7 @@ The following filters are those that are [shipped with Jinja2](https://jinja.pal
| Name | Trusted |
-|----------|----------|
+| ---- | ------- |
{% for filter in builtin %}
| {{ filter.name }} | {% if filter.trusted %}✅{% else %}❌{% endif %} |
{% endfor %}
@@ -20,7 +20,7 @@ The following filters are those that are [shipped with Jinja2](https://jinja.pal
The following Jinja2 filters from Netutils are included within Infrahub.
| Name | Trusted |
-|----------|----------|
+| ---- | ------- |
{% for filter in netutils %}
| {{ filter.name }} | {% if filter.trusted %}✅{% else %}❌{% endif %} |
{% endfor %}
diff --git a/docs/docs/infrahubctl/infrahubctl-branch.mdx b/docs/docs/infrahubctl/infrahubctl-branch.mdx
index 1a6c0b3e..a0524ff5 100644
--- a/docs/docs/infrahubctl/infrahubctl-branch.mdx
+++ b/docs/docs/infrahubctl/infrahubctl-branch.mdx
@@ -23,6 +23,7 @@ $ infrahubctl branch [OPTIONS] COMMAND [ARGS]...
* `list`: List all existing branches.
* `merge`: Merge a Branch with main.
* `rebase`: Rebase a Branch with main.
+* `report`: Generate branch cleanup status report.
* `validate`: Validate if a branch has some conflict and...
## `infrahubctl branch create`
@@ -118,6 +119,26 @@ $ infrahubctl branch rebase [OPTIONS] BRANCH_NAME
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
* `--help`: Show this message and exit.
+## `infrahubctl branch report`
+
+Generate branch cleanup status report.
+
+**Usage**:
+
+```console
+$ infrahubctl branch report [OPTIONS] BRANCH_NAME
+```
+
+**Arguments**:
+
+* `BRANCH_NAME`: Branch name to generate report for [required]
+
+**Options**:
+
+* `--update-diff`: Update diff before generating report
+* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
+* `--help`: Show this message and exit.
+
## `infrahubctl branch validate`
Validate if a branch has some conflict and is passing all the tests (NOT IMPLEMENTED YET).
diff --git a/docs/docs/python-sdk/reference/templating.mdx b/docs/docs/python-sdk/reference/templating.mdx
index 043d8dcc..b74f5f2f 100644
--- a/docs/docs/python-sdk/reference/templating.mdx
+++ b/docs/docs/python-sdk/reference/templating.mdx
@@ -9,7 +9,7 @@ The following filters are those that are [shipped with Jinja2](https://jinja.pal
| Name | Trusted |
-|----------|----------|
+| ---- | ------- |
| abs | ✅ |
| attr | ❌ |
| batch | ❌ |
@@ -71,7 +71,7 @@ The following filters are those that are [shipped with Jinja2](https://jinja.pal
The following Jinja2 filters from Netutils are included within Infrahub.
| Name | Trusted |
-|----------|----------|
+| ---- | ------- |
| abbreviated_interface_name | ✅ |
| abbreviated_interface_name_list | ✅ |
| asn_to_int | ✅ |
diff --git a/docs/docs/python-sdk/topics/object_file.mdx b/docs/docs/python-sdk/topics/object_file.mdx
index f3e426ae..751599f0 100644
--- a/docs/docs/python-sdk/topics/object_file.mdx
+++ b/docs/docs/python-sdk/topics/object_file.mdx
@@ -72,8 +72,8 @@ spec:
The `parameters` field controls how the data in the object file is processed before loading into Infrahub:
-| Parameter | Description | Default |
-|-----------|-------------|---------|
+| Parameter | Description | Default |
+| -------------- | ------------------------------------------------------------------------------------------------------- | ------- |
| `expand_range` | When set to `true`, range patterns (e.g., `[1-5]`) in string fields are expanded into multiple objects. | `false` |
When `expand_range` is not specified, it defaults to `false`.
diff --git a/infrahub_sdk/async_typer.py b/infrahub_sdk/async_typer.py
index 39014a32..aab67824 100644
--- a/infrahub_sdk/async_typer.py
+++ b/infrahub_sdk/async_typer.py
@@ -2,8 +2,9 @@
import asyncio
import inspect
+from collections.abc import Callable
from functools import partial, wraps
-from typing import Any, Callable
+from typing import Any
from typer import Typer
diff --git a/infrahub_sdk/batch.py b/infrahub_sdk/batch.py
index 49e974ca..c86d7c77 100644
--- a/infrahub_sdk/batch.py
+++ b/infrahub_sdk/batch.py
@@ -1,10 +1,10 @@
from __future__ import annotations
import asyncio
-from collections.abc import AsyncGenerator, Awaitable, Generator
+from collections.abc import AsyncGenerator, Awaitable, Callable, Generator
from concurrent.futures import ThreadPoolExecutor
from dataclasses import dataclass
-from typing import TYPE_CHECKING, Any, Callable
+from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
from .node import InfrahubNode, InfrahubNodeSync
diff --git a/infrahub_sdk/client.py b/infrahub_sdk/client.py
index d7b79047..2ef90c0a 100644
--- a/infrahub_sdk/client.py
+++ b/infrahub_sdk/client.py
@@ -5,14 +5,13 @@
import logging
import time
import warnings
-from collections.abc import Coroutine, Mapping, MutableMapping
+from collections.abc import Callable, Coroutine, Mapping, MutableMapping
from datetime import datetime
from functools import wraps
from time import sleep
from typing import (
TYPE_CHECKING,
Any,
- Callable,
Literal,
TypedDict,
TypeVar,
@@ -35,7 +34,7 @@
from .constants import InfrahubClientMode
from .convert_object_type import CONVERT_OBJECT_MUTATION, ConversionFieldInput
from .data import RepositoryBranchInfo, RepositoryData
-from .diff import NodeDiff, diff_tree_node_to_node_diff, get_diff_summary_query
+from .diff import DiffTreeData, NodeDiff, diff_tree_node_to_node_diff, get_diff_summary_query, get_diff_tree_query
from .exceptions import (
AuthenticationError,
Error,
@@ -300,7 +299,7 @@ def _build_ip_prefix_allocation_query(
if prefix_length:
input_data["prefix_length"] = prefix_length
if member_type:
- if member_type not in ("prefix", "address"):
+ if member_type not in {"prefix", "address"}:
raise ValueError("member_type possible values are 'prefix' or 'address'")
input_data["member_type"] = member_type
if prefix_type:
@@ -957,7 +956,7 @@ async def execute_graphql(
try:
resp = await self._post(url=url, payload=payload, headers=headers, timeout=timeout)
- if raise_for_error in (None, True):
+ if raise_for_error in {None, True}:
resp.raise_for_status()
retry = False
@@ -971,7 +970,7 @@ async def execute_graphql(
self.log.error(f"Unable to connect to {self.address} .. ")
raise
except httpx.HTTPStatusError as exc:
- if exc.response.status_code in [401, 403]:
+ if exc.response.status_code in {401, 403}:
response = decode_json(response=exc.response)
errors = response.get("errors", [])
messages = [error.get("message") for error in errors]
@@ -1209,7 +1208,7 @@ async def query_gql_query(
timeout=timeout or self.default_timeout,
)
- if raise_for_error in (None, True):
+ if raise_for_error in {None, True}:
resp.raise_for_status()
return decode_json(response=resp)
@@ -1283,6 +1282,62 @@ async def get_diff_summary(
return node_diffs
+ async def get_diff_tree(
+ self,
+ branch: str,
+ name: str | None = None,
+ from_time: datetime | None = None,
+ to_time: datetime | None = None,
+ timeout: int | None = None,
+ tracker: str | None = None,
+ ) -> DiffTreeData | None:
+ """Get complete diff tree with metadata and nodes.
+
+ Returns None if no diff exists.
+ """
+ query = get_diff_tree_query()
+ input_data = {"branch_name": branch}
+ if name:
+ input_data["name"] = name
+ if from_time and to_time and from_time > to_time:
+ raise ValueError("from_time must be <= to_time")
+ if from_time:
+ input_data["from_time"] = from_time.isoformat()
+ if to_time:
+ input_data["to_time"] = to_time.isoformat()
+
+ response = await self.execute_graphql(
+ query=query.render(),
+ branch_name=branch,
+ timeout=timeout,
+ tracker=tracker,
+ variables=input_data,
+ )
+
+ diff_tree = response["DiffTree"]
+ if diff_tree is None:
+ return None
+
+ # Convert nodes to NodeDiff objects
+ node_diffs: list[NodeDiff] = []
+ if "nodes" in diff_tree:
+ for node_dict in diff_tree["nodes"]:
+ node_diff = diff_tree_node_to_node_diff(node_dict=node_dict, branch_name=branch)
+ node_diffs.append(node_diff)
+
+ return DiffTreeData(
+ num_added=diff_tree.get("num_added") or 0,
+ num_updated=diff_tree.get("num_updated") or 0,
+ num_removed=diff_tree.get("num_removed") or 0,
+ num_conflicts=diff_tree.get("num_conflicts") or 0,
+ to_time=diff_tree["to_time"],
+ from_time=diff_tree["from_time"],
+ base_branch=diff_tree["base_branch"],
+ diff_branch=diff_tree["diff_branch"],
+ name=diff_tree.get("name"),
+ nodes=node_diffs,
+ )
+
@overload
async def allocate_next_ip_address(
self,
@@ -1818,7 +1873,7 @@ def execute_graphql(
try:
resp = self._post(url=url, payload=payload, headers=headers, timeout=timeout)
- if raise_for_error in (None, True):
+ if raise_for_error in {None, True}:
resp.raise_for_status()
retry = False
@@ -1832,7 +1887,7 @@ def execute_graphql(
self.log.error(f"Unable to connect to {self.address} .. ")
raise
except httpx.HTTPStatusError as exc:
- if exc.response.status_code in [401, 403]:
+ if exc.response.status_code in {401, 403}:
response = decode_json(response=exc.response)
errors = response.get("errors", [])
messages = [error.get("message") for error in errors]
@@ -2447,7 +2502,7 @@ def query_gql_query(
timeout=timeout or self.default_timeout,
)
- if raise_for_error in (None, True):
+ if raise_for_error in {None, True}:
resp.raise_for_status()
return decode_json(response=resp)
@@ -2521,6 +2576,62 @@ def get_diff_summary(
return node_diffs
+ def get_diff_tree(
+ self,
+ branch: str,
+ name: str | None = None,
+ from_time: datetime | None = None,
+ to_time: datetime | None = None,
+ timeout: int | None = None,
+ tracker: str | None = None,
+ ) -> DiffTreeData | None:
+ """Get complete diff tree with metadata and nodes.
+
+ Returns None if no diff exists.
+ """
+ query = get_diff_tree_query()
+ input_data = {"branch_name": branch}
+ if name:
+ input_data["name"] = name
+ if from_time and to_time and from_time > to_time:
+ raise ValueError("from_time must be <= to_time")
+ if from_time:
+ input_data["from_time"] = from_time.isoformat()
+ if to_time:
+ input_data["to_time"] = to_time.isoformat()
+
+ response = self.execute_graphql(
+ query=query.render(),
+ branch_name=branch,
+ timeout=timeout,
+ tracker=tracker,
+ variables=input_data,
+ )
+
+ diff_tree = response["DiffTree"]
+ if diff_tree is None:
+ return None
+
+ # Convert nodes to NodeDiff objects
+ node_diffs: list[NodeDiff] = []
+ if "nodes" in diff_tree:
+ for node_dict in diff_tree["nodes"]:
+ node_diff = diff_tree_node_to_node_diff(node_dict=node_dict, branch_name=branch)
+ node_diffs.append(node_diff)
+
+ return DiffTreeData(
+ num_added=diff_tree.get("num_added") or 0,
+ num_updated=diff_tree.get("num_updated") or 0,
+ num_removed=diff_tree.get("num_removed") or 0,
+ num_conflicts=diff_tree.get("num_conflicts") or 0,
+ to_time=diff_tree["to_time"],
+ from_time=diff_tree["from_time"],
+ base_branch=diff_tree["base_branch"],
+ diff_branch=diff_tree["diff_branch"],
+ name=diff_tree.get("name"),
+ nodes=node_diffs,
+ )
+
@overload
def allocate_next_ip_address(
self,
diff --git a/infrahub_sdk/config.py b/infrahub_sdk/config.py
index 9a27df82..4c3ebbed 100644
--- a/infrahub_sdk/config.py
+++ b/infrahub_sdk/config.py
@@ -173,7 +173,7 @@ def logger(self) -> InfrahubLoggers:
# When using structlog the logger doesn't expose the expected methods by looking at the
# object to pydantic rejects them. This is a workaround to allow structlog to be used
# as a logger
- return self.log # type: ignore
+ return self.log # type: ignore[return-value]
@model_validator(mode="before")
@classmethod
@@ -194,7 +194,7 @@ def clone(self, branch: str | None = None) -> Config:
"log": self.log,
}
covered_keys = list(config.keys())
- for field in Config.model_fields.keys():
+ for field in Config.model_fields:
if field not in covered_keys:
config[field] = deepcopy(getattr(self, field))
diff --git a/infrahub_sdk/ctl/branch.py b/infrahub_sdk/ctl/branch.py
index 42d88384..60d67e86 100644
--- a/infrahub_sdk/ctl/branch.py
+++ b/infrahub_sdk/ctl/branch.py
@@ -1,15 +1,24 @@
import logging
+import sys
+from datetime import datetime, timezone
+from typing import TYPE_CHECKING
import typer
from rich.console import Console
from rich.table import Table
from ..async_typer import AsyncTyper
-from ..utils import calculate_time_diff
+from ..branch import BranchData
+from ..diff import DiffTreeData
+from ..protocols import CoreProposedChange
+from ..utils import calculate_time_diff, decode_json
from .client import initialize_client
from .parameters import CONFIG_PARAM
from .utils import catch_exception
+if TYPE_CHECKING:
+ from ..client import InfrahubClient
+
app = AsyncTyper()
console = Console()
@@ -18,6 +27,108 @@
ENVVAR_CONFIG_FILE = "INFRAHUBCTL_CONFIG"
+def format_timestamp(timestamp: str) -> str:
+ """Format ISO timestamp to 'YYYY-MM-DD HH:MM:SS'.
+ Args:
+ timestamp (str): ISO fromatted timestamp
+
+ Returns:
+ (str): the datetime as string formatted as 'YYYY-MM-DD HH:MM:SS'
+
+ Raises:
+ Any execptions returned from formatting the timestamp are propogated to the caller
+ """
+ dt = datetime.fromisoformat(timestamp.replace("Z", "+00:00"))
+ return dt.strftime("%Y-%m-%d %H:%M:%S")
+
+
+async def check_git_files_changed(client: "InfrahubClient", branch: str) -> bool:
+ """Check if there are any Git file changes in a branch.
+
+ Args:
+ client: Infrahub client instance
+ branch: Branch name to check
+
+ Returns:
+ True if files have changed, False otherwise
+
+ Raises:
+ Any exceptions from the API call are propagated to the caller
+ """
+ url = f"{client.address}/api/diff/files?branch={branch}"
+ resp = await client._get(url=url, timeout=client.default_timeout)
+ resp.raise_for_status()
+ data = decode_json(response=resp)
+
+ # Check if any repository has files
+ if branch in data:
+ for repo_data in data[branch].values():
+ if isinstance(repo_data, dict) and "files" in repo_data and len(repo_data["files"]) > 0:
+ return True
+
+ return False
+
+
+def generate_branch_report_table(
+ branch: BranchData, diff_tree: DiffTreeData | None, git_files_changed: bool | None
+) -> Table:
+ branch_table = Table(show_header=False, box=None)
+ branch_table.add_column(justify="left")
+ branch_table.add_column(justify="right")
+
+ branch_table.add_row("Created at", format_timestamp(branch.branched_from))
+
+ status_value = branch.status.value if hasattr(branch.status, "value") else str(branch.status)
+ branch_table.add_row("Status", status_value)
+
+ branch_table.add_row("Synced with Git", "Yes" if branch.sync_with_git else "No")
+
+ if git_files_changed is not None:
+ branch_table.add_row("Git files changed", "Yes" if git_files_changed else "No")
+ else:
+ branch_table.add_row("Git files changed", "N/A")
+
+ branch_table.add_row("Has schema changes", "Yes" if branch.has_schema_changes else "No")
+
+ if diff_tree:
+ branch_table.add_row("Diff last updated", format_timestamp(diff_tree["to_time"]))
+ branch_table.add_row("Amount of additions", str(diff_tree["num_added"]))
+ branch_table.add_row("Amount of deletions", str(diff_tree["num_removed"]))
+ branch_table.add_row("Amount of updates", str(diff_tree["num_updated"]))
+ branch_table.add_row("Amount of conflicts", str(diff_tree["num_conflicts"]))
+ else:
+ branch_table.add_row("Diff last updated", "No diff available")
+ branch_table.add_row("Amount of additions", "-")
+ branch_table.add_row("Amount of deletions", "-")
+ branch_table.add_row("Amount of updates", "-")
+ branch_table.add_row("Amount of conflicts", "-")
+
+ return branch_table
+
+
+def generate_proposed_change_tables(proposed_changes: list[CoreProposedChange]) -> list[Table]:
+ proposed_change_tables: list[Table] = []
+
+ for pc in proposed_changes:
+ # Create proposal table
+ proposed_change_table = Table(show_header=False, box=None)
+ proposed_change_table.add_column(justify="left")
+ proposed_change_table.add_column(justify="right")
+
+ # Extract data from node
+ proposed_change_table.add_row("Name", pc.name.value)
+ proposed_change_table.add_row("State", str(pc.state.value))
+ proposed_change_table.add_row("Is draft", "Yes" if pc.is_draft.value else "No")
+ proposed_change_table.add_row("Created by", pc.created_by.peer.name.value) # type: ignore[union-attr]
+ proposed_change_table.add_row("Created at", format_timestamp(str(pc.created_by.updated_at)))
+ proposed_change_table.add_row("Approvals", str(len(pc.approved_by.peers)))
+ proposed_change_table.add_row("Rejections", str(len(pc.rejected_by.peers)))
+
+ proposed_change_tables.append(proposed_change_table)
+
+ return proposed_change_tables
+
+
@app.callback()
def callback() -> None:
"""
@@ -49,7 +160,7 @@ async def list_branch(_: str = CONFIG_PARAM) -> None:
table.add_column("Status")
# identify the default branch and always print it first
- default_branch = [branch for branch in branches.values() if branch.is_default][0]
+ default_branch = next(branch for branch in branches.values() if branch.is_default)
table.add_row(
default_branch.name,
default_branch.description or " - ",
@@ -143,3 +254,66 @@ async def validate(branch_name: str, _: str = CONFIG_PARAM) -> None:
client = initialize_client()
await client.branch.validate(branch_name=branch_name)
console.print(f"Branch '{branch_name}' is valid.")
+
+
+@app.command()
+@catch_exception(console=console)
+async def report(
+ branch_name: str = typer.Argument(..., help="Branch name to generate report for"),
+ update_diff: bool = typer.Option(False, "--update-diff", help="Update diff before generating report"),
+ _: str = CONFIG_PARAM,
+) -> None:
+ """Generate branch cleanup status report."""
+
+ client = initialize_client()
+
+ # Fetch branch metadata first (needed for diff creation)
+ branch = await client.branch.get(branch_name=branch_name)
+
+ if branch.is_default:
+ console.print("[red]Cannot create a report for the default branch!")
+ sys.exit(1)
+
+ # Update diff if requested
+ if update_diff:
+ console.print("Updating diff...")
+ # Create diff from branch creation to now
+ from_time = datetime.fromisoformat(branch.branched_from.replace("Z", "+00:00"))
+ to_time = datetime.now(timezone.utc)
+ await client.create_diff(
+ branch=branch_name,
+ name=f"report-{branch_name}",
+ from_time=from_time,
+ to_time=to_time,
+ )
+ console.print("Diff updated\n")
+
+ diff_tree = await client.get_diff_tree(branch=branch_name)
+
+ git_files_changed = await check_git_files_changed(client, branch=branch_name)
+
+ proposed_changes = await client.filters(
+ kind=CoreProposedChange, # type: ignore[type-abstract]
+ source_branch__value=branch_name,
+ include=["created_by"],
+ prefetch_relationships=True,
+ property=True,
+ )
+
+ branch_table = generate_branch_report_table(branch=branch, diff_tree=diff_tree, git_files_changed=git_files_changed)
+ proposed_change_tables = generate_proposed_change_tables(proposed_changes=proposed_changes)
+
+ console.print()
+ console.print(f"[bold]Branch: {branch_name}[/bold]")
+
+ console.print(branch_table)
+ console.print()
+
+ if not proposed_changes:
+ console.print("No proposed changes for this branch")
+ console.print()
+
+ for proposed_change, proposed_change_table in zip(proposed_changes, proposed_change_tables, strict=True):
+ console.print(f"Proposed change: {proposed_change.name.value}")
+ console.print(proposed_change_table)
+ console.print()
diff --git a/infrahub_sdk/ctl/check.py b/infrahub_sdk/ctl/check.py
index 92d852e6..dfed8dd0 100644
--- a/infrahub_sdk/ctl/check.py
+++ b/infrahub_sdk/ctl/check.py
@@ -5,7 +5,7 @@
from asyncio import run as aiorun
from dataclasses import dataclass
from pathlib import Path
-from typing import TYPE_CHECKING, Optional
+from typing import TYPE_CHECKING
import typer
from rich.console import Console
@@ -49,8 +49,8 @@ def run(
format_json: bool,
list_available: bool,
variables: dict[str, str],
- name: Optional[str] = None,
- branch: Optional[str] = None,
+ name: str | None = None,
+ branch: str | None = None,
) -> None:
"""Locate and execute all checks under the defined path."""
diff --git a/infrahub_sdk/ctl/cli_commands.py b/infrahub_sdk/ctl/cli_commands.py
index 42a8764f..538bad6b 100644
--- a/infrahub_sdk/ctl/cli_commands.py
+++ b/infrahub_sdk/ctl/cli_commands.py
@@ -6,8 +6,9 @@
import logging
import platform
import sys
+from collections.abc import Callable
from pathlib import Path
-from typing import TYPE_CHECKING, Any, Callable, Optional
+from typing import TYPE_CHECKING, Any
import typer
import ujson
@@ -77,13 +78,13 @@
@catch_exception(console=console)
def check(
check_name: str = typer.Argument(default="", help="Name of the Python check"),
- branch: Optional[str] = None,
+ branch: str | None = None,
path: str = typer.Option(".", help="Root directory"),
debug: bool = False,
format_json: bool = False,
_: str = CONFIG_PARAM,
list_available: bool = typer.Option(False, "--list", help="Show available Python checks"),
- variables: Optional[list[str]] = typer.Argument(
+ variables: list[str] | None = typer.Argument(
None, help="Variables to pass along with the query. Format key=value key=value."
),
) -> None:
@@ -105,12 +106,12 @@ def check(
@catch_exception(console=console)
async def generator(
generator_name: str = typer.Argument(default="", help="Name of the Generator"),
- branch: Optional[str] = None,
+ branch: str | None = None,
path: str = typer.Option(".", help="Root directory"),
debug: bool = False,
_: str = CONFIG_PARAM,
list_available: bool = typer.Option(False, "--list", help="Show available Generators"),
- variables: Optional[list[str]] = typer.Argument(
+ variables: list[str] | None = typer.Argument(
None, help="Variables to pass along with the query. Format key=value key=value."
),
) -> None:
@@ -133,13 +134,13 @@ async def run(
debug: bool = False,
_: str = CONFIG_PARAM,
branch: str = typer.Option(None, help="Branch on which to run the script."),
- concurrent: Optional[int] = typer.Option(
+ concurrent: int | None = typer.Option(
None,
help="Maximum number of requests to execute at the same time.",
envvar="INFRAHUB_MAX_CONCURRENT_EXECUTION",
),
timeout: int = typer.Option(60, help="Timeout in sec", envvar="INFRAHUB_TIMEOUT"),
- variables: Optional[list[str]] = typer.Argument(
+ variables: list[str] | None = typer.Argument(
None, help="Variables to pass along with the query. Format key=value key=value."
),
) -> None:
@@ -250,7 +251,7 @@ async def _run_transform(
@catch_exception(console=console)
async def render(
transform_name: str = typer.Argument(default="", help="Name of the Python transformation", show_default=False),
- variables: Optional[list[str]] = typer.Argument(
+ variables: list[str] | None = typer.Argument(
None, help="Variables to pass along with the query. Format key=value key=value."
),
branch: str = typer.Option(None, help="Branch on which to render the transform."),
@@ -300,7 +301,7 @@ async def render(
@catch_exception(console=console)
def transform(
transform_name: str = typer.Argument(default="", help="Name of the Python transformation", show_default=False),
- variables: Optional[list[str]] = typer.Argument(
+ variables: list[str] | None = typer.Argument(
None, help="Variables to pass along with the query. Format key=value key=value."
),
branch: str = typer.Option(None, help="Branch on which to run the transformation"),
diff --git a/infrahub_sdk/ctl/generator.py b/infrahub_sdk/ctl/generator.py
index 75354ee1..f224760d 100644
--- a/infrahub_sdk/ctl/generator.py
+++ b/infrahub_sdk/ctl/generator.py
@@ -1,7 +1,7 @@
from __future__ import annotations
from pathlib import Path
-from typing import TYPE_CHECKING, Optional
+from typing import TYPE_CHECKING
import typer
from rich.console import Console
@@ -22,7 +22,7 @@ async def run(
debug: bool,
list_available: bool,
branch: str | None = None,
- variables: Optional[list[str]] = None,
+ variables: list[str] | None = None,
) -> None:
init_logging(debug=debug)
repository_config = get_repository_config(find_repository_config_file())
diff --git a/infrahub_sdk/ctl/graphql.py b/infrahub_sdk/ctl/graphql.py
index 3b983abd..6229d42a 100644
--- a/infrahub_sdk/ctl/graphql.py
+++ b/infrahub_sdk/ctl/graphql.py
@@ -3,7 +3,6 @@
import ast
from collections import defaultdict
from pathlib import Path
-from typing import Optional
import typer
from ariadne_codegen.client_generators.package import PackageGenerator, get_package_generator
@@ -108,14 +107,14 @@ async def export_schema(
schema_text = await client.schema.get_graphql_schema()
destination.parent.mkdir(parents=True, exist_ok=True)
- destination.write_text(schema_text)
+ destination.write_text(schema_text, encoding="utf-8")
console.print(f"[green]Schema exported to {destination}")
@app.command()
@catch_exception(console=console)
async def generate_return_types(
- query: Optional[Path] = typer.Argument(
+ query: Path | None = typer.Argument(
None, help="Location of the GraphQL query file(s). Defaults to current directory if not specified."
),
schema: Path = typer.Option("schema.graphql", help="Path to the GraphQL schema file."),
@@ -180,5 +179,5 @@ async def generate_return_types(
generate_result_types(directory=directory, package=package_generator, fragment=module_fragment)
- for file_name in package_generator._result_types_files.keys():
+ for file_name in package_generator._result_types_files:
console.print(f"[green]Generated {file_name} in {directory}")
diff --git a/infrahub_sdk/ctl/importer.py b/infrahub_sdk/ctl/importer.py
index e9181c8b..420c6d75 100644
--- a/infrahub_sdk/ctl/importer.py
+++ b/infrahub_sdk/ctl/importer.py
@@ -2,7 +2,6 @@
from asyncio import run as aiorun
from pathlib import Path
-from typing import Optional
import typer
from rich.console import Console
@@ -16,7 +15,7 @@
def local_directory() -> Path:
# We use a function here to avoid failure when generating the documentation due to directory name
- return Path().resolve()
+ return Path.cwd()
def load(
@@ -27,7 +26,7 @@ def load(
quiet: bool = typer.Option(False, help="No console output"),
_: str = CONFIG_PARAM,
branch: str = typer.Option(None, help="Branch from which to export"),
- concurrent: Optional[int] = typer.Option(
+ concurrent: int | None = typer.Option(
None,
help="Maximum number of requests to execute at the same time.",
envvar="INFRAHUB_MAX_CONCURRENT_EXECUTION",
diff --git a/infrahub_sdk/ctl/repository.py b/infrahub_sdk/ctl/repository.py
index 5c9423d1..4ce141b8 100644
--- a/infrahub_sdk/ctl/repository.py
+++ b/infrahub_sdk/ctl/repository.py
@@ -2,7 +2,6 @@
import asyncio
from pathlib import Path
-from typing import Optional
import typer
import yaml
@@ -109,7 +108,7 @@ async def add(
name: str,
location: str,
description: str = "",
- username: Optional[str] = None,
+ username: str | None = None,
password: str = "",
ref: str = "",
read_only: bool = False,
@@ -155,7 +154,7 @@ async def add(
@app.command()
async def list(
- branch: Optional[str] = typer.Option(None, help="Branch on which to list repositories."),
+ branch: str | None = typer.Option(None, help="Branch on which to list repositories."),
debug: bool = False,
_: str = CONFIG_PARAM,
) -> None:
@@ -214,12 +213,12 @@ async def init(
default="https://github.com/opsmill/infrahub-template.git",
help="Template to use for the new repository. Can be a local path or a git repository URL.",
),
- data: Optional[Path] = typer.Option(default=None, help="Path to YAML file containing answers to CLI prompt."),
- vcs_ref: Optional[str] = typer.Option(
+ data: Path | None = typer.Option(default=None, help="Path to YAML file containing answers to CLI prompt."),
+ vcs_ref: str | None = typer.Option(
default="HEAD",
help="VCS reference to use for the template. Defaults to HEAD.",
),
- trust: Optional[bool] = typer.Option(
+ trust: bool | None = typer.Option(
default=False,
help="Trust the template repository. If set, the template will be cloned without verification.",
),
diff --git a/infrahub_sdk/ctl/task.py b/infrahub_sdk/ctl/task.py
index b95f7924..1ffe58c1 100644
--- a/infrahub_sdk/ctl/task.py
+++ b/infrahub_sdk/ctl/task.py
@@ -1,7 +1,5 @@
from __future__ import annotations
-from typing import Optional
-
import typer
from rich.console import Console
from rich.table import Table
@@ -75,8 +73,8 @@ async def list_tasks(
state: list[str] = typer.Option(
None, "--state", "-s", help="Filter by task state. Can be provided multiple times."
),
- limit: Optional[int] = typer.Option(None, help="Maximum number of tasks to retrieve."),
- offset: Optional[int] = typer.Option(None, help="Offset for pagination."),
+ limit: int | None = typer.Option(None, help="Maximum number of tasks to retrieve."),
+ offset: int | None = typer.Option(None, help="Offset for pagination."),
include_related_nodes: bool = typer.Option(False, help="Include related nodes in the output."),
include_logs: bool = typer.Option(False, help="Include task logs in the output."),
json_output: bool = typer.Option(False, "--json", help="Output the result as JSON."),
diff --git a/infrahub_sdk/ctl/utils.py b/infrahub_sdk/ctl/utils.py
index d4fc6ee8..9db07957 100644
--- a/infrahub_sdk/ctl/utils.py
+++ b/infrahub_sdk/ctl/utils.py
@@ -3,10 +3,10 @@
import asyncio
import logging
import traceback
-from collections.abc import Coroutine
+from collections.abc import Callable, Coroutine
from functools import wraps
from pathlib import Path
-from typing import TYPE_CHECKING, Any, Callable, NoReturn, Optional, TypeVar
+from typing import TYPE_CHECKING, Any, NoReturn, TypeVar
import typer
from click.exceptions import Exit
@@ -149,7 +149,7 @@ def print_graphql_errors(console: Console, errors: list) -> None:
console.print(f"[red]{escape(str(error))}")
-def parse_cli_vars(variables: Optional[list[str]]) -> dict[str, str]:
+def parse_cli_vars(variables: list[str] | None) -> dict[str, str]:
if not variables:
return {}
diff --git a/infrahub_sdk/ctl/validate.py b/infrahub_sdk/ctl/validate.py
index d1715d9f..3ffbd85a 100644
--- a/infrahub_sdk/ctl/validate.py
+++ b/infrahub_sdk/ctl/validate.py
@@ -2,7 +2,6 @@
import sys
from pathlib import Path
-from typing import Optional
import typer
import ujson
@@ -58,7 +57,7 @@ async def validate_schema(schema: Path, _: str = CONFIG_PARAM) -> None:
@catch_exception(console=console)
def validate_graphql(
query: str,
- variables: Optional[list[str]] = typer.Argument(
+ variables: list[str] | None = typer.Argument(
None, help="Variables to pass along with the query. Format key=value key=value."
),
debug: bool = typer.Option(False, help="Display more troubleshooting information."),
diff --git a/infrahub_sdk/diff.py b/infrahub_sdk/diff.py
index fad10080..8e5513e2 100644
--- a/infrahub_sdk/diff.py
+++ b/infrahub_sdk/diff.py
@@ -1,11 +1,12 @@
from __future__ import annotations
-from typing import (
- Any,
-)
+from datetime import datetime
+from typing import Any
from typing_extensions import NotRequired, TypedDict
+from infrahub_sdk.graphql.query import Query
+
class NodeDiff(TypedDict):
branch: str
@@ -35,6 +36,19 @@ class NodeDiffPeer(TypedDict):
summary: NodeDiffSummary
+class DiffTreeData(TypedDict):
+ num_added: int
+ num_updated: int
+ num_removed: int
+ num_conflicts: int
+ to_time: str
+ from_time: str
+ base_branch: str
+ diff_branch: str
+ name: NotRequired[str | None]
+ nodes: list[NodeDiff]
+
+
def get_diff_summary_query() -> str:
return """
query GetDiffTree($branch_name: String!, $name: String, $from_time: DateTime, $to_time: DateTime) {
@@ -125,3 +139,66 @@ def diff_tree_node_to_node_diff(node_dict: dict[str, Any], branch_name: str) ->
display_label=str(node_dict.get("label")),
elements=element_diffs,
)
+
+
+def get_diff_tree_query() -> Query:
+ node_structure = {
+ "uuid": None,
+ "kind": None,
+ "status": None,
+ "label": None,
+ "num_added": None,
+ "num_updated": None,
+ "num_removed": None,
+ "attributes": {
+ "name": None,
+ "status": None,
+ "num_added": None,
+ "num_updated": None,
+ "num_removed": None,
+ },
+ "relationships": {
+ "name": None,
+ "status": None,
+ "cardinality": None,
+ "num_added": None,
+ "num_updated": None,
+ "num_removed": None,
+ "elements": {
+ "status": None,
+ "num_added": None,
+ "num_updated": None,
+ "num_removed": None,
+ },
+ },
+ }
+
+ return Query(
+ name="GetDiffTree",
+ query={
+ "DiffTree": {
+ "@filters": {
+ "branch": "$branch_name",
+ "name": "$name",
+ "from_time": "$from_time",
+ "to_time": "$to_time",
+ },
+ "name": None,
+ "to_time": None,
+ "from_time": None,
+ "base_branch": None,
+ "diff_branch": None,
+ "num_added": None,
+ "num_updated": None,
+ "num_removed": None,
+ "num_conflicts": None,
+ "nodes": node_structure,
+ },
+ },
+ variables={
+ "branch_name": str,
+ "name": str | None,
+ "from_time": datetime | None,
+ "to_time": datetime | None,
+ },
+ )
diff --git a/infrahub_sdk/graphql/constants.py b/infrahub_sdk/graphql/constants.py
index cd20fd4d..e2033155 100644
--- a/infrahub_sdk/graphql/constants.py
+++ b/infrahub_sdk/graphql/constants.py
@@ -1 +1,14 @@
-VARIABLE_TYPE_MAPPING = ((str, "String!"), (int, "Int!"), (float, "Float!"), (bool, "Boolean!"))
+from datetime import datetime
+
+VARIABLE_TYPE_MAPPING = (
+ (str, "String!"),
+ (str | None, "String"),
+ (int, "Int!"),
+ (int | None, "Int"),
+ (float, "Float!"),
+ (float | None, "Float"),
+ (bool, "Boolean!"),
+ (bool | None, "Boolean"),
+ (datetime, "DateTime!"),
+ (datetime | None, "DateTime"),
+)
diff --git a/infrahub_sdk/graphql/renderers.py b/infrahub_sdk/graphql/renderers.py
index 1b757949..3cd3e557 100644
--- a/infrahub_sdk/graphql/renderers.py
+++ b/infrahub_sdk/graphql/renderers.py
@@ -1,6 +1,7 @@
from __future__ import annotations
import json
+from datetime import datetime
from enum import Enum
from typing import Any
@@ -66,7 +67,10 @@ def convert_to_graphql_as_string(value: Any, convert_enum: bool = False) -> str:
return str(value)
-def render_variables_to_string(data: dict[str, type[str | int | float | bool]]) -> str:
+GRAPHQL_VARIABLE_TYPES = type[str | int | float | bool | datetime | None]
+
+
+def render_variables_to_string(data: dict[str, GRAPHQL_VARIABLE_TYPES]) -> str:
"""Render a dict into a variable string that will be used in a GraphQL Query.
The $ sign will be automatically added to the name of the query.
diff --git a/infrahub_sdk/node/attribute.py b/infrahub_sdk/node/attribute.py
index 848bbeb8..a0d00a96 100644
--- a/infrahub_sdk/node/attribute.py
+++ b/infrahub_sdk/node/attribute.py
@@ -1,7 +1,8 @@
from __future__ import annotations
import ipaddress
-from typing import TYPE_CHECKING, Any, Callable, get_args
+from collections.abc import Callable
+from typing import TYPE_CHECKING, Any, get_args
from ..protocols_base import CoreNodeBase
from ..uuidt import UUIDT
@@ -25,7 +26,7 @@ def __init__(self, name: str, schema: AttributeSchemaAPI, data: Any | dict) -> N
self.name = name
self._schema = schema
- if not isinstance(data, dict) or "value" not in data.keys():
+ if not isinstance(data, dict) or "value" not in data:
data = {"value": data}
self._properties_flag = PROPERTIES_FLAG
@@ -34,12 +35,12 @@ def __init__(self, name: str, schema: AttributeSchemaAPI, data: Any | dict) -> N
self._read_only = ["updated_at", "is_inherited"]
- self.id: str | None = data.get("id", None)
+ self.id: str | None = data.get("id")
- self._value: Any | None = data.get("value", None)
+ self._value: Any | None = data.get("value")
self.value_has_been_mutated = False
- self.is_default: bool | None = data.get("is_default", None)
- self.is_from_profile: bool | None = data.get("is_from_profile", None)
+ self.is_default: bool | None = data.get("is_default")
+ self.is_from_profile: bool | None = data.get("is_from_profile")
if self._value:
value_mapper: dict[str, Callable] = {
@@ -49,10 +50,10 @@ def __init__(self, name: str, schema: AttributeSchemaAPI, data: Any | dict) -> N
mapper = value_mapper.get(schema.kind, lambda value: value)
self._value = mapper(data.get("value"))
- self.is_inherited: bool | None = data.get("is_inherited", None)
- self.updated_at: str | None = data.get("updated_at", None)
+ self.is_inherited: bool | None = data.get("is_inherited")
+ self.updated_at: str | None = data.get("updated_at")
- self.is_protected: bool | None = data.get("is_protected", None)
+ self.is_protected: bool | None = data.get("is_protected")
self.source: NodeProperty | None = None
self.owner: NodeProperty | None = None
diff --git a/infrahub_sdk/node/constants.py b/infrahub_sdk/node/constants.py
index 3d3147a8..d1f31717 100644
--- a/infrahub_sdk/node/constants.py
+++ b/infrahub_sdk/node/constants.py
@@ -1,12 +1,11 @@
import ipaddress
import re
-from typing import Union
-PROPERTIES_FLAG = ["is_protected"]
+PROPERTIES_FLAG = ["is_protected", "updated_at"]
PROPERTIES_OBJECT = ["source", "owner"]
SAFE_VALUE = re.compile(r"(^[\. /:a-zA-Z0-9_-]+$)|(^$)")
-IP_TYPES = Union[ipaddress.IPv4Interface, ipaddress.IPv6Interface, ipaddress.IPv4Network, ipaddress.IPv6Network]
+IP_TYPES = ipaddress.IPv4Interface | ipaddress.IPv6Interface | ipaddress.IPv4Network | ipaddress.IPv6Network
ARTIFACT_FETCH_FEATURE_NOT_SUPPORTED_MESSAGE = (
"calling artifact_fetch is only supported for nodes that are Artifact Definition target"
diff --git a/infrahub_sdk/node/node.py b/infrahub_sdk/node/node.py
index 72624467..1208ca4c 100644
--- a/infrahub_sdk/node/node.py
+++ b/infrahub_sdk/node/node.py
@@ -284,12 +284,12 @@ def _generate_input_data( # noqa: C901
def _strip_unmodified_dict(data: dict, original_data: dict, variables: dict, item: str) -> None:
data_item = data.get(item)
if item in original_data and isinstance(original_data[item], dict) and isinstance(data_item, dict):
- for item_key in original_data[item].keys():
+ for item_key in original_data[item]:
for property_name in PROPERTIES_OBJECT:
if item_key == property_name and isinstance(original_data[item][property_name], dict):
if original_data[item][property_name].get("id"):
original_data[item][property_name] = original_data[item][property_name]["id"]
- if item_key in data[item].keys():
+ if item_key in data[item]:
if item_key == "id" and len(data[item].keys()) > 1:
# Related nodes typically require an ID. So the ID is only
# removed if it's the last key in the current context
@@ -335,8 +335,8 @@ def _strip_unmodified(self, data: dict, variables: dict) -> tuple[dict, dict]:
elif isinstance(relationship_property, RelationshipManagerBase) and not relationship_property.has_update:
data.pop(relationship)
- for item in original_data.keys():
- if item in data.keys():
+ for item in original_data:
+ if item in data:
if data[item] == original_data[item]:
if attr := getattr(self, item, None): # this should never be None, just a safety default value
if not isinstance(attr, Attribute) or not attr.value_has_been_mutated:
@@ -741,7 +741,7 @@ async def generate_query_data_node(
if (
rel_schema.cardinality == RelationshipCardinality.MANY # type: ignore[union-attr]
- and rel_schema.kind not in [RelationshipKind.ATTRIBUTE, RelationshipKind.PARENT] # type: ignore[union-attr]
+ and rel_schema.kind not in {RelationshipKind.ATTRIBUTE, RelationshipKind.PARENT} # type: ignore[union-attr]
and not (include and rel_name in include)
):
continue
@@ -895,6 +895,7 @@ async def _process_relationships(
branch: str,
related_nodes: list[InfrahubNode],
timeout: int | None = None,
+ recursive: bool = False,
) -> None:
"""Processes the Relationships of a InfrahubNode and add Related Nodes to a list.
@@ -903,6 +904,7 @@ async def _process_relationships(
branch (str): The branch name.
related_nodes (list[InfrahubNode]): The list to which related nodes will be appended.
timeout (int, optional): Overrides default timeout used when querying the graphql API. Specified in seconds.
+ recursive:(bool): Whether to recursively process relationships of related nodes.
"""
for rel_name in self._relationships:
rel = getattr(self, rel_name)
@@ -910,17 +912,37 @@ async def _process_relationships(
relation = node_data["node"].get(rel_name, None)
if relation and relation.get("node", None):
related_node = await InfrahubNode.from_graphql(
- client=self._client, branch=branch, data=relation, timeout=timeout
+ client=self._client,
+ branch=branch,
+ data=relation,
+ timeout=timeout,
)
related_nodes.append(related_node)
+ if recursive:
+ await related_node._process_relationships(
+ node_data=relation,
+ branch=branch,
+ related_nodes=related_nodes,
+ recursive=recursive,
+ )
elif rel and isinstance(rel, RelationshipManager):
peers = node_data["node"].get(rel_name, None)
if peers and peers["edges"]:
for peer in peers["edges"]:
related_node = await InfrahubNode.from_graphql(
- client=self._client, branch=branch, data=peer, timeout=timeout
+ client=self._client,
+ branch=branch,
+ data=peer,
+ timeout=timeout,
)
related_nodes.append(related_node)
+ if recursive:
+ await related_node._process_relationships(
+ node_data=peer,
+ branch=branch,
+ related_nodes=related_nodes,
+ recursive=recursive,
+ )
async def get_pool_allocated_resources(self, resource: InfrahubNode) -> list[InfrahubNode]:
"""Fetch all nodes that were allocated for the pool and a given resource.
@@ -1364,7 +1386,7 @@ def generate_query_data_node(
if (
rel_schema.cardinality == RelationshipCardinality.MANY # type: ignore[union-attr]
- and rel_schema.kind not in [RelationshipKind.ATTRIBUTE, RelationshipKind.PARENT] # type: ignore[union-attr]
+ and rel_schema.kind not in {RelationshipKind.ATTRIBUTE, RelationshipKind.PARENT} # type: ignore[union-attr]
and not (include and rel_name in include)
):
continue
@@ -1520,6 +1542,7 @@ def _process_relationships(
branch: str,
related_nodes: list[InfrahubNodeSync],
timeout: int | None = None,
+ recursive: bool = False,
) -> None:
"""Processes the Relationships of a InfrahubNodeSync and add Related Nodes to a list.
@@ -1528,7 +1551,7 @@ def _process_relationships(
branch (str): The branch name.
related_nodes (list[InfrahubNodeSync]): The list to which related nodes will be appended.
timeout (int, optional): Overrides default timeout used when querying the graphql API. Specified in seconds.
-
+ recursive:(bool): Whether to recursively process relationships of related nodes.
"""
for rel_name in self._relationships:
rel = getattr(self, rel_name)
@@ -1536,17 +1559,37 @@ def _process_relationships(
relation = node_data["node"].get(rel_name, None)
if relation and relation.get("node", None):
related_node = InfrahubNodeSync.from_graphql(
- client=self._client, branch=branch, data=relation, timeout=timeout
+ client=self._client,
+ branch=branch,
+ data=relation,
+ timeout=timeout,
)
related_nodes.append(related_node)
+ if recursive:
+ related_node._process_relationships(
+ node_data=relation,
+ branch=branch,
+ related_nodes=related_nodes,
+ recursive=recursive,
+ )
elif rel and isinstance(rel, RelationshipManagerSync):
peers = node_data["node"].get(rel_name, None)
if peers and peers["edges"]:
for peer in peers["edges"]:
related_node = InfrahubNodeSync.from_graphql(
- client=self._client, branch=branch, data=peer, timeout=timeout
+ client=self._client,
+ branch=branch,
+ data=peer,
+ timeout=timeout,
)
related_nodes.append(related_node)
+ if recursive:
+ related_node._process_relationships(
+ node_data=peer,
+ branch=branch,
+ related_nodes=related_nodes,
+ recursive=recursive,
+ )
def get_pool_allocated_resources(self, resource: InfrahubNodeSync) -> list[InfrahubNodeSync]:
"""Fetch all nodes that were allocated for the pool and a given resource.
diff --git a/infrahub_sdk/node/related_node.py b/infrahub_sdk/node/related_node.py
index ab6cf17f..daa9726b 100644
--- a/infrahub_sdk/node/related_node.py
+++ b/infrahub_sdk/node/related_node.py
@@ -64,7 +64,7 @@ def __init__(self, branch: str, schema: RelationshipSchemaAPI, data: Any | dict,
self._display_label = node_data.get("display_label", None)
self._typename = node_data.get("__typename", None)
- self.updated_at: str | None = data.get("updated_at", data.get("_relation__updated_at", None))
+ self.updated_at: str | None = data.get("updated_at", properties_data.get("updated_at", None))
# FIXME, we won't need that once we are only supporting paginated results
if self._typename and self._typename.startswith("Related"):
@@ -171,7 +171,6 @@ def _generate_query_data(cls, peer_data: dict[str, Any] | None = None, property:
for prop_name in PROPERTIES_OBJECT:
properties[prop_name] = {"id": None, "display_label": None, "__typename": None}
- if properties:
data["properties"] = properties
if peer_data:
data["node"].update(peer_data)
diff --git a/infrahub_sdk/node/relationship.py b/infrahub_sdk/node/relationship.py
index 55aad544..6dcc66ce 100644
--- a/infrahub_sdk/node/relationship.py
+++ b/infrahub_sdk/node/relationship.py
@@ -87,9 +87,8 @@ def _generate_query_data(cls, peer_data: dict[str, Any] | None = None, property:
properties[prop_name] = None
for prop_name in PROPERTIES_OBJECT:
properties[prop_name] = {"id": None, "display_label": None, "__typename": None}
-
- if properties:
data["edges"]["properties"] = properties
+
if peer_data:
data["edges"]["node"].update(peer_data)
diff --git a/infrahub_sdk/object_store.py b/infrahub_sdk/object_store.py
index a6cd4bdb..bf5fc862 100644
--- a/infrahub_sdk/object_store.py
+++ b/infrahub_sdk/object_store.py
@@ -33,7 +33,7 @@ async def get(self, identifier: str, tracker: str | None = None) -> str:
self.client.log.error(f"Unable to connect to {self.client.address} .. ")
raise
except httpx.HTTPStatusError as exc:
- if exc.response.status_code in [401, 403]:
+ if exc.response.status_code in {401, 403}:
response = exc.response.json()
errors = response.get("errors")
messages = [error.get("message") for error in errors]
@@ -54,7 +54,7 @@ async def upload(self, content: str, tracker: str | None = None) -> dict[str, st
self.client.log.error(f"Unable to connect to {self.client.address} .. ")
raise
except httpx.HTTPStatusError as exc:
- if exc.response.status_code in [401, 403]:
+ if exc.response.status_code in {401, 403}:
response = exc.response.json()
errors = response.get("errors")
messages = [error.get("message") for error in errors]
@@ -81,7 +81,7 @@ def get(self, identifier: str, tracker: str | None = None) -> str:
self.client.log.error(f"Unable to connect to {self.client.address} .. ")
raise
except httpx.HTTPStatusError as exc:
- if exc.response.status_code in [401, 403]:
+ if exc.response.status_code in {401, 403}:
response = exc.response.json()
errors = response.get("errors")
messages = [error.get("message") for error in errors]
@@ -102,7 +102,7 @@ def upload(self, content: str, tracker: str | None = None) -> dict[str, str]:
self.client.log.error(f"Unable to connect to {self.client.address} .. ")
raise
except httpx.HTTPStatusError as exc:
- if exc.response.status_code in [401, 403]:
+ if exc.response.status_code in {401, 403}:
response = exc.response.json()
errors = response.get("errors")
messages = [error.get("message") for error in errors]
diff --git a/infrahub_sdk/operation.py b/infrahub_sdk/operation.py
index 4f431a5e..3ae3d9c9 100644
--- a/infrahub_sdk/operation.py
+++ b/infrahub_sdk/operation.py
@@ -65,14 +65,14 @@ async def process_nodes(self, data: dict) -> None:
await self._init_client.schema.all(branch=self.branch_name)
for kind in data:
- if kind in self._init_client.schema.cache[self.branch_name].nodes.keys():
+ if kind in self._init_client.schema.cache[self.branch_name].nodes:
for result in data[kind].get("edges", []):
node = await self.infrahub_node.from_graphql(
client=self._init_client, branch=self.branch_name, data=result
)
self._nodes.append(node)
await node._process_relationships(
- node_data=result, branch=self.branch_name, related_nodes=self._related_nodes
+ node_data=result, branch=self.branch_name, related_nodes=self._related_nodes, recursive=True
)
for node in self._nodes + self._related_nodes:
diff --git a/infrahub_sdk/protocols_generator/generator.py b/infrahub_sdk/protocols_generator/generator.py
index 82771fa6..ee80732f 100644
--- a/infrahub_sdk/protocols_generator/generator.py
+++ b/infrahub_sdk/protocols_generator/generator.py
@@ -56,7 +56,7 @@ def __init__(self, schema: dict[str, MainSchemaTypesAll]) -> None:
if not e.startswith("__")
and not e.endswith("__")
and e
- not in ("TYPE_CHECKING", "CoreNode", "Optional", "Protocol", "Union", "annotations", "runtime_checkable")
+ not in {"TYPE_CHECKING", "CoreNode", "Optional", "Protocol", "Union", "annotations", "runtime_checkable"}
]
self.sorted_generics = self._sort_and_filter_models(self.generics, filters=["CoreNode"] + self.base_protocols)
diff --git a/infrahub_sdk/pytest_plugin/AGENTS.md b/infrahub_sdk/pytest_plugin/AGENTS.md
index 1239d3a7..a137f862 100644
--- a/infrahub_sdk/pytest_plugin/AGENTS.md
+++ b/infrahub_sdk/pytest_plugin/AGENTS.md
@@ -21,7 +21,7 @@ infrahub_tests:
## Test Kinds
| Resource | Smoke | Unit | Integration |
-|----------|-------|------|-------------|
+| -------- | ----- | ---- | ----------- |
| Check | `check-smoke` | `check-unit-process` | `check-integration` |
| GraphQL | `graphql-query-smoke` | - | `graphql-query-integration` |
| Jinja2 | `jinja2-transform-smoke` | `jinja2-transform-unit-render` | `jinja2-transform-integration` |
diff --git a/infrahub_sdk/pytest_plugin/items/jinja2_transform.py b/infrahub_sdk/pytest_plugin/items/jinja2_transform.py
index 4ed2e2c5..433309a4 100644
--- a/infrahub_sdk/pytest_plugin/items/jinja2_transform.py
+++ b/infrahub_sdk/pytest_plugin/items/jinja2_transform.py
@@ -83,7 +83,7 @@ def repr_failure(self, excinfo: ExceptionInfo, style: str | None = None) -> str:
class InfrahubJinja2TransformSmokeItem(InfrahubJinja2Item):
def runtest(self) -> None:
file_path: Path = self.session.infrahub_config_path.parent / self.resource_config.template_path # type: ignore[attr-defined]
- self.get_jinja2_environment().parse(file_path.read_text(), filename=file_path.name)
+ self.get_jinja2_environment().parse(file_path.read_text(encoding="utf-8"), filename=file_path.name)
class InfrahubJinja2TransformUnitRenderItem(InfrahubJinja2Item):
diff --git a/infrahub_sdk/pytest_plugin/models.py b/infrahub_sdk/pytest_plugin/models.py
index 122b3687..2bebfa77 100644
--- a/infrahub_sdk/pytest_plugin/models.py
+++ b/infrahub_sdk/pytest_plugin/models.py
@@ -55,7 +55,7 @@ def parse_user_provided_data(path: Path | None) -> Any:
if suffix and suffix == "json":
return ujson.loads(text)
- if suffix in ("yml", "yaml"):
+ if suffix in {"yml", "yaml"}:
return yaml.safe_load(text)
return text
diff --git a/infrahub_sdk/pytest_plugin/plugin.py b/infrahub_sdk/pytest_plugin/plugin.py
index 64c2080b..74148a05 100644
--- a/infrahub_sdk/pytest_plugin/plugin.py
+++ b/infrahub_sdk/pytest_plugin/plugin.py
@@ -90,7 +90,7 @@ def pytest_sessionstart(session: Session) -> None:
def pytest_collect_file(parent: Collector | Item, file_path: Path) -> InfrahubYamlFile | None:
- if file_path.suffix in [".yml", ".yaml"] and file_path.name.startswith("test_"):
+ if file_path.suffix in {".yml", ".yaml"} and file_path.name.startswith("test_"):
return InfrahubYamlFile.from_parent(parent, path=file_path)
return None
diff --git a/infrahub_sdk/query_groups.py b/infrahub_sdk/query_groups.py
index fec00474..696aa260 100644
--- a/infrahub_sdk/query_groups.py
+++ b/infrahub_sdk/query_groups.py
@@ -168,7 +168,7 @@ async def update_group(self) -> None:
return
# Calculate how many nodes should be deleted
- self.unused_member_ids = set(existing_group.members.peer_ids) - set(members) # type: ignore
+ self.unused_member_ids = list(set(existing_group.members.peer_ids) - set(members)) # type: ignore[union-attr]
if not self.delete_unused_nodes:
return
@@ -262,7 +262,7 @@ def update_group(self) -> None:
return
# Calculate how many nodes should be deleted
- self.unused_member_ids = set(existing_group.members.peer_ids) - set(members) # type: ignore
+ self.unused_member_ids = list(set(existing_group.members.peer_ids) - set(members)) # type: ignore[union-attr]
if not self.delete_unused_nodes:
return
diff --git a/infrahub_sdk/schema/__init__.py b/infrahub_sdk/schema/__init__.py
index caa5f122..3e61ad2a 100644
--- a/infrahub_sdk/schema/__init__.py
+++ b/infrahub_sdk/schema/__init__.py
@@ -7,12 +7,11 @@
from collections.abc import MutableMapping
from enum import Enum
from time import sleep
-from typing import TYPE_CHECKING, Any, TypedDict, Union
+from typing import TYPE_CHECKING, Any, TypeAlias, TypedDict
from urllib.parse import urlencode
import httpx
from pydantic import BaseModel, Field
-from typing_extensions import TypeAlias
from ..exceptions import (
BranchNotFoundError,
@@ -46,7 +45,7 @@
from ..client import InfrahubClient, InfrahubClientSync, SchemaType, SchemaTypeSync
from ..node import InfrahubNode, InfrahubNodeSync
- InfrahubNodeTypes = Union[InfrahubNode, InfrahubNodeSync]
+ InfrahubNodeTypes: TypeAlias = InfrahubNode | InfrahubNodeSync
__all__ = [
@@ -84,11 +83,11 @@ class EnumMutation(str, Enum):
remove = "SchemaEnumRemove"
-MainSchemaTypes: TypeAlias = Union[NodeSchema, GenericSchema]
-MainSchemaTypesAPI: TypeAlias = Union[NodeSchemaAPI, GenericSchemaAPI, ProfileSchemaAPI, TemplateSchemaAPI]
-MainSchemaTypesAll: TypeAlias = Union[
- NodeSchema, GenericSchema, NodeSchemaAPI, GenericSchemaAPI, ProfileSchemaAPI, TemplateSchemaAPI
-]
+MainSchemaTypes: TypeAlias = NodeSchema | GenericSchema
+MainSchemaTypesAPI: TypeAlias = NodeSchemaAPI | GenericSchemaAPI | ProfileSchemaAPI | TemplateSchemaAPI
+MainSchemaTypesAll: TypeAlias = (
+ NodeSchema | GenericSchema | NodeSchemaAPI | GenericSchemaAPI | ProfileSchemaAPI | TemplateSchemaAPI
+)
class SchemaWarningType(Enum):
@@ -123,7 +122,7 @@ def validate(self, data: dict[str, Any]) -> None:
SchemaRoot(**data)
def validate_data_against_schema(self, schema: MainSchemaTypesAPI, data: dict) -> None:
- for key in data.keys():
+ for key in data:
if key not in schema.relationship_names + schema.attribute_names:
identifier = f"{schema.kind}"
raise ValidationError(
@@ -191,12 +190,12 @@ def _validate_load_schema_response(response: httpx.Response) -> SchemaLoadRespon
hash=status["hash"], previous_hash=status["previous_hash"], warnings=status.get("warnings") or []
)
- if response.status_code in [
+ if response.status_code in {
httpx.codes.BAD_REQUEST,
httpx.codes.UNPROCESSABLE_ENTITY,
httpx.codes.UNAUTHORIZED,
httpx.codes.FORBIDDEN,
- ]:
+ }:
return SchemaLoadResponse(errors=response.json())
response.raise_for_status()
diff --git a/infrahub_sdk/schema/main.py b/infrahub_sdk/schema/main.py
index f704fdaa..34a35177 100644
--- a/infrahub_sdk/schema/main.py
+++ b/infrahub_sdk/schema/main.py
@@ -3,7 +3,7 @@
import warnings
from collections.abc import MutableMapping
from enum import Enum
-from typing import TYPE_CHECKING, Any, Union
+from typing import TYPE_CHECKING, Any
from pydantic import BaseModel, ConfigDict, Field
from typing_extensions import Self
@@ -11,7 +11,7 @@
if TYPE_CHECKING:
from ..node import InfrahubNode, InfrahubNodeSync
- InfrahubNodeTypes = Union[InfrahubNode, InfrahubNodeSync]
+ InfrahubNodeTypes = InfrahubNode | InfrahubNodeSync
class RelationshipCardinality(str, Enum):
diff --git a/infrahub_sdk/schema/repository.py b/infrahub_sdk/schema/repository.py
index 7a793d01..9bd770cc 100644
--- a/infrahub_sdk/schema/repository.py
+++ b/infrahub_sdk/schema/repository.py
@@ -1,7 +1,7 @@
from __future__ import annotations
from pathlib import Path
-from typing import TYPE_CHECKING, Any, TypeVar, Union
+from typing import TYPE_CHECKING, Any, TypeVar
from pydantic import BaseModel, ConfigDict, Field, field_validator
@@ -18,7 +18,7 @@
if TYPE_CHECKING:
from ..node import InfrahubNode, InfrahubNodeSync
- InfrahubNodeTypes = Union[InfrahubNode, InfrahubNodeSync]
+ InfrahubNodeTypes = InfrahubNode | InfrahubNodeSync
ResourceClass = TypeVar("ResourceClass")
diff --git a/infrahub_sdk/spec/object.py b/infrahub_sdk/spec/object.py
index 77a0babf..0df3f95c 100644
--- a/infrahub_sdk/spec/object.py
+++ b/infrahub_sdk/spec/object.py
@@ -74,7 +74,7 @@ def is_valid(self) -> bool:
@property
def is_reference(self) -> bool:
- return self.format in [RelationshipDataFormat.ONE_REF, RelationshipDataFormat.MANY_REF]
+ return self.format in {RelationshipDataFormat.ONE_REF, RelationshipDataFormat.MANY_REF}
def get_context(self, value: Any) -> dict:
"""Return a dict to insert to the context if the relationship is mandatory"""
@@ -230,7 +230,7 @@ async def validate_object(
# First validate if all mandatory fields are present
for element in schema.mandatory_input_names:
- if not any([element in data.keys(), element in context.keys()]):
+ if not any([element in data, element in context]):
errors.append(ObjectValidationError(position=position + [element], message=f"{element} is mandatory"))
# Validate if all attributes are valid
diff --git a/infrahub_sdk/spec/range_expansion.py b/infrahub_sdk/spec/range_expansion.py
index 8f47b71f..99638b06 100644
--- a/infrahub_sdk/spec/range_expansion.py
+++ b/infrahub_sdk/spec/range_expansion.py
@@ -69,7 +69,7 @@ def _extract_constants(pattern: str, re_compiled: re.Pattern) -> tuple[list[int]
def _expand_interfaces(pattern: str, interface_constant: list[int], cartesian_list: list[list[str]]) -> list[str]:
def _pairwise(lst: list[int]) -> list[tuple[int, int]]:
it = iter(lst)
- return list(zip(it, it))
+ return list(zip(it, it, strict=False))
if interface_constant[-1] < len(pattern):
interface_constant.append(len(pattern))
diff --git a/infrahub_sdk/template/__init__.py b/infrahub_sdk/template/__init__.py
index c43f7ad9..910ec216 100644
--- a/infrahub_sdk/template/__init__.py
+++ b/infrahub_sdk/template/__init__.py
@@ -1,8 +1,9 @@
from __future__ import annotations
import linecache
+from collections.abc import Callable
from pathlib import Path
-from typing import Any, Callable, NoReturn
+from typing import Any, NoReturn
import jinja2
from jinja2 import meta, nodes
diff --git a/infrahub_sdk/transfer/importer/json.py b/infrahub_sdk/transfer/importer/json.py
index cd3e4508..d9e6ad13 100644
--- a/infrahub_sdk/transfer/importer/json.py
+++ b/infrahub_sdk/transfer/importer/json.py
@@ -62,7 +62,7 @@ async def import_data(self, import_directory: Path, branch: str) -> None:
with self.wrapped_task_output("Analyzing import"):
import_nodes_by_kind = defaultdict(list)
- for graphql_data, kind in zip(table.column("graphql_json"), table.column("kind")):
+ for graphql_data, kind in zip(table.column("graphql_json"), table.column("kind"), strict=False):
node = await InfrahubNode.from_graphql(self.client, branch, ujson.loads(str(graphql_data)))
import_nodes_by_kind[str(kind)].append(node)
self.all_nodes[node.id] = node
@@ -109,7 +109,7 @@ async def remove_and_store_optional_relationships(self) -> None:
relationship_schema
)
- for relationship_name in self.optional_relationships_schemas_by_node_kind[node_kind].keys():
+ for relationship_name in self.optional_relationships_schemas_by_node_kind[node_kind]:
relationship_value = getattr(node, relationship_name)
if isinstance(relationship_value, RelationshipManager):
if relationship_value.peer_ids:
@@ -144,7 +144,7 @@ async def update_optional_relationships(self) -> None:
await self.execute_batches([update_batch], "Adding optional relationships to nodes")
async def update_many_to_many_relationships(self, file: Path) -> None:
- relationships = ujson.loads(file.read_text())
+ relationships = ujson.loads(file.read_text(encoding="utf-8"))
update_batch = await self.client.create_batch(return_exceptions=True)
for relationship in relationships:
diff --git a/infrahub_sdk/types.py b/infrahub_sdk/types.py
index f6a75fd9..666bb71c 100644
--- a/infrahub_sdk/types.py
+++ b/infrahub_sdk/types.py
@@ -2,7 +2,7 @@
import enum
from logging import Logger
-from typing import TYPE_CHECKING, Any, Protocol, Union, runtime_checkable
+from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
from pydantic import BaseModel
@@ -65,7 +65,7 @@ def exception(self, event: str | None = None, *args: Any, **kw: Any) -> Any:
"""Send an exception event."""
-InfrahubLoggers = Union[InfrahubLogger, Logger]
+InfrahubLoggers = InfrahubLogger | Logger
class Order(BaseModel):
diff --git a/infrahub_sdk/utils.py b/infrahub_sdk/utils.py
index d90c1f96..8556b012 100644
--- a/infrahub_sdk/utils.py
+++ b/infrahub_sdk/utils.py
@@ -168,7 +168,7 @@ def str_to_bool(value: str) -> bool:
if isinstance(value, bool):
return value
- if isinstance(value, int) and value in [0, 1]:
+ if isinstance(value, int) and value in {0, 1}:
return bool(value)
if not isinstance(value, str):
@@ -318,7 +318,7 @@ def write_to_file(path: Path, value: Any) -> bool:
raise FileExistsError(f"{path} is a directory")
to_write = str(value)
- written = path.write_text(to_write)
+ written = path.write_text(to_write, encoding="utf-8")
return written is not None
diff --git a/pyproject.toml b/pyproject.toml
index fef9bbb3..52a3a5b9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,17 +1,16 @@
[project]
name = "infrahub-sdk"
-version = "1.15.1"
+version = "1.16.0"
description = "Python Client to interact with Infrahub"
authors = [
{name = "OpsMill", email = "info@opsmill.com"}
]
readme = "README.md"
license = {text = "Apache-2.0"}
-requires-python = ">=3.9,<3.14"
+requires-python = ">=3.10,<3.14"
classifiers = [
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
@@ -26,7 +25,6 @@ dependencies = [
"dulwich>=0.21.4",
"whenever>=0.7.2,<0.8.0",
"netutils>=1.0.0",
- "eval-type-backport>=0.2.2; python_version>='3.9' and python_version<'3.10'",
"tomli>=1.1.0; python_version<'3.11'",
]
@@ -83,7 +81,7 @@ tests = [
lint = [
"yamllint",
"mypy==1.11.2",
- "ruff==0.11.0",
+ "ruff==0.14.5",
"astroid>=3.1,<4.0",
]
types = [
@@ -159,14 +157,12 @@ ignore = [
"DOC", # pydoclint
"CPY", # flake8-copyright
"T201", # use of `print`
- "ISC", # flake8-implicit-str-concat
"COM812", # missing-trailing-comma
##################################################################################################
# Rules below needs to be Investigated #
##################################################################################################
"PT", # flake8-pytest-style
- "PGH", # pygrep-hooks
"ERA", # eradicate commented-out code
"SLF001", # flake8-self
"EM", # flake8-errmsg
@@ -178,7 +174,6 @@ ignore = [
"G", # flake8-logging-format
"RSE", # flake8-raise
"BLE", # flake8-blind-except (BLE)
- "A", # flake8-builtins
##################################################################################################
# The ignored rules below should be removed once the code has been updated, they are included #
@@ -189,7 +184,6 @@ ignore = [
"B904", # Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
"FURB110", # Replace ternary `if` expression with `or` operator
"FURB113", # Use `lines.extend((" " * self.indentation + "}", "}"))` instead of repeatedly calling `lines.append()`
- "FURB177", # Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups
"INP001", # File declares a package, but is nested under an implicit namespace package.
"N802", # Function name should be lowercase
"N806", # Variable in function should be lowercase
@@ -200,16 +194,13 @@ ignore = [
"PLR0913", # Too many arguments in function definition
"PLR0917", # Too many positional arguments
"PLR2004", # Magic value used in comparison
- "PLR6201", # Use a `set` literal when testing for membership
"PLR6301", # Method could be a function, class method, or static method
"PLW0603", # Using the global statement to update `SETTINGS` is discouraged
"PLW1641", # Object does not implement `__hash__` method
"PTH100", # `os.path.abspath()` should be replaced by `Path.resolve()`
"PTH109", # `os.getcwd()` should be replaced by `Path.cwd()`
"RUF005", # Consider `[*path, str(key)]` instead of concatenation
- "RUF015", # Prefer `next(iter(input_data["variables"].keys()))` over single element slice
"RUF029", # Function is declared `async`, but doesn't `await` or use `async` features.
- "S108", # Probable insecure usage of temporary file or directory
"S311", # Standard pseudo-random generators are not suitable for cryptographic purposes
"S701", # By default, jinja2 sets `autoescape` to `False`. Consider using `autoescape=True`
"SIM102", # Use a single `if` statement instead of nested `if` statements
@@ -217,11 +208,8 @@ ignore = [
"SIM108", # Use ternary operator `key_str = f"{value[ALIAS_KEY]}: {key}" if ALIAS_KEY in value and value[ALIAS_KEY] else key` instead of `if`-`else`-block
"SIM110", # Use `return any(getattr(item, resource_field) == resource_id for item in getattr(self, RESOURCE_MAP[resource_type]))` instead of `for` loop
"SIM114", # Combine `if` branches using logical `or` operator
- "SIM117", # Use a single `with` statement with multiple contexts instead of nested `with` statements
- "SIM118", # Use `key in dict` instead of `key in dict.keys)
"TC003", # Move standard library import `collections.abc.Iterable` into a type-checking block
"UP031", # Use format specifiers instead of percent format
- "UP045", # Use `X | None` for type annotations
]
@@ -232,6 +220,19 @@ indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
+
+[tool.ruff.lint.flake8-builtins]
+ignorelist = [
+ "id",
+ # Review and update builtin shadowing below this line
+ "filter",
+ "format",
+ "input",
+ "list",
+ "property",
+]
+
+
[tool.ruff.lint.isort]
known-first-party = ["infrahub_sdk", "infrahub_ctl"]
@@ -248,12 +249,9 @@ max-complexity = 17
##################################################################################################
# Review and change the below later #
##################################################################################################
- "ANN202", # Missing return type annotation for private function
- "ANN401", # Dynamically typed expressions (typing.Any) are disallowed
-]
-
-"infrahub_sdk/ctl/**/*.py" = [
- "UP007", # Use `X | Y` for type annotations | Required for Typer until we can drop the support for Python 3.9
+ "ANN202", # Missing return type annotation for private function
+ "ANN401", # Dynamically typed expressions (typing.Any) are disallowed
+ "ASYNC240", # Async functions should not use pathlib.Path methods, use trio.Path or anyio.path
]
"infrahub_sdk/client.py" = [
@@ -279,16 +277,6 @@ max-complexity = 17
# Review and change the below later #
##################################################################################################
"ANN001", # Missing type annotation for function argument
- "ANN201", # ANN201 Missing return type annotation for public function
- "RET504", # Unnecessary assignment to `data` before `return` statement
-]
-
-"tests/unit/sdk/test_client.py" = [
- "W293", # Blank line contains whitespace (used within output check)
-]
-
-"tests/fixtures/unit/test_graphql_plugin/*.py" = [
- "FA100", # Add `from __future__ import annotations` to simplify `typing.Optional`
]
"tasks.py" = [
diff --git a/tests/__init__.py b/tests/__init__.py
index c6ca0edb..b0e99a74 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -3,5 +3,5 @@
from rich import inspect as rinspect
from rich import print as rprint
-builtins.rprint = rprint # type: ignore
-builtins.rinspect = rinspect # type: ignore
+builtins.rprint = rprint # type: ignore[attr-defined]
+builtins.rinspect = rinspect # type: ignore[attr-defined]
diff --git a/tests/conftest.py b/tests/conftest.py
index edabd8a6..953e9c6b 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,5 +1,6 @@
import asyncio
import os
+from collections.abc import Generator
import pytest
@@ -11,7 +12,7 @@
@pytest.fixture(scope="session")
-def event_loop():
+def event_loop() -> Generator[asyncio.AbstractEventLoop]:
"""Overrides pytest default function scoped event loop"""
policy = asyncio.get_event_loop_policy()
loop = policy.new_event_loop()
@@ -26,7 +27,7 @@ def execute_before_any_test() -> None:
@pytest.fixture(scope="session", autouse=True)
-def clean_env_vars():
+def clean_env_vars() -> Generator:
"""Cleans the environment variables before any test is run."""
original_values = {}
for name in ENV_VARS_TO_CLEAN:
diff --git a/tests/fixtures/integration/test_infrahubctl/tags_transform/tags_transform.py b/tests/fixtures/integration/test_infrahubctl/tags_transform/tags_transform.py
index 78d59fb6..99786479 100644
--- a/tests/fixtures/integration/test_infrahubctl/tags_transform/tags_transform.py
+++ b/tests/fixtures/integration/test_infrahubctl/tags_transform/tags_transform.py
@@ -5,7 +5,7 @@ class TagsTransform(InfrahubTransform):
query = "tags_query"
url = "my-tags"
- async def transform(self, data):
+ async def transform(self, data) -> dict[str, str]:
tag = data["BuiltinTag"]["edges"][0]["node"]
tag_name = tag["name"]["value"]
tag_description = tag["description"]["value"]
diff --git a/tests/helpers/fixtures.py b/tests/helpers/fixtures.py
index cb60150d..349d2c17 100644
--- a/tests/helpers/fixtures.py
+++ b/tests/helpers/fixtures.py
@@ -11,6 +11,4 @@ def read_fixture(file_name: str, fixture_subdir: str = ".") -> str:
"""Read the contents of a fixture."""
file_path = get_fixtures_dir() / fixture_subdir / file_name
with file_path.open("r", encoding="utf-8") as fhd:
- fixture_contents = fhd.read()
-
- return fixture_contents
+ return fhd.read()
diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py
index 752f8fdc..a999d84e 100644
--- a/tests/integration/conftest.py
+++ b/tests/integration/conftest.py
@@ -248,7 +248,7 @@
# },
# ],
# }
-# return NodeSchema(**data) # type: ignore
+# return NodeSchema(**data)
# @pytest.fixture
diff --git a/tests/integration/test_infrahub_client.py b/tests/integration/test_infrahub_client.py
index 8c972d0a..db86d759 100644
--- a/tests/integration/test_infrahub_client.py
+++ b/tests/integration/test_infrahub_client.py
@@ -1,5 +1,6 @@
from __future__ import annotations
+from collections.abc import AsyncGenerator
from typing import TYPE_CHECKING
import pytest
@@ -33,7 +34,7 @@ async def base_dataset(
await client.branch.create(branch_name="branch01")
@pytest.fixture
- async def set_pagination_size3(self, client: InfrahubClient):
+ async def set_pagination_size3(self, client: InfrahubClient) -> AsyncGenerator:
original_pagination_size = client.pagination_size
client.pagination_size = 3
yield
@@ -56,8 +57,8 @@ async def test_branch_delete(self, client: InfrahubClient, base_dataset) -> None
pre_delete = await client.branch.all()
await client.branch.delete(async_branch)
post_delete = await client.branch.all()
- assert async_branch in pre_delete.keys()
- assert async_branch not in post_delete.keys()
+ assert async_branch in pre_delete
+ assert async_branch not in post_delete
async def test_get_all(self, client: InfrahubClient, base_dataset) -> None:
nodes = await client.all(kind=TESTING_CAT)
@@ -105,7 +106,7 @@ async def test_get_generic(self, client: InfrahubClient, base_dataset) -> None:
async def test_get_generic_fragment(self, client: InfrahubClient, base_dataset) -> None:
nodes = await client.all(kind=TESTING_ANIMAL, fragment=True)
assert len(nodes)
- assert nodes[0].typename in [TESTING_DOG, TESTING_CAT]
+ assert nodes[0].typename in {TESTING_DOG, TESTING_CAT}
assert nodes[0].breed.value is not None
async def test_get_related_nodes(self, client: InfrahubClient, base_dataset, person_ethan) -> None:
diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py
index 9c48bcf9..2bb8e725 100644
--- a/tests/unit/__init__.py
+++ b/tests/unit/__init__.py
@@ -2,4 +2,4 @@
from rich import print as rprint
-builtins.rprint = rprint # type: ignore
+builtins.rprint = rprint # type: ignore[attr-defined]
diff --git a/tests/unit/ctl/conftest.py b/tests/unit/ctl/conftest.py
index 30ce70d7..b4089388 100644
--- a/tests/unit/ctl/conftest.py
+++ b/tests/unit/ctl/conftest.py
@@ -1,3 +1,5 @@
+from typing import Any
+
import pytest
import ujson
from pytest_httpx import HTTPXMock
@@ -63,8 +65,8 @@ async def mock_branches_list_query(httpx_mock: HTTPXMock) -> HTTPXMock:
@pytest.fixture
-async def authentication_error_payload():
- response = {
+async def authentication_error_payload() -> dict[str, Any]:
+ return {
"data": None,
"errors": [
{
@@ -74,8 +76,6 @@ async def authentication_error_payload():
],
}
- return response
-
@pytest.fixture
async def mock_branch_create_error(httpx_mock: HTTPXMock) -> HTTPXMock:
diff --git a/tests/unit/ctl/test_branch_report.py b/tests/unit/ctl/test_branch_report.py
new file mode 100644
index 00000000..27fc3a40
--- /dev/null
+++ b/tests/unit/ctl/test_branch_report.py
@@ -0,0 +1,443 @@
+import pytest
+from httpx import HTTPStatusError
+from pytest_httpx import HTTPXMock
+from typer.testing import CliRunner
+
+from infrahub_sdk import Config, InfrahubClient
+from infrahub_sdk.ctl.branch import app, check_git_files_changed, format_timestamp
+
+pytestmark = pytest.mark.httpx_mock(can_send_already_matched_responses=True)
+
+
+def test_format_timestamp_valid_iso() -> None:
+ """Test format_timestamp with valid ISO timestamp."""
+ timestamp = "2025-11-14T12:30:45Z"
+ result = format_timestamp(timestamp)
+ assert result == "2025-11-14 12:30:45"
+
+
+def test_format_timestamp_with_timezone() -> None:
+ """Test format_timestamp with timezone offset."""
+ timestamp = "2025-11-14T12:30:45+00:00"
+ result = format_timestamp(timestamp)
+ assert result == "2025-11-14 12:30:45"
+
+
+def test_format_timestamp_invalid() -> None:
+ """Test format_timestamp with invalid timestamp returns original."""
+ timestamp = "not-a-timestamp"
+ with pytest.raises(ValueError):
+ format_timestamp(timestamp)
+
+
+@pytest.fixture
+async def mock_git_files_changed_yes(httpx_mock: HTTPXMock) -> HTTPXMock:
+ """Mock REST API response with files changed."""
+ response = {
+ "test-branch": {
+ "repo-id-1": {
+ "files": [
+ {"path": "file1.py", "status": "modified"},
+ {"path": "file2.py", "status": "added"},
+ ]
+ }
+ }
+ }
+
+ httpx_mock.add_response(
+ method="GET",
+ url="http://mock/api/diff/files?branch=test-branch",
+ json=response,
+ )
+ return httpx_mock
+
+
+async def test_check_git_files_changed_with_files(
+ mock_git_files_changed_yes: HTTPXMock,
+) -> None:
+ """Test check_git_files_changed returns True when files exist."""
+ client = InfrahubClient(config=Config(address="http://mock"))
+ result = await check_git_files_changed(client, branch="test-branch")
+ assert result is True
+
+
+async def test_check_git_files_changed_no_files(httpx_mock: HTTPXMock) -> None:
+ """Test check_git_files_changed returns False when no files."""
+ response = {"test-branch": {"repo-id-1": {"files": []}}}
+
+ httpx_mock.add_response(
+ method="GET",
+ url="http://mock/api/diff/files?branch=test-branch",
+ json=response,
+ )
+ client = InfrahubClient(config=Config(address="http://mock"))
+ result = await check_git_files_changed(client, branch="test-branch")
+ assert result is False
+
+
+async def test_check_git_files_changed_empty_response(httpx_mock: HTTPXMock) -> None:
+ response = {}
+
+ httpx_mock.add_response(
+ method="GET",
+ url="http://mock/api/diff/files?branch=test-branch",
+ json=response,
+ )
+
+ """Test check_git_files_changed returns False when branch not in response."""
+ client = InfrahubClient(config=Config(address="http://mock"))
+ result = await check_git_files_changed(client, branch="test-branch")
+ assert result is False
+
+
+async def test_check_git_files_changed_http_error(httpx_mock: HTTPXMock) -> None:
+ """Test check_git_files_changed raises exception on HTTP error."""
+ httpx_mock.add_response(
+ method="GET",
+ url="http://mock/api/diff/files?branch=test-branch",
+ status_code=404,
+ )
+
+ client = InfrahubClient(config=Config(address="http://mock"))
+ with pytest.raises(HTTPStatusError):
+ await check_git_files_changed(client, branch="test-branch")
+
+
+@pytest.fixture
+def mock_branch_report_default_branch(httpx_mock: HTTPXMock) -> HTTPXMock:
+ """Mock all responses for branch report CLI command."""
+ httpx_mock.add_response(
+ method="POST",
+ json={
+ "data": {
+ "Branch": [
+ {
+ "id": "default-branch-id",
+ "name": "main",
+ "sync_with_git": True,
+ "is_default": True,
+ "origin_branch": "main",
+ "branched_from": "2025-11-01t10:00:00z",
+ "has_schema_changes": False,
+ "status": "OPEN",
+ },
+ ],
+ },
+ },
+ match_headers={"X-Infrahub-Tracker": "query-branch"},
+ )
+
+
+@pytest.fixture
+def mock_branch_report_command(httpx_mock: HTTPXMock) -> HTTPXMock:
+ """Mock all responses for branch report CLI command."""
+ httpx_mock.add_response(
+ method="POST",
+ json={
+ "data": {
+ "Branch": [
+ {
+ "id": "test-branch-id",
+ "name": "test-branch",
+ "sync_with_git": True,
+ "is_default": False,
+ "origin_branch": "main",
+ "branched_from": "2025-11-01t10:00:00Z",
+ "has_schema_changes": False,
+ "status": "OPEN",
+ }
+ ]
+ }
+ },
+ match_headers={"X-Infrahub-Tracker": "query-branch"},
+ )
+
+ httpx_mock.add_response(
+ method="POST",
+ json={
+ "data": {
+ "DiffTree": {
+ "num_added": 5,
+ "num_updated": 3,
+ "num_removed": 1,
+ "num_conflicts": 0,
+ "to_time": "2025-11-14T18:00:00Z",
+ "from_time": "2025-11-01T10:00:00Z",
+ "base_branch": "main",
+ "diff_branch": "test-branch",
+ "name": None,
+ "nodes": [],
+ }
+ }
+ },
+ )
+
+ httpx_mock.add_response(
+ method="GET",
+ json={"test-branch": {"repo-1": {"files": [{"path": "test.py"}]}}},
+ )
+
+ httpx_mock.add_response(
+ method="POST",
+ json={"data": {"CoreProposedChange": {"count": 0, "edges": []}}},
+ )
+
+ return httpx_mock
+
+
+def test_branch_report_command_without_proposed_change(
+ mock_branch_report_command: HTTPXMock,
+ mock_schema_query_05: HTTPXMock,
+) -> None:
+ """Test branch report CLI command with no proposed changes."""
+ runner = CliRunner()
+ result = runner.invoke(app, ["report", "test-branch"])
+
+ assert result.exit_code == 0, f"Command failed: {result.stdout}"
+ assert "Branch: test-branch" in result.stdout
+ assert "2025-11-01 10:00:00" in result.stdout
+ assert "OPEN" in result.stdout
+ assert "Amount of additions" in result.stdout
+ assert "5" in result.stdout
+ assert "No proposed changes for this branch" in result.stdout
+
+
+def test_branch_report_command_main_branch(mock_branch_report_default_branch) -> None:
+ """Test branch report CLI command on main branch."""
+ runner = CliRunner()
+ result = runner.invoke(app, ["report", "main"])
+
+ assert result.exit_code == 1
+ assert "Cannot create a report for the default branch!" in result.stdout
+
+
+@pytest.fixture
+async def schema_with_proposed_change() -> dict:
+ """Schema fixture that includes CoreProposedChange with is_draft."""
+ return {
+ "nodes": [
+ {
+ "name": "ProposedChange",
+ "namespace": "Core",
+ "default_filter": "name__value",
+ "attributes": [
+ {"name": "name", "kind": "Text"},
+ {"name": "state", "kind": "Text"},
+ {"name": "is_draft", "kind": "Boolean"},
+ ],
+ "relationships": [
+ {"name": "created_by", "peer": "CoreAccount", "cardinality": "one"},
+ {"name": "approved_by", "peer": "CoreAccount", "cardinality": "many"},
+ {"name": "rejected_by", "peer": "CoreAccount", "cardinality": "many"},
+ ],
+ },
+ {
+ "name": "Account",
+ "namespace": "Core",
+ "default_filter": "name__value",
+ "attributes": [
+ {"name": "name", "kind": "Text"},
+ {"name": "updated_at", "kind": "DateTime"},
+ ],
+ "relationships": [],
+ },
+ ]
+ }
+
+
+@pytest.fixture
+def mock_schema_with_proposed_change(httpx_mock: HTTPXMock, schema_with_proposed_change: dict) -> HTTPXMock:
+ """Mock schema endpoint with CoreProposedChange."""
+ httpx_mock.add_response(
+ method="GET",
+ url="http://mock/api/schema?branch=main",
+ json=schema_with_proposed_change,
+ is_reusable=True,
+ )
+ return httpx_mock
+
+
+@pytest.fixture
+def mock_branch_report_with_proposed_changes(httpx_mock: HTTPXMock) -> HTTPXMock:
+ """Mock all responses for branch report with proposed changes."""
+ httpx_mock.add_response(
+ method="POST",
+ json={
+ "data": {
+ "Branch": [
+ {
+ "id": "test-branch-id",
+ "name": "test-branch",
+ "sync_with_git": True,
+ "is_default": False,
+ "origin_branch": "main",
+ "branched_from": "2025-11-01T10:00:00Z",
+ "has_schema_changes": False,
+ "status": "OPEN",
+ }
+ ]
+ }
+ },
+ match_headers={"X-Infrahub-Tracker": "query-branch"},
+ )
+
+ httpx_mock.add_response(
+ method="POST",
+ json={
+ "data": {
+ "DiffTree": {
+ "num_added": 5,
+ "num_updated": 3,
+ "num_removed": 1,
+ "num_conflicts": 0,
+ "to_time": "2025-11-14T18:00:00Z",
+ "from_time": "2025-11-01T10:00:00Z",
+ "base_branch": "main",
+ "diff_branch": "test-branch",
+ "name": None,
+ "nodes": [],
+ }
+ }
+ },
+ )
+
+ httpx_mock.add_response(
+ method="GET",
+ json={"test-branch": {"repo-1": {"files": [{"path": "test.py"}]}}},
+ )
+
+ httpx_mock.add_response(
+ method="POST",
+ json={
+ "data": {
+ "CoreProposedChange": {
+ "count": 2,
+ "edges": [
+ {
+ "node": {
+ "id": "18789937-1263-f1cb-3615-c51259b5cd8c",
+ "hfid": None,
+ "display_label": "Add new feature",
+ "__typename": "CoreProposedChange",
+ "is_draft": {"value": False},
+ "name": {"value": "Add new feature"},
+ "state": {"value": "open"},
+ "approved_by": {
+ "count": 2,
+ "edges": [
+ {
+ "node": {
+ "id": "user-1",
+ "__typename": "CoreAccount",
+ }
+ },
+ {
+ "node": {
+ "id": "user-2",
+ "__typename": "CoreAccount",
+ }
+ },
+ ],
+ },
+ "rejected_by": {"count": 0, "edges": []},
+ "created_by": {
+ "node": {
+ "id": "187895d8-723e-8f5d-3614-c517ac8e761c",
+ "hfid": ["johndoe"],
+ "display_label": "John Doe",
+ "__typename": "CoreAccount",
+ "name": {"value": "John Doe"},
+ },
+ "properties": {
+ "updated_at": "2025-11-10T14:30:00Z",
+ },
+ },
+ }
+ },
+ {
+ "node": {
+ "id": "28789937-1263-f1cb-3615-c51259b5cd8d",
+ "hfid": None,
+ "display_label": "Fix bug in network module",
+ "__typename": "CoreProposedChange",
+ "is_draft": {"value": True},
+ "name": {"value": "Fix bug in network module"},
+ "state": {"value": "merged"},
+ "approved_by": {
+ "count": 1,
+ "edges": [
+ {
+ "node": {
+ "id": "user-3",
+ "__typename": "CoreAccount",
+ }
+ },
+ ],
+ },
+ "rejected_by": {
+ "count": 2,
+ "edges": [
+ {
+ "node": {
+ "id": "user-4",
+ "__typename": "CoreAccount",
+ }
+ },
+ {
+ "node": {
+ "id": "user-5",
+ "__typename": "CoreAccount",
+ }
+ },
+ ],
+ },
+ "created_by": {
+ "node": {
+ "id": "287895d8-723e-8f5d-3614-c517ac8e762c",
+ "hfid": ["janesmith"],
+ "display_label": "Jane Smith",
+ "__typename": "CoreAccount",
+ "name": {"value": "Jane Smith"},
+ },
+ "properties": {
+ "updated_at": "2025-11-10T14:30:00Z",
+ },
+ },
+ }
+ },
+ ],
+ }
+ }
+ },
+ )
+
+ return httpx_mock
+
+
+def test_branch_report_command_with_proposed_changes(
+ mock_branch_report_with_proposed_changes: HTTPXMock,
+ mock_schema_with_proposed_change: HTTPXMock,
+) -> None:
+ """Test branch report CLI command with proposed changes."""
+ runner = CliRunner()
+ result = runner.invoke(app, ["report", "test-branch"])
+
+ assert result.exit_code == 0, f"Command failed: {result.stdout}"
+ assert "Branch: test-branch" in result.stdout
+
+ assert "Proposed change: Add new feature" in result.stdout
+ assert "Proposed change: Fix bug in network module" in result.stdout
+
+ assert "open" in result.stdout
+ assert "merged" in result.stdout
+
+ assert "Is draft No" in result.stdout
+ assert "Is draft Yes" in result.stdout
+
+ assert "John Doe" in result.stdout
+ assert "Jane Smith" in result.stdout
+
+ assert "Approvals 2" in result.stdout
+ assert "Rejections 0" in result.stdout
+ assert "Approvals 1" in result.stdout
+ assert "Rejections 2" in result.stdout
diff --git a/tests/unit/ctl/test_render_app.py b/tests/unit/ctl/test_render_app.py
index 0589acda..88e71f86 100644
--- a/tests/unit/ctl/test_render_app.py
+++ b/tests/unit/ctl/test_render_app.py
@@ -1,6 +1,5 @@
import json
import os
-import sys
from dataclasses import dataclass
from pathlib import Path
@@ -17,8 +16,6 @@
FIXTURE_BASE_DIR = Path(Path(os.path.abspath(__file__)).parent / ".." / ".." / "fixtures" / "repos")
-requires_python_310 = pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10 or higher")
-
@dataclass
class RenderAppFailure:
@@ -55,7 +52,6 @@ class RenderAppFailure:
"test_case",
[pytest.param(tc, id=tc.name) for tc in RENDER_APP_FAIL_TEST_CASES],
)
-@requires_python_310
def test_validate_template_not_found(test_case: RenderAppFailure, httpx_mock: HTTPXMock) -> None:
"""Ensure that the correct errors are caught"""
httpx_mock.add_response(
@@ -83,8 +79,9 @@ def test_validate_template_not_found(test_case: RenderAppFailure, httpx_mock: HT
(None, None, True, "git-branch"),
],
)
-@requires_python_310
-def test_render_branch_selection(monkeypatch, httpx_mock: HTTPXMock, cli_branch, env_branch, from_git, expected_branch):
+def test_render_branch_selection(
+ monkeypatch, httpx_mock: HTTPXMock, cli_branch, env_branch, from_git, expected_branch
+) -> None:
"""Test that the render command uses the correct branch source."""
if from_git:
diff --git a/tests/unit/ctl/test_repository_app.py b/tests/unit/ctl/test_repository_app.py
index f8636824..5f23bb60 100644
--- a/tests/unit/ctl/test_repository_app.py
+++ b/tests/unit/ctl/test_repository_app.py
@@ -19,8 +19,7 @@
@pytest.fixture
def mock_client() -> mock.Mock:
"""Fixture for a mocked InfrahubClient."""
- client = mock.create_autospec(InfrahubClient)
- return client
+ return mock.create_autospec(InfrahubClient)
# ---------------------------------------------------------
diff --git a/tests/unit/ctl/test_transform_app.py b/tests/unit/ctl/test_transform_app.py
index 498d70de..9ae4585d 100644
--- a/tests/unit/ctl/test_transform_app.py
+++ b/tests/unit/ctl/test_transform_app.py
@@ -3,8 +3,8 @@
import json
import os
import shutil
-import sys
import tempfile
+from collections.abc import Generator
from pathlib import Path
import pytest
@@ -23,11 +23,9 @@
Path(os.path.abspath(__file__)).parent / ".." / ".." / "fixtures" / "integration" / "test_infrahubctl"
)
-requires_python_310 = pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10 or higher")
-
@pytest.fixture
-def tags_transform_dir():
+def tags_transform_dir() -> Generator[str]:
temp_dir = tempfile.mkdtemp()
try:
@@ -51,7 +49,6 @@ class TestInfrahubctlTransform:
"""Groups the 'infrahubctl transform' test cases."""
@staticmethod
- @requires_python_310
def test_transform_not_exist_in_infrahub_yml(tags_transform_dir: str) -> None:
"""Case transform is not specified in the infrahub.yml file."""
transform_name = "not_existing_transform"
@@ -61,7 +58,6 @@ def test_transform_not_exist_in_infrahub_yml(tags_transform_dir: str) -> None:
assert output.exit_code == 1
@staticmethod
- @requires_python_310
def test_transform_python_file_not_defined(tags_transform_dir: str) -> None:
"""Case transform python file not defined."""
# Remove transform file
@@ -76,7 +72,6 @@ def test_transform_python_file_not_defined(tags_transform_dir: str) -> None:
assert output.exit_code == 1
@staticmethod
- @requires_python_310
def test_transform_python_class_not_defined(tags_transform_dir: str) -> None:
"""Case transform python class not defined."""
# Rename transform inside of python file so the class name searched for no longer exists
@@ -96,7 +91,6 @@ def test_transform_python_class_not_defined(tags_transform_dir: str) -> None:
assert output.exit_code == 1
@staticmethod
- @requires_python_310
def test_gql_query_not_defined(tags_transform_dir: str) -> None:
"""Case GraphQL Query is not defined"""
# Remove GraphQL Query file
@@ -110,7 +104,6 @@ def test_gql_query_not_defined(tags_transform_dir: str) -> None:
assert output.exit_code == 1
@staticmethod
- @requires_python_310
def test_infrahubctl_transform_cmd_success(httpx_mock: HTTPXMock, tags_transform_dir: str) -> None:
"""Case infrahubctl transform command executes successfully"""
httpx_mock.add_response(
diff --git a/tests/unit/sdk/checks/test_checks.py b/tests/unit/sdk/checks/test_checks.py
index 8b4cd82a..7fe0c691 100644
--- a/tests/unit/sdk/checks/test_checks.py
+++ b/tests/unit/sdk/checks/test_checks.py
@@ -1,3 +1,5 @@
+from pathlib import Path
+
import pytest
from infrahub_sdk import InfrahubClient
@@ -6,7 +8,7 @@
pytestmark = pytest.mark.httpx_mock(can_send_already_matched_responses=True)
-async def test_class_init() -> None:
+async def test_class_init(tmp_path: Path) -> None:
class IFCheckNoQuery(InfrahubCheck):
pass
@@ -29,9 +31,9 @@ class IFCheckNoName(InfrahubCheck):
check = IFCheckNoName()
assert check.name == "IFCheckNoName"
- check = IFCheckWithName(root_directory="/tmp")
+ check = IFCheckWithName(root_directory=str(tmp_path))
assert check.name == "my_check"
- assert check.root_directory == "/tmp"
+ assert check.root_directory == str(tmp_path)
async def test_async_init(client) -> None:
diff --git a/tests/unit/sdk/conftest.py b/tests/unit/sdk/conftest.py
index 50bf3203..281b2d80 100644
--- a/tests/unit/sdk/conftest.py
+++ b/tests/unit/sdk/conftest.py
@@ -2,11 +2,11 @@
import re
import sys
-from collections.abc import AsyncGenerator, Mapping
+from collections.abc import AsyncGenerator, Callable, Mapping
from dataclasses import dataclass
from inspect import Parameter
from io import StringIO
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Any
import pytest
import ujson
@@ -40,11 +40,10 @@ async def client_sync() -> InfrahubClientSync:
@pytest.fixture
async def clients() -> BothClients:
- both = BothClients(
+ return BothClients(
standard=InfrahubClient(config=Config(address="http://mock", insert_tracker=True, pagination_size=3)),
sync=InfrahubClientSync(config=Config(address="http://mock", insert_tracker=True, pagination_size=3)),
)
- return both
@pytest.fixture
@@ -93,7 +92,7 @@ def return_annotation_map() -> dict[str, str]:
@pytest.fixture
-def replace_async_return_annotation(return_annotation_map: dict[str, str]):
+def replace_async_return_annotation(return_annotation_map: dict[str, str]) -> Callable[[str], str]:
"""Allows for comparison between sync and async return annotations."""
def replace_annotation(annotation: str) -> str:
@@ -103,11 +102,13 @@ def replace_annotation(annotation: str) -> str:
@pytest.fixture
-def replace_async_parameter_annotations(replace_async_return_annotation):
+def replace_async_parameter_annotations(
+ replace_async_return_annotation,
+) -> Callable[[Mapping[str, Parameter]], list[tuple[str, str]]]:
"""Allows for comparison between sync and async parameter annotations."""
- def replace_annotations(parameters: Mapping[str, Parameter]) -> tuple[str, str]:
- parameter_tuples = []
+ def replace_annotations(parameters: Mapping[str, Parameter]) -> list[tuple[str, str]]:
+ parameter_tuples: list[tuple[str, str]] = []
for name, parameter in parameters.items():
parameter_tuples.append((name, replace_async_return_annotation(parameter.annotation)))
@@ -117,7 +118,7 @@ def replace_annotations(parameters: Mapping[str, Parameter]) -> tuple[str, str]:
@pytest.fixture
-def replace_sync_return_annotation(return_annotation_map: dict[str, str]) -> str:
+def replace_sync_return_annotation(return_annotation_map: dict[str, str]) -> Callable[[str], str]:
"""Allows for comparison between sync and async return annotations."""
def replace_annotation(annotation: str) -> str:
@@ -128,11 +129,13 @@ def replace_annotation(annotation: str) -> str:
@pytest.fixture
-def replace_sync_parameter_annotations(replace_sync_return_annotation):
+def replace_sync_parameter_annotations(
+ replace_sync_return_annotation,
+) -> Callable[[Mapping[str, Parameter]], list[tuple[str, str]]]:
"""Allows for comparison between sync and async parameter annotations."""
- def replace_annotations(parameters: Mapping[str, Parameter]) -> tuple[str, str]:
- parameter_tuples = []
+ def replace_annotations(parameters: Mapping[str, Parameter]) -> list[tuple[str, str]]:
+ parameter_tuples: list[tuple[str, str]] = []
for name, parameter in parameters.items():
parameter_tuples.append((name, replace_sync_return_annotation(parameter.annotation)))
@@ -174,7 +177,7 @@ async def location_schema() -> NodeSchemaAPI:
},
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
@@ -216,7 +219,7 @@ async def location_schema_with_dropdown() -> NodeSchemaAPI:
},
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
@@ -281,7 +284,7 @@ async def schema_with_hfid() -> dict[str, NodeSchemaAPI]:
],
},
}
- return {k: NodeSchema(**v).convert_api() for k, v in data.items()} # type: ignore
+ return {k: NodeSchema(**v).convert_api() for k, v in data.items()}
@pytest.fixture
@@ -295,12 +298,12 @@ async def std_group_schema() -> NodeSchemaAPI:
{"name": "description", "kind": "String", "optional": True},
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
-async def location_data01_no_pagination():
- data = {
+async def location_data01_no_pagination() -> dict[str, Any]:
+ return {
"__typename": "BuiltinLocation",
"id": "llllllll-llll-llll-llll-llllllllllll",
"display_label": "dfw1",
@@ -342,12 +345,10 @@ async def location_data01_no_pagination():
],
}
- return data
-
@pytest.fixture
-async def location_data02_no_pagination():
- data = {
+async def location_data02_no_pagination() -> dict[str, Any]:
+ return {
"__typename": "BuiltinLocation",
"id": "llllllll-llll-llll-llll-llllllllllll",
"display_label": "dfw1",
@@ -405,12 +406,10 @@ async def location_data02_no_pagination():
],
}
- return data
-
@pytest.fixture
-async def location_data01():
- data = {
+async def location_data01() -> dict[str, Any]:
+ return {
"node": {
"__typename": "BuiltinLocation",
"id": "llllllll-llll-llll-llll-llllllllllll",
@@ -446,12 +445,10 @@ async def location_data01():
}
}
- return data
-
@pytest.fixture
-async def location_data01_property():
- data = {
+async def location_data01_property() -> dict[str, Any]:
+ return {
"node": {
"__typename": "BuiltinLocation",
"id": "llllllll-llll-llll-llll-llllllllllll",
@@ -460,18 +457,21 @@ async def location_data01_property():
"is_protected": True,
"owner": None,
"source": None,
+ "updated_at": "2024-01-15T10:30:00.000000Z",
"value": "DFW",
},
"description": {
"is_protected": False,
"owner": None,
"source": None,
+ "updated_at": "2024-01-15T10:30:00.000000Z",
"value": None,
},
"type": {
"is_protected": True,
"owner": None,
"source": None,
+ "updated_at": "2024-01-15T10:30:00.000000Z",
"value": "SITE",
},
"primary_tag": {
@@ -479,6 +479,7 @@ async def location_data01_property():
"is_protected": True,
"owner": None,
"source": None,
+ "updated_at": "2024-01-15T10:30:00.000000Z",
},
"node": {
"id": "rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr",
@@ -494,6 +495,7 @@ async def location_data01_property():
"is_protected": True,
"owner": None,
"source": None,
+ "updated_at": "2024-01-15T10:30:00.000000Z",
},
"node": {
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
@@ -506,12 +508,10 @@ async def location_data01_property():
}
}
- return data
-
@pytest.fixture
-async def location_data02():
- data = {
+async def location_data02() -> dict[str, Any]:
+ return {
"node": {
"__typename": "BuiltinLocation",
"id": "llllllll-llll-llll-llll-llllllllllll",
@@ -547,12 +547,10 @@ async def location_data02():
}
}
- return data
-
@pytest.fixture
-async def location_data02_property():
- data = {
+async def location_data02_property() -> dict[str, Any]:
+ return {
"node": {
"__typename": "BuiltinLocation",
"id": "llllllll-llll-llll-llll-llllllllllll",
@@ -565,12 +563,14 @@ async def location_data02_property():
"display_label": "CRM",
"id": "cccccccc-cccc-cccc-cccc-cccccccccccc",
},
+ "updated_at": "2024-01-15T10:30:00.000000Z",
"value": "dfw1",
},
"description": {
"is_protected": False,
"owner": None,
"source": None,
+ "updated_at": "2024-01-15T10:30:00.000000Z",
"value": None,
},
"type": {
@@ -581,6 +581,7 @@ async def location_data02_property():
"display_label": "CRM",
"id": "cccccccc-cccc-cccc-cccc-cccccccccccc",
},
+ "updated_at": "2024-01-15T10:30:00.000000Z",
"value": "SITE",
},
"primary_tag": {
@@ -592,6 +593,7 @@ async def location_data02_property():
"display_label": "CRM",
"id": "cccccccc-cccc-cccc-cccc-cccccccccccc",
},
+ "updated_at": "2024-01-15T10:30:00.000000Z",
},
"node": {
"id": "rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr",
@@ -611,6 +613,7 @@ async def location_data02_property():
"display_label": "CRM",
"id": "cccccccc-cccc-cccc-cccc-cccccccccccc",
},
+ "updated_at": "2024-01-15T10:30:00.000000Z",
},
"node": {
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
@@ -623,11 +626,9 @@ async def location_data02_property():
}
}
- return data
-
@pytest.fixture
-async def rfile_userdata01():
+async def rfile_userdata01() -> dict[str, Any]:
return {
"name": {"value": "rfile01"},
"template_path": {"value": "mytemplate.j2"},
@@ -638,7 +639,7 @@ async def rfile_userdata01():
@pytest.fixture
-async def rfile_userdata01_property():
+async def rfile_userdata01_property() -> dict[str, Any]:
return {
"name": {"value": "rfile01", "is_protected": True, "source": "ffffffff"},
"template_path": {"value": "mytemplate.j2"},
@@ -659,12 +660,12 @@ async def tag_schema() -> NodeSchemaAPI:
{"name": "description", "kind": "Text", "optional": True},
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
-async def tag_blue_data_no_pagination():
- data = {
+async def tag_blue_data_no_pagination() -> dict[str, Any]:
+ return {
"__typename": "BuiltinTag",
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
"display_label": "blue",
@@ -685,12 +686,11 @@ async def tag_blue_data_no_pagination():
"value": None,
},
}
- return data
@pytest.fixture
-async def tag_red_data_no_pagination():
- data = {
+async def tag_red_data_no_pagination() -> dict[str, Any]:
+ return {
"__typename": "BuiltinTag",
"id": "rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr",
"display_label": "red",
@@ -711,12 +711,11 @@ async def tag_red_data_no_pagination():
"value": None,
},
}
- return data
@pytest.fixture
-async def tag_green_data_no_pagination():
- data = {
+async def tag_green_data_no_pagination() -> dict[str, Any]:
+ return {
"__typename": "BuiltinTag",
"id": "gggggggg-gggg-gggg-gggg-gggggggggggg",
"display_label": "green",
@@ -737,12 +736,11 @@ async def tag_green_data_no_pagination():
"value": None,
},
}
- return data
@pytest.fixture
-async def tag_blue_data():
- data = {
+async def tag_blue_data() -> dict[str, Any]:
+ return {
"node": {
"__typename": "BuiltinTag",
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
@@ -765,12 +763,11 @@ async def tag_blue_data():
},
}
}
- return data
@pytest.fixture
-async def tag_red_data():
- data = {
+async def tag_red_data() -> dict[str, Any]:
+ return {
"node": {
"__typename": "BuiltinTag",
"id": "rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr",
@@ -793,12 +790,11 @@ async def tag_red_data():
},
}
}
- return data
@pytest.fixture
-async def tag_green_data():
- data = {
+async def tag_green_data() -> dict[str, Any]:
+ return {
"node": {
"__typename": "BuiltinTag",
"id": "gggggggg-gggg-gggg-gggg-gggggggggggg",
@@ -821,7 +817,6 @@ async def tag_green_data():
},
}
}
- return data
@pytest.fixture
@@ -885,7 +880,7 @@ async def ipaddress_schema() -> NodeSchemaAPI:
}
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
@@ -909,7 +904,7 @@ async def ipnetwork_schema() -> NodeSchemaAPI:
}
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
@@ -922,7 +917,7 @@ async def ipam_ipprefix_schema() -> NodeSchemaAPI:
"order_by": ["prefix_value"],
"inherit_from": ["BuiltinIPAddress"],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
@@ -954,12 +949,12 @@ async def simple_device_schema() -> NodeSchemaAPI:
},
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
-async def ipam_ipprefix_data():
- data = {
+async def ipam_ipprefix_data() -> dict[str, Any]:
+ return {
"node": {
"__typename": "IpamIPPrefix",
"id": "llllllll-llll-llll-llll-llllllllllll",
@@ -1019,8 +1014,6 @@ async def ipam_ipprefix_data():
}
}
- return data
-
@pytest.fixture
async def ipaddress_pool_schema() -> NodeSchemaAPI:
@@ -1069,7 +1062,7 @@ async def ipaddress_pool_schema() -> NodeSchemaAPI:
},
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
@@ -1128,7 +1121,7 @@ async def ipprefix_pool_schema() -> NodeSchemaAPI:
},
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
@@ -1151,8 +1144,8 @@ async def address_schema() -> NodeSchemaAPI:
@pytest.fixture
-async def address_data():
- data = {
+async def address_data() -> dict[str, Any]:
+ return {
"node": {
"__typename": "Address",
"id": "d5994b18-b25e-4261-9e63-17c2844a0b45",
@@ -1183,7 +1176,6 @@ async def address_data():
},
}
}
- return data
@pytest.fixture
@@ -1233,12 +1225,12 @@ async def device_schema() -> NodeSchemaAPI:
{"name": "artifacts", "peer": "CoreArtifact", "optional": True, "cardinality": "many", "kind": "Generic"},
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
-async def device_data():
- data = {
+async def device_data() -> dict[str, Any]:
+ return {
"node": {
"id": "1799f647-203c-cd41-3409-c51d55097213",
"display_label": "atl1-edge1",
@@ -1383,7 +1375,6 @@ async def device_data():
},
}
}
- return data
@pytest.fixture
@@ -1400,12 +1391,12 @@ async def artifact_definition_schema() -> NodeSchemaAPI:
{"name": "artifact_name", "kind": "Text"},
],
}
- return NodeSchema(**data).convert_api() # type: ignore
+ return NodeSchema(**data).convert_api()
@pytest.fixture
-async def artifact_definition_data():
- data = {
+async def artifact_definition_data() -> dict[str, Any]:
+ return {
"node": {
"id": "1799fd6e-cc5d-219f-3371-c514ed70bf23",
"display_label": "Startup Config for Edge devices",
@@ -1432,7 +1423,6 @@ async def artifact_definition_data():
},
}
}
- return data
@pytest.fixture
@@ -2194,7 +2184,7 @@ async def mock_query_infrahub_user(httpx_mock: HTTPXMock) -> HTTPXMock:
@pytest.fixture
def query_01() -> str:
"""Simple query with one document"""
- query = """
+ return """
query {
TestPerson {
edges {
@@ -2216,12 +2206,11 @@ def query_01() -> str:
}
}
"""
- return query
@pytest.fixture
def query_02() -> str:
- query = """
+ return """
query {
TestPerson {
edges {
@@ -2262,13 +2251,12 @@ def query_02() -> str:
}
}
"""
- return query
@pytest.fixture
def query_03() -> str:
"""Advanced Query with 2 documents"""
- query = """
+ return """
query FirstQuery {
TestPerson {
edges {
@@ -2302,13 +2290,12 @@ def query_03() -> str:
}
}
"""
- return query
@pytest.fixture
def query_04() -> str:
"""Simple query with variables"""
- query = """
+ return """
query ($person: String!){
TestPerson(name__value: $person) {
edges {
@@ -2321,12 +2308,11 @@ def query_04() -> str:
}
}
"""
- return query
@pytest.fixture
def query_05() -> str:
- query = """
+ return """
query MyQuery {
CoreRepository {
edges {
@@ -2355,13 +2341,11 @@ def query_05() -> str:
}
"""
- return query
-
@pytest.fixture
def query_06() -> str:
"""Simple query with variables"""
- query = """
+ return """
query (
$str1: String,
$str2: String = "default2",
@@ -2384,12 +2368,11 @@ def query_06() -> str:
}
}
"""
- return query
@pytest.fixture
def bad_query_01() -> str:
- query = """
+ return """
query {
TestPerson {
edges {
@@ -2409,12 +2392,11 @@ def bad_query_01() -> str:
}
}
"""
- return query
@pytest.fixture
def query_introspection() -> str:
- query = """
+ return """
query IntrospectionQuery {
__schema {
queryType {
@@ -2515,7 +2497,6 @@ def query_introspection() -> str:
}
}
"""
- return query
@pytest.fixture
@@ -2629,3 +2610,31 @@ async def mock_query_tasks_05(httpx_mock: HTTPXMock) -> HTTPXMock:
is_reusable=True,
)
return httpx_mock
+
+
+@pytest.fixture
+async def nested_device_with_interfaces_schema() -> NodeSchemaAPI:
+ """Schema for Device with interfaces relationship for deep nesting tests."""
+ data = {
+ "name": "Device",
+ "namespace": "Infra",
+ "label": "Device",
+ "default_filter": "name__value",
+ "order_by": ["name__value"],
+ "display_labels": ["name__value"],
+ "attributes": [
+ {"name": "name", "kind": "Text", "unique": True},
+ {"name": "description", "kind": "Text", "optional": True},
+ ],
+ "relationships": [
+ {
+ "name": "interfaces",
+ "peer": "InfraInterfaceL3",
+ "identifier": "device__interface",
+ "optional": True,
+ "cardinality": "many",
+ "kind": "Component",
+ },
+ ],
+ }
+ return NodeSchema(**data).convert_api()
diff --git a/tests/unit/sdk/graphql/conftest.py b/tests/unit/sdk/graphql/conftest.py
index 21960088..2e6d0a5c 100644
--- a/tests/unit/sdk/graphql/conftest.py
+++ b/tests/unit/sdk/graphql/conftest.py
@@ -1,4 +1,5 @@
from enum import Enum
+from typing import Any
import pytest
@@ -14,8 +15,8 @@ class MyIntEnum(int, Enum):
@pytest.fixture
-def query_data_no_filter():
- data = {
+def query_data_no_filter() -> dict[str, Any]:
+ return {
"device": {
"name": {"value": None},
"description": {"value": None},
@@ -23,12 +24,10 @@ def query_data_no_filter():
}
}
- return data
-
@pytest.fixture
-def query_data_alias():
- data = {
+def query_data_alias() -> dict[str, Any]:
+ return {
"device": {
"name": {"@alias": "new_name", "value": None},
"description": {"value": {"@alias": "myvalue"}},
@@ -36,12 +35,10 @@ def query_data_alias():
}
}
- return data
-
@pytest.fixture
-def query_data_fragment():
- data = {
+def query_data_fragment() -> dict[str, Any]:
+ return {
"device": {
"name": {"value": None},
"...on Builtin": {
@@ -51,12 +48,10 @@ def query_data_fragment():
}
}
- return data
-
@pytest.fixture
-def query_data_empty_filter():
- data = {
+def query_data_empty_filter() -> dict[str, Any]:
+ return {
"device": {
"@filters": {},
"name": {"value": None},
@@ -65,12 +60,10 @@ def query_data_empty_filter():
}
}
- return data
-
@pytest.fixture
-def query_data_filters_01():
- data = {
+def query_data_filters_01() -> dict[str, Any]:
+ return {
"device": {
"@filters": {"name__value": "$name"},
"name": {"value": None},
@@ -81,12 +74,11 @@ def query_data_filters_01():
},
}
}
- return data
@pytest.fixture
-def query_data_filters_02():
- data = {
+def query_data_filters_02() -> dict[str, Any]:
+ return {
"device": {
"@filters": {"name__value": "myname", "integer__value": 44, "enumstr__value": MyStrEnum.VALUE2},
"name": {"value": None},
@@ -96,12 +88,11 @@ def query_data_filters_02():
},
}
}
- return data
@pytest.fixture
-def input_data_01():
- data = {
+def input_data_01() -> dict[str, Any]:
+ return {
"data": {
"name": {"value": "$name"},
"some_number": {"value": 88},
@@ -110,4 +101,3 @@ def input_data_01():
"query": {"value": "my_query"},
}
}
- return data
diff --git a/tests/unit/sdk/graphql/test_plugin.py b/tests/unit/sdk/graphql/test_plugin.py
index 81b42d16..ae5f048f 100644
--- a/tests/unit/sdk/graphql/test_plugin.py
+++ b/tests/unit/sdk/graphql/test_plugin.py
@@ -35,7 +35,7 @@ def python02_after_annotation_file() -> str:
return python02_file.read_text(encoding="UTF-8")
-def test_future_annotation_plugin_already_present(graphql_schema: GraphQLSchema, python01_file: str):
+def test_future_annotation_plugin_already_present(graphql_schema: GraphQLSchema, python01_file: str) -> None:
python01 = ast.parse(python01_file)
python01_expected = ast.parse(python01_file)
python01_expected_str = ast_to_str(python01_expected)
@@ -50,7 +50,7 @@ def test_future_annotation_plugin_already_present(graphql_schema: GraphQLSchema,
def test_future_annotation_plugin_not_present(
graphql_schema: GraphQLSchema, python02_file: str, python02_after_annotation_file: str
-):
+) -> None:
python02 = ast.parse(python02_file)
python02_expected = ast.parse(python02_after_annotation_file)
python02_expected_str = ast_to_str(python02_expected)
diff --git a/tests/unit/sdk/test_batch.py b/tests/unit/sdk/test_batch.py
index 03ca3b42..2998f767 100644
--- a/tests/unit/sdk/test_batch.py
+++ b/tests/unit/sdk/test_batch.py
@@ -67,12 +67,12 @@ async def test_batch_return_exception(
result_iter = batch.execute()
# Assert first node success
- node, result = await result_iter.__anext__()
+ node, result = await anext(result_iter)
assert node == results[0]
assert not isinstance(result, Exception)
# Assert second node failure
- node, result = await result_iter.__anext__()
+ node, result = await anext(result_iter)
assert node == results[1]
assert isinstance(result, GraphQLError)
assert "An error occurred while executing the GraphQL Query" in str(result)
diff --git a/tests/unit/sdk/test_diff_summary.py b/tests/unit/sdk/test_diff_summary.py
index 73832cab..49a6d128 100644
--- a/tests/unit/sdk/test_diff_summary.py
+++ b/tests/unit/sdk/test_diff_summary.py
@@ -1,7 +1,10 @@
+from datetime import datetime, timezone
+
import pytest
from pytest_httpx import HTTPXMock
from infrahub_sdk import InfrahubClient
+from infrahub_sdk.diff import get_diff_tree_query
from tests.unit.sdk.conftest import BothClients
client_types = ["standard", "sync"]
@@ -158,3 +161,233 @@ async def test_diffsummary(clients: BothClients, mock_diff_tree_query, client_ty
},
],
} in node_diffs
+
+
+def test_get_diff_tree_query_structure() -> None:
+ """Test that get_diff_tree_query returns proper Query object."""
+ query = get_diff_tree_query()
+
+ assert query.name == "GetDiffTree"
+
+ rendered = query.render()
+ assert "query GetDiffTree" in rendered
+ assert "$branch_name: String!" in rendered
+ assert "$name: String" in rendered
+ assert "$from_time: DateTime" in rendered
+ assert "$to_time: DateTime" in rendered
+ assert "DiffTree" in rendered
+ assert "num_added" in rendered
+ assert "num_updated" in rendered
+ assert "num_removed" in rendered
+ assert "num_conflicts" in rendered
+ assert "to_time" in rendered
+ assert "from_time" in rendered
+ assert "base_branch" in rendered
+ assert "diff_branch" in rendered
+ assert "nodes" in rendered
+
+
+@pytest.fixture
+async def mock_diff_tree_with_metadata(httpx_mock: HTTPXMock, client: InfrahubClient) -> HTTPXMock:
+ """Mock diff tree response with complete metadata."""
+ response = {
+ "data": {
+ "DiffTree": {
+ "num_added": 10,
+ "num_updated": 5,
+ "num_removed": 2,
+ "num_conflicts": 0,
+ "to_time": "2025-11-14T12:00:00Z",
+ "from_time": "2025-11-01T00:00:00Z",
+ "base_branch": "main",
+ "diff_branch": "feature-branch",
+ "name": "my-diff",
+ "nodes": [
+ {
+ "attributes": [
+ {"name": "name", "num_added": 0, "num_removed": 0, "num_updated": 1, "status": "UPDATED"}
+ ],
+ "kind": "TestPerson",
+ "label": "John",
+ "num_added": 0,
+ "num_removed": 0,
+ "num_updated": 1,
+ "relationships": [],
+ "status": "UPDATED",
+ "uuid": "17fbadf0-1111-1111-1111-111111111111",
+ },
+ {
+ "attributes": [],
+ "kind": "TestDevice",
+ "label": "Router1",
+ "num_added": 1,
+ "num_removed": 0,
+ "num_updated": 0,
+ "relationships": [],
+ "status": "ADDED",
+ "uuid": "17fbadf0-2222-2222-2222-222222222222",
+ },
+ ],
+ }
+ }
+ }
+
+ httpx_mock.add_response(
+ method="POST",
+ json=response,
+ match_headers={"X-Infrahub-Tracker": "query-difftree-metadata"},
+ )
+ return httpx_mock
+
+
+@pytest.mark.parametrize("client_type", client_types)
+async def test_get_diff_tree(clients: BothClients, mock_diff_tree_with_metadata, client_type) -> None:
+ """Test get_diff_tree returns complete DiffTreeData with metadata."""
+ if client_type == "standard":
+ diff_tree = await clients.standard.get_diff_tree(
+ branch="feature-branch",
+ tracker="query-difftree-metadata",
+ )
+ else:
+ diff_tree = clients.sync.get_diff_tree(
+ branch="feature-branch",
+ tracker="query-difftree-metadata",
+ )
+
+ # Verify diff_tree is not None
+ assert diff_tree is not None
+
+ # Verify metadata
+ assert diff_tree["num_added"] == 10
+ assert diff_tree["num_updated"] == 5
+ assert diff_tree["num_removed"] == 2
+ assert diff_tree["num_conflicts"] == 0
+ assert diff_tree["to_time"] == "2025-11-14T12:00:00Z"
+ assert diff_tree["from_time"] == "2025-11-01T00:00:00Z"
+ assert diff_tree["base_branch"] == "main"
+ assert diff_tree["diff_branch"] == "feature-branch"
+ assert diff_tree["name"] == "my-diff"
+
+ # Verify nodes
+ assert len(diff_tree["nodes"]) == 2
+
+ # Verify first node
+ assert diff_tree["nodes"][0]["branch"] == "feature-branch"
+ assert diff_tree["nodes"][0]["kind"] == "TestPerson"
+ assert diff_tree["nodes"][0]["id"] == "17fbadf0-1111-1111-1111-111111111111"
+ assert diff_tree["nodes"][0]["action"] == "UPDATED"
+ assert diff_tree["nodes"][0]["display_label"] == "John"
+ assert len(diff_tree["nodes"][0]["elements"]) == 1
+
+ # Verify second node
+ assert diff_tree["nodes"][1]["kind"] == "TestDevice"
+ assert diff_tree["nodes"][1]["action"] == "ADDED"
+
+
+@pytest.fixture
+async def mock_diff_tree_none(httpx_mock: HTTPXMock, client: InfrahubClient) -> HTTPXMock:
+ """Mock diff tree response when no diff exists."""
+ response = {"data": {"DiffTree": None}}
+
+ httpx_mock.add_response(
+ method="POST",
+ json=response,
+ match_headers={"X-Infrahub-Tracker": "query-difftree-none"},
+ )
+ return httpx_mock
+
+
+@pytest.mark.parametrize("client_type", client_types)
+async def test_get_diff_tree_none(clients: BothClients, mock_diff_tree_none, client_type) -> None:
+ """Test get_diff_tree returns None when no diff exists."""
+ if client_type == "standard":
+ diff_tree = await clients.standard.get_diff_tree(
+ branch="no-diff-branch",
+ tracker="query-difftree-none",
+ )
+ else:
+ diff_tree = clients.sync.get_diff_tree(
+ branch="no-diff-branch",
+ tracker="query-difftree-none",
+ )
+
+ assert diff_tree is None
+
+
+@pytest.fixture
+async def mock_diff_tree_with_params(httpx_mock: HTTPXMock, client: InfrahubClient) -> HTTPXMock:
+ """Mock diff tree response for testing with name and time parameters."""
+ response = {
+ "data": {
+ "DiffTree": {
+ "num_added": 3,
+ "num_updated": 1,
+ "num_removed": 0,
+ "num_conflicts": 0,
+ "to_time": "2025-11-14T18:00:00Z",
+ "from_time": "2025-11-14T12:00:00Z",
+ "base_branch": "main",
+ "diff_branch": "test-branch",
+ "name": "named-diff",
+ "nodes": [],
+ }
+ }
+ }
+
+ httpx_mock.add_response(
+ method="POST",
+ json=response,
+ match_headers={"X-Infrahub-Tracker": "query-difftree-params"},
+ )
+ return httpx_mock
+
+
+@pytest.mark.parametrize("client_type", client_types)
+async def test_get_diff_tree_with_parameters(clients: BothClients, mock_diff_tree_with_params, client_type) -> None:
+ """Test get_diff_tree with name and time range parameters."""
+ from_time = datetime(2025, 11, 14, 12, 0, 0, tzinfo=timezone.utc)
+ to_time = datetime(2025, 11, 14, 18, 0, 0, tzinfo=timezone.utc)
+
+ if client_type == "standard":
+ diff_tree = await clients.standard.get_diff_tree(
+ branch="test-branch",
+ name="named-diff",
+ from_time=from_time,
+ to_time=to_time,
+ tracker="query-difftree-params",
+ )
+ else:
+ diff_tree = clients.sync.get_diff_tree(
+ branch="test-branch",
+ name="named-diff",
+ from_time=from_time,
+ to_time=to_time,
+ tracker="query-difftree-params",
+ )
+
+ assert diff_tree is not None
+ assert diff_tree["name"] == "named-diff"
+ assert diff_tree["to_time"] == "2025-11-14T18:00:00Z"
+ assert diff_tree["from_time"] == "2025-11-14T12:00:00Z"
+ assert diff_tree["num_added"] == 3
+
+
+@pytest.mark.parametrize("client_type", client_types)
+async def test_get_diff_tree_time_validation(clients: BothClients, client_type) -> None:
+ """Test get_diff_tree raises error when from_time > to_time."""
+ from_time = datetime(2025, 11, 14, 18, 0, 0, tzinfo=timezone.utc)
+ to_time = datetime(2025, 11, 14, 12, 0, 0, tzinfo=timezone.utc) # Earlier than from_time
+
+ with pytest.raises(ValueError, match="from_time must be <= to_time"):
+ if client_type == "standard":
+ await clients.standard.get_diff_tree(
+ branch="test-branch",
+ from_time=from_time,
+ to_time=to_time,
+ )
+ else:
+ clients.sync.get_diff_tree(
+ branch="test-branch",
+ from_time=from_time,
+ to_time=to_time,
+ )
diff --git a/tests/unit/sdk/test_node.py b/tests/unit/sdk/test_node.py
index 2a225b2e..c0c9e9bf 100644
--- a/tests/unit/sdk/test_node.py
+++ b/tests/unit/sdk/test_node.py
@@ -17,6 +17,7 @@
from infrahub_sdk.node.constants import SAFE_VALUE
from infrahub_sdk.node.related_node import RelatedNode, RelatedNodeSync
from infrahub_sdk.schema import GenericSchema, NodeSchemaAPI
+from tests.unit.sdk.conftest import BothClients
if TYPE_CHECKING:
from infrahub_sdk.client import InfrahubClient, InfrahubClientSync
@@ -24,10 +25,10 @@
# type: ignore[attr-defined]
async_node_methods = [
- method for method in dir(InfrahubNode) if not method.startswith("_") and method not in ("hfid", "hfid_str")
+ method for method in dir(InfrahubNode) if not method.startswith("_") and method not in {"hfid", "hfid_str"}
]
sync_node_methods = [
- method for method in dir(InfrahubNodeSync) if not method.startswith("_") and method not in ("hfid", "hfid_str")
+ method for method in dir(InfrahubNodeSync) if not method.startswith("_") and method not in {"hfid", "hfid_str"}
]
client_types = ["standard", "sync"]
@@ -325,6 +326,7 @@ async def test_query_data_no_filters_property(clients, location_schema: NodeSche
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"description": {
@@ -341,6 +343,7 @@ async def test_query_data_no_filters_property(clients, location_schema: NodeSche
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"type": {
@@ -357,6 +360,7 @@ async def test_query_data_no_filters_property(clients, location_schema: NodeSche
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"primary_tag": {
@@ -372,6 +376,7 @@ async def test_query_data_no_filters_property(clients, location_schema: NodeSche
"display_label": None,
"id": None,
},
+ "updated_at": None,
},
"node": {
"id": None,
@@ -448,6 +453,7 @@ async def test_query_data_node_property(clients, location_schema: NodeSchemaAPI,
"is_protected": None,
"owner": {"__typename": None, "display_label": None, "id": None},
"source": {"__typename": None, "display_label": None, "id": None},
+ "updated_at": None,
"value": None,
},
"description": {
@@ -456,6 +462,7 @@ async def test_query_data_node_property(clients, location_schema: NodeSchemaAPI,
"is_protected": None,
"owner": {"__typename": None, "display_label": None, "id": None},
"source": {"__typename": None, "display_label": None, "id": None},
+ "updated_at": None,
"value": None,
},
"type": {
@@ -464,6 +471,7 @@ async def test_query_data_node_property(clients, location_schema: NodeSchemaAPI,
"is_protected": None,
"owner": {"__typename": None, "display_label": None, "id": None},
"source": {"__typename": None, "display_label": None, "id": None},
+ "updated_at": None,
"value": None,
},
"primary_tag": {
@@ -479,6 +487,7 @@ async def test_query_data_node_property(clients, location_schema: NodeSchemaAPI,
"display_label": None,
"id": None,
},
+ "updated_at": None,
},
"node": {
"id": None,
@@ -559,6 +568,7 @@ async def test_query_data_with_prefetch_relationships_property(clients, mock_sch
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"description": {
@@ -575,6 +585,7 @@ async def test_query_data_with_prefetch_relationships_property(clients, mock_sch
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"type": {
@@ -591,6 +602,7 @@ async def test_query_data_with_prefetch_relationships_property(clients, mock_sch
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"primary_tag": {
@@ -606,6 +618,7 @@ async def test_query_data_with_prefetch_relationships_property(clients, mock_sch
"display_label": None,
"id": None,
},
+ "updated_at": None,
},
"node": {
"id": None,
@@ -626,6 +639,7 @@ async def test_query_data_with_prefetch_relationships_property(clients, mock_sch
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"name": {
@@ -642,6 +656,7 @@ async def test_query_data_with_prefetch_relationships_property(clients, mock_sch
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
},
@@ -724,6 +739,7 @@ async def test_query_data_node_with_prefetch_relationships_property(clients, moc
"is_protected": None,
"owner": {"__typename": None, "display_label": None, "id": None},
"source": {"__typename": None, "display_label": None, "id": None},
+ "updated_at": None,
"value": None,
},
"name": {
@@ -732,6 +748,7 @@ async def test_query_data_node_with_prefetch_relationships_property(clients, moc
"is_protected": None,
"owner": {"__typename": None, "display_label": None, "id": None},
"source": {"__typename": None, "display_label": None, "id": None},
+ "updated_at": None,
"value": None,
},
"primary_tag": {
@@ -743,6 +760,7 @@ async def test_query_data_node_with_prefetch_relationships_property(clients, moc
"is_protected": None,
"owner": {"__typename": None, "display_label": None, "id": None},
"source": {"__typename": None, "display_label": None, "id": None},
+ "updated_at": None,
"value": None,
},
"display_label": None,
@@ -754,6 +772,7 @@ async def test_query_data_node_with_prefetch_relationships_property(clients, moc
"is_protected": None,
"owner": {"__typename": None, "display_label": None, "id": None},
"source": {"__typename": None, "display_label": None, "id": None},
+ "updated_at": None,
"value": None,
},
},
@@ -761,6 +780,7 @@ async def test_query_data_node_with_prefetch_relationships_property(clients, moc
"is_protected": None,
"owner": {"__typename": None, "display_label": None, "id": None},
"source": {"__typename": None, "display_label": None, "id": None},
+ "updated_at": None,
},
},
"type": {
@@ -769,6 +789,7 @@ async def test_query_data_node_with_prefetch_relationships_property(clients, moc
"is_protected": None,
"owner": {"__typename": None, "display_label": None, "id": None},
"source": {"__typename": None, "display_label": None, "id": None},
+ "updated_at": None,
"value": None,
},
}
@@ -879,6 +900,7 @@ async def test_query_data_generic_fragment_property(clients, mock_schema_query_0
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"name": {
@@ -896,6 +918,7 @@ async def test_query_data_generic_fragment_property(clients, mock_schema_query_0
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"primary_tag": {
@@ -918,6 +941,7 @@ async def test_query_data_generic_fragment_property(clients, mock_schema_query_0
"display_label": None,
"id": None,
},
+ "updated_at": None,
},
},
"type": {
@@ -935,6 +959,7 @@ async def test_query_data_generic_fragment_property(clients, mock_schema_query_0
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
},
@@ -954,6 +979,7 @@ async def test_query_data_generic_fragment_property(clients, mock_schema_query_0
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"name": {
@@ -971,6 +997,7 @@ async def test_query_data_generic_fragment_property(clients, mock_schema_query_0
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
},
@@ -1085,6 +1112,7 @@ async def test_query_data_include_property(
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"description": {
@@ -1101,6 +1129,7 @@ async def test_query_data_include_property(
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"type": {
@@ -1117,6 +1146,7 @@ async def test_query_data_include_property(
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"primary_tag": {
@@ -1132,6 +1162,7 @@ async def test_query_data_include_property(
"display_label": None,
"id": None,
},
+ "updated_at": None,
},
"node": {
"id": None,
@@ -1155,6 +1186,7 @@ async def test_query_data_include_property(
"display_label": None,
"id": None,
},
+ "updated_at": None,
},
"node": {
"id": None,
@@ -1263,6 +1295,7 @@ async def test_query_data_exclude_property(client, location_schema: NodeSchemaAP
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
"type": {
@@ -1279,6 +1312,7 @@ async def test_query_data_exclude_property(client, location_schema: NodeSchemaAP
"display_label": None,
"id": None,
},
+ "updated_at": None,
"value": None,
},
},
@@ -1383,7 +1417,7 @@ async def test_create_input_data__with_relationships_02(client, location_schema,
input_data = node._generate_input_data()
assert len(input_data["variables"].keys()) == 1
- key = list(input_data["variables"].keys())[0]
+ key = next(iter(input_data["variables"].keys()))
value = input_data["variables"][key]
expected = {
@@ -1669,10 +1703,18 @@ async def test_update_input_data__with_relationships_01(
expected_result_with_property = {
"data": {
"id": "llllllll-llll-llll-llll-llllllllllll",
- "name": {"is_protected": True, "value": "DFW"},
+ "name": {
+ "is_protected": True,
+ "value": "DFW",
+ "updated_at": "2024-01-15T10:30:00.000000Z",
+ },
"primary_tag": {"id": "gggggggg-gggg-gggg-gggg-gggggggggggg"},
"tags": [{"id": "gggggggg-gggg-gggg-gggg-gggggggggggg"}, {"id": "rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr"}],
- "type": {"is_protected": True, "value": "SITE"},
+ "type": {
+ "is_protected": True,
+ "value": "SITE",
+ "updated_at": "2024-01-15T10:30:00.000000Z",
+ },
},
}
@@ -1721,14 +1763,17 @@ async def test_update_input_data_with_relationships_02(
"is_protected": True,
"source": "cccccccc-cccc-cccc-cccc-cccccccccccc",
"value": "dfw1",
+ "updated_at": "2024-01-15T10:30:00.000000Z",
},
"primary_tag": {
+ "_relation__updated_at": "2024-01-15T10:30:00.000000Z",
"_relation__is_protected": True,
"_relation__source": "cccccccc-cccc-cccc-cccc-cccccccccccc",
"id": "rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr",
},
"tags": [
{
+ "_relation__updated_at": "2024-01-15T10:30:00.000000Z",
"_relation__is_protected": True,
"_relation__source": "cccccccc-cccc-cccc-cccc-cccccccccccc",
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
@@ -1738,6 +1783,7 @@ async def test_update_input_data_with_relationships_02(
"is_protected": True,
"source": "cccccccc-cccc-cccc-cccc-cccccccccccc",
"value": "SITE",
+ "updated_at": "2024-01-15T10:30:00.000000Z",
},
},
}
@@ -1774,6 +1820,7 @@ async def test_update_input_data_with_relationships_02_exclude_unmodified(
"primary_tag": {
"_relation__is_protected": True,
"_relation__source": "cccccccc-cccc-cccc-cccc-cccccccccccc",
+ "_relation__updated_at": "2024-01-15T10:30:00.000000Z",
"id": "rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr",
},
},
@@ -1823,10 +1870,18 @@ async def test_update_input_data_empty_relationship(
expected_result_with_property = {
"data": {
"id": "llllllll-llll-llll-llll-llllllllllll",
- "name": {"is_protected": True, "value": "DFW"},
+ "name": {
+ "is_protected": True,
+ "value": "DFW",
+ "updated_at": "2024-01-15T10:30:00.000000Z",
+ },
"primary_tag": None,
"tags": [],
- "type": {"is_protected": True, "value": "SITE"},
+ "type": {
+ "is_protected": True,
+ "value": "SITE",
+ "updated_at": "2024-01-15T10:30:00.000000Z",
+ },
},
}
@@ -2356,3 +2411,215 @@ async def test_from_graphql(clients, mock_schema_query_01, location_data01, clie
node = InfrahubNodeSync.from_graphql(client=clients.sync, schema=schema, branch="main", data=location_data01)
assert node.id == "llllllll-llll-llll-llll-llllllllllll"
+
+
+@pytest.mark.parametrize("client_type", client_types)
+async def test_process_relationships_recursive_deep_nesting(
+ clients: BothClients,
+ nested_device_with_interfaces_schema: NodeSchemaAPI,
+ client_type: str,
+) -> None:
+ """Test that _process_relationships with recursive=True processes deeply nested relationships.
+
+ This test validates 3-level deep nesting:
+ Device -> Interfaces (many) -> IP Addresses (many)
+
+ With recursive=False, only level 1 (interfaces) should be processed.
+ With recursive=True, all 3 levels (device, interfaces, ip_addresses) should be processed.
+ """
+ nested_device_data = {
+ "node": {
+ "id": "device-1",
+ "__typename": "InfraDevice",
+ "display_label": "atl1-edge1",
+ "name": {"value": "atl1-edge1"},
+ "description": {"value": "Edge device in Atlanta"},
+ "interfaces": {
+ "edges": [
+ {
+ "node": {
+ "id": "interface-1",
+ "__typename": "InfraInterfaceL3",
+ "display_label": "Ethernet1",
+ "name": {"value": "Ethernet1"},
+ "description": {"value": "Primary interface"},
+ "ip_addresses": {
+ "edges": [
+ {
+ "node": {
+ "id": "ip-1",
+ "__typename": "InfraIPAddress",
+ "display_label": "10.0.0.1/24",
+ "address": {"value": "10.0.0.1/24"},
+ }
+ },
+ {
+ "node": {
+ "id": "ip-2",
+ "__typename": "InfraIPAddress",
+ "display_label": "10.0.0.2/24",
+ "address": {"value": "10.0.0.2/24"},
+ }
+ },
+ ]
+ },
+ }
+ },
+ {
+ "node": {
+ "id": "interface-2",
+ "__typename": "InfraInterfaceL3",
+ "display_label": "Ethernet2",
+ "name": {"value": "Ethernet2"},
+ "description": {"value": "Secondary interface"},
+ "ip_addresses": {
+ "edges": [
+ {
+ "node": {
+ "id": "ip-3",
+ "__typename": "InfraIPAddress",
+ "display_label": "10.0.1.1/24",
+ "address": {"value": "10.0.1.1/24"},
+ }
+ }
+ ]
+ },
+ }
+ },
+ ]
+ },
+ }
+ }
+ schema_data = {
+ "version": "1.0",
+ "nodes": [
+ # Convert the schema objects back to dictionaries
+ {
+ "name": "Device",
+ "namespace": "Infra",
+ "attributes": [{"name": "name", "kind": "Text"}],
+ "relationships": [
+ {
+ "name": "interfaces",
+ "peer": "InfraInterfaceL3",
+ "cardinality": "many",
+ "optional": True,
+ }
+ ],
+ },
+ {
+ "name": "InterfaceL3",
+ "namespace": "Infra",
+ "attributes": [{"name": "name", "kind": "Text"}],
+ "relationships": [
+ {
+ "name": "ip_addresses",
+ "peer": "InfraIPAddress",
+ "cardinality": "many",
+ "optional": True,
+ }
+ ],
+ },
+ {
+ "name": "IPAddress",
+ "namespace": "Infra",
+ "attributes": [{"name": "address", "kind": "IPHost"}],
+ "relationships": [],
+ },
+ ],
+ }
+
+ # Set up schemas in the client cache to enable schema lookups
+ if client_type == "standard":
+ # Create a properly structured schema response with all three schemas
+
+ clients.standard.schema.set_cache(schema_data, branch="main")
+
+ # Test with recursive=False - should only process interfaces (level 1)
+ device_node = await InfrahubNode.from_graphql(
+ client=clients.standard,
+ schema=nested_device_with_interfaces_schema,
+ branch="main",
+ data=nested_device_data,
+ )
+ related_nodes_non_recursive_async: list[InfrahubNode] = []
+ await device_node._process_relationships(
+ node_data=nested_device_data,
+ branch="main",
+ related_nodes=related_nodes_non_recursive_async,
+ recursive=False,
+ )
+ related_nodes_non_recursive = related_nodes_non_recursive_async
+
+ # Test with recursive=True - should process all levels
+ device_node_recursive = await InfrahubNode.from_graphql(
+ client=clients.standard,
+ schema=nested_device_with_interfaces_schema,
+ branch="main",
+ data=nested_device_data,
+ )
+ related_nodes_recursive_async: list[InfrahubNode] = []
+ await device_node_recursive._process_relationships(
+ node_data=nested_device_data,
+ branch="main",
+ related_nodes=related_nodes_recursive_async,
+ recursive=True,
+ )
+ related_nodes_recursive = related_nodes_recursive_async
+
+ else:
+ # Sync client test
+ clients.sync.schema.set_cache(schema_data, branch="main")
+
+ # Test with recursive=False
+ device_node = InfrahubNodeSync.from_graphql(
+ client=clients.sync,
+ schema=nested_device_with_interfaces_schema,
+ branch="main",
+ data=nested_device_data,
+ )
+ related_nodes_non_recursive_sync: list[InfrahubNodeSync] = []
+ device_node._process_relationships(
+ node_data=nested_device_data,
+ branch="main",
+ related_nodes=related_nodes_non_recursive_sync,
+ recursive=False,
+ )
+ related_nodes_non_recursive = related_nodes_non_recursive_sync
+
+ # Test with recursive=True
+ device_node_recursive = InfrahubNodeSync.from_graphql(
+ client=clients.sync,
+ schema=nested_device_with_interfaces_schema,
+ branch="main",
+ data=nested_device_data,
+ )
+ related_nodes_recursive_sync: list[InfrahubNodeSync] = []
+ device_node_recursive._process_relationships(
+ node_data=nested_device_data,
+ branch="main",
+ related_nodes=related_nodes_recursive_sync,
+ recursive=True,
+ )
+
+ related_nodes_recursive = related_nodes_recursive_sync
+
+ # With recursive=False, should only process the 2 interfaces (level 1)
+ # IP addresses (level 2) should NOT be processed
+ non_recursive_ids = {rn.id for rn in related_nodes_non_recursive}
+ assert "interface-1" in non_recursive_ids
+ assert "interface-2" in non_recursive_ids
+ # IP addresses should NOT be in the list when recursive=False
+ assert "ip-1" not in non_recursive_ids
+ assert "ip-2" not in non_recursive_ids
+ assert "ip-3" not in non_recursive_ids
+ assert len(related_nodes_non_recursive) == 2 # Only 2 interfaces
+
+ # With recursive=True, should process interfaces AND their IP addresses
+ recursive_ids = {rn.id for rn in related_nodes_recursive}
+ assert "interface-1" in recursive_ids
+ assert "interface-2" in recursive_ids
+ assert "ip-1" in recursive_ids # From interface-1
+ assert "ip-2" in recursive_ids # From interface-1
+ assert "ip-3" in recursive_ids # From interface-2
+ assert len(related_nodes_recursive) == 5 # 2 interfaces + 3 IP addresses
diff --git a/tests/unit/sdk/test_repository.py b/tests/unit/sdk/test_repository.py
index 69f34e19..4e4bf177 100644
--- a/tests/unit/sdk/test_repository.py
+++ b/tests/unit/sdk/test_repository.py
@@ -1,4 +1,5 @@
import tempfile
+from collections.abc import Generator
from pathlib import Path
import pytest
@@ -10,7 +11,7 @@
@pytest.fixture
-def temp_dir():
+def temp_dir() -> Generator[str]:
"""Fixture to create a temporary directory for testing."""
with tempfile.TemporaryDirectory() as tmp_dir:
yield tmp_dir
diff --git a/tests/unit/sdk/test_schema.py b/tests/unit/sdk/test_schema.py
index 4db4d37b..54713fa8 100644
--- a/tests/unit/sdk/test_schema.py
+++ b/tests/unit/sdk/test_schema.py
@@ -455,7 +455,7 @@ async def test_display_schema_load_errors_details_when_error_is_in_attribute_or_
assert output == expected_console
-def test_schema_base__get_schema_name__returns_correct_schema_name_for_protocols():
+def test_schema_base__get_schema_name__returns_correct_schema_name_for_protocols() -> None:
assert InfrahubSchemaBase._get_schema_name(schema=BuiltinTagSync) == "BuiltinTag"
assert InfrahubSchemaBase._get_schema_name(schema=BuiltinTag) == "BuiltinTag"
assert InfrahubSchemaBase._get_schema_name(schema="BuiltinTag") == "BuiltinTag"
diff --git a/tests/unit/sdk/test_template.py b/tests/unit/sdk/test_template.py
index b8854e54..2554dc46 100644
--- a/tests/unit/sdk/test_template.py
+++ b/tests/unit/sdk/test_template.py
@@ -220,7 +220,7 @@ async def test_render_string_errors(test_case: JinjaTestCaseFailing) -> None:
name="top-level template code",
),
syntax=Syntax(
- code="\n
\n\n{% for server in servers %}\n - {{server.name}}: {{ server.ip.primary }}
\n{% endfor %}\n
\n\n\n\n\n", # noqa E501
+ code="\n\n\n{% for server in servers %}\n - {{server.name}}: {{ server.ip.primary }}
\n{% endfor %}\n
\n\n\n\n\n", # noqa: E501
lexer="",
),
)
diff --git a/tests/unit/sdk/test_yaml.py b/tests/unit/sdk/test_yaml.py
index 9835ae40..e99ba6fc 100644
--- a/tests/unit/sdk/test_yaml.py
+++ b/tests/unit/sdk/test_yaml.py
@@ -11,12 +11,12 @@
def test_read_missing_file() -> None:
file_name = "i_do_not_exist.yml"
- dir = here / "test_data"
- full_path = dir / file_name
+ test_data_dir = here / "test_data"
+ full_path = test_data_dir / file_name
yaml_file = YamlFile(location=full_path)
yaml_file.load_content()
assert not yaml_file.valid
- assert yaml_file.error_message == f"{file_name}: not found at {dir}"
+ assert yaml_file.error_message == f"{file_name}: not found at {test_data_dir}"
def test_read_incorrect_encoding() -> None:
diff --git a/uv.lock b/uv.lock
index 4ebe9b60..366c7618 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1,12 +1,11 @@
version = 1
revision = 3
-requires-python = ">=3.9, <3.14"
+requires-python = ">=3.10, <3.14"
resolution-markers = [
"python_full_version >= '3.13'",
"python_full_version == '3.12.*'",
"python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
- "python_full_version < '3.10'",
+ "python_full_version < '3.11'",
]
[[package]]
@@ -52,8 +51,7 @@ dependencies = [
{ name = "click" },
{ name = "graphql-core" },
{ name = "httpx" },
- { name = "isort", version = "6.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "isort", version = "7.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "isort" },
{ name = "pydantic" },
{ name = "toml" },
]
@@ -135,8 +133,7 @@ dependencies = [
{ name = "mypy-extensions" },
{ name = "packaging" },
{ name = "pathspec" },
- { name = "platformdirs", version = "4.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "platformdirs", version = "4.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "platformdirs" },
{ name = "pytokens" },
{ name = "tomli", marker = "python_full_version < '3.11'" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
@@ -159,10 +156,6 @@ wheels = [
{ 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/c4/26/0f724eb152bc9fc03029a9c903ddd77a288285042222a381050d27e64ac1/black-25.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ef69351df3c84485a8beb6f7b8f9721e2009e20ef80a8d619e2d1788b7816d47", size = 1715243, upload-time = "2025-09-19T00:34:14.216Z" },
- { url = "https://files.pythonhosted.org/packages/fb/be/cb986ea2f0fabd0ee58668367724ba16c3a042842e9ebe009c139f8221c9/black-25.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e3c1f4cd5e93842774d9ee4ef6cd8d17790e65f44f7cdbaab5f2cf8ccf22a823", size = 1571246, upload-time = "2025-09-19T00:31:39.624Z" },
- { url = "https://files.pythonhosted.org/packages/82/ce/74cf4d66963fca33ab710e4c5817ceeff843c45649f61f41d88694c2e5db/black-25.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:154b06d618233fe468236ba1f0e40823d4eb08b26f5e9261526fde34916b9140", size = 1631265, upload-time = "2025-09-19T00:31:05.341Z" },
- { url = "https://files.pythonhosted.org/packages/ff/f3/9b11e001e84b4d1721f75e20b3c058854a748407e6fc1abe6da0aa22014f/black-25.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:e593466de7b998374ea2585a471ba90553283fb9beefcfa430d84a2651ed5933", size = 1326615, upload-time = "2025-09-19T00:31:25.347Z" },
{ 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" },
]
@@ -263,22 +256,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" },
{ url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" },
{ url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" },
- { url = "https://files.pythonhosted.org/packages/46/7c/0c4760bccf082737ca7ab84a4c2034fcc06b1f21cf3032ea98bd6feb1725/charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9", size = 209609, upload-time = "2025-10-14T04:42:10.922Z" },
- { url = "https://files.pythonhosted.org/packages/bb/a4/69719daef2f3d7f1819de60c9a6be981b8eeead7542d5ec4440f3c80e111/charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d", size = 149029, upload-time = "2025-10-14T04:42:12.38Z" },
- { url = "https://files.pythonhosted.org/packages/e6/21/8d4e1d6c1e6070d3672908b8e4533a71b5b53e71d16828cc24d0efec564c/charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608", size = 144580, upload-time = "2025-10-14T04:42:13.549Z" },
- { url = "https://files.pythonhosted.org/packages/a7/0a/a616d001b3f25647a9068e0b9199f697ce507ec898cacb06a0d5a1617c99/charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc", size = 162340, upload-time = "2025-10-14T04:42:14.892Z" },
- { url = "https://files.pythonhosted.org/packages/85/93/060b52deb249a5450460e0585c88a904a83aec474ab8e7aba787f45e79f2/charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e", size = 159619, upload-time = "2025-10-14T04:42:16.676Z" },
- { url = "https://files.pythonhosted.org/packages/dd/21/0274deb1cc0632cd587a9a0ec6b4674d9108e461cb4cd40d457adaeb0564/charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1", size = 153980, upload-time = "2025-10-14T04:42:17.917Z" },
- { url = "https://files.pythonhosted.org/packages/28/2b/e3d7d982858dccc11b31906976323d790dded2017a0572f093ff982d692f/charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3", size = 152174, upload-time = "2025-10-14T04:42:19.018Z" },
- { url = "https://files.pythonhosted.org/packages/6e/ff/4a269f8e35f1e58b2df52c131a1fa019acb7ef3f8697b7d464b07e9b492d/charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6", size = 151666, upload-time = "2025-10-14T04:42:20.171Z" },
- { url = "https://files.pythonhosted.org/packages/da/c9/ec39870f0b330d58486001dd8e532c6b9a905f5765f58a6f8204926b4a93/charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88", size = 145550, upload-time = "2025-10-14T04:42:21.324Z" },
- { url = "https://files.pythonhosted.org/packages/75/8f/d186ab99e40e0ed9f82f033d6e49001701c81244d01905dd4a6924191a30/charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1", size = 163721, upload-time = "2025-10-14T04:42:22.46Z" },
- { url = "https://files.pythonhosted.org/packages/96/b1/6047663b9744df26a7e479ac1e77af7134b1fcf9026243bb48ee2d18810f/charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf", size = 152127, upload-time = "2025-10-14T04:42:23.712Z" },
- { url = "https://files.pythonhosted.org/packages/59/78/e5a6eac9179f24f704d1be67d08704c3c6ab9f00963963524be27c18ed87/charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318", size = 161175, upload-time = "2025-10-14T04:42:24.87Z" },
- { url = "https://files.pythonhosted.org/packages/e5/43/0e626e42d54dd2f8dd6fc5e1c5ff00f05fbca17cb699bedead2cae69c62f/charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c", size = 155375, upload-time = "2025-10-14T04:42:27.246Z" },
- { url = "https://files.pythonhosted.org/packages/e9/91/d9615bf2e06f35e4997616ff31248c3657ed649c5ab9d35ea12fce54e380/charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505", size = 99692, upload-time = "2025-10-14T04:42:28.425Z" },
- { url = "https://files.pythonhosted.org/packages/d1/a9/6c040053909d9d1ef4fcab45fddec083aedc9052c10078339b47c8573ea8/charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966", size = 107192, upload-time = "2025-10-14T04:42:29.482Z" },
- { url = "https://files.pythonhosted.org/packages/f0/c6/4fa536b2c0cd3edfb7ccf8469fa0f363ea67b7213a842b90909ca33dd851/charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50", size = 100220, upload-time = "2025-10-14T04:42:30.632Z" },
{ url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" },
]
@@ -308,8 +285,7 @@ name = "codecov"
version = "2.1.13"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "coverage", version = "7.10.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "coverage", version = "7.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "coverage" },
{ name = "requests" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2c/bb/594b26d2c85616be6195a64289c578662678afa4910cef2d3ce8417cf73e/codecov-2.1.13.tar.gz", hash = "sha256:2362b685633caeaf45b9951a9b76ce359cd3581dd515b430c6c3f5dfb4d92a8c", size = 21416, upload-time = "2023-04-17T23:11:39.779Z" }
@@ -342,14 +318,12 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama" },
{ name = "dunamai" },
- { name = "eval-type-backport", marker = "python_full_version < '3.10'" },
{ name = "funcy" },
{ name = "jinja2" },
{ name = "jinja2-ansible-filters" },
{ name = "packaging" },
{ name = "pathspec" },
- { name = "platformdirs", version = "4.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "platformdirs", version = "4.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "platformdirs" },
{ name = "plumbum" },
{ name = "pydantic" },
{ name = "pygments" },
@@ -362,109 +336,10 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ed/f2/58ee35dbd55d0ffa13197365ec4725c36da2f7ec72eaa1dd154bfbd2676e/copier-9.10.3-py3-none-any.whl", hash = "sha256:7165239566f68e9e36c148f71e0552bf1e4911eef96bfa7cf33e6a0dbfed3c96", size = 56186, upload-time = "2025-10-17T18:26:02.856Z" },
]
-[[package]]
-name = "coverage"
-version = "7.10.7"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-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/e5/6c/3a3f7a46888e69d18abe3ccc6fe4cb16cccb1e6a2f99698931dafca489e6/coverage-7.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fc04cc7a3db33664e0c2d10eb8990ff6b3536f6842c9590ae8da4c614b9ed05a", size = 217987, upload-time = "2025-09-21T20:00:57.218Z" },
- { url = "https://files.pythonhosted.org/packages/03/94/952d30f180b1a916c11a56f5c22d3535e943aa22430e9e3322447e520e1c/coverage-7.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e201e015644e207139f7e2351980feb7040e6f4b2c2978892f3e3789d1c125e5", size = 218388, upload-time = "2025-09-21T20:01:00.081Z" },
- { url = "https://files.pythonhosted.org/packages/50/2b/9e0cf8ded1e114bcd8b2fd42792b57f1c4e9e4ea1824cde2af93a67305be/coverage-7.10.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:240af60539987ced2c399809bd34f7c78e8abe0736af91c3d7d0e795df633d17", size = 245148, upload-time = "2025-09-21T20:01:01.768Z" },
- { url = "https://files.pythonhosted.org/packages/19/20/d0384ac06a6f908783d9b6aa6135e41b093971499ec488e47279f5b846e6/coverage-7.10.7-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8421e088bc051361b01c4b3a50fd39a4b9133079a2229978d9d30511fd05231b", size = 246958, upload-time = "2025-09-21T20:01:03.355Z" },
- { url = "https://files.pythonhosted.org/packages/60/83/5c283cff3d41285f8eab897651585db908a909c572bdc014bcfaf8a8b6ae/coverage-7.10.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6be8ed3039ae7f7ac5ce058c308484787c86e8437e72b30bf5e88b8ea10f3c87", size = 248819, upload-time = "2025-09-21T20:01:04.968Z" },
- { url = "https://files.pythonhosted.org/packages/60/22/02eb98fdc5ff79f423e990d877693e5310ae1eab6cb20ae0b0b9ac45b23b/coverage-7.10.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e28299d9f2e889e6d51b1f043f58d5f997c373cc12e6403b90df95b8b047c13e", size = 245754, upload-time = "2025-09-21T20:01:06.321Z" },
- { url = "https://files.pythonhosted.org/packages/b4/bc/25c83bcf3ad141b32cd7dc45485ef3c01a776ca3aa8ef0a93e77e8b5bc43/coverage-7.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c4e16bd7761c5e454f4efd36f345286d6f7c5fa111623c355691e2755cae3b9e", size = 246860, upload-time = "2025-09-21T20:01:07.605Z" },
- { url = "https://files.pythonhosted.org/packages/3c/b7/95574702888b58c0928a6e982038c596f9c34d52c5e5107f1eef729399b5/coverage-7.10.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b1c81d0e5e160651879755c9c675b974276f135558cf4ba79fee7b8413a515df", size = 244877, upload-time = "2025-09-21T20:01:08.829Z" },
- { url = "https://files.pythonhosted.org/packages/47/b6/40095c185f235e085df0e0b158f6bd68cc6e1d80ba6c7721dc81d97ec318/coverage-7.10.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:606cc265adc9aaedcc84f1f064f0e8736bc45814f15a357e30fca7ecc01504e0", size = 245108, upload-time = "2025-09-21T20:01:10.527Z" },
- { url = "https://files.pythonhosted.org/packages/c8/50/4aea0556da7a4b93ec9168420d170b55e2eb50ae21b25062513d020c6861/coverage-7.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:10b24412692df990dbc34f8fb1b6b13d236ace9dfdd68df5b28c2e39cafbba13", size = 245752, upload-time = "2025-09-21T20:01:11.857Z" },
- { url = "https://files.pythonhosted.org/packages/6a/28/ea1a84a60828177ae3b100cb6723838523369a44ec5742313ed7db3da160/coverage-7.10.7-cp310-cp310-win32.whl", hash = "sha256:b51dcd060f18c19290d9b8a9dd1e0181538df2ce0717f562fff6cf74d9fc0b5b", size = 220497, upload-time = "2025-09-21T20:01:13.459Z" },
- { url = "https://files.pythonhosted.org/packages/fc/1a/a81d46bbeb3c3fd97b9602ebaa411e076219a150489bcc2c025f151bd52d/coverage-7.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:3a622ac801b17198020f09af3eaf45666b344a0d69fc2a6ffe2ea83aeef1d807", size = 221392, upload-time = "2025-09-21T20:01:14.722Z" },
- { url = "https://files.pythonhosted.org/packages/d2/5d/c1a17867b0456f2e9ce2d8d4708a4c3a089947d0bec9c66cdf60c9e7739f/coverage-7.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a609f9c93113be646f44c2a0256d6ea375ad047005d7f57a5c15f614dc1b2f59", size = 218102, upload-time = "2025-09-21T20:01:16.089Z" },
- { url = "https://files.pythonhosted.org/packages/54/f0/514dcf4b4e3698b9a9077f084429681bf3aad2b4a72578f89d7f643eb506/coverage-7.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:65646bb0359386e07639c367a22cf9b5bf6304e8630b565d0626e2bdf329227a", size = 218505, upload-time = "2025-09-21T20:01:17.788Z" },
- { url = "https://files.pythonhosted.org/packages/20/f6/9626b81d17e2a4b25c63ac1b425ff307ecdeef03d67c9a147673ae40dc36/coverage-7.10.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5f33166f0dfcce728191f520bd2692914ec70fac2713f6bf3ce59c3deacb4699", size = 248898, upload-time = "2025-09-21T20:01:19.488Z" },
- { url = "https://files.pythonhosted.org/packages/b0/ef/bd8e719c2f7417ba03239052e099b76ea1130ac0cbb183ee1fcaa58aaff3/coverage-7.10.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:35f5e3f9e455bb17831876048355dca0f758b6df22f49258cb5a91da23ef437d", size = 250831, upload-time = "2025-09-21T20:01:20.817Z" },
- { url = "https://files.pythonhosted.org/packages/a5/b6/bf054de41ec948b151ae2b79a55c107f5760979538f5fb80c195f2517718/coverage-7.10.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4da86b6d62a496e908ac2898243920c7992499c1712ff7c2b6d837cc69d9467e", size = 252937, upload-time = "2025-09-21T20:01:22.171Z" },
- { url = "https://files.pythonhosted.org/packages/0f/e5/3860756aa6f9318227443c6ce4ed7bf9e70bb7f1447a0353f45ac5c7974b/coverage-7.10.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6b8b09c1fad947c84bbbc95eca841350fad9cbfa5a2d7ca88ac9f8d836c92e23", size = 249021, upload-time = "2025-09-21T20:01:23.907Z" },
- { url = "https://files.pythonhosted.org/packages/26/0f/bd08bd042854f7fd07b45808927ebcce99a7ed0f2f412d11629883517ac2/coverage-7.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4376538f36b533b46f8971d3a3e63464f2c7905c9800db97361c43a2b14792ab", size = 250626, upload-time = "2025-09-21T20:01:25.721Z" },
- { url = "https://files.pythonhosted.org/packages/8e/a7/4777b14de4abcc2e80c6b1d430f5d51eb18ed1d75fca56cbce5f2db9b36e/coverage-7.10.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:121da30abb574f6ce6ae09840dae322bef734480ceafe410117627aa54f76d82", size = 248682, upload-time = "2025-09-21T20:01:27.105Z" },
- { url = "https://files.pythonhosted.org/packages/34/72/17d082b00b53cd45679bad682fac058b87f011fd8b9fe31d77f5f8d3a4e4/coverage-7.10.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:88127d40df529336a9836870436fc2751c339fbaed3a836d42c93f3e4bd1d0a2", size = 248402, upload-time = "2025-09-21T20:01:28.629Z" },
- { url = "https://files.pythonhosted.org/packages/81/7a/92367572eb5bdd6a84bfa278cc7e97db192f9f45b28c94a9ca1a921c3577/coverage-7.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ba58bbcd1b72f136080c0bccc2400d66cc6115f3f906c499013d065ac33a4b61", size = 249320, upload-time = "2025-09-21T20:01:30.004Z" },
- { url = "https://files.pythonhosted.org/packages/2f/88/a23cc185f6a805dfc4fdf14a94016835eeb85e22ac3a0e66d5e89acd6462/coverage-7.10.7-cp311-cp311-win32.whl", hash = "sha256:972b9e3a4094b053a4e46832b4bc829fc8a8d347160eb39d03f1690316a99c14", size = 220536, upload-time = "2025-09-21T20:01:32.184Z" },
- { url = "https://files.pythonhosted.org/packages/fe/ef/0b510a399dfca17cec7bc2f05ad8bd78cf55f15c8bc9a73ab20c5c913c2e/coverage-7.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:a7b55a944a7f43892e28ad4bc0561dfd5f0d73e605d1aa5c3c976b52aea121d2", size = 221425, upload-time = "2025-09-21T20:01:33.557Z" },
- { url = "https://files.pythonhosted.org/packages/51/7f/023657f301a276e4ba1850f82749bc136f5a7e8768060c2e5d9744a22951/coverage-7.10.7-cp311-cp311-win_arm64.whl", hash = "sha256:736f227fb490f03c6488f9b6d45855f8e0fd749c007f9303ad30efab0e73c05a", size = 220103, upload-time = "2025-09-21T20:01:34.929Z" },
- { url = "https://files.pythonhosted.org/packages/13/e4/eb12450f71b542a53972d19117ea5a5cea1cab3ac9e31b0b5d498df1bd5a/coverage-7.10.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7bb3b9ddb87ef7725056572368040c32775036472d5a033679d1fa6c8dc08417", size = 218290, upload-time = "2025-09-21T20:01:36.455Z" },
- { url = "https://files.pythonhosted.org/packages/37/66/593f9be12fc19fb36711f19a5371af79a718537204d16ea1d36f16bd78d2/coverage-7.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:18afb24843cbc175687225cab1138c95d262337f5473512010e46831aa0c2973", size = 218515, upload-time = "2025-09-21T20:01:37.982Z" },
- { url = "https://files.pythonhosted.org/packages/66/80/4c49f7ae09cafdacc73fbc30949ffe77359635c168f4e9ff33c9ebb07838/coverage-7.10.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:399a0b6347bcd3822be369392932884b8216d0944049ae22925631a9b3d4ba4c", size = 250020, upload-time = "2025-09-21T20:01:39.617Z" },
- { url = "https://files.pythonhosted.org/packages/a6/90/a64aaacab3b37a17aaedd83e8000142561a29eb262cede42d94a67f7556b/coverage-7.10.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:314f2c326ded3f4b09be11bc282eb2fc861184bc95748ae67b360ac962770be7", size = 252769, upload-time = "2025-09-21T20:01:41.341Z" },
- { url = "https://files.pythonhosted.org/packages/98/2e/2dda59afd6103b342e096f246ebc5f87a3363b5412609946c120f4e7750d/coverage-7.10.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c41e71c9cfb854789dee6fc51e46743a6d138b1803fab6cb860af43265b42ea6", size = 253901, upload-time = "2025-09-21T20:01:43.042Z" },
- { url = "https://files.pythonhosted.org/packages/53/dc/8d8119c9051d50f3119bb4a75f29f1e4a6ab9415cd1fa8bf22fcc3fb3b5f/coverage-7.10.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc01f57ca26269c2c706e838f6422e2a8788e41b3e3c65e2f41148212e57cd59", size = 250413, upload-time = "2025-09-21T20:01:44.469Z" },
- { url = "https://files.pythonhosted.org/packages/98/b3/edaff9c5d79ee4d4b6d3fe046f2b1d799850425695b789d491a64225d493/coverage-7.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a6442c59a8ac8b85812ce33bc4d05bde3fb22321fa8294e2a5b487c3505f611b", size = 251820, upload-time = "2025-09-21T20:01:45.915Z" },
- { url = "https://files.pythonhosted.org/packages/11/25/9a0728564bb05863f7e513e5a594fe5ffef091b325437f5430e8cfb0d530/coverage-7.10.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:78a384e49f46b80fb4c901d52d92abe098e78768ed829c673fbb53c498bef73a", size = 249941, upload-time = "2025-09-21T20:01:47.296Z" },
- { url = "https://files.pythonhosted.org/packages/e0/fd/ca2650443bfbef5b0e74373aac4df67b08180d2f184b482c41499668e258/coverage-7.10.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:5e1e9802121405ede4b0133aa4340ad8186a1d2526de5b7c3eca519db7bb89fb", size = 249519, upload-time = "2025-09-21T20:01:48.73Z" },
- { url = "https://files.pythonhosted.org/packages/24/79/f692f125fb4299b6f963b0745124998ebb8e73ecdfce4ceceb06a8c6bec5/coverage-7.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d41213ea25a86f69efd1575073d34ea11aabe075604ddf3d148ecfec9e1e96a1", size = 251375, upload-time = "2025-09-21T20:01:50.529Z" },
- { url = "https://files.pythonhosted.org/packages/5e/75/61b9bbd6c7d24d896bfeec57acba78e0f8deac68e6baf2d4804f7aae1f88/coverage-7.10.7-cp312-cp312-win32.whl", hash = "sha256:77eb4c747061a6af8d0f7bdb31f1e108d172762ef579166ec84542f711d90256", size = 220699, upload-time = "2025-09-21T20:01:51.941Z" },
- { url = "https://files.pythonhosted.org/packages/ca/f3/3bf7905288b45b075918d372498f1cf845b5b579b723c8fd17168018d5f5/coverage-7.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:f51328ffe987aecf6d09f3cd9d979face89a617eacdaea43e7b3080777f647ba", size = 221512, upload-time = "2025-09-21T20:01:53.481Z" },
- { url = "https://files.pythonhosted.org/packages/5c/44/3e32dbe933979d05cf2dac5e697c8599cfe038aaf51223ab901e208d5a62/coverage-7.10.7-cp312-cp312-win_arm64.whl", hash = "sha256:bda5e34f8a75721c96085903c6f2197dc398c20ffd98df33f866a9c8fd95f4bf", size = 220147, upload-time = "2025-09-21T20:01:55.2Z" },
- { 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/a3/ad/d1c25053764b4c42eb294aae92ab617d2e4f803397f9c7c8295caa77a260/coverage-7.10.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fff7b9c3f19957020cac546c70025331113d2e61537f6e2441bc7657913de7d3", size = 217978, upload-time = "2025-09-21T20:03:30.362Z" },
- { url = "https://files.pythonhosted.org/packages/52/2f/b9f9daa39b80ece0b9548bbb723381e29bc664822d9a12c2135f8922c22b/coverage-7.10.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bc91b314cef27742da486d6839b677b3f2793dfe52b51bbbb7cf736d5c29281c", size = 218370, upload-time = "2025-09-21T20:03:32.147Z" },
- { url = "https://files.pythonhosted.org/packages/dd/6e/30d006c3b469e58449650642383dddf1c8fb63d44fdf92994bfd46570695/coverage-7.10.7-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:567f5c155eda8df1d3d439d40a45a6a5f029b429b06648235f1e7e51b522b396", size = 244802, upload-time = "2025-09-21T20:03:33.919Z" },
- { url = "https://files.pythonhosted.org/packages/b0/49/8a070782ce7e6b94ff6a0b6d7c65ba6bc3091d92a92cef4cd4eb0767965c/coverage-7.10.7-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2af88deffcc8a4d5974cf2d502251bc3b2db8461f0b66d80a449c33757aa9f40", size = 246625, upload-time = "2025-09-21T20:03:36.09Z" },
- { url = "https://files.pythonhosted.org/packages/6a/92/1c1c5a9e8677ce56d42b97bdaca337b2d4d9ebe703d8c174ede52dbabd5f/coverage-7.10.7-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7315339eae3b24c2d2fa1ed7d7a38654cba34a13ef19fbcb9425da46d3dc594", size = 248399, upload-time = "2025-09-21T20:03:38.342Z" },
- { url = "https://files.pythonhosted.org/packages/c0/54/b140edee7257e815de7426d5d9846b58505dffc29795fff2dfb7f8a1c5a0/coverage-7.10.7-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:912e6ebc7a6e4adfdbb1aec371ad04c68854cd3bf3608b3514e7ff9062931d8a", size = 245142, upload-time = "2025-09-21T20:03:40.591Z" },
- { url = "https://files.pythonhosted.org/packages/e4/9e/6d6b8295940b118e8b7083b29226c71f6154f7ff41e9ca431f03de2eac0d/coverage-7.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f49a05acd3dfe1ce9715b657e28d138578bc40126760efb962322c56e9ca344b", size = 246284, upload-time = "2025-09-21T20:03:42.355Z" },
- { url = "https://files.pythonhosted.org/packages/db/e5/5e957ca747d43dbe4d9714358375c7546cb3cb533007b6813fc20fce37ad/coverage-7.10.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cce2109b6219f22ece99db7644b9622f54a4e915dad65660ec435e89a3ea7cc3", size = 244353, upload-time = "2025-09-21T20:03:44.218Z" },
- { url = "https://files.pythonhosted.org/packages/9a/45/540fc5cc92536a1b783b7ef99450bd55a4b3af234aae35a18a339973ce30/coverage-7.10.7-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:f3c887f96407cea3916294046fc7dab611c2552beadbed4ea901cbc6a40cc7a0", size = 244430, upload-time = "2025-09-21T20:03:46.065Z" },
- { url = "https://files.pythonhosted.org/packages/75/0b/8287b2e5b38c8fe15d7e3398849bb58d382aedc0864ea0fa1820e8630491/coverage-7.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:635adb9a4507c9fd2ed65f39693fa31c9a3ee3a8e6dc64df033e8fdf52a7003f", size = 245311, upload-time = "2025-09-21T20:03:48.19Z" },
- { url = "https://files.pythonhosted.org/packages/0c/1d/29724999984740f0c86d03e6420b942439bf5bd7f54d4382cae386a9d1e9/coverage-7.10.7-cp39-cp39-win32.whl", hash = "sha256:5a02d5a850e2979b0a014c412573953995174743a3f7fa4ea5a6e9a3c5617431", size = 220500, upload-time = "2025-09-21T20:03:50.024Z" },
- { url = "https://files.pythonhosted.org/packages/43/11/4b1e6b129943f905ca54c339f343877b55b365ae2558806c1be4f7476ed5/coverage-7.10.7-cp39-cp39-win_amd64.whl", hash = "sha256:c134869d5ffe34547d14e174c866fd8fe2254918cc0a95e99052903bc1543e07", size = 221408, upload-time = "2025-09-21T20:03:51.803Z" },
- { 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.optional-dependencies]
-toml = [
- { name = "tomli", marker = "python_full_version < '3.10'" },
-]
-
[[package]]
name = "coverage"
version = "7.11.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
sdist = { url = "https://files.pythonhosted.org/packages/1c/38/ee22495420457259d2f3390309505ea98f98a5eed40901cf62196abad006/coverage-7.11.0.tar.gz", hash = "sha256:167bd504ac1ca2af7ff3b81d245dfea0292c5032ebef9d66cc08a7d28c1b8050", size = 811905, upload-time = "2025-10-15T15:15:08.542Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/12/95/c49df0aceb5507a80b9fe5172d3d39bf23f05be40c23c8d77d556df96cec/coverage-7.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb53f1e8adeeb2e78962bade0c08bfdc461853c7969706ed901821e009b35e31", size = 215800, upload-time = "2025-10-15T15:12:19.824Z" },
@@ -536,7 +411,7 @@ wheels = [
[package.optional-dependencies]
toml = [
- { name = "tomli", marker = "python_full_version >= '3.10' and python_full_version <= '3.11'" },
+ { name = "tomli", marker = "python_full_version <= '3.11'" },
]
[[package]]
@@ -618,11 +493,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/91/c3/bfaf8426ebd44d4834f7578e543727543a2ccdda8e7b40be919b857872b5/dulwich-0.24.7-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:d8c42e45c217506759170b01b09e194acce1463aafd61f71fb7094b192ad09aa", size = 1304168, upload-time = "2025-10-23T11:01:16.677Z" },
{ url = "https://files.pythonhosted.org/packages/8a/52/3a7d40831ba5ab0701fc3bf67d28cc10c4fcddfc8ae5a600232837e1ffe1/dulwich-0.24.7-cp313-cp313-win32.whl", hash = "sha256:32e7e18edfad5dfb978ccf8e575b5776234110b722ea677d4e843058a1df1dd0", size = 867697, upload-time = "2025-10-23T11:01:18.654Z" },
{ url = "https://files.pythonhosted.org/packages/5a/b7/8d026a8ee3186c3a939ae41248eee47b374427547bd660088f4b8beb5920/dulwich-0.24.7-cp313-cp313-win_amd64.whl", hash = "sha256:265549c96680be1f6322cfeabb41337714c1a128824ab7e06d8c9d8a2640f4fb", size = 884367, upload-time = "2025-10-23T11:01:19.993Z" },
- { url = "https://files.pythonhosted.org/packages/f1/81/a2b6974aad0829e8d091a22202ba5987cde4c2a9f64cc5916e56243b2173/dulwich-0.24.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ad2b37d65f1f97f9635febf43cf5ecc643900c18463e3dbe43538076c9778bf", size = 1205644, upload-time = "2025-10-23T11:01:25.835Z" },
- { url = "https://files.pythonhosted.org/packages/fa/6e/ba3cedac0535e739ca081899e964ff411c2e0ab42363846fd8e5434b4282/dulwich-0.24.7-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:f48a06d635b061f1196e63e91046e9b8ba9c9865fa8ac1ec7b21580538c9ef0c", size = 1286552, upload-time = "2025-10-23T11:01:27.163Z" },
- { url = "https://files.pythonhosted.org/packages/42/a5/7e9e71a9275f533691487b6d012392dcf7b008d40798a37bd766cfa6937f/dulwich-0.24.7-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:9fe8e6c075fe9de2532ee176145172fcb52529b9fbe63708392ddca9c185cf91", size = 1312660, upload-time = "2025-10-23T11:01:28.529Z" },
- { url = "https://files.pythonhosted.org/packages/07/04/bb4c01639de80510e0b07a4b96ad392994a765efadba41ebbc1e9e4eae3e/dulwich-0.24.7-cp39-cp39-win32.whl", hash = "sha256:c7143322dbbeaf78a8a8a433a13f62b51def640b699426c64643f58bf80dfbee", size = 875602, upload-time = "2025-10-23T11:01:30.398Z" },
- { url = "https://files.pythonhosted.org/packages/42/cf/6373eb0635da0832bad5908c5e32ab94417d35d33bbc77c8b28e553fd164/dulwich-0.24.7-cp39-cp39-win_amd64.whl", hash = "sha256:8f86d5da9dd29ee20f3b5e4aa18a088707e5a05413ae29cf67d7d7474b88de99", size = 889769, upload-time = "2025-10-23T11:01:31.699Z" },
{ url = "https://files.pythonhosted.org/packages/14/30/d5c337fcf96e2b159b61053fd5b374b80629d28267f471483a3da5577ce3/dulwich-0.24.7-py3-none-any.whl", hash = "sha256:c1d6e35d7c41982d4ba375ce8ba9db783f4b4ca1a00c62f3121eb881f5c03c53", size = 545605, upload-time = "2025-10-23T11:01:33.566Z" },
]
@@ -638,15 +508,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/36/41/04e2a649058b0713b00d6c9bd22da35618bb157289e05d068e51fddf8d7e/dunamai-1.25.0-py3-none-any.whl", hash = "sha256:7f9dc687dd3256e613b6cc978d9daabfd2bb5deb8adc541fc135ee423ffa98ab", size = 27022, upload-time = "2025-07-04T19:25:54.863Z" },
]
-[[package]]
-name = "eval-type-backport"
-version = "0.2.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/30/ea/8b0ac4469d4c347c6a385ff09dc3c048c2d021696664e26c7ee6791631b5/eval_type_backport-0.2.2.tar.gz", hash = "sha256:f0576b4cf01ebb5bd358d02314d31846af5e07678387486e2c798af0e7d849c1", size = 9079, upload-time = "2024-12-21T20:09:46.005Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/ce/31/55cd413eaccd39125368be33c46de24a1f639f2e12349b0361b4678f3915/eval_type_backport-0.2.2-py3-none-any.whl", hash = "sha256:cb6ad7c393517f476f96d456d0412ea80f0a8cf96f6892834cd9340149111b0a", size = 5830, upload-time = "2024-12-21T20:09:44.175Z" },
-]
-
[[package]]
name = "exceptiongroup"
version = "1.3.0"
@@ -692,28 +553,10 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/eb/23/dfb161e91db7c92727db505dc72a384ee79681fe0603f706f9f9f52c2901/fastapi-0.121.2-py3-none-any.whl", hash = "sha256:f2d80b49a86a846b70cc3a03eb5ea6ad2939298bf6a7fe377aa9cd3dd079d358", size = 109201, upload-time = "2025-11-13T17:05:52.718Z" },
]
-[[package]]
-name = "filelock"
-version = "3.19.1"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz", hash = "sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size = 17687, upload-time = "2025-08-14T16:56:03.016Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" },
-]
-
[[package]]
name = "filelock"
version = "3.20.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" },
@@ -741,9 +584,6 @@ wheels = [
name = "graphql-core"
version = "3.2.6"
source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "typing-extensions", marker = "python_full_version < '3.10'" },
-]
sdist = { url = "https://files.pythonhosted.org/packages/c4/16/7574029da84834349b60ed71614d66ca3afe46e9bf9c7b9562102acb7d4f/graphql_core-3.2.6.tar.gz", hash = "sha256:c08eec22f9e40f0bd61d805907e3b3b1b9a320bc606e23dc145eebca07c8fbab", size = 505353, upload-time = "2025-01-26T16:36:27.374Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ae/4f/7297663840621022bc73c22d7d9d80dbc78b4db6297f764b545cd5dd462d/graphql_core-3.2.6-py3-none-any.whl", hash = "sha256:78b016718c161a6fb20a7d97bbf107f331cd1afe53e45566c59f776ed7f0b45f", size = 203416, upload-time = "2025-01-26T16:36:24.868Z" },
@@ -758,33 +598,12 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl", hash = "sha256:54f33de9f4f911d7e84e4191749cac8cc5653f815b06738c54db9a15ab8b1e42", size = 47300, upload-time = "2025-06-15T09:35:04.433Z" },
]
-[[package]]
-name = "griffe"
-version = "1.14.0"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-dependencies = [
- { name = "colorama", marker = "python_full_version < '3.10'" },
-]
-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/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]]
name = "griffe"
version = "1.15.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
dependencies = [
- { name = "colorama", marker = "python_full_version >= '3.10'" },
+ { name = "colorama" },
]
sdist = { url = "https://files.pythonhosted.org/packages/0d/0c/3a471b6e31951dce2360477420d0a8d1e00dea6cf33b70f3e8c3ab6e28e1/griffe-1.15.0.tar.gz", hash = "sha256:7726e3afd6f298fbc3696e67958803e7ac843c1cfe59734b6251a40cdbfb5eea", size = 424112, upload-time = "2025-11-10T15:03:15.52Z" }
wheels = [
@@ -855,28 +674,10 @@ http2 = [
{ name = "h2" },
]
-[[package]]
-name = "humanize"
-version = "4.13.0"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/98/1d/3062fcc89ee05a715c0b9bfe6490c00c576314f27ffee3a704122c6fd259/humanize-4.13.0.tar.gz", hash = "sha256:78f79e68f76f0b04d711c4e55d32bebef5be387148862cb1ef83d2b58e7935a0", size = 81884, upload-time = "2025-08-25T09:39:20.04Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/1e/c7/316e7ca04d26695ef0635dc81683d628350810eb8e9b2299fc08ba49f366/humanize-4.13.0-py3-none-any.whl", hash = "sha256:b810820b31891813b1673e8fec7f1ed3312061eab2f26e3fa192c393d11ed25f", size = 128869, upload-time = "2025-08-25T09:39:18.54Z" },
-]
-
[[package]]
name = "humanize"
version = "4.14.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
sdist = { url = "https://files.pythonhosted.org/packages/b6/43/50033d25ad96a7f3845f40999b4778f753c3901a11808a584fed7c00d9f5/humanize-4.14.0.tar.gz", hash = "sha256:2fa092705ea640d605c435b1ca82b2866a1b601cdf96f076d70b79a855eba90d", size = 82939, upload-time = "2025-10-15T13:04:51.214Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c3/5b/9512c5fb6c8218332b530f13500c6ff5f3ce3342f35e0dd7be9ac3856fd3/humanize-4.14.0-py3-none-any.whl", hash = "sha256:d57701248d040ad456092820e6fde56c930f17749956ac47f4f655c0c547bfff", size = 132092, upload-time = "2025-10-15T13:04:49.404Z" },
@@ -921,25 +722,12 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" },
]
-[[package]]
-name = "importlib-resources"
-version = "6.5.2"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "zipp", marker = "python_full_version < '3.10'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/cf/8c/f834fbf984f691b4f7ff60f50b514cc3de5cc08abfc3295564dd89c5e2e7/importlib_resources-6.5.2.tar.gz", hash = "sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c", size = 44693, upload-time = "2025-01-03T18:51:56.698Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl", hash = "sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec", size = 37461, upload-time = "2025-01-03T18:51:54.306Z" },
-]
-
[[package]]
name = "infrahub-sdk"
-version = "1.15.1"
+version = "1.16.0"
source = { editable = "." }
dependencies = [
{ name = "dulwich" },
- { name = "eval-type-backport", marker = "python_full_version < '3.10'" },
{ name = "graphql-core" },
{ name = "httpx" },
{ name = "netutils" },
@@ -956,11 +744,9 @@ all = [
{ name = "click" },
{ name = "copier" },
{ name = "jinja2" },
- { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
+ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
{ name = "numpy", version = "2.3.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
- { name = "pyarrow", version = "21.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "pyarrow", version = "22.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "pyarrow" },
{ name = "pytest" },
{ name = "pyyaml" },
{ name = "rich" },
@@ -971,11 +757,9 @@ ctl = [
{ name = "click" },
{ name = "copier" },
{ name = "jinja2" },
- { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
+ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
{ name = "numpy", version = "2.3.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
- { name = "pyarrow", version = "21.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "pyarrow", version = "22.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "pyarrow" },
{ name = "pyyaml" },
{ name = "rich" },
{ name = "typer" },
@@ -987,8 +771,7 @@ dev = [
{ name = "codecov" },
{ name = "infrahub-testcontainers" },
{ name = "invoke" },
- { name = "ipython", version = "8.18.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "ipython", version = "8.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
+ { name = "ipython", version = "8.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
{ name = "ipython", version = "9.6.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
{ name = "mypy" },
{ name = "pre-commit" },
@@ -1036,7 +819,6 @@ requires-dist = [
{ name = "copier", marker = "extra == 'all'", specifier = ">=9.8.0" },
{ name = "copier", marker = "extra == 'ctl'", specifier = ">=9.8.0" },
{ name = "dulwich", specifier = ">=0.21.4" },
- { name = "eval-type-backport", marker = "python_full_version == '3.9.*'", specifier = ">=0.2.2" },
{ name = "graphql-core", specifier = ">=3.1,<3.3" },
{ name = "httpx", specifier = ">=0.20" },
{ name = "jinja2", marker = "extra == 'all'", specifier = ">=3" },
@@ -1079,7 +861,7 @@ dev = [
{ name = "pytest-httpx", specifier = ">=0.30" },
{ name = "pytest-xdist", specifier = ">=3.3.1" },
{ name = "requests" },
- { name = "ruff", specifier = "==0.11.0" },
+ { name = "ruff", specifier = "==0.14.5" },
{ name = "towncrier", specifier = ">=24.8.0" },
{ name = "types-python-slugify", specifier = ">=8.0.0.3" },
{ name = "types-pyyaml" },
@@ -1089,7 +871,7 @@ dev = [
lint = [
{ name = "astroid", specifier = ">=3.1,<4.0" },
{ name = "mypy", specifier = "==1.11.2" },
- { name = "ruff", specifier = "==0.11.0" },
+ { name = "ruff", specifier = "==0.14.5" },
{ name = "yamllint" },
]
tests = [
@@ -1124,28 +906,10 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/22/62/fb936916fff9eddfe5e64ebe3dab33045ec30f63b7ff7aa409d57a008db3/infrahub_testcontainers-1.5.1-py3-none-any.whl", hash = "sha256:7b32ff5c0b3d5b516df28a6fc2a0c8b410a5224e1e08d3591f431e5008d9f475", size = 23109, upload-time = "2025-11-13T15:29:02.834Z" },
]
-[[package]]
-name = "iniconfig"
-version = "2.1.0"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-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/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 = "iniconfig"
version = "2.3.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
@@ -1160,50 +924,25 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl", hash = "sha256:2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8", size = 160287, upload-time = "2025-10-11T00:36:33.703Z" },
]
-[[package]]
-name = "ipython"
-version = "8.18.1"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-dependencies = [
- { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" },
- { name = "decorator", marker = "python_full_version < '3.10'" },
- { name = "exceptiongroup", marker = "python_full_version < '3.10'" },
- { name = "jedi", marker = "python_full_version < '3.10'" },
- { name = "matplotlib-inline", marker = "python_full_version < '3.10'" },
- { name = "pexpect", marker = "python_full_version < '3.10' and sys_platform != 'win32'" },
- { name = "prompt-toolkit", marker = "python_full_version < '3.10'" },
- { name = "pygments", marker = "python_full_version < '3.10'" },
- { name = "stack-data", marker = "python_full_version < '3.10'" },
- { name = "traitlets", marker = "python_full_version < '3.10'" },
- { name = "typing-extensions", marker = "python_full_version < '3.10'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/b1/b9/3ba6c45a6df813c09a48bac313c22ff83efa26cbb55011218d925a46e2ad/ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27", size = 5486330, upload-time = "2023-11-27T09:58:34.596Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/47/6b/d9fdcdef2eb6a23f391251fde8781c38d42acd82abe84d054cb74f7863b0/ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397", size = 808161, upload-time = "2023-11-27T09:58:30.538Z" },
-]
-
[[package]]
name = "ipython"
version = "8.37.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
- "python_full_version == '3.10.*'",
+ "python_full_version < '3.11'",
]
dependencies = [
- { name = "colorama", marker = "python_full_version == '3.10.*' and sys_platform == 'win32'" },
- { name = "decorator", marker = "python_full_version == '3.10.*'" },
- { name = "exceptiongroup", marker = "python_full_version == '3.10.*'" },
- { name = "jedi", marker = "python_full_version == '3.10.*'" },
- { name = "matplotlib-inline", marker = "python_full_version == '3.10.*'" },
- { name = "pexpect", marker = "python_full_version == '3.10.*' and sys_platform != 'emscripten' and sys_platform != 'win32'" },
- { name = "prompt-toolkit", marker = "python_full_version == '3.10.*'" },
- { name = "pygments", marker = "python_full_version == '3.10.*'" },
- { name = "stack-data", marker = "python_full_version == '3.10.*'" },
- { name = "traitlets", marker = "python_full_version == '3.10.*'" },
- { name = "typing-extensions", marker = "python_full_version == '3.10.*'" },
+ { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" },
+ { name = "decorator", marker = "python_full_version < '3.11'" },
+ { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
+ { name = "jedi", marker = "python_full_version < '3.11'" },
+ { name = "matplotlib-inline", marker = "python_full_version < '3.11'" },
+ { name = "pexpect", marker = "python_full_version < '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" },
+ { name = "prompt-toolkit", marker = "python_full_version < '3.11'" },
+ { name = "pygments", marker = "python_full_version < '3.11'" },
+ { name = "stack-data", marker = "python_full_version < '3.11'" },
+ { name = "traitlets", marker = "python_full_version < '3.11'" },
+ { name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/85/31/10ac88f3357fc276dc8a64e8880c82e80e7459326ae1d0a211b40abf6665/ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216", size = 5606088, upload-time = "2025-05-31T16:39:09.613Z" }
wheels = [
@@ -1249,31 +988,10 @@ wheels = [
{ 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]]
-name = "isort"
-version = "6.1.0"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-dependencies = [
- { name = "importlib-metadata", marker = "python_full_version < '3.10'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/1e/82/fa43935523efdfcce6abbae9da7f372b627b27142c3419fcf13bf5b0c397/isort-6.1.0.tar.gz", hash = "sha256:9b8f96a14cfee0677e78e941ff62f03769a06d412aabb9e2a90487b3b7e8d481", size = 824325, upload-time = "2025-10-01T16:26:45.027Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/7f/cc/9b681a170efab4868a032631dea1e8446d8ec718a7f657b94d49d1a12643/isort-6.1.0-py3-none-any.whl", hash = "sha256:58d8927ecce74e5087aef019f778d4081a3b6c98f15a80ba35782ca8a2097784", size = 94329, upload-time = "2025-10-01T16:26:43.291Z" },
-]
-
[[package]]
name = "isort"
version = "7.0.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
sdist = { url = "https://files.pythonhosted.org/packages/63/53/4f3c058e3bace40282876f9b553343376ee687f3c35a525dc79dbd450f88/isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187", size = 805049, upload-time = "2025-10-11T13:30:59.107Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7f/ed/e3705d6d02b4f7aea715a353c8ce193efd0b5db13e204df895d38734c244/isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1", size = 94672, upload-time = "2025-10-11T13:30:57.665Z" },
@@ -1344,10 +1062,8 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "attrs" },
{ name = "jsonschema-specifications" },
- { name = "referencing", version = "0.36.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "referencing", version = "0.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
- { name = "rpds-py", version = "0.27.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "rpds-py", version = "0.28.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "referencing" },
+ { name = "rpds-py" },
]
sdist = { url = "https://files.pythonhosted.org/packages/74/69/f7185de793a29082a9f3c7728268ffb31cb5095131a9c139a74078e27336/jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85", size = 357342, upload-time = "2025-08-18T17:03:50.038Z" }
wheels = [
@@ -1359,41 +1075,19 @@ name = "jsonschema-specifications"
version = "2025.9.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "referencing", version = "0.36.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "referencing", version = "0.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "referencing" },
]
sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" },
]
-[[package]]
-name = "markdown-it-py"
-version = "3.0.0"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-dependencies = [
- { name = "mdurl", marker = "python_full_version < '3.10'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" },
-]
-
[[package]]
name = "markdown-it-py"
version = "4.0.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
dependencies = [
- { name = "mdurl", marker = "python_full_version >= '3.10'" },
+ { name = "mdurl" },
]
sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" }
wheels = [
@@ -1461,17 +1155,6 @@ wheels = [
{ 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/56/23/0d8c13a44bde9154821586520840643467aee574d8ce79a17da539ee7fed/markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26", size = 11623, upload-time = "2025-09-27T18:37:29.296Z" },
- { url = "https://files.pythonhosted.org/packages/fd/23/07a2cb9a8045d5f3f0890a8c3bc0859d7a47bfd9a560b563899bec7b72ed/markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc", size = 12049, upload-time = "2025-09-27T18:37:30.234Z" },
- { url = "https://files.pythonhosted.org/packages/bc/e4/6be85eb81503f8e11b61c0b6369b6e077dcf0a74adbd9ebf6b349937b4e9/markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c", size = 21923, upload-time = "2025-09-27T18:37:31.177Z" },
- { url = "https://files.pythonhosted.org/packages/6f/bc/4dc914ead3fe6ddaef035341fee0fc956949bbd27335b611829292b89ee2/markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42", size = 20543, upload-time = "2025-09-27T18:37:32.168Z" },
- { url = "https://files.pythonhosted.org/packages/89/6e/5fe81fbcfba4aef4093d5f856e5c774ec2057946052d18d168219b7bd9f9/markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b", size = 20585, upload-time = "2025-09-27T18:37:33.166Z" },
- { url = "https://files.pythonhosted.org/packages/f6/f6/e0e5a3d3ae9c4020f696cd055f940ef86b64fe88de26f3a0308b9d3d048c/markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758", size = 21387, upload-time = "2025-09-27T18:37:34.185Z" },
- { url = "https://files.pythonhosted.org/packages/c8/25/651753ef4dea08ea790f4fbb65146a9a44a014986996ca40102e237aa49a/markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2", size = 20133, upload-time = "2025-09-27T18:37:35.138Z" },
- { url = "https://files.pythonhosted.org/packages/dc/0a/c3cf2b4fef5f0426e8a6d7fce3cb966a17817c568ce59d76b92a233fdbec/markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d", size = 20588, upload-time = "2025-09-27T18:37:36.096Z" },
- { url = "https://files.pythonhosted.org/packages/cd/1b/a7782984844bd519ad4ffdbebbba2671ec5d0ebbeac34736c15fb86399e8/markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7", size = 14566, upload-time = "2025-09-27T18:37:37.09Z" },
- { url = "https://files.pythonhosted.org/packages/18/1f/8d9c20e1c9440e215a44be5ab64359e207fcb4f675543f1cf9a2a7f648d0/markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e", size = 15053, upload-time = "2025-09-27T18:37:38.054Z" },
- { url = "https://files.pythonhosted.org/packages/4e/d3/fe08482b5cd995033556d45041a4f4e76e7f0521112a9c9991d40d39825f/markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8", size = 13928, upload-time = "2025-09-27T18:37:39.037Z" },
]
[[package]]
@@ -1521,11 +1204,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f3/3c/350a9da895f8a7e87ade0028b962be0252d152e0c2fbaafa6f0658b4d0d4/mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987", size = 12506856, upload-time = "2024-08-24T22:50:08.804Z" },
{ url = "https://files.pythonhosted.org/packages/b6/49/ee5adf6a49ff13f4202d949544d3d08abb0ea1f3e7f2a6d5b4c10ba0360a/mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca", size = 12952066, upload-time = "2024-08-24T22:50:03.89Z" },
{ url = "https://files.pythonhosted.org/packages/27/c0/b19d709a42b24004d720db37446a42abadf844d5c46a2c442e2a074d70d9/mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70", size = 9664000, upload-time = "2024-08-24T22:49:59.703Z" },
- { url = "https://files.pythonhosted.org/packages/16/64/bb5ed751487e2bea0dfaa6f640a7e3bb88083648f522e766d5ef4a76f578/mypy-1.11.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6", size = 10937294, upload-time = "2024-08-24T22:49:37.878Z" },
- { url = "https://files.pythonhosted.org/packages/a9/a3/67a0069abed93c3bf3b0bebb8857e2979a02828a4a3fd82f107f8f1143e8/mypy-1.11.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70", size = 10107707, upload-time = "2024-08-24T22:49:00.237Z" },
- { url = "https://files.pythonhosted.org/packages/2f/4d/0379daf4258b454b1f9ed589a9dabd072c17f97496daea7b72fdacf7c248/mypy-1.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d", size = 12498367, upload-time = "2024-08-24T22:49:06.504Z" },
- { url = "https://files.pythonhosted.org/packages/3b/dc/3976a988c280b3571b8eb6928882dc4b723a403b21735a6d8ae6ed20e82b/mypy-1.11.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d", size = 13018014, upload-time = "2024-08-24T22:49:09.242Z" },
- { url = "https://files.pythonhosted.org/packages/83/84/adffc7138fb970e7e2a167bd20b33bb78958370179853a4ebe9008139342/mypy-1.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24", size = 9568056, upload-time = "2024-08-24T22:49:45.55Z" },
{ url = "https://files.pythonhosted.org/packages/42/3a/bdf730640ac523229dd6578e8a581795720a9321399de494374afc437ec5/mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12", size = 2619625, upload-time = "2024-08-24T22:50:01.842Z" },
]
@@ -1556,67 +1234,12 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" },
]
-[[package]]
-name = "numpy"
-version = "2.0.2"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/a9/75/10dd1f8116a8b796cb2c737b674e02d02e80454bda953fa7e65d8c12b016/numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78", size = 18902015, upload-time = "2024-08-26T20:19:40.945Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/21/91/3495b3237510f79f5d81f2508f9f13fea78ebfdf07538fc7444badda173d/numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece", size = 21165245, upload-time = "2024-08-26T20:04:14.625Z" },
- { url = "https://files.pythonhosted.org/packages/05/33/26178c7d437a87082d11019292dce6d3fe6f0e9026b7b2309cbf3e489b1d/numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04", size = 13738540, upload-time = "2024-08-26T20:04:36.784Z" },
- { url = "https://files.pythonhosted.org/packages/ec/31/cc46e13bf07644efc7a4bf68df2df5fb2a1a88d0cd0da9ddc84dc0033e51/numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66", size = 5300623, upload-time = "2024-08-26T20:04:46.491Z" },
- { url = "https://files.pythonhosted.org/packages/6e/16/7bfcebf27bb4f9d7ec67332ffebee4d1bf085c84246552d52dbb548600e7/numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b", size = 6901774, upload-time = "2024-08-26T20:04:58.173Z" },
- { url = "https://files.pythonhosted.org/packages/f9/a3/561c531c0e8bf082c5bef509d00d56f82e0ea7e1e3e3a7fc8fa78742a6e5/numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd", size = 13907081, upload-time = "2024-08-26T20:05:19.098Z" },
- { url = "https://files.pythonhosted.org/packages/fa/66/f7177ab331876200ac7563a580140643d1179c8b4b6a6b0fc9838de2a9b8/numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318", size = 19523451, upload-time = "2024-08-26T20:05:47.479Z" },
- { url = "https://files.pythonhosted.org/packages/25/7f/0b209498009ad6453e4efc2c65bcdf0ae08a182b2b7877d7ab38a92dc542/numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8", size = 19927572, upload-time = "2024-08-26T20:06:17.137Z" },
- { url = "https://files.pythonhosted.org/packages/3e/df/2619393b1e1b565cd2d4c4403bdd979621e2c4dea1f8532754b2598ed63b/numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326", size = 14400722, upload-time = "2024-08-26T20:06:39.16Z" },
- { url = "https://files.pythonhosted.org/packages/22/ad/77e921b9f256d5da36424ffb711ae79ca3f451ff8489eeca544d0701d74a/numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97", size = 6472170, upload-time = "2024-08-26T20:06:50.361Z" },
- { url = "https://files.pythonhosted.org/packages/10/05/3442317535028bc29cf0c0dd4c191a4481e8376e9f0db6bcf29703cadae6/numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131", size = 15905558, upload-time = "2024-08-26T20:07:13.881Z" },
- { url = "https://files.pythonhosted.org/packages/8b/cf/034500fb83041aa0286e0fb16e7c76e5c8b67c0711bb6e9e9737a717d5fe/numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448", size = 21169137, upload-time = "2024-08-26T20:07:45.345Z" },
- { url = "https://files.pythonhosted.org/packages/4a/d9/32de45561811a4b87fbdee23b5797394e3d1504b4a7cf40c10199848893e/numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195", size = 13703552, upload-time = "2024-08-26T20:08:06.666Z" },
- { url = "https://files.pythonhosted.org/packages/c1/ca/2f384720020c7b244d22508cb7ab23d95f179fcfff33c31a6eeba8d6c512/numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57", size = 5298957, upload-time = "2024-08-26T20:08:15.83Z" },
- { url = "https://files.pythonhosted.org/packages/0e/78/a3e4f9fb6aa4e6fdca0c5428e8ba039408514388cf62d89651aade838269/numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a", size = 6905573, upload-time = "2024-08-26T20:08:27.185Z" },
- { url = "https://files.pythonhosted.org/packages/a0/72/cfc3a1beb2caf4efc9d0b38a15fe34025230da27e1c08cc2eb9bfb1c7231/numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669", size = 13914330, upload-time = "2024-08-26T20:08:48.058Z" },
- { url = "https://files.pythonhosted.org/packages/ba/a8/c17acf65a931ce551fee11b72e8de63bf7e8a6f0e21add4c937c83563538/numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951", size = 19534895, upload-time = "2024-08-26T20:09:16.536Z" },
- { url = "https://files.pythonhosted.org/packages/ba/86/8767f3d54f6ae0165749f84648da9dcc8cd78ab65d415494962c86fac80f/numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9", size = 19937253, upload-time = "2024-08-26T20:09:46.263Z" },
- { url = "https://files.pythonhosted.org/packages/df/87/f76450e6e1c14e5bb1eae6836478b1028e096fd02e85c1c37674606ab752/numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15", size = 14414074, upload-time = "2024-08-26T20:10:08.483Z" },
- { url = "https://files.pythonhosted.org/packages/5c/ca/0f0f328e1e59f73754f06e1adfb909de43726d4f24c6a3f8805f34f2b0fa/numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4", size = 6470640, upload-time = "2024-08-26T20:10:19.732Z" },
- { url = "https://files.pythonhosted.org/packages/eb/57/3a3f14d3a759dcf9bf6e9eda905794726b758819df4663f217d658a58695/numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc", size = 15910230, upload-time = "2024-08-26T20:10:43.413Z" },
- { url = "https://files.pythonhosted.org/packages/45/40/2e117be60ec50d98fa08c2f8c48e09b3edea93cfcabd5a9ff6925d54b1c2/numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b", size = 20895803, upload-time = "2024-08-26T20:11:13.916Z" },
- { url = "https://files.pythonhosted.org/packages/46/92/1b8b8dee833f53cef3e0a3f69b2374467789e0bb7399689582314df02651/numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e", size = 13471835, upload-time = "2024-08-26T20:11:34.779Z" },
- { url = "https://files.pythonhosted.org/packages/7f/19/e2793bde475f1edaea6945be141aef6c8b4c669b90c90a300a8954d08f0a/numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c", size = 5038499, upload-time = "2024-08-26T20:11:43.902Z" },
- { url = "https://files.pythonhosted.org/packages/e3/ff/ddf6dac2ff0dd50a7327bcdba45cb0264d0e96bb44d33324853f781a8f3c/numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c", size = 6633497, upload-time = "2024-08-26T20:11:55.09Z" },
- { url = "https://files.pythonhosted.org/packages/72/21/67f36eac8e2d2cd652a2e69595a54128297cdcb1ff3931cfc87838874bd4/numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692", size = 13621158, upload-time = "2024-08-26T20:12:14.95Z" },
- { url = "https://files.pythonhosted.org/packages/39/68/e9f1126d757653496dbc096cb429014347a36b228f5a991dae2c6b6cfd40/numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a", size = 19236173, upload-time = "2024-08-26T20:12:44.049Z" },
- { url = "https://files.pythonhosted.org/packages/d1/e9/1f5333281e4ebf483ba1c888b1d61ba7e78d7e910fdd8e6499667041cc35/numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c", size = 19634174, upload-time = "2024-08-26T20:13:13.634Z" },
- { url = "https://files.pythonhosted.org/packages/71/af/a469674070c8d8408384e3012e064299f7a2de540738a8e414dcfd639996/numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded", size = 14099701, upload-time = "2024-08-26T20:13:34.851Z" },
- { url = "https://files.pythonhosted.org/packages/d0/3d/08ea9f239d0e0e939b6ca52ad403c84a2bce1bde301a8eb4888c1c1543f1/numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5", size = 6174313, upload-time = "2024-08-26T20:13:45.653Z" },
- { url = "https://files.pythonhosted.org/packages/b2/b5/4ac39baebf1fdb2e72585c8352c56d063b6126be9fc95bd2bb5ef5770c20/numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a", size = 15606179, upload-time = "2024-08-26T20:14:08.786Z" },
- { url = "https://files.pythonhosted.org/packages/43/c1/41c8f6df3162b0c6ffd4437d729115704bd43363de0090c7f913cfbc2d89/numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9059e10581ce4093f735ed23f3b9d283b9d517ff46009ddd485f1747eb22653c", size = 21169942, upload-time = "2024-08-26T20:14:40.108Z" },
- { url = "https://files.pythonhosted.org/packages/39/bc/fd298f308dcd232b56a4031fd6ddf11c43f9917fbc937e53762f7b5a3bb1/numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:423e89b23490805d2a5a96fe40ec507407b8ee786d66f7328be214f9679df6dd", size = 13711512, upload-time = "2024-08-26T20:15:00.985Z" },
- { url = "https://files.pythonhosted.org/packages/96/ff/06d1aa3eeb1c614eda245c1ba4fb88c483bee6520d361641331872ac4b82/numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:2b2955fa6f11907cf7a70dab0d0755159bca87755e831e47932367fc8f2f2d0b", size = 5306976, upload-time = "2024-08-26T20:15:10.876Z" },
- { url = "https://files.pythonhosted.org/packages/2d/98/121996dcfb10a6087a05e54453e28e58694a7db62c5a5a29cee14c6e047b/numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:97032a27bd9d8988b9a97a8c4d2c9f2c15a81f61e2f21404d7e8ef00cb5be729", size = 6906494, upload-time = "2024-08-26T20:15:22.055Z" },
- { url = "https://files.pythonhosted.org/packages/15/31/9dffc70da6b9bbf7968f6551967fc21156207366272c2a40b4ed6008dc9b/numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e795a8be3ddbac43274f18588329c72939870a16cae810c2b73461c40718ab1", size = 13912596, upload-time = "2024-08-26T20:15:42.452Z" },
- { url = "https://files.pythonhosted.org/packages/b9/14/78635daab4b07c0930c919d451b8bf8c164774e6a3413aed04a6d95758ce/numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b258c385842546006213344c50655ff1555a9338e2e5e02a0756dc3e803dd", size = 19526099, upload-time = "2024-08-26T20:16:11.048Z" },
- { url = "https://files.pythonhosted.org/packages/26/4c/0eeca4614003077f68bfe7aac8b7496f04221865b3a5e7cb230c9d055afd/numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fec9451a7789926bcf7c2b8d187292c9f93ea30284802a0ab3f5be8ab36865d", size = 19932823, upload-time = "2024-08-26T20:16:40.171Z" },
- { url = "https://files.pythonhosted.org/packages/f1/46/ea25b98b13dccaebddf1a803f8c748680d972e00507cd9bc6dcdb5aa2ac1/numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9189427407d88ff25ecf8f12469d4d39d35bee1db5d39fc5c168c6f088a6956d", size = 14404424, upload-time = "2024-08-26T20:17:02.604Z" },
- { url = "https://files.pythonhosted.org/packages/c8/a6/177dd88d95ecf07e722d21008b1b40e681a929eb9e329684d449c36586b2/numpy-2.0.2-cp39-cp39-win32.whl", hash = "sha256:905d16e0c60200656500c95b6b8dca5d109e23cb24abc701d41c02d74c6b3afa", size = 6476809, upload-time = "2024-08-26T20:17:13.553Z" },
- { url = "https://files.pythonhosted.org/packages/ea/2b/7fc9f4e7ae5b507c1a3a21f0f15ed03e794c1242ea8a242ac158beb56034/numpy-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:a3f4ab0caa7f053f6797fcd4e1e25caee367db3112ef2b6ef82d749530768c73", size = 15911314, upload-time = "2024-08-26T20:17:36.72Z" },
- { url = "https://files.pythonhosted.org/packages/8f/3b/df5a870ac6a3be3a86856ce195ef42eec7ae50d2a202be1f5a4b3b340e14/numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f0a0c6f12e07fa94133c8a67404322845220c06a9e80e85999afe727f7438b8", size = 21025288, upload-time = "2024-08-26T20:18:07.732Z" },
- { url = "https://files.pythonhosted.org/packages/2c/97/51af92f18d6f6f2d9ad8b482a99fb74e142d71372da5d834b3a2747a446e/numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:312950fdd060354350ed123c0e25a71327d3711584beaef30cdaa93320c392d4", size = 6762793, upload-time = "2024-08-26T20:18:19.125Z" },
- { url = "https://files.pythonhosted.org/packages/12/46/de1fbd0c1b5ccaa7f9a005b66761533e2f6a3e560096682683a223631fe9/numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26df23238872200f63518dd2aa984cfca675d82469535dc7162dc2ee52d9dd5c", size = 19334885, upload-time = "2024-08-26T20:18:47.237Z" },
- { url = "https://files.pythonhosted.org/packages/cc/dc/d330a6faefd92b446ec0f0dfea4c3207bb1fef3c4771d19cf4543efd2c78/numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a46288ec55ebbd58947d31d72be2c63cbf839f0a63b49cb755022310792a3385", size = 15828784, upload-time = "2024-08-26T20:19:11.19Z" },
-]
-
[[package]]
name = "numpy"
version = "2.2.6"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
- "python_full_version == '3.10.*'",
+ "python_full_version < '3.11'",
]
sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" }
wheels = [
@@ -1817,19 +1440,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/9f/37/acd14b12dc62db9a0e1d12386271b8661faae270b22492580d5258808975/orjson-3.11.4-cp313-cp313-win32.whl", hash = "sha256:6c13879c0d2964335491463302a6ca5ad98105fc5db3565499dcb80b1b4bd839", size = 136007, upload-time = "2025-10-24T15:49:49.938Z" },
{ url = "https://files.pythonhosted.org/packages/c0/a9/967be009ddf0a1fffd7a67de9c36656b28c763659ef91352acc02cbe364c/orjson-3.11.4-cp313-cp313-win_amd64.whl", hash = "sha256:09bf242a4af98732db9f9a1ec57ca2604848e16f132e3f72edfd3c5c96de009a", size = 131314, upload-time = "2025-10-24T15:49:51.248Z" },
{ url = "https://files.pythonhosted.org/packages/cb/db/399abd6950fbd94ce125cb8cd1a968def95174792e127b0642781e040ed4/orjson-3.11.4-cp313-cp313-win_arm64.whl", hash = "sha256:a85f0adf63319d6c1ba06fb0dbf997fced64a01179cf17939a6caca662bf92de", size = 126152, upload-time = "2025-10-24T15:49:52.922Z" },
- { url = "https://files.pythonhosted.org/packages/1d/b3/08601f14923f4bacb92e920155873e69109c6b3354b27e9960a7a8c5600a/orjson-3.11.4-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:405261b0a8c62bcbd8e2931c26fdc08714faf7025f45531541e2b29e544b545b", size = 243477, upload-time = "2025-10-24T15:50:17.252Z" },
- { url = "https://files.pythonhosted.org/packages/90/13/a49832a439ad8f7737fbde30fadf6ca6b5e3f6b74b0efa2c53b386525a5c/orjson-3.11.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af02ff34059ee9199a3546f123a6ab4c86caf1708c79042caf0820dc290a6d4f", size = 130269, upload-time = "2025-10-24T15:50:18.763Z" },
- { url = "https://files.pythonhosted.org/packages/01/ca/458c11205db897a66fa00b13360b4f62c2e837b8c14f2ed96b7d59f3f5bb/orjson-3.11.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0b2eba969ea4203c177c7b38b36c69519e6067ee68c34dc37081fac74c796e10", size = 129207, upload-time = "2025-10-24T15:50:20.883Z" },
- { url = "https://files.pythonhosted.org/packages/c4/32/6cc2a8ccaa003c9fd1e1851e01ad6a90909cafce0949b5fda678173e552d/orjson-3.11.4-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0baa0ea43cfa5b008a28d3c07705cf3ada40e5d347f0f44994a64b1b7b4b5350", size = 136312, upload-time = "2025-10-24T15:50:22.258Z" },
- { url = "https://files.pythonhosted.org/packages/38/3b/14bf796bb07b69c4fb690e72b8734fe71172de325101b52b57a827eadc09/orjson-3.11.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80fd082f5dcc0e94657c144f1b2a3a6479c44ad50be216cf0c244e567f5eae19", size = 137439, upload-time = "2025-10-24T15:50:23.834Z" },
- { url = "https://files.pythonhosted.org/packages/83/63/5b092e5cfa00c0a361704fff46778637007d73dae5ccffcb462e90f0f452/orjson-3.11.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e3704d35e47d5bee811fb1cbd8599f0b4009b14d451c4c57be5a7e25eb89a13", size = 136692, upload-time = "2025-10-24T15:50:25.61Z" },
- { url = "https://files.pythonhosted.org/packages/d1/7a/76b8111154457ee5e95016039f9c5e44c180752f966080607a74f8965c65/orjson-3.11.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa447f2b5356779d914658519c874cf3b7629e99e63391ed519c28c8aea4919", size = 136117, upload-time = "2025-10-24T15:50:27.032Z" },
- { url = "https://files.pythonhosted.org/packages/bf/73/9424c616173c3e6fef7b739cbb3158f0d16b15d79f482ddf422c3edb96cf/orjson-3.11.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bba5118143373a86f91dadb8df41d9457498226698ebdf8e11cbb54d5b0e802d", size = 140324, upload-time = "2025-10-24T15:50:28.512Z" },
- { url = "https://files.pythonhosted.org/packages/ab/91/7d9e9c72a502810eff2f5ed59b9fcbf86aa066052f5a166aa68ced1a1e58/orjson-3.11.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:622463ab81d19ef3e06868b576551587de8e4d518892d1afab71e0fbc1f9cffc", size = 406365, upload-time = "2025-10-24T15:50:29.961Z" },
- { url = "https://files.pythonhosted.org/packages/8e/76/0c78bb6a30adce7f363054ef260d7236500070ce30739b1d2417a46c59f1/orjson-3.11.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3e0a700c4b82144b72946b6629968df9762552ee1344bfdb767fecdd634fbd5a", size = 149593, upload-time = "2025-10-24T15:50:31.87Z" },
- { url = "https://files.pythonhosted.org/packages/d9/99/d350e07175e92bf114f9e955722f3aa932c3fd3e94841199bb6fc4a87e57/orjson-3.11.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6e18a5c15e764e5f3fc569b47872450b4bcea24f2a6354c0a0e95ad21045d5a9", size = 139835, upload-time = "2025-10-24T15:50:33.333Z" },
- { url = "https://files.pythonhosted.org/packages/4d/e3/3a50e2401809db6800a2da31624a663768c67a76f227c4016e61d07d2f68/orjson-3.11.4-cp39-cp39-win32.whl", hash = "sha256:fb1c37c71cad991ef4d89c7a634b5ffb4447dbd7ae3ae13e8f5ee7f1775e7ab1", size = 135792, upload-time = "2025-10-24T15:50:35.068Z" },
- { url = "https://files.pythonhosted.org/packages/84/c7/13bed8834936ddb38a2f366aea9458ebb4fe80c459054e6a0cfbcae68e0d/orjson-3.11.4-cp39-cp39-win_amd64.whl", hash = "sha256:e2985ce8b8c42d00492d0ed79f2bd2b6460d00f2fa671dfde4bf2e02f49bf5c6", size = 131383, upload-time = "2025-10-24T15:50:36.511Z" },
]
[[package]]
@@ -1908,15 +1518,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/01/33/2c0d5216cc53d16db0c4b3d510f141ee0a540937f8675948541190fbd48b/pendulum-3.1.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7378084fe54faab4ee481897a00b710876f2e901ded6221671e827a253e643f2", size = 523221, upload-time = "2025-04-19T14:01:53.275Z" },
{ url = "https://files.pythonhosted.org/packages/51/89/8de955c339c31aeae77fd86d3225509b998c81875e9dba28cb88b8cbf4b3/pendulum-3.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:8539db7ae2c8da430ac2515079e288948c8ebf7eb1edd3e8281b5cdf433040d6", size = 260501, upload-time = "2025-04-19T14:01:54.749Z" },
{ url = "https://files.pythonhosted.org/packages/15/c3/226a3837363e94f8722461848feec18bfdd7d5172564d53aa3c3397ff01e/pendulum-3.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:1ce26a608e1f7387cd393fba2a129507c4900958d4f47b90757ec17656856571", size = 253087, upload-time = "2025-04-19T14:01:55.998Z" },
- { url = "https://files.pythonhosted.org/packages/c9/eb/e128af9e1a216c17b932f8c7f1f927f97cd8fd71d6e60148e1c69ad2bcf4/pendulum-3.1.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:2504df1a7ff8e0827781a601ff399bfcad23e7b7943f87ef33db02c11131f5e8", size = 339467, upload-time = "2025-04-19T14:01:57.346Z" },
- { url = "https://files.pythonhosted.org/packages/2f/c3/a7f515c6dbe89f2d92216ccd9a2e31dd657767d7f64177da1579092a41e3/pendulum-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4041a7156695499b6676ed092f27e17760db2341bf350f6c5ea9137dd2cfd3f6", size = 326898, upload-time = "2025-04-19T14:01:58.789Z" },
- { url = "https://files.pythonhosted.org/packages/15/da/80774350340e9d06789460b6e8def2d497cffe09334a8911be8d226caec5/pendulum-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b277e9177651d6af8500b95f0af1e3c1769064f2353c06f638d3c1e065063e", size = 344866, upload-time = "2025-04-19T14:02:00.688Z" },
- { url = "https://files.pythonhosted.org/packages/55/cf/771d1fee8d14abefbccbed99622c6f26e33b839b8964a18188b4f9159bf1/pendulum-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:784cf82b676118816fb81ea6bcbdf8f3b0c49aa74fcb895647ef7f8046093471", size = 382902, upload-time = "2025-04-19T14:02:02.077Z" },
- { url = "https://files.pythonhosted.org/packages/bd/95/0660ae5dbe9212c99fbccb27ca64361018600aa954fab95641653a39ce36/pendulum-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e44277a391fa5ad2e9ce02b1b24fd9489cb2a371ae2459eddb238301d31204d", size = 437782, upload-time = "2025-04-19T14:02:03.984Z" },
- { url = "https://files.pythonhosted.org/packages/04/1f/007dff40bb0325ae91eba3d4d6ce911945d808f87d3cebaa4556ca07f35d/pendulum-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a7d0bca8cca92d60734b64fa4fa58b17b8ec1f55112bf77d00ee65248d19177", size = 354462, upload-time = "2025-04-19T14:02:05.831Z" },
- { url = "https://files.pythonhosted.org/packages/e6/cc/8d2ed88beab1622623e321bd1f754eee174bb97e6ffcd34ceb9cce87a4ea/pendulum-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bfac5e02faee02c180444e722c298690688ec1c3dfa1aab65fb4e0e3825d84ed", size = 525009, upload-time = "2025-04-19T14:02:07.231Z" },
- { url = "https://files.pythonhosted.org/packages/44/c0/a503df53796b0dc1dae7d50573d936f86f8f482cf4acd9adbbd2a30ef817/pendulum-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e0da70941b062220e734c2c510ad30daa60aca1a37e893f1baa0da065ffa4c72", size = 526351, upload-time = "2025-04-19T14:02:08.619Z" },
- { url = "https://files.pythonhosted.org/packages/c6/bc/1fbc57b2e482a0ee3b5a0759c4b3b5127f0401cdce4afef111a3b6179d8d/pendulum-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:300a237fb81028edb9604d4d1bb205b80515fd22ab9c1a4c55014d07869122f8", size = 260813, upload-time = "2025-04-19T14:02:10.677Z" },
{ url = "https://files.pythonhosted.org/packages/66/10/3258c084653606d2be2c7168998eda4a57cf1559cecb43cf1100000fda5f/pendulum-3.1.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d2cac744940299d8da41a3ed941aa1e02b5abbc9ae2c525f3aa2ae30c28a86b5", size = 339442, upload-time = "2025-04-19T14:02:12.512Z" },
{ url = "https://files.pythonhosted.org/packages/98/d5/98a1a10cd1cfb3390fbf070864e9a10de8e70a9d4509832132f4d900d655/pendulum-3.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:ffb39c3f3906a9c9a108fa98e5556f18b52d2c6451984bbfe2f14436ec4fc9d4", size = 326609, upload-time = "2025-04-19T14:02:13.838Z" },
{ url = "https://files.pythonhosted.org/packages/0a/2e/448abdebc11b9c54e190d273cb084162643199fc184cb1bb6bff7900e67f/pendulum-3.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebe18b1c2eb364064cc4a68a65900f1465cac47d0891dab82341766bcc05b40c", size = 344777, upload-time = "2025-04-19T14:02:15.512Z" },
@@ -1924,13 +1525,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/bc/d4/e63a57df65e2b2d10f3aa917a4069be9abf5ac7d56d11336e0510742d8a6/pendulum-3.1.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a3be19b73a9c6a866724419295482f817727e635ccc82f07ae6f818943a1ee96", size = 524948, upload-time = "2025-04-19T14:02:18.808Z" },
{ url = "https://files.pythonhosted.org/packages/93/87/04e74600c5a5674e5f341b8888b530a9de9b84b31889f80fac3bee3e9e87/pendulum-3.1.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:24a53b523819bda4c70245687a589b5ea88711f7caac4be5f276d843fe63076b", size = 526340, upload-time = "2025-04-19T14:02:20.242Z" },
{ url = "https://files.pythonhosted.org/packages/48/27/d3577a5f6f7d1fbf1138d87ce21ebab363c78642513b991d1c424d658d09/pendulum-3.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bd701789414fbd0be3c75f46803f31e91140c23821e4bcb0fa2bddcdd051c425", size = 261089, upload-time = "2025-04-19T14:02:21.631Z" },
- { url = "https://files.pythonhosted.org/packages/53/8f/6620b0df6acdd8c020ec4f5907e3deb8c6d46970568299b66eed9b5f53b4/pendulum-3.1.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0803639fc98e03f74d0b83955a2800bcee1c99b0700638aae9ab7ceb1a7dcca3", size = 340056, upload-time = "2025-04-19T14:02:23.041Z" },
- { url = "https://files.pythonhosted.org/packages/dd/90/957491643cff9d97764e443bd0ef7c5c549e733e306159d6ca8ab4034fb5/pendulum-3.1.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:4cceff50503ef9cb021e53a238f867c9843b4dd55859582d682f3c9e52460699", size = 327095, upload-time = "2025-04-19T14:02:24.866Z" },
- { url = "https://files.pythonhosted.org/packages/fe/f2/550855e0285671278f763963b2470f437d340759aaef927fedb204e58fb0/pendulum-3.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2cf8adcf3030eef78c3cd82afd9948cd1a4ae1a9450e9ac128b9e744c42825f", size = 345131, upload-time = "2025-04-19T14:02:26.332Z" },
- { url = "https://files.pythonhosted.org/packages/b4/8f/938b83fe3e1450f4b04d1f96e8b2c288e07ad6b942260fef24cfd98cc3d0/pendulum-3.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5bce0f71c10e983e1c39e1eb37b9a5f5c2aa0c15a36edaaa0a844fb1fbc7bbb", size = 354886, upload-time = "2025-04-19T14:02:28.205Z" },
- { url = "https://files.pythonhosted.org/packages/d9/aa/0e3c231a7e35b362226204d7276a47c0e225aa59b30c7c9cd2a8e2660967/pendulum-3.1.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c1354be2df38f031ac6a985949b6541be7d39dd7e44c8804f4bc9a39dea9f3bb", size = 525344, upload-time = "2025-04-19T14:02:30.116Z" },
- { url = "https://files.pythonhosted.org/packages/0b/c7/d3654a790129684d0e8dc04707cb6d75633d7b102a962c6dc0f862c64c25/pendulum-3.1.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e4cbd933a40c915ed5c41b083115cca15c7afa8179363b2a61db167c64fa0670", size = 526685, upload-time = "2025-04-19T14:02:31.523Z" },
- { url = "https://files.pythonhosted.org/packages/50/d9/4a166256386b7973e36ff44135e8d009f4afb25d6c72df5380ccfd6fbb89/pendulum-3.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3363a470b5d67dbf8d9fd1bf77dcdbf720788bc3be4a10bdcd28ae5d7dbd26c4", size = 261170, upload-time = "2025-04-19T14:02:33.099Z" },
{ url = "https://files.pythonhosted.org/packages/6e/23/e98758924d1b3aac11a626268eabf7f3cf177e7837c28d47bf84c64532d0/pendulum-3.1.0-py3-none-any.whl", hash = "sha256:f9178c2a8e291758ade1e8dd6371b1d26d08371b4c7730a6e9a3ef8b16ebae0f", size = 111799, upload-time = "2025-04-19T14:02:34.739Z" },
]
@@ -1946,28 +1540,10 @@ wheels = [
{ 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.4.0"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" },
-]
-
[[package]]
name = "platformdirs"
version = "4.5.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
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/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" },
@@ -2034,13 +1610,10 @@ dependencies = [
{ name = "fastapi" },
{ name = "fsspec" },
{ name = "graphviz" },
- { name = "griffe", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "griffe", version = "1.15.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "griffe" },
{ name = "httpcore" },
{ name = "httpx", extra = ["http2"] },
- { name = "humanize", version = "4.13.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "humanize", version = "4.14.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
- { name = "importlib-metadata", marker = "python_full_version < '3.10'" },
+ { name = "humanize" },
{ name = "jsonpatch" },
{ name = "jsonschema" },
{ name = "opentelemetry-api" },
@@ -2132,69 +1705,10 @@ wheels = [
{ 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 = "pyarrow"
-version = "21.0.0"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/ef/c2/ea068b8f00905c06329a3dfcd40d0fcc2b7d0f2e355bdb25b65e0a0e4cd4/pyarrow-21.0.0.tar.gz", hash = "sha256:5051f2dccf0e283ff56335760cbc8622cf52264d67e359d5569541ac11b6d5bc", size = 1133487, upload-time = "2025-07-18T00:57:31.761Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/17/d9/110de31880016e2afc52d8580b397dbe47615defbf09ca8cf55f56c62165/pyarrow-21.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e563271e2c5ff4d4a4cbeb2c83d5cf0d4938b891518e676025f7268c6fe5fe26", size = 31196837, upload-time = "2025-07-18T00:54:34.755Z" },
- { url = "https://files.pythonhosted.org/packages/df/5f/c1c1997613abf24fceb087e79432d24c19bc6f7259cab57c2c8e5e545fab/pyarrow-21.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:fee33b0ca46f4c85443d6c450357101e47d53e6c3f008d658c27a2d020d44c79", size = 32659470, upload-time = "2025-07-18T00:54:38.329Z" },
- { url = "https://files.pythonhosted.org/packages/3e/ed/b1589a777816ee33ba123ba1e4f8f02243a844fed0deec97bde9fb21a5cf/pyarrow-21.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:7be45519b830f7c24b21d630a31d48bcebfd5d4d7f9d3bdb49da9cdf6d764edb", size = 41055619, upload-time = "2025-07-18T00:54:42.172Z" },
- { url = "https://files.pythonhosted.org/packages/44/28/b6672962639e85dc0ac36f71ab3a8f5f38e01b51343d7aa372a6b56fa3f3/pyarrow-21.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:26bfd95f6bff443ceae63c65dc7e048670b7e98bc892210acba7e4995d3d4b51", size = 42733488, upload-time = "2025-07-18T00:54:47.132Z" },
- { url = "https://files.pythonhosted.org/packages/f8/cc/de02c3614874b9089c94eac093f90ca5dfa6d5afe45de3ba847fd950fdf1/pyarrow-21.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bd04ec08f7f8bd113c55868bd3fc442a9db67c27af098c5f814a3091e71cc61a", size = 43329159, upload-time = "2025-07-18T00:54:51.686Z" },
- { url = "https://files.pythonhosted.org/packages/a6/3e/99473332ac40278f196e105ce30b79ab8affab12f6194802f2593d6b0be2/pyarrow-21.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9b0b14b49ac10654332a805aedfc0147fb3469cbf8ea951b3d040dab12372594", size = 45050567, upload-time = "2025-07-18T00:54:56.679Z" },
- { url = "https://files.pythonhosted.org/packages/7b/f5/c372ef60593d713e8bfbb7e0c743501605f0ad00719146dc075faf11172b/pyarrow-21.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:9d9f8bcb4c3be7738add259738abdeddc363de1b80e3310e04067aa1ca596634", size = 26217959, upload-time = "2025-07-18T00:55:00.482Z" },
- { url = "https://files.pythonhosted.org/packages/94/dc/80564a3071a57c20b7c32575e4a0120e8a330ef487c319b122942d665960/pyarrow-21.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c077f48aab61738c237802836fc3844f85409a46015635198761b0d6a688f87b", size = 31243234, upload-time = "2025-07-18T00:55:03.812Z" },
- { url = "https://files.pythonhosted.org/packages/ea/cc/3b51cb2db26fe535d14f74cab4c79b191ed9a8cd4cbba45e2379b5ca2746/pyarrow-21.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:689f448066781856237eca8d1975b98cace19b8dd2ab6145bf49475478bcaa10", size = 32714370, upload-time = "2025-07-18T00:55:07.495Z" },
- { url = "https://files.pythonhosted.org/packages/24/11/a4431f36d5ad7d83b87146f515c063e4d07ef0b7240876ddb885e6b44f2e/pyarrow-21.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:479ee41399fcddc46159a551705b89c05f11e8b8cb8e968f7fec64f62d91985e", size = 41135424, upload-time = "2025-07-18T00:55:11.461Z" },
- { url = "https://files.pythonhosted.org/packages/74/dc/035d54638fc5d2971cbf1e987ccd45f1091c83bcf747281cf6cc25e72c88/pyarrow-21.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:40ebfcb54a4f11bcde86bc586cbd0272bac0d516cfa539c799c2453768477569", size = 42823810, upload-time = "2025-07-18T00:55:16.301Z" },
- { url = "https://files.pythonhosted.org/packages/2e/3b/89fced102448a9e3e0d4dded1f37fa3ce4700f02cdb8665457fcc8015f5b/pyarrow-21.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8d58d8497814274d3d20214fbb24abcad2f7e351474357d552a8d53bce70c70e", size = 43391538, upload-time = "2025-07-18T00:55:23.82Z" },
- { url = "https://files.pythonhosted.org/packages/fb/bb/ea7f1bd08978d39debd3b23611c293f64a642557e8141c80635d501e6d53/pyarrow-21.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:585e7224f21124dd57836b1530ac8f2df2afc43c861d7bf3d58a4870c42ae36c", size = 45120056, upload-time = "2025-07-18T00:55:28.231Z" },
- { url = "https://files.pythonhosted.org/packages/6e/0b/77ea0600009842b30ceebc3337639a7380cd946061b620ac1a2f3cb541e2/pyarrow-21.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:555ca6935b2cbca2c0e932bedd853e9bc523098c39636de9ad4693b5b1df86d6", size = 26220568, upload-time = "2025-07-18T00:55:32.122Z" },
- { url = "https://files.pythonhosted.org/packages/ca/d4/d4f817b21aacc30195cf6a46ba041dd1be827efa4a623cc8bf39a1c2a0c0/pyarrow-21.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:3a302f0e0963db37e0a24a70c56cf91a4faa0bca51c23812279ca2e23481fccd", size = 31160305, upload-time = "2025-07-18T00:55:35.373Z" },
- { url = "https://files.pythonhosted.org/packages/a2/9c/dcd38ce6e4b4d9a19e1d36914cb8e2b1da4e6003dd075474c4cfcdfe0601/pyarrow-21.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:b6b27cf01e243871390474a211a7922bfbe3bda21e39bc9160daf0da3fe48876", size = 32684264, upload-time = "2025-07-18T00:55:39.303Z" },
- { url = "https://files.pythonhosted.org/packages/4f/74/2a2d9f8d7a59b639523454bec12dba35ae3d0a07d8ab529dc0809f74b23c/pyarrow-21.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e72a8ec6b868e258a2cd2672d91f2860ad532d590ce94cdf7d5e7ec674ccf03d", size = 41108099, upload-time = "2025-07-18T00:55:42.889Z" },
- { url = "https://files.pythonhosted.org/packages/ad/90/2660332eeb31303c13b653ea566a9918484b6e4d6b9d2d46879a33ab0622/pyarrow-21.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b7ae0bbdc8c6674259b25bef5d2a1d6af5d39d7200c819cf99e07f7dfef1c51e", size = 42829529, upload-time = "2025-07-18T00:55:47.069Z" },
- { url = "https://files.pythonhosted.org/packages/33/27/1a93a25c92717f6aa0fca06eb4700860577d016cd3ae51aad0e0488ac899/pyarrow-21.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:58c30a1729f82d201627c173d91bd431db88ea74dcaa3885855bc6203e433b82", size = 43367883, upload-time = "2025-07-18T00:55:53.069Z" },
- { url = "https://files.pythonhosted.org/packages/05/d9/4d09d919f35d599bc05c6950095e358c3e15148ead26292dfca1fb659b0c/pyarrow-21.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:072116f65604b822a7f22945a7a6e581cfa28e3454fdcc6939d4ff6090126623", size = 45133802, upload-time = "2025-07-18T00:55:57.714Z" },
- { url = "https://files.pythonhosted.org/packages/71/30/f3795b6e192c3ab881325ffe172e526499eb3780e306a15103a2764916a2/pyarrow-21.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:cf56ec8b0a5c8c9d7021d6fd754e688104f9ebebf1bf4449613c9531f5346a18", size = 26203175, upload-time = "2025-07-18T00:56:01.364Z" },
- { url = "https://files.pythonhosted.org/packages/16/ca/c7eaa8e62db8fb37ce942b1ea0c6d7abfe3786ca193957afa25e71b81b66/pyarrow-21.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e99310a4ebd4479bcd1964dff9e14af33746300cb014aa4a3781738ac63baf4a", size = 31154306, upload-time = "2025-07-18T00:56:04.42Z" },
- { url = "https://files.pythonhosted.org/packages/ce/e8/e87d9e3b2489302b3a1aea709aaca4b781c5252fcb812a17ab6275a9a484/pyarrow-21.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:d2fe8e7f3ce329a71b7ddd7498b3cfac0eeb200c2789bd840234f0dc271a8efe", size = 32680622, upload-time = "2025-07-18T00:56:07.505Z" },
- { url = "https://files.pythonhosted.org/packages/84/52/79095d73a742aa0aba370c7942b1b655f598069489ab387fe47261a849e1/pyarrow-21.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:f522e5709379d72fb3da7785aa489ff0bb87448a9dc5a75f45763a795a089ebd", size = 41104094, upload-time = "2025-07-18T00:56:10.994Z" },
- { url = "https://files.pythonhosted.org/packages/89/4b/7782438b551dbb0468892a276b8c789b8bbdb25ea5c5eb27faadd753e037/pyarrow-21.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:69cbbdf0631396e9925e048cfa5bce4e8c3d3b41562bbd70c685a8eb53a91e61", size = 42825576, upload-time = "2025-07-18T00:56:15.569Z" },
- { url = "https://files.pythonhosted.org/packages/b3/62/0f29de6e0a1e33518dec92c65be0351d32d7ca351e51ec5f4f837a9aab91/pyarrow-21.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:731c7022587006b755d0bdb27626a1a3bb004bb56b11fb30d98b6c1b4718579d", size = 43368342, upload-time = "2025-07-18T00:56:19.531Z" },
- { url = "https://files.pythonhosted.org/packages/90/c7/0fa1f3f29cf75f339768cc698c8ad4ddd2481c1742e9741459911c9ac477/pyarrow-21.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dc56bc708f2d8ac71bd1dcb927e458c93cec10b98eb4120206a4091db7b67b99", size = 45131218, upload-time = "2025-07-18T00:56:23.347Z" },
- { url = "https://files.pythonhosted.org/packages/01/63/581f2076465e67b23bc5a37d4a2abff8362d389d29d8105832e82c9c811c/pyarrow-21.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:186aa00bca62139f75b7de8420f745f2af12941595bbbfa7ed3870ff63e25636", size = 26087551, upload-time = "2025-07-18T00:56:26.758Z" },
- { url = "https://files.pythonhosted.org/packages/c9/ab/357d0d9648bb8241ee7348e564f2479d206ebe6e1c47ac5027c2e31ecd39/pyarrow-21.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:a7a102574faa3f421141a64c10216e078df467ab9576684d5cd696952546e2da", size = 31290064, upload-time = "2025-07-18T00:56:30.214Z" },
- { url = "https://files.pythonhosted.org/packages/3f/8a/5685d62a990e4cac2043fc76b4661bf38d06efed55cf45a334b455bd2759/pyarrow-21.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:1e005378c4a2c6db3ada3ad4c217b381f6c886f0a80d6a316fe586b90f77efd7", size = 32727837, upload-time = "2025-07-18T00:56:33.935Z" },
- { url = "https://files.pythonhosted.org/packages/fc/de/c0828ee09525c2bafefd3e736a248ebe764d07d0fd762d4f0929dbc516c9/pyarrow-21.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:65f8e85f79031449ec8706b74504a316805217b35b6099155dd7e227eef0d4b6", size = 41014158, upload-time = "2025-07-18T00:56:37.528Z" },
- { url = "https://files.pythonhosted.org/packages/6e/26/a2865c420c50b7a3748320b614f3484bfcde8347b2639b2b903b21ce6a72/pyarrow-21.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:3a81486adc665c7eb1a2bde0224cfca6ceaba344a82a971ef059678417880eb8", size = 42667885, upload-time = "2025-07-18T00:56:41.483Z" },
- { url = "https://files.pythonhosted.org/packages/0a/f9/4ee798dc902533159250fb4321267730bc0a107d8c6889e07c3add4fe3a5/pyarrow-21.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fc0d2f88b81dcf3ccf9a6ae17f89183762c8a94a5bdcfa09e05cfe413acf0503", size = 43276625, upload-time = "2025-07-18T00:56:48.002Z" },
- { url = "https://files.pythonhosted.org/packages/5a/da/e02544d6997037a4b0d22d8e5f66bc9315c3671371a8b18c79ade1cefe14/pyarrow-21.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6299449adf89df38537837487a4f8d3bd91ec94354fdd2a7d30bc11c48ef6e79", size = 44951890, upload-time = "2025-07-18T00:56:52.568Z" },
- { url = "https://files.pythonhosted.org/packages/e5/4e/519c1bc1876625fe6b71e9a28287c43ec2f20f73c658b9ae1d485c0c206e/pyarrow-21.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:222c39e2c70113543982c6b34f3077962b44fca38c0bd9e68bb6781534425c10", size = 26371006, upload-time = "2025-07-18T00:56:56.379Z" },
- { url = "https://files.pythonhosted.org/packages/3e/cc/ce4939f4b316457a083dc5718b3982801e8c33f921b3c98e7a93b7c7491f/pyarrow-21.0.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:a7f6524e3747e35f80744537c78e7302cd41deee8baa668d56d55f77d9c464b3", size = 31211248, upload-time = "2025-07-18T00:56:59.7Z" },
- { url = "https://files.pythonhosted.org/packages/1f/c2/7a860931420d73985e2f340f06516b21740c15b28d24a0e99a900bb27d2b/pyarrow-21.0.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:203003786c9fd253ebcafa44b03c06983c9c8d06c3145e37f1b76a1f317aeae1", size = 32676896, upload-time = "2025-07-18T00:57:03.884Z" },
- { url = "https://files.pythonhosted.org/packages/68/a8/197f989b9a75e59b4ca0db6a13c56f19a0ad8a298c68da9cc28145e0bb97/pyarrow-21.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:3b4d97e297741796fead24867a8dabf86c87e4584ccc03167e4a811f50fdf74d", size = 41067862, upload-time = "2025-07-18T00:57:07.587Z" },
- { url = "https://files.pythonhosted.org/packages/fa/82/6ecfa89487b35aa21accb014b64e0a6b814cc860d5e3170287bf5135c7d8/pyarrow-21.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:898afce396b80fdda05e3086b4256f8677c671f7b1d27a6976fa011d3fd0a86e", size = 42747508, upload-time = "2025-07-18T00:57:13.917Z" },
- { url = "https://files.pythonhosted.org/packages/3b/b7/ba252f399bbf3addc731e8643c05532cf32e74cebb5e32f8f7409bc243cf/pyarrow-21.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:067c66ca29aaedae08218569a114e413b26e742171f526e828e1064fcdec13f4", size = 43345293, upload-time = "2025-07-18T00:57:19.828Z" },
- { url = "https://files.pythonhosted.org/packages/ff/0a/a20819795bd702b9486f536a8eeb70a6aa64046fce32071c19ec8230dbaa/pyarrow-21.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0c4e75d13eb76295a49e0ea056eb18dbd87d81450bfeb8afa19a7e5a75ae2ad7", size = 45060670, upload-time = "2025-07-18T00:57:24.477Z" },
- { url = "https://files.pythonhosted.org/packages/10/15/6b30e77872012bbfe8265d42a01d5b3c17ef0ac0f2fae531ad91b6a6c02e/pyarrow-21.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdc4c17afda4dab2a9c0b79148a43a7f4e1094916b3e18d8975bfd6d6d52241f", size = 26227521, upload-time = "2025-07-18T00:57:29.119Z" },
-]
-
[[package]]
name = "pyarrow"
version = "22.0.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
sdist = { url = "https://files.pythonhosted.org/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151, upload-time = "2025-10-24T12:30:00.762Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d9/9b/cb3f7e0a345353def531ca879053e9ef6b9f38ed91aebcf68b09ba54dec0/pyarrow-22.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:77718810bd3066158db1e95a63c160ad7ce08c6b0710bc656055033e39cdad88", size = 34223968, upload-time = "2025-10-24T10:03:31.21Z" },
@@ -2318,19 +1832,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/07/ea/3df927c4384ed9b503c9cc2d076cf983b4f2adb0c754578dfb1245c51e46/pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d25e97bc1f5f8f7985bdc2335ef9e73843bb561eb1fa6831fdfc295c1c2061cf", size = 2042819, upload-time = "2025-10-14T10:21:26.683Z" },
{ url = "https://files.pythonhosted.org/packages/6a/ee/df8e871f07074250270a3b1b82aad4cd0026b588acd5d7d3eb2fcb1471a3/pydantic_core-2.41.4-cp313-cp313t-win_amd64.whl", hash = "sha256:d405d14bea042f166512add3091c1af40437c2e7f86988f3915fabd27b1e9cd2", size = 1995866, upload-time = "2025-10-14T10:21:28.951Z" },
{ url = "https://files.pythonhosted.org/packages/fc/de/b20f4ab954d6d399499c33ec4fafc46d9551e11dc1858fb7f5dca0748ceb/pydantic_core-2.41.4-cp313-cp313t-win_arm64.whl", hash = "sha256:19f3684868309db5263a11bace3c45d93f6f24afa2ffe75a647583df22a2ff89", size = 1970034, upload-time = "2025-10-14T10:21:30.869Z" },
- { url = "https://files.pythonhosted.org/packages/2c/36/f86d582be5fb47d4014506cd9ddd10a3979b6d0f2d237aa6ad3e7033b3ea/pydantic_core-2.41.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:646e76293345954acea6966149683047b7b2ace793011922208c8e9da12b0062", size = 2112444, upload-time = "2025-10-14T10:22:16.165Z" },
- { url = "https://files.pythonhosted.org/packages/ba/e5/63c521dc2dd106ba6b5941c080617ea9db252f8a7d5625231e9d761bc28c/pydantic_core-2.41.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cc8e85a63085a137d286e2791037f5fdfff0aabb8b899483ca9c496dd5797338", size = 1938218, upload-time = "2025-10-14T10:22:19.443Z" },
- { url = "https://files.pythonhosted.org/packages/30/56/c84b638a3e6e9f5a612b9f5abdad73182520423de43669d639ed4f14b011/pydantic_core-2.41.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:692c622c8f859a17c156492783902d8370ac7e121a611bd6fe92cc71acf9ee8d", size = 1971449, upload-time = "2025-10-14T10:22:21.567Z" },
- { url = "https://files.pythonhosted.org/packages/99/c6/e974aade34fc7a0248fdfd0a373d62693502a407c596ab3470165e38183c/pydantic_core-2.41.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d1e2906efb1031a532600679b424ef1d95d9f9fb507f813951f23320903adbd7", size = 2054023, upload-time = "2025-10-14T10:22:24.229Z" },
- { url = "https://files.pythonhosted.org/packages/4f/91/2507dda801f50980a38d1353c313e8f51349a42b008e63a4e45bf4620562/pydantic_core-2.41.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04e2f7f8916ad3ddd417a7abdd295276a0bf216993d9318a5d61cc058209166", size = 2251614, upload-time = "2025-10-14T10:22:26.498Z" },
- { url = "https://files.pythonhosted.org/packages/b2/ad/05d886bc96938f4d31bed24e8d3fc3496d9aea7e77bcff6e4b93127c6de7/pydantic_core-2.41.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df649916b81822543d1c8e0e1d079235f68acdc7d270c911e8425045a8cfc57e", size = 2378807, upload-time = "2025-10-14T10:22:28.733Z" },
- { url = "https://files.pythonhosted.org/packages/6a/0a/d26e1bb9a80b9fc12cc30d9288193fbc9e60a799e55843804ee37bd38a9c/pydantic_core-2.41.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66c529f862fdba70558061bb936fe00ddbaaa0c647fd26e4a4356ef1d6561891", size = 2076891, upload-time = "2025-10-14T10:22:30.853Z" },
- { url = "https://files.pythonhosted.org/packages/d9/66/af014e3a294d9933ebfecf11a5d858709014bd2315fa9616195374dd82f0/pydantic_core-2.41.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3b4c5a1fd3a311563ed866c2c9b62da06cb6398bee186484ce95c820db71cb", size = 2192179, upload-time = "2025-10-14T10:22:33.481Z" },
- { url = "https://files.pythonhosted.org/packages/e7/3e/79783f97024037d0ea6e1b3ebcd761463a925199e04ce2625727e9f27d06/pydantic_core-2.41.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6e0fc40d84448f941df9b3334c4b78fe42f36e3bf631ad54c3047a0cdddc2514", size = 2153067, upload-time = "2025-10-14T10:22:35.792Z" },
- { url = "https://files.pythonhosted.org/packages/b3/97/ea83b0f87d9e742405fb687d5682e7a26334eef2c82a2de06bfbdc305fab/pydantic_core-2.41.4-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:44e7625332683b6c1c8b980461475cde9595eff94447500e80716db89b0da005", size = 2319048, upload-time = "2025-10-14T10:22:38.144Z" },
- { url = "https://files.pythonhosted.org/packages/64/4a/36d8c966a0b086362ac10a7ee75978ed15c5f2dfdfc02a1578d19d3802fb/pydantic_core-2.41.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:170ee6835f6c71081d031ef1c3b4dc4a12b9efa6a9540f93f95b82f3c7571ae8", size = 2321830, upload-time = "2025-10-14T10:22:40.337Z" },
- { url = "https://files.pythonhosted.org/packages/a2/6e/d80cc4909dde5f6842861288aa1a7181e7afbfc50940c862ed2848df15bd/pydantic_core-2.41.4-cp39-cp39-win32.whl", hash = "sha256:3adf61415efa6ce977041ba9745183c0e1f637ca849773afa93833e04b163feb", size = 1976706, upload-time = "2025-10-14T10:22:42.61Z" },
- { url = "https://files.pythonhosted.org/packages/29/ee/5bda8d960d4a8b24a7eeb8a856efa9c865a7a6cab714ed387b29507dc278/pydantic_core-2.41.4-cp39-cp39-win_amd64.whl", hash = "sha256:a238dd3feee263eeaeb7dc44aea4ba1364682c4f9f9467e6af5596ba322c2332", size = 2027640, upload-time = "2025-10-14T10:22:44.907Z" },
{ url = "https://files.pythonhosted.org/packages/b0/12/5ba58daa7f453454464f92b3ca7b9d7c657d8641c48e370c3ebc9a82dd78/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:a1b2cfec3879afb742a7b0bcfa53e4f22ba96571c9e54d6a3afe1052d17d843b", size = 2122139, upload-time = "2025-10-14T10:22:47.288Z" },
{ url = "https://files.pythonhosted.org/packages/21/fb/6860126a77725c3108baecd10fd3d75fec25191d6381b6eb2ac660228eac/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:d175600d975b7c244af6eb9c9041f10059f20b8bbffec9e33fdd5ee3f67cdc42", size = 1936674, upload-time = "2025-10-14T10:22:49.555Z" },
{ url = "https://files.pythonhosted.org/packages/de/be/57dcaa3ed595d81f8757e2b44a38240ac5d37628bce25fb20d02c7018776/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f184d657fa4947ae5ec9c47bd7e917730fa1cbb78195037e32dcbab50aca5ee", size = 1956398, upload-time = "2025-10-14T10:22:52.19Z" },
@@ -2409,8 +1910,7 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
- { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "iniconfig" },
{ name = "packaging" },
{ name = "pluggy" },
{ name = "pygments" },
@@ -2449,8 +1949,7 @@ name = "pytest-cov"
version = "7.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "coverage", version = "7.10.7", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version < '3.10'" },
- { name = "coverage", version = "7.11.0", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version >= '3.10'" },
+ { name = "coverage", extra = ["toml"] },
{ name = "pluggy" },
{ name = "pytest" },
]
@@ -2567,9 +2066,6 @@ wheels = [
{ 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/59/42/b86689aac0cdaee7ae1c58d464b0ff04ca909c19bb6502d4973cdd9f9544/pywin32-311-cp39-cp39-win32.whl", hash = "sha256:aba8f82d551a942cb20d4a83413ccbac30790b50efb89a75e4f586ac0bb8056b", size = 8760837, upload-time = "2025-07-14T20:12:59.59Z" },
- { url = "https://files.pythonhosted.org/packages/9f/8a/1403d0353f8c5a2f0829d2b1c4becbf9da2f0a4d040886404fc4a5431e4d/pywin32-311-cp39-cp39-win_amd64.whl", hash = "sha256:e0c4cfb0621281fe40387df582097fd796e80430597cb9944f0ae70447bacd91", size = 9590187, upload-time = "2025-07-14T20:13:01.419Z" },
- { url = "https://files.pythonhosted.org/packages/60/22/e0e8d802f124772cec9c75430b01a212f86f9de7546bda715e54140d5aeb/pywin32-311-cp39-cp39-win_arm64.whl", hash = "sha256:62ea666235135fee79bb154e695f3ff67370afefd71bd7fea7512fc70ef31e3d", size = 8778162, upload-time = "2025-07-14T20:13:03.544Z" },
]
[[package]]
@@ -2616,15 +2112,6 @@ wheels = [
{ 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/9f/62/67fc8e68a75f738c9200422bf65693fb79a4cd0dc5b23310e5202e978090/pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", size = 184450, upload-time = "2025-09-25T21:33:00.618Z" },
- { url = "https://files.pythonhosted.org/packages/ae/92/861f152ce87c452b11b9d0977952259aa7df792d71c1053365cc7b09cc08/pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", size = 174319, upload-time = "2025-09-25T21:33:02.086Z" },
- { url = "https://files.pythonhosted.org/packages/d0/cd/f0cfc8c74f8a030017a2b9c771b7f47e5dd702c3e28e5b2071374bda2948/pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", size = 737631, upload-time = "2025-09-25T21:33:03.25Z" },
- { url = "https://files.pythonhosted.org/packages/ef/b2/18f2bd28cd2055a79a46c9b0895c0b3d987ce40ee471cecf58a1a0199805/pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", size = 836795, upload-time = "2025-09-25T21:33:05.014Z" },
- { url = "https://files.pythonhosted.org/packages/73/b9/793686b2d54b531203c160ef12bec60228a0109c79bae6c1277961026770/pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", size = 750767, upload-time = "2025-09-25T21:33:06.398Z" },
- { url = "https://files.pythonhosted.org/packages/a9/86/a137b39a611def2ed78b0e66ce2fe13ee701a07c07aebe55c340ed2a050e/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", size = 727982, upload-time = "2025-09-25T21:33:08.708Z" },
- { url = "https://files.pythonhosted.org/packages/dd/62/71c27c94f457cf4418ef8ccc71735324c549f7e3ea9d34aba50874563561/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", size = 755677, upload-time = "2025-09-25T21:33:09.876Z" },
- { url = "https://files.pythonhosted.org/packages/29/3d/6f5e0d58bd924fb0d06c3a6bad00effbdae2de5adb5cda5648006ffbd8d3/pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", size = 142592, upload-time = "2025-09-25T21:33:10.983Z" },
- { url = "https://files.pythonhosted.org/packages/f0/0c/25113e0b5e103d7f1490c0e947e303fe4a696c10b501dea7a9f49d4e876c/pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", size = 158777, upload-time = "2025-09-25T21:33:15.55Z" },
]
[[package]]
@@ -2639,37 +2126,14 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl", hash = "sha256:a51af13f345f1cdea62347589fbb6df3b290306ab8930713bfae4d475a7d4a59", size = 36753, upload-time = "2025-08-28T19:00:19.56Z" },
]
-[[package]]
-name = "referencing"
-version = "0.36.2"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-dependencies = [
- { name = "attrs", marker = "python_full_version < '3.10'" },
- { name = "rpds-py", version = "0.27.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "typing-extensions", marker = "python_full_version < '3.10'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" },
-]
-
[[package]]
name = "referencing"
version = "0.37.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
dependencies = [
- { name = "attrs", marker = "python_full_version >= '3.10'" },
- { name = "rpds-py", version = "0.28.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
- { name = "typing-extensions", marker = "python_full_version >= '3.10' and python_full_version < '3.13'" },
+ { name = "attrs" },
+ { name = "rpds-py" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" }
wheels = [
@@ -2753,21 +2217,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/4f/f9/8bd6b656592f925b6845fcbb4d57603a3ac2fb2373344ffa1ed70aa6820a/regex-2025.11.3-cp313-cp313t-win32.whl", hash = "sha256:9ddc42e68114e161e51e272f667d640f97e84a2b9ef14b7477c53aac20c2d59a", size = 268792, upload-time = "2025-11-03T21:32:44.13Z" },
{ url = "https://files.pythonhosted.org/packages/e5/87/0e7d603467775ff65cd2aeabf1b5b50cc1c3708556a8b849a2fa4dd1542b/regex-2025.11.3-cp313-cp313t-win_amd64.whl", hash = "sha256:7a7c7fdf755032ffdd72c77e3d8096bdcb0eb92e89e17571a196f03d88b11b3c", size = 280214, upload-time = "2025-11-03T21:32:45.853Z" },
{ url = "https://files.pythonhosted.org/packages/8d/d0/2afc6f8e94e2b64bfb738a7c2b6387ac1699f09f032d363ed9447fd2bb57/regex-2025.11.3-cp313-cp313t-win_arm64.whl", hash = "sha256:df9eb838c44f570283712e7cff14c16329a9f0fb19ca492d21d4b7528ee6821e", size = 271469, upload-time = "2025-11-03T21:32:48.026Z" },
- { url = "https://files.pythonhosted.org/packages/13/a2/71d9e3de7a8ba4dd301ce6327d3feacc911413dc0660a4e2256a8b43401b/regex-2025.11.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:81519e25707fc076978c6143b81ea3dc853f176895af05bf7ec51effe818aeec", size = 488097, upload-time = "2025-11-03T21:33:47.455Z" },
- { url = "https://files.pythonhosted.org/packages/68/c2/c74c874de5c3e73302ea1f47968f2a990c2517c6fb827c95d2b857e01098/regex-2025.11.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3bf28b1873a8af8bbb58c26cc56ea6e534d80053b41fb511a35795b6de507e6a", size = 290540, upload-time = "2025-11-03T21:33:49.296Z" },
- { url = "https://files.pythonhosted.org/packages/4e/4d/97cc016a7f705a496328d4d569db2023a200c2c391b0a0ddf36e66dd80f5/regex-2025.11.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:856a25c73b697f2ce2a24e7968285579e62577a048526161a2c0f53090bea9f9", size = 288419, upload-time = "2025-11-03T21:33:51.309Z" },
- { url = "https://files.pythonhosted.org/packages/e4/e6/725cd713a926a13f55bb9c4585d4cca51ab7d9ef77cb96eba8398e207418/regex-2025.11.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a3d571bd95fade53c86c0517f859477ff3a93c3fde10c9e669086f038e0f207", size = 781001, upload-time = "2025-11-03T21:33:53.375Z" },
- { url = "https://files.pythonhosted.org/packages/15/15/ff1e7428b64a66c83dd53a88294c3e1c3e6a08653d9670efd24cbb068fa5/regex-2025.11.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:732aea6de26051af97b94bc98ed86448821f839d058e5d259c72bf6d73ad0fc0", size = 850430, upload-time = "2025-11-03T21:33:55.362Z" },
- { url = "https://files.pythonhosted.org/packages/89/1d/d4045ff7c563eb73be4419784a06efc7de02e15959b917fee335de8c10de/regex-2025.11.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:51c1c1847128238f54930edb8805b660305dca164645a9fd29243f5610beea34", size = 898038, upload-time = "2025-11-03T21:33:57.73Z" },
- { url = "https://files.pythonhosted.org/packages/60/ee/e9c71bdf334edc14ff769463bd6173966b0445e442a28b18f790b84032f5/regex-2025.11.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22dd622a402aad4558277305350699b2be14bc59f64d64ae1d928ce7d072dced", size = 791201, upload-time = "2025-11-03T21:33:59.848Z" },
- { url = "https://files.pythonhosted.org/packages/aa/21/cc19ad5a091f921fea0caae5e4fb926d5b5350c376d09e2ada9f5d58b54c/regex-2025.11.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f3b5a391c7597ffa96b41bd5cbd2ed0305f515fcbb367dfa72735679d5502364", size = 781906, upload-time = "2025-11-03T21:34:02.28Z" },
- { url = "https://files.pythonhosted.org/packages/98/cc/22c52f2aff7f7e2591fe18db4b6143236c18800752e8e4c2cf938b64fe06/regex-2025.11.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:cc4076a5b4f36d849fd709284b4a3b112326652f3b0466f04002a6c15a0c96c1", size = 774267, upload-time = "2025-11-03T21:34:05.232Z" },
- { url = "https://files.pythonhosted.org/packages/6a/db/424728b5d831ebd15e86ca55f13990e2bc3c5b417dddaaaa3bd712f12e32/regex-2025.11.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a295ca2bba5c1c885826ce3125fa0b9f702a1be547d821c01d65f199e10c01e2", size = 845211, upload-time = "2025-11-03T21:34:07.57Z" },
- { url = "https://files.pythonhosted.org/packages/91/fc/48d64dcef7a8f3ecdb9fe60bb3a6c97b317dea089ac72594eccf6cad1938/regex-2025.11.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:b4774ff32f18e0504bfc4e59a3e71e18d83bc1e171a3c8ed75013958a03b2f14", size = 835575, upload-time = "2025-11-03T21:34:10.781Z" },
- { url = "https://files.pythonhosted.org/packages/48/0b/c0cbc34e933ed528bb225d298df572a2e75fbe1db1b36fe719867a5e582d/regex-2025.11.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e7d1cdfa88ef33a2ae6aa0d707f9255eb286ffbd90045f1088246833223aee", size = 779426, upload-time = "2025-11-03T21:34:13.498Z" },
- { url = "https://files.pythonhosted.org/packages/90/54/4987210bc0d139d90b579fbbdaafca2d4acee9c413843d6c1c8ac0dd56bf/regex-2025.11.3-cp39-cp39-win32.whl", hash = "sha256:74d04244852ff73b32eeede4f76f51c5bcf44bc3c207bc3e6cf1c5c45b890708", size = 265836, upload-time = "2025-11-03T21:34:15.556Z" },
- { url = "https://files.pythonhosted.org/packages/ab/68/0a3a1bf596db98c369d0f10242b006f4a928633e001906889f80c9b4b639/regex-2025.11.3-cp39-cp39-win_amd64.whl", hash = "sha256:7a50cd39f73faa34ec18d6720ee25ef10c4c1839514186fcda658a06c06057a2", size = 277807, upload-time = "2025-11-03T21:34:17.502Z" },
- { url = "https://files.pythonhosted.org/packages/7c/98/4ed5b608130249810977b030b86abfc7fcd19b31aa75060d8ad11003826d/regex-2025.11.3-cp39-cp39-win_arm64.whl", hash = "sha256:43b4fb020e779ca81c1b5255015fe2b82816c76ec982354534ad9ec09ad7c9e3", size = 270328, upload-time = "2025-11-03T21:34:19.783Z" },
]
[[package]]
@@ -2802,8 +2251,7 @@ name = "rich"
version = "13.9.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "markdown-it-py" },
{ name = "pygments" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
@@ -2812,152 +2260,10 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424, upload-time = "2024-11-01T16:43:55.817Z" },
]
-[[package]]
-name = "rpds-py"
-version = "0.27.1"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/e9/dd/2c0cbe774744272b0ae725f44032c77bdcab6e8bcf544bffa3b6e70c8dba/rpds_py-0.27.1.tar.gz", hash = "sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8", size = 27479, upload-time = "2025-08-27T12:16:36.024Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a5/ed/3aef893e2dd30e77e35d20d4ddb45ca459db59cead748cad9796ad479411/rpds_py-0.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:68afeec26d42ab3b47e541b272166a0b4400313946871cba3ed3a4fc0cab1cef", size = 371606, upload-time = "2025-08-27T12:12:25.189Z" },
- { url = "https://files.pythonhosted.org/packages/6d/82/9818b443e5d3eb4c83c3994561387f116aae9833b35c484474769c4a8faf/rpds_py-0.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74e5b2f7bb6fa38b1b10546d27acbacf2a022a8b5543efb06cfebc72a59c85be", size = 353452, upload-time = "2025-08-27T12:12:27.433Z" },
- { url = "https://files.pythonhosted.org/packages/99/c7/d2a110ffaaa397fc6793a83c7bd3545d9ab22658b7cdff05a24a4535cc45/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9024de74731df54546fab0bfbcdb49fae19159ecaecfc8f37c18d2c7e2c0bd61", size = 381519, upload-time = "2025-08-27T12:12:28.719Z" },
- { url = "https://files.pythonhosted.org/packages/5a/bc/e89581d1f9d1be7d0247eaef602566869fdc0d084008ba139e27e775366c/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:31d3ebadefcd73b73928ed0b2fd696f7fefda8629229f81929ac9c1854d0cffb", size = 394424, upload-time = "2025-08-27T12:12:30.207Z" },
- { url = "https://files.pythonhosted.org/packages/ac/2e/36a6861f797530e74bb6ed53495f8741f1ef95939eed01d761e73d559067/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2e7f8f169d775dd9092a1743768d771f1d1300453ddfe6325ae3ab5332b4657", size = 523467, upload-time = "2025-08-27T12:12:31.808Z" },
- { url = "https://files.pythonhosted.org/packages/c4/59/c1bc2be32564fa499f988f0a5c6505c2f4746ef96e58e4d7de5cf923d77e/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d905d16f77eb6ab2e324e09bfa277b4c8e5e6b8a78a3e7ff8f3cdf773b4c013", size = 402660, upload-time = "2025-08-27T12:12:33.444Z" },
- { url = "https://files.pythonhosted.org/packages/0a/ec/ef8bf895f0628dd0a59e54d81caed6891663cb9c54a0f4bb7da918cb88cf/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50c946f048209e6362e22576baea09193809f87687a95a8db24e5fbdb307b93a", size = 384062, upload-time = "2025-08-27T12:12:34.857Z" },
- { url = "https://files.pythonhosted.org/packages/69/f7/f47ff154be8d9a5e691c083a920bba89cef88d5247c241c10b9898f595a1/rpds_py-0.27.1-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:3deab27804d65cd8289eb814c2c0e807c4b9d9916c9225e363cb0cf875eb67c1", size = 401289, upload-time = "2025-08-27T12:12:36.085Z" },
- { url = "https://files.pythonhosted.org/packages/3b/d9/ca410363efd0615814ae579f6829cafb39225cd63e5ea5ed1404cb345293/rpds_py-0.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b61097f7488de4be8244c89915da8ed212832ccf1e7c7753a25a394bf9b1f10", size = 417718, upload-time = "2025-08-27T12:12:37.401Z" },
- { url = "https://files.pythonhosted.org/packages/e3/a0/8cb5c2ff38340f221cc067cc093d1270e10658ba4e8d263df923daa18e86/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8a3f29aba6e2d7d90528d3c792555a93497fe6538aa65eb675b44505be747808", size = 558333, upload-time = "2025-08-27T12:12:38.672Z" },
- { url = "https://files.pythonhosted.org/packages/6f/8c/1b0de79177c5d5103843774ce12b84caa7164dfc6cd66378768d37db11bf/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd6cd0485b7d347304067153a6dc1d73f7d4fd995a396ef32a24d24b8ac63ac8", size = 589127, upload-time = "2025-08-27T12:12:41.48Z" },
- { url = "https://files.pythonhosted.org/packages/c8/5e/26abb098d5e01266b0f3a2488d299d19ccc26849735d9d2b95c39397e945/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6f4461bf931108c9fa226ffb0e257c1b18dc2d44cd72b125bec50ee0ab1248a9", size = 554899, upload-time = "2025-08-27T12:12:42.925Z" },
- { url = "https://files.pythonhosted.org/packages/de/41/905cc90ced13550db017f8f20c6d8e8470066c5738ba480d7ba63e3d136b/rpds_py-0.27.1-cp310-cp310-win32.whl", hash = "sha256:ee5422d7fb21f6a00c1901bf6559c49fee13a5159d0288320737bbf6585bd3e4", size = 217450, upload-time = "2025-08-27T12:12:44.813Z" },
- { url = "https://files.pythonhosted.org/packages/75/3d/6bef47b0e253616ccdf67c283e25f2d16e18ccddd38f92af81d5a3420206/rpds_py-0.27.1-cp310-cp310-win_amd64.whl", hash = "sha256:3e039aabf6d5f83c745d5f9a0a381d031e9ed871967c0a5c38d201aca41f3ba1", size = 228447, upload-time = "2025-08-27T12:12:46.204Z" },
- { url = "https://files.pythonhosted.org/packages/b5/c1/7907329fbef97cbd49db6f7303893bd1dd5a4a3eae415839ffdfb0762cae/rpds_py-0.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:be898f271f851f68b318872ce6ebebbc62f303b654e43bf72683dbdc25b7c881", size = 371063, upload-time = "2025-08-27T12:12:47.856Z" },
- { url = "https://files.pythonhosted.org/packages/11/94/2aab4bc86228bcf7c48760990273653a4900de89c7537ffe1b0d6097ed39/rpds_py-0.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:62ac3d4e3e07b58ee0ddecd71d6ce3b1637de2d373501412df395a0ec5f9beb5", size = 353210, upload-time = "2025-08-27T12:12:49.187Z" },
- { url = "https://files.pythonhosted.org/packages/3a/57/f5eb3ecf434342f4f1a46009530e93fd201a0b5b83379034ebdb1d7c1a58/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4708c5c0ceb2d034f9991623631d3d23cb16e65c83736ea020cdbe28d57c0a0e", size = 381636, upload-time = "2025-08-27T12:12:50.492Z" },
- { url = "https://files.pythonhosted.org/packages/ae/f4/ef95c5945e2ceb5119571b184dd5a1cc4b8541bbdf67461998cfeac9cb1e/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abfa1171a9952d2e0002aba2ad3780820b00cc3d9c98c6630f2e93271501f66c", size = 394341, upload-time = "2025-08-27T12:12:52.024Z" },
- { url = "https://files.pythonhosted.org/packages/5a/7e/4bd610754bf492d398b61725eb9598ddd5eb86b07d7d9483dbcd810e20bc/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b507d19f817ebaca79574b16eb2ae412e5c0835542c93fe9983f1e432aca195", size = 523428, upload-time = "2025-08-27T12:12:53.779Z" },
- { url = "https://files.pythonhosted.org/packages/9f/e5/059b9f65a8c9149361a8b75094864ab83b94718344db511fd6117936ed2a/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168b025f8fd8d8d10957405f3fdcef3dc20f5982d398f90851f4abc58c566c52", size = 402923, upload-time = "2025-08-27T12:12:55.15Z" },
- { url = "https://files.pythonhosted.org/packages/f5/48/64cabb7daced2968dd08e8a1b7988bf358d7bd5bcd5dc89a652f4668543c/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb56c6210ef77caa58e16e8c17d35c63fe3f5b60fd9ba9d424470c3400bcf9ed", size = 384094, upload-time = "2025-08-27T12:12:57.194Z" },
- { url = "https://files.pythonhosted.org/packages/ae/e1/dc9094d6ff566bff87add8a510c89b9e158ad2ecd97ee26e677da29a9e1b/rpds_py-0.27.1-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:d252f2d8ca0195faa707f8eb9368955760880b2b42a8ee16d382bf5dd807f89a", size = 401093, upload-time = "2025-08-27T12:12:58.985Z" },
- { url = "https://files.pythonhosted.org/packages/37/8e/ac8577e3ecdd5593e283d46907d7011618994e1d7ab992711ae0f78b9937/rpds_py-0.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6e5e54da1e74b91dbc7996b56640f79b195d5925c2b78efaa8c5d53e1d88edde", size = 417969, upload-time = "2025-08-27T12:13:00.367Z" },
- { url = "https://files.pythonhosted.org/packages/66/6d/87507430a8f74a93556fe55c6485ba9c259949a853ce407b1e23fea5ba31/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ffce0481cc6e95e5b3f0a47ee17ffbd234399e6d532f394c8dce320c3b089c21", size = 558302, upload-time = "2025-08-27T12:13:01.737Z" },
- { url = "https://files.pythonhosted.org/packages/3a/bb/1db4781ce1dda3eecc735e3152659a27b90a02ca62bfeea17aee45cc0fbc/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a205fdfe55c90c2cd8e540ca9ceba65cbe6629b443bc05db1f590a3db8189ff9", size = 589259, upload-time = "2025-08-27T12:13:03.127Z" },
- { url = "https://files.pythonhosted.org/packages/7b/0e/ae1c8943d11a814d01b482e1f8da903f88047a962dff9bbdadf3bd6e6fd1/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:689fb5200a749db0415b092972e8eba85847c23885c8543a8b0f5c009b1a5948", size = 554983, upload-time = "2025-08-27T12:13:04.516Z" },
- { url = "https://files.pythonhosted.org/packages/b2/d5/0b2a55415931db4f112bdab072443ff76131b5ac4f4dc98d10d2d357eb03/rpds_py-0.27.1-cp311-cp311-win32.whl", hash = "sha256:3182af66048c00a075010bc7f4860f33913528a4b6fc09094a6e7598e462fe39", size = 217154, upload-time = "2025-08-27T12:13:06.278Z" },
- { url = "https://files.pythonhosted.org/packages/24/75/3b7ffe0d50dc86a6a964af0d1cc3a4a2cdf437cb7b099a4747bbb96d1819/rpds_py-0.27.1-cp311-cp311-win_amd64.whl", hash = "sha256:b4938466c6b257b2f5c4ff98acd8128ec36b5059e5c8f8372d79316b1c36bb15", size = 228627, upload-time = "2025-08-27T12:13:07.625Z" },
- { url = "https://files.pythonhosted.org/packages/8d/3f/4fd04c32abc02c710f09a72a30c9a55ea3cc154ef8099078fd50a0596f8e/rpds_py-0.27.1-cp311-cp311-win_arm64.whl", hash = "sha256:2f57af9b4d0793e53266ee4325535a31ba48e2f875da81a9177c9926dfa60746", size = 220998, upload-time = "2025-08-27T12:13:08.972Z" },
- { url = "https://files.pythonhosted.org/packages/bd/fe/38de28dee5df58b8198c743fe2bea0c785c6d40941b9950bac4cdb71a014/rpds_py-0.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90", size = 361887, upload-time = "2025-08-27T12:13:10.233Z" },
- { url = "https://files.pythonhosted.org/packages/7c/9a/4b6c7eedc7dd90986bf0fab6ea2a091ec11c01b15f8ba0a14d3f80450468/rpds_py-0.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5", size = 345795, upload-time = "2025-08-27T12:13:11.65Z" },
- { url = "https://files.pythonhosted.org/packages/6f/0e/e650e1b81922847a09cca820237b0edee69416a01268b7754d506ade11ad/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e", size = 385121, upload-time = "2025-08-27T12:13:13.008Z" },
- { url = "https://files.pythonhosted.org/packages/1b/ea/b306067a712988e2bff00dcc7c8f31d26c29b6d5931b461aa4b60a013e33/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881", size = 398976, upload-time = "2025-08-27T12:13:14.368Z" },
- { url = "https://files.pythonhosted.org/packages/2c/0a/26dc43c8840cb8fe239fe12dbc8d8de40f2365e838f3d395835dde72f0e5/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec", size = 525953, upload-time = "2025-08-27T12:13:15.774Z" },
- { url = "https://files.pythonhosted.org/packages/22/14/c85e8127b573aaf3a0cbd7fbb8c9c99e735a4a02180c84da2a463b766e9e/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb", size = 407915, upload-time = "2025-08-27T12:13:17.379Z" },
- { url = "https://files.pythonhosted.org/packages/ed/7b/8f4fee9ba1fb5ec856eb22d725a4efa3deb47f769597c809e03578b0f9d9/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5", size = 386883, upload-time = "2025-08-27T12:13:18.704Z" },
- { url = "https://files.pythonhosted.org/packages/86/47/28fa6d60f8b74fcdceba81b272f8d9836ac0340570f68f5df6b41838547b/rpds_py-0.27.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a", size = 405699, upload-time = "2025-08-27T12:13:20.089Z" },
- { url = "https://files.pythonhosted.org/packages/d0/fd/c5987b5e054548df56953a21fe2ebed51fc1ec7c8f24fd41c067b68c4a0a/rpds_py-0.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444", size = 423713, upload-time = "2025-08-27T12:13:21.436Z" },
- { url = "https://files.pythonhosted.org/packages/ac/ba/3c4978b54a73ed19a7d74531be37a8bcc542d917c770e14d372b8daea186/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a", size = 562324, upload-time = "2025-08-27T12:13:22.789Z" },
- { url = "https://files.pythonhosted.org/packages/b5/6c/6943a91768fec16db09a42b08644b960cff540c66aab89b74be6d4a144ba/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1", size = 593646, upload-time = "2025-08-27T12:13:24.122Z" },
- { url = "https://files.pythonhosted.org/packages/11/73/9d7a8f4be5f4396f011a6bb7a19fe26303a0dac9064462f5651ced2f572f/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998", size = 558137, upload-time = "2025-08-27T12:13:25.557Z" },
- { url = "https://files.pythonhosted.org/packages/6e/96/6772cbfa0e2485bcceef8071de7821f81aeac8bb45fbfd5542a3e8108165/rpds_py-0.27.1-cp312-cp312-win32.whl", hash = "sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39", size = 221343, upload-time = "2025-08-27T12:13:26.967Z" },
- { url = "https://files.pythonhosted.org/packages/67/b6/c82f0faa9af1c6a64669f73a17ee0eeef25aff30bb9a1c318509efe45d84/rpds_py-0.27.1-cp312-cp312-win_amd64.whl", hash = "sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594", size = 232497, upload-time = "2025-08-27T12:13:28.326Z" },
- { url = "https://files.pythonhosted.org/packages/e1/96/2817b44bd2ed11aebacc9251da03689d56109b9aba5e311297b6902136e2/rpds_py-0.27.1-cp312-cp312-win_arm64.whl", hash = "sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502", size = 222790, upload-time = "2025-08-27T12:13:29.71Z" },
- { url = "https://files.pythonhosted.org/packages/cc/77/610aeee8d41e39080c7e14afa5387138e3c9fa9756ab893d09d99e7d8e98/rpds_py-0.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e4b9fcfbc021633863a37e92571d6f91851fa656f0180246e84cbd8b3f6b329b", size = 361741, upload-time = "2025-08-27T12:13:31.039Z" },
- { url = "https://files.pythonhosted.org/packages/3a/fc/c43765f201c6a1c60be2043cbdb664013def52460a4c7adace89d6682bf4/rpds_py-0.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1441811a96eadca93c517d08df75de45e5ffe68aa3089924f963c782c4b898cf", size = 345574, upload-time = "2025-08-27T12:13:32.902Z" },
- { url = "https://files.pythonhosted.org/packages/20/42/ee2b2ca114294cd9847d0ef9c26d2b0851b2e7e00bf14cc4c0b581df0fc3/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55266dafa22e672f5a4f65019015f90336ed31c6383bd53f5e7826d21a0e0b83", size = 385051, upload-time = "2025-08-27T12:13:34.228Z" },
- { url = "https://files.pythonhosted.org/packages/fd/e8/1e430fe311e4799e02e2d1af7c765f024e95e17d651612425b226705f910/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78827d7ac08627ea2c8e02c9e5b41180ea5ea1f747e9db0915e3adf36b62dcf", size = 398395, upload-time = "2025-08-27T12:13:36.132Z" },
- { url = "https://files.pythonhosted.org/packages/82/95/9dc227d441ff2670651c27a739acb2535ccaf8b351a88d78c088965e5996/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae92443798a40a92dc5f0b01d8a7c93adde0c4dc965310a29ae7c64d72b9fad2", size = 524334, upload-time = "2025-08-27T12:13:37.562Z" },
- { url = "https://files.pythonhosted.org/packages/87/01/a670c232f401d9ad461d9a332aa4080cd3cb1d1df18213dbd0d2a6a7ab51/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c46c9dd2403b66a2a3b9720ec4b74d4ab49d4fabf9f03dfdce2d42af913fe8d0", size = 407691, upload-time = "2025-08-27T12:13:38.94Z" },
- { url = "https://files.pythonhosted.org/packages/03/36/0a14aebbaa26fe7fab4780c76f2239e76cc95a0090bdb25e31d95c492fcd/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2efe4eb1d01b7f5f1939f4ef30ecea6c6b3521eec451fb93191bf84b2a522418", size = 386868, upload-time = "2025-08-27T12:13:40.192Z" },
- { url = "https://files.pythonhosted.org/packages/3b/03/8c897fb8b5347ff6c1cc31239b9611c5bf79d78c984430887a353e1409a1/rpds_py-0.27.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:15d3b4d83582d10c601f481eca29c3f138d44c92187d197aff663a269197c02d", size = 405469, upload-time = "2025-08-27T12:13:41.496Z" },
- { url = "https://files.pythonhosted.org/packages/da/07/88c60edc2df74850d496d78a1fdcdc7b54360a7f610a4d50008309d41b94/rpds_py-0.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4ed2e16abbc982a169d30d1a420274a709949e2cbdef119fe2ec9d870b42f274", size = 422125, upload-time = "2025-08-27T12:13:42.802Z" },
- { url = "https://files.pythonhosted.org/packages/6b/86/5f4c707603e41b05f191a749984f390dabcbc467cf833769b47bf14ba04f/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a75f305c9b013289121ec0f1181931975df78738cdf650093e6b86d74aa7d8dd", size = 562341, upload-time = "2025-08-27T12:13:44.472Z" },
- { url = "https://files.pythonhosted.org/packages/b2/92/3c0cb2492094e3cd9baf9e49bbb7befeceb584ea0c1a8b5939dca4da12e5/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:67ce7620704745881a3d4b0ada80ab4d99df390838839921f99e63c474f82cf2", size = 592511, upload-time = "2025-08-27T12:13:45.898Z" },
- { url = "https://files.pythonhosted.org/packages/10/bb/82e64fbb0047c46a168faa28d0d45a7851cd0582f850b966811d30f67ad8/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d992ac10eb86d9b6f369647b6a3f412fc0075cfd5d799530e84d335e440a002", size = 557736, upload-time = "2025-08-27T12:13:47.408Z" },
- { url = "https://files.pythonhosted.org/packages/00/95/3c863973d409210da7fb41958172c6b7dbe7fc34e04d3cc1f10bb85e979f/rpds_py-0.27.1-cp313-cp313-win32.whl", hash = "sha256:4f75e4bd8ab8db624e02c8e2fc4063021b58becdbe6df793a8111d9343aec1e3", size = 221462, upload-time = "2025-08-27T12:13:48.742Z" },
- { url = "https://files.pythonhosted.org/packages/ce/2c/5867b14a81dc217b56d95a9f2a40fdbc56a1ab0181b80132beeecbd4b2d6/rpds_py-0.27.1-cp313-cp313-win_amd64.whl", hash = "sha256:f9025faafc62ed0b75a53e541895ca272815bec18abe2249ff6501c8f2e12b83", size = 232034, upload-time = "2025-08-27T12:13:50.11Z" },
- { url = "https://files.pythonhosted.org/packages/c7/78/3958f3f018c01923823f1e47f1cc338e398814b92d83cd278364446fac66/rpds_py-0.27.1-cp313-cp313-win_arm64.whl", hash = "sha256:ed10dc32829e7d222b7d3b93136d25a406ba9788f6a7ebf6809092da1f4d279d", size = 222392, upload-time = "2025-08-27T12:13:52.587Z" },
- { url = "https://files.pythonhosted.org/packages/01/76/1cdf1f91aed5c3a7bf2eba1f1c4e4d6f57832d73003919a20118870ea659/rpds_py-0.27.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:92022bbbad0d4426e616815b16bc4127f83c9a74940e1ccf3cfe0b387aba0228", size = 358355, upload-time = "2025-08-27T12:13:54.012Z" },
- { url = "https://files.pythonhosted.org/packages/c3/6f/bf142541229374287604caf3bb2a4ae17f0a580798fd72d3b009b532db4e/rpds_py-0.27.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47162fdab9407ec3f160805ac3e154df042e577dd53341745fc7fb3f625e6d92", size = 342138, upload-time = "2025-08-27T12:13:55.791Z" },
- { url = "https://files.pythonhosted.org/packages/1a/77/355b1c041d6be40886c44ff5e798b4e2769e497b790f0f7fd1e78d17e9a8/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb89bec23fddc489e5d78b550a7b773557c9ab58b7946154a10a6f7a214a48b2", size = 380247, upload-time = "2025-08-27T12:13:57.683Z" },
- { url = "https://files.pythonhosted.org/packages/d6/a4/d9cef5c3946ea271ce2243c51481971cd6e34f21925af2783dd17b26e815/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e48af21883ded2b3e9eb48cb7880ad8598b31ab752ff3be6457001d78f416723", size = 390699, upload-time = "2025-08-27T12:13:59.137Z" },
- { url = "https://files.pythonhosted.org/packages/3a/06/005106a7b8c6c1a7e91b73169e49870f4af5256119d34a361ae5240a0c1d/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f5b7bd8e219ed50299e58551a410b64daafb5017d54bbe822e003856f06a802", size = 521852, upload-time = "2025-08-27T12:14:00.583Z" },
- { url = "https://files.pythonhosted.org/packages/e5/3e/50fb1dac0948e17a02eb05c24510a8fe12d5ce8561c6b7b7d1339ab7ab9c/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08f1e20bccf73b08d12d804d6e1c22ca5530e71659e6673bce31a6bb71c1e73f", size = 402582, upload-time = "2025-08-27T12:14:02.034Z" },
- { url = "https://files.pythonhosted.org/packages/cb/b0/f4e224090dc5b0ec15f31a02d746ab24101dd430847c4d99123798661bfc/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dc5dceeaefcc96dc192e3a80bbe1d6c410c469e97bdd47494a7d930987f18b2", size = 384126, upload-time = "2025-08-27T12:14:03.437Z" },
- { url = "https://files.pythonhosted.org/packages/54/77/ac339d5f82b6afff1df8f0fe0d2145cc827992cb5f8eeb90fc9f31ef7a63/rpds_py-0.27.1-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d76f9cc8665acdc0c9177043746775aa7babbf479b5520b78ae4002d889f5c21", size = 399486, upload-time = "2025-08-27T12:14:05.443Z" },
- { url = "https://files.pythonhosted.org/packages/d6/29/3e1c255eee6ac358c056a57d6d6869baa00a62fa32eea5ee0632039c50a3/rpds_py-0.27.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:134fae0e36022edad8290a6661edf40c023562964efea0cc0ec7f5d392d2aaef", size = 414832, upload-time = "2025-08-27T12:14:06.902Z" },
- { url = "https://files.pythonhosted.org/packages/3f/db/6d498b844342deb3fa1d030598db93937a9964fcf5cb4da4feb5f17be34b/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb11a4f1b2b63337cfd3b4d110af778a59aae51c81d195768e353d8b52f88081", size = 557249, upload-time = "2025-08-27T12:14:08.37Z" },
- { url = "https://files.pythonhosted.org/packages/60/f3/690dd38e2310b6f68858a331399b4d6dbb9132c3e8ef8b4333b96caf403d/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:13e608ac9f50a0ed4faec0e90ece76ae33b34c0e8656e3dceb9a7db994c692cd", size = 587356, upload-time = "2025-08-27T12:14:10.034Z" },
- { url = "https://files.pythonhosted.org/packages/86/e3/84507781cccd0145f35b1dc32c72675200c5ce8d5b30f813e49424ef68fc/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dd2135527aa40f061350c3f8f89da2644de26cd73e4de458e79606384f4f68e7", size = 555300, upload-time = "2025-08-27T12:14:11.783Z" },
- { url = "https://files.pythonhosted.org/packages/e5/ee/375469849e6b429b3516206b4580a79e9ef3eb12920ddbd4492b56eaacbe/rpds_py-0.27.1-cp313-cp313t-win32.whl", hash = "sha256:3020724ade63fe320a972e2ffd93b5623227e684315adce194941167fee02688", size = 216714, upload-time = "2025-08-27T12:14:13.629Z" },
- { url = "https://files.pythonhosted.org/packages/21/87/3fc94e47c9bd0742660e84706c311a860dcae4374cf4a03c477e23ce605a/rpds_py-0.27.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8ee50c3e41739886606388ba3ab3ee2aae9f35fb23f833091833255a31740797", size = 228943, upload-time = "2025-08-27T12:14:14.937Z" },
- { url = "https://files.pythonhosted.org/packages/7f/6c/252e83e1ce7583c81f26d1d884b2074d40a13977e1b6c9c50bbf9a7f1f5a/rpds_py-0.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c918c65ec2e42c2a78d19f18c553d77319119bf43aa9e2edf7fb78d624355527", size = 372140, upload-time = "2025-08-27T12:15:05.441Z" },
- { url = "https://files.pythonhosted.org/packages/9d/71/949c195d927c5aeb0d0629d329a20de43a64c423a6aa53836290609ef7ec/rpds_py-0.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1fea2b1a922c47c51fd07d656324531adc787e415c8b116530a1d29c0516c62d", size = 354086, upload-time = "2025-08-27T12:15:07.404Z" },
- { url = "https://files.pythonhosted.org/packages/9f/02/e43e332ad8ce4f6c4342d151a471a7f2900ed1d76901da62eb3762663a71/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbf94c58e8e0cd6b6f38d8de67acae41b3a515c26169366ab58bdca4a6883bb8", size = 382117, upload-time = "2025-08-27T12:15:09.275Z" },
- { url = "https://files.pythonhosted.org/packages/d0/05/b0fdeb5b577197ad72812bbdfb72f9a08fa1e64539cc3940b1b781cd3596/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c2a8fed130ce946d5c585eddc7c8eeef0051f58ac80a8ee43bd17835c144c2cc", size = 394520, upload-time = "2025-08-27T12:15:10.727Z" },
- { url = "https://files.pythonhosted.org/packages/67/1f/4cfef98b2349a7585181e99294fa2a13f0af06902048a5d70f431a66d0b9/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:037a2361db72ee98d829bc2c5b7cc55598ae0a5e0ec1823a56ea99374cfd73c1", size = 522657, upload-time = "2025-08-27T12:15:12.613Z" },
- { url = "https://files.pythonhosted.org/packages/44/55/ccf37ddc4c6dce7437b335088b5ca18da864b334890e2fe9aa6ddc3f79a9/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5281ed1cc1d49882f9997981c88df1a22e140ab41df19071222f7e5fc4e72125", size = 402967, upload-time = "2025-08-27T12:15:14.113Z" },
- { url = "https://files.pythonhosted.org/packages/74/e5/5903f92e41e293b07707d5bf00ef39a0eb2af7190aff4beaf581a6591510/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fd50659a069c15eef8aa3d64bbef0d69fd27bb4a50c9ab4f17f83a16cbf8905", size = 384372, upload-time = "2025-08-27T12:15:15.842Z" },
- { url = "https://files.pythonhosted.org/packages/8f/e3/fbb409e18aeefc01e49f5922ac63d2d914328430e295c12183ce56ebf76b/rpds_py-0.27.1-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:c4b676c4ae3921649a15d28ed10025548e9b561ded473aa413af749503c6737e", size = 401264, upload-time = "2025-08-27T12:15:17.388Z" },
- { url = "https://files.pythonhosted.org/packages/55/79/529ad07794e05cb0f38e2f965fc5bb20853d523976719400acecc447ec9d/rpds_py-0.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:079bc583a26db831a985c5257797b2b5d3affb0386e7ff886256762f82113b5e", size = 418691, upload-time = "2025-08-27T12:15:19.144Z" },
- { url = "https://files.pythonhosted.org/packages/33/39/6554a7fd6d9906fda2521c6d52f5d723dca123529fb719a5b5e074c15e01/rpds_py-0.27.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4e44099bd522cba71a2c6b97f68e19f40e7d85399de899d66cdb67b32d7cb786", size = 558989, upload-time = "2025-08-27T12:15:21.087Z" },
- { url = "https://files.pythonhosted.org/packages/19/b2/76fa15173b6f9f445e5ef15120871b945fb8dd9044b6b8c7abe87e938416/rpds_py-0.27.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e202e6d4188e53c6661af813b46c37ca2c45e497fc558bacc1a7630ec2695aec", size = 589835, upload-time = "2025-08-27T12:15:22.696Z" },
- { url = "https://files.pythonhosted.org/packages/ee/9e/5560a4b39bab780405bed8a88ee85b30178061d189558a86003548dea045/rpds_py-0.27.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f41f814b8eaa48768d1bb551591f6ba45f87ac76899453e8ccd41dba1289b04b", size = 555227, upload-time = "2025-08-27T12:15:24.278Z" },
- { url = "https://files.pythonhosted.org/packages/52/d7/cd9c36215111aa65724c132bf709c6f35175973e90b32115dedc4ced09cb/rpds_py-0.27.1-cp39-cp39-win32.whl", hash = "sha256:9e71f5a087ead99563c11fdaceee83ee982fd39cf67601f4fd66cb386336ee52", size = 217899, upload-time = "2025-08-27T12:15:25.926Z" },
- { url = "https://files.pythonhosted.org/packages/5b/e0/d75ab7b4dd8ba777f6b365adbdfc7614bbfe7c5f05703031dfa4b61c3d6c/rpds_py-0.27.1-cp39-cp39-win_amd64.whl", hash = "sha256:71108900c9c3c8590697244b9519017a400d9ba26a36c48381b3f64743a44aab", size = 228725, upload-time = "2025-08-27T12:15:27.398Z" },
- { url = "https://files.pythonhosted.org/packages/d5/63/b7cc415c345625d5e62f694ea356c58fb964861409008118f1245f8c3347/rpds_py-0.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7ba22cb9693df986033b91ae1d7a979bc399237d45fccf875b76f62bb9e52ddf", size = 371360, upload-time = "2025-08-27T12:15:29.218Z" },
- { url = "https://files.pythonhosted.org/packages/e5/8c/12e1b24b560cf378b8ffbdb9dc73abd529e1adcfcf82727dfd29c4a7b88d/rpds_py-0.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b640501be9288c77738b5492b3fd3abc4ba95c50c2e41273c8a1459f08298d3", size = 353933, upload-time = "2025-08-27T12:15:30.837Z" },
- { url = "https://files.pythonhosted.org/packages/9b/85/1bb2210c1f7a1b99e91fea486b9f0f894aa5da3a5ec7097cbad7dec6d40f/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb08b65b93e0c6dd70aac7f7890a9c0938d5ec71d5cb32d45cf844fb8ae47636", size = 382962, upload-time = "2025-08-27T12:15:32.348Z" },
- { url = "https://files.pythonhosted.org/packages/cc/c9/a839b9f219cf80ed65f27a7f5ddbb2809c1b85c966020ae2dff490e0b18e/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d7ff07d696a7a38152ebdb8212ca9e5baab56656749f3d6004b34ab726b550b8", size = 394412, upload-time = "2025-08-27T12:15:33.839Z" },
- { url = "https://files.pythonhosted.org/packages/02/2d/b1d7f928b0b1f4fc2e0133e8051d199b01d7384875adc63b6ddadf3de7e5/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb7c72262deae25366e3b6c0c0ba46007967aea15d1eea746e44ddba8ec58dcc", size = 523972, upload-time = "2025-08-27T12:15:35.377Z" },
- { url = "https://files.pythonhosted.org/packages/a9/af/2cbf56edd2d07716df1aec8a726b3159deb47cb5c27e1e42b71d705a7c2f/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b002cab05d6339716b03a4a3a2ce26737f6231d7b523f339fa061d53368c9d8", size = 403273, upload-time = "2025-08-27T12:15:37.051Z" },
- { url = "https://files.pythonhosted.org/packages/c0/93/425e32200158d44ff01da5d9612c3b6711fe69f606f06e3895511f17473b/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23f6b69d1c26c4704fec01311963a41d7de3ee0570a84ebde4d544e5a1859ffc", size = 385278, upload-time = "2025-08-27T12:15:38.571Z" },
- { url = "https://files.pythonhosted.org/packages/eb/1a/1a04a915ecd0551bfa9e77b7672d1937b4b72a0fc204a17deef76001cfb2/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:530064db9146b247351f2a0250b8f00b289accea4596a033e94be2389977de71", size = 402084, upload-time = "2025-08-27T12:15:40.529Z" },
- { url = "https://files.pythonhosted.org/packages/51/f7/66585c0fe5714368b62951d2513b684e5215beaceab2c6629549ddb15036/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b90b0496570bd6b0321724a330d8b545827c4df2034b6ddfc5f5275f55da2ad", size = 419041, upload-time = "2025-08-27T12:15:42.191Z" },
- { url = "https://files.pythonhosted.org/packages/8e/7e/83a508f6b8e219bba2d4af077c35ba0e0cdd35a751a3be6a7cba5a55ad71/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:879b0e14a2da6a1102a3fc8af580fc1ead37e6d6692a781bd8c83da37429b5ab", size = 560084, upload-time = "2025-08-27T12:15:43.839Z" },
- { url = "https://files.pythonhosted.org/packages/66/66/bb945683b958a1b19eb0fe715594630d0f36396ebdef4d9b89c2fa09aa56/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:0d807710df3b5faa66c731afa162ea29717ab3be17bdc15f90f2d9f183da4059", size = 590115, upload-time = "2025-08-27T12:15:46.647Z" },
- { url = "https://files.pythonhosted.org/packages/12/00/ccfaafaf7db7e7adace915e5c2f2c2410e16402561801e9c7f96683002d3/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:3adc388fc3afb6540aec081fa59e6e0d3908722771aa1e37ffe22b220a436f0b", size = 556561, upload-time = "2025-08-27T12:15:48.219Z" },
- { url = "https://files.pythonhosted.org/packages/e1/b7/92b6ed9aad103bfe1c45df98453dfae40969eef2cb6c6239c58d7e96f1b3/rpds_py-0.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c796c0c1cc68cb08b0284db4229f5af76168172670c74908fdbd4b7d7f515819", size = 229125, upload-time = "2025-08-27T12:15:49.956Z" },
- { url = "https://files.pythonhosted.org/packages/0c/ed/e1fba02de17f4f76318b834425257c8ea297e415e12c68b4361f63e8ae92/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cdfe4bb2f9fe7458b7453ad3c33e726d6d1c7c0a72960bcc23800d77384e42df", size = 371402, upload-time = "2025-08-27T12:15:51.561Z" },
- { url = "https://files.pythonhosted.org/packages/af/7c/e16b959b316048b55585a697e94add55a4ae0d984434d279ea83442e460d/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8fabb8fd848a5f75a2324e4a84501ee3a5e3c78d8603f83475441866e60b94a3", size = 354084, upload-time = "2025-08-27T12:15:53.219Z" },
- { url = "https://files.pythonhosted.org/packages/de/c1/ade645f55de76799fdd08682d51ae6724cb46f318573f18be49b1e040428/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda8719d598f2f7f3e0f885cba8646644b55a187762bec091fa14a2b819746a9", size = 383090, upload-time = "2025-08-27T12:15:55.158Z" },
- { url = "https://files.pythonhosted.org/packages/1f/27/89070ca9b856e52960da1472efcb6c20ba27cfe902f4f23ed095b9cfc61d/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c64d07e95606ec402a0a1c511fe003873fa6af630bda59bac77fac8b4318ebc", size = 394519, upload-time = "2025-08-27T12:15:57.238Z" },
- { url = "https://files.pythonhosted.org/packages/b3/28/be120586874ef906aa5aeeae95ae8df4184bc757e5b6bd1c729ccff45ed5/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93a2ed40de81bcff59aabebb626562d48332f3d028ca2036f1d23cbb52750be4", size = 523817, upload-time = "2025-08-27T12:15:59.237Z" },
- { url = "https://files.pythonhosted.org/packages/a8/ef/70cc197bc11cfcde02a86f36ac1eed15c56667c2ebddbdb76a47e90306da/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:387ce8c44ae94e0ec50532d9cb0edce17311024c9794eb196b90e1058aadeb66", size = 403240, upload-time = "2025-08-27T12:16:00.923Z" },
- { url = "https://files.pythonhosted.org/packages/cf/35/46936cca449f7f518f2f4996e0e8344db4b57e2081e752441154089d2a5f/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf94f812c95b5e60ebaf8bfb1898a7d7cb9c1af5744d4a67fa47796e0465d4e", size = 385194, upload-time = "2025-08-27T12:16:02.802Z" },
- { url = "https://files.pythonhosted.org/packages/e1/62/29c0d3e5125c3270b51415af7cbff1ec587379c84f55a5761cc9efa8cd06/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4848ca84d6ded9b58e474dfdbad4b8bfb450344c0551ddc8d958bf4b36aa837c", size = 402086, upload-time = "2025-08-27T12:16:04.806Z" },
- { url = "https://files.pythonhosted.org/packages/8f/66/03e1087679227785474466fdd04157fb793b3b76e3fcf01cbf4c693c1949/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bde09cbcf2248b73c7c323be49b280180ff39fadcfe04e7b6f54a678d02a7cf", size = 419272, upload-time = "2025-08-27T12:16:06.471Z" },
- { url = "https://files.pythonhosted.org/packages/6a/24/e3e72d265121e00b063aef3e3501e5b2473cf1b23511d56e529531acf01e/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:94c44ee01fd21c9058f124d2d4f0c9dc7634bec93cd4b38eefc385dabe71acbf", size = 560003, upload-time = "2025-08-27T12:16:08.06Z" },
- { url = "https://files.pythonhosted.org/packages/26/ca/f5a344c534214cc2d41118c0699fffbdc2c1bc7046f2a2b9609765ab9c92/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:df8b74962e35c9249425d90144e721eed198e6555a0e22a563d29fe4486b51f6", size = 590482, upload-time = "2025-08-27T12:16:10.137Z" },
- { url = "https://files.pythonhosted.org/packages/ce/08/4349bdd5c64d9d193c360aa9db89adeee6f6682ab8825dca0a3f535f434f/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:dc23e6820e3b40847e2f4a7726462ba0cf53089512abe9ee16318c366494c17a", size = 556523, upload-time = "2025-08-27T12:16:12.188Z" },
- { url = "https://files.pythonhosted.org/packages/4e/ea/5463cd5048a7a2fcdae308b6e96432802132c141bfb9420260142632a0f1/rpds_py-0.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:aa8933159edc50be265ed22b401125c9eebff3171f570258854dbce3ecd55475", size = 371778, upload-time = "2025-08-27T12:16:13.851Z" },
- { url = "https://files.pythonhosted.org/packages/0d/c8/f38c099db07f5114029c1467649d308543906933eebbc226d4527a5f4693/rpds_py-0.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a50431bf02583e21bf273c71b89d710e7a710ad5e39c725b14e685610555926f", size = 354394, upload-time = "2025-08-27T12:16:15.609Z" },
- { url = "https://files.pythonhosted.org/packages/7d/79/b76f97704d9dd8ddbd76fed4c4048153a847c5d6003afe20a6b5c3339065/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78af06ddc7fe5cc0e967085a9115accee665fb912c22a3f54bad70cc65b05fe6", size = 382348, upload-time = "2025-08-27T12:16:17.251Z" },
- { url = "https://files.pythonhosted.org/packages/8a/3f/ef23d3c1be1b837b648a3016d5bbe7cfe711422ad110b4081c0a90ef5a53/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:70d0738ef8fee13c003b100c2fbd667ec4f133468109b3472d249231108283a3", size = 394159, upload-time = "2025-08-27T12:16:19.251Z" },
- { url = "https://files.pythonhosted.org/packages/74/8a/9e62693af1a34fd28b1a190d463d12407bd7cf561748cb4745845d9548d3/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2f6fd8a1cea5bbe599b6e78a6e5ee08db434fc8ffea51ff201c8765679698b3", size = 522775, upload-time = "2025-08-27T12:16:20.929Z" },
- { url = "https://files.pythonhosted.org/packages/36/0d/8d5bb122bf7a60976b54c5c99a739a3819f49f02d69df3ea2ca2aff47d5c/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8177002868d1426305bb5de1e138161c2ec9eb2d939be38291d7c431c4712df8", size = 402633, upload-time = "2025-08-27T12:16:22.548Z" },
- { url = "https://files.pythonhosted.org/packages/0f/0e/237948c1f425e23e0cf5a566d702652a6e55c6f8fbd332a1792eb7043daf/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:008b839781d6c9bf3b6a8984d1d8e56f0ec46dc56df61fd669c49b58ae800400", size = 384867, upload-time = "2025-08-27T12:16:24.29Z" },
- { url = "https://files.pythonhosted.org/packages/d6/0a/da0813efcd998d260cbe876d97f55b0f469ada8ba9cbc47490a132554540/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:a55b9132bb1ade6c734ddd2759c8dc132aa63687d259e725221f106b83a0e485", size = 401791, upload-time = "2025-08-27T12:16:25.954Z" },
- { url = "https://files.pythonhosted.org/packages/51/78/c6c9e8a8aaca416a6f0d1b6b4a6ee35b88fe2c5401d02235d0a056eceed2/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a46fdec0083a26415f11d5f236b79fa1291c32aaa4a17684d82f7017a1f818b1", size = 419525, upload-time = "2025-08-27T12:16:27.659Z" },
- { url = "https://files.pythonhosted.org/packages/a3/69/5af37e1d71487cf6d56dd1420dc7e0c2732c1b6ff612aa7a88374061c0a8/rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:8a63b640a7845f2bdd232eb0d0a4a2dd939bcdd6c57e6bb134526487f3160ec5", size = 559255, upload-time = "2025-08-27T12:16:29.343Z" },
- { url = "https://files.pythonhosted.org/packages/40/7f/8b7b136069ef7ac3960eda25d832639bdb163018a34c960ed042dd1707c8/rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:7e32721e5d4922deaaf963469d795d5bde6093207c52fec719bd22e5d1bedbc4", size = 590384, upload-time = "2025-08-27T12:16:31.005Z" },
- { url = "https://files.pythonhosted.org/packages/d8/06/c316d3f6ff03f43ccb0eba7de61376f8ec4ea850067dddfafe98274ae13c/rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:2c426b99a068601b5f4623573df7a7c3d72e87533a2dd2253353a03e7502566c", size = 555959, upload-time = "2025-08-27T12:16:32.73Z" },
- { url = "https://files.pythonhosted.org/packages/60/94/384cf54c430b9dac742bbd2ec26c23feb78ded0d43d6d78563a281aec017/rpds_py-0.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4fc9b7fe29478824361ead6e14e4f5aed570d477e06088826537e202d25fe859", size = 228784, upload-time = "2025-08-27T12:16:34.428Z" },
-]
-
[[package]]
name = "rpds-py"
version = "0.28.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.13'",
- "python_full_version == '3.12.*'",
- "python_full_version == '3.11.*'",
- "python_full_version == '3.10.*'",
-]
sdist = { url = "https://files.pythonhosted.org/packages/48/dc/95f074d43452b3ef5d06276696ece4b3b5d696e7c9ad7173c54b1390cd70/rpds_py-0.28.0.tar.gz", hash = "sha256:abd4df20485a0983e2ca334a216249b6186d6e3c1627e106651943dbdb791aea", size = 27419, upload-time = "2025-10-22T22:24:29.327Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/82/f8/13bb772dc7cbf2c3c5b816febc34fa0cb2c64a08e0569869585684ce6631/rpds_py-0.28.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7b6013db815417eeb56b2d9d7324e64fcd4fa289caeee6e7a78b2e11fc9b438a", size = 362820, upload-time = "2025-10-22T22:21:15.074Z" },
@@ -3105,41 +2411,32 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/3d/ac/3c5c2b27a183f4fda8a57c82211721c016bcb689a4a175865f7646db9f94/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b30110b29484adc597df6bd92a37b90e63a8c152ca8136aad100a02f8ba6d1b6", size = 765196, upload-time = "2025-09-22T19:51:05.916Z" },
{ url = "https://files.pythonhosted.org/packages/92/2e/06f56a71fd55021c993ed6e848c9b2e5e9cfce180a42179f0ddd28253f7c/ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl", hash = "sha256:f4e97a1cf0b7a30af9e1d9dad10a5671157b9acee790d9e26996391f49b965a2", size = 98635, upload-time = "2025-09-22T19:51:08.183Z" },
{ url = "https://files.pythonhosted.org/packages/51/79/76aba16a1689b50528224b182f71097ece338e7a4ab55e84c2e73443b78a/ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl", hash = "sha256:090782b5fb9d98df96509eecdbcaffd037d47389a89492320280d52f91330d78", size = 115238, upload-time = "2025-09-22T19:51:07.081Z" },
- { url = "https://files.pythonhosted.org/packages/2a/a0/e709dc2f58054049cd154319a7d37917689785b12ec43ea2df47ea5344ef/ruamel.yaml.clib-0.2.14-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:18c041b28f3456ddef1f1951d4492dbebe0f8114157c1b3c981a4611c2020792", size = 270636, upload-time = "2025-09-23T14:24:17.855Z" },
- { url = "https://files.pythonhosted.org/packages/18/81/491c9e394976e10682a596f2b785ba7066db525cc17f267005ae8ca33c73/ruamel.yaml.clib-0.2.14-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:d8354515ab62f95a07deaf7f845886cc50e2f345ceab240a3d2d09a9f7d77853", size = 137954, upload-time = "2025-09-22T19:51:12.851Z" },
- { url = "https://files.pythonhosted.org/packages/ad/a5/c6d1c767e051bbc00146a93132bf199b3e6ec2c219131b9d3e19eff428f3/ruamel.yaml.clib-0.2.14-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:275f938692013a3883edbd848edde6d9f26825d65c9a2eb1db8baa1adc96a05d", size = 636162, upload-time = "2025-09-22T19:51:16.823Z" },
- { url = "https://files.pythonhosted.org/packages/e3/6f/4746e2e8f60b3489b6cd6fad96a8e2aaa0cf7dd6760de3daad1a6e9f5789/ruamel.yaml.clib-0.2.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16a60d69f4057ad9a92f3444e2367c08490daed6428291aa16cefb445c29b0e9", size = 723934, upload-time = "2025-09-22T19:51:13.948Z" },
- { url = "https://files.pythonhosted.org/packages/26/47/5446e8cea2f6b5391fba653196f38b3f14030c1c324bd9aa67f1773d24ec/ruamel.yaml.clib-0.2.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ac5ff9425d8acb8f59ac5b96bcb7fd3d272dc92d96a7c730025928ffcc88a7a", size = 686265, upload-time = "2025-09-22T19:51:15.142Z" },
- { url = "https://files.pythonhosted.org/packages/52/d7/344d7b3010b6a01af97431bdf89056abb2d8bd704d0f3430e7b50232cce4/ruamel.yaml.clib-0.2.14-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e1d1735d97fd8a48473af048739379975651fab186f8a25a9f683534e6904179", size = 693042, upload-time = "2025-09-23T18:42:53.238Z" },
- { url = "https://files.pythonhosted.org/packages/b3/d5/a0f2cce1b6cfa9bf1921b8a19ebceafc7a9b3c27882e5af5a07ae080b1bd/ruamel.yaml.clib-0.2.14-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:83bbd8354f6abb3fdfb922d1ed47ad8d1db3ea72b0523dac8d07cdacfe1c0fcf", size = 706110, upload-time = "2025-09-22T19:51:18.467Z" },
- { url = "https://files.pythonhosted.org/packages/42/cd/85b422d24ee2096eaf6faa360c95ef9bdb59097d19b9624cebce4dd9bc2a/ruamel.yaml.clib-0.2.14-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:808c7190a0fe7ae7014c42f73897cf8e9ef14ff3aa533450e51b1e72ec5239ad", size = 725028, upload-time = "2025-09-22T19:51:19.782Z" },
- { url = "https://files.pythonhosted.org/packages/4d/ac/99e6e0ea2584f84f447069d0187fe411e9b5deb7e3ddecda25001cfc7a95/ruamel.yaml.clib-0.2.14-cp39-cp39-win32.whl", hash = "sha256:6d5472f63a31b042aadf5ed28dd3ef0523da49ac17f0463e10fda9c4a2773352", size = 100915, upload-time = "2025-09-22T19:51:21.764Z" },
- { url = "https://files.pythonhosted.org/packages/5d/8d/846e43369658958c99d959bb7774136fff9210f9017d91a4277818ceafbf/ruamel.yaml.clib-0.2.14-cp39-cp39-win_amd64.whl", hash = "sha256:8dd3c2cc49caa7a8d64b67146462aed6723a0495e44bf0aa0a2e94beaa8432f6", size = 118706, upload-time = "2025-09-22T19:51:20.878Z" },
]
[[package]]
name = "ruff"
-version = "0.11.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/77/2b/7ca27e854d92df5e681e6527dc0f9254c9dc06c8408317893cf96c851cdd/ruff-0.11.0.tar.gz", hash = "sha256:e55c620690a4a7ee6f1cccb256ec2157dc597d109400ae75bbf944fc9d6462e2", size = 3799407, upload-time = "2025-03-14T13:52:36.539Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/48/40/3d0340a9e5edc77d37852c0cd98c5985a5a8081fc3befaeb2ae90aaafd2b/ruff-0.11.0-py3-none-linux_armv6l.whl", hash = "sha256:dc67e32bc3b29557513eb7eeabb23efdb25753684b913bebb8a0c62495095acb", size = 10098158, upload-time = "2025-03-14T13:51:55.69Z" },
- { url = "https://files.pythonhosted.org/packages/ec/a9/d8f5abb3b87b973b007649ac7bf63665a05b2ae2b2af39217b09f52abbbf/ruff-0.11.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:38c23fd9bdec4eb437b4c1e3595905a0a8edfccd63a790f818b28c78fe345639", size = 10879071, upload-time = "2025-03-14T13:51:58.989Z" },
- { url = "https://files.pythonhosted.org/packages/ab/62/aaa198614c6211677913ec480415c5e6509586d7b796356cec73a2f8a3e6/ruff-0.11.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7c8661b0be91a38bd56db593e9331beaf9064a79028adee2d5f392674bbc5e88", size = 10247944, upload-time = "2025-03-14T13:52:02.318Z" },
- { url = "https://files.pythonhosted.org/packages/9f/52/59e0a9f2cf1ce5e6cbe336b6dd0144725c8ea3b97cac60688f4e7880bf13/ruff-0.11.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6c0e8d3d2db7e9f6efd884f44b8dc542d5b6b590fc4bb334fdbc624d93a29a2", size = 10421725, upload-time = "2025-03-14T13:52:04.303Z" },
- { url = "https://files.pythonhosted.org/packages/a6/c3/dcd71acc6dff72ce66d13f4be5bca1dbed4db678dff2f0f6f307b04e5c02/ruff-0.11.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c3156d3f4b42e57247275a0a7e15a851c165a4fc89c5e8fa30ea6da4f7407b8", size = 9954435, upload-time = "2025-03-14T13:52:06.602Z" },
- { url = "https://files.pythonhosted.org/packages/a6/9a/342d336c7c52dbd136dee97d4c7797e66c3f92df804f8f3b30da59b92e9c/ruff-0.11.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:490b1e147c1260545f6d041c4092483e3f6d8eba81dc2875eaebcf9140b53905", size = 11492664, upload-time = "2025-03-14T13:52:08.613Z" },
- { url = "https://files.pythonhosted.org/packages/84/35/6e7defd2d7ca95cc385ac1bd9f7f2e4a61b9cc35d60a263aebc8e590c462/ruff-0.11.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1bc09a7419e09662983b1312f6fa5dab829d6ab5d11f18c3760be7ca521c9329", size = 12207856, upload-time = "2025-03-14T13:52:11.019Z" },
- { url = "https://files.pythonhosted.org/packages/22/78/da669c8731bacf40001c880ada6d31bcfb81f89cc996230c3b80d319993e/ruff-0.11.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcfa478daf61ac8002214eb2ca5f3e9365048506a9d52b11bea3ecea822bb844", size = 11645156, upload-time = "2025-03-14T13:52:13.383Z" },
- { url = "https://files.pythonhosted.org/packages/ee/47/e27d17d83530a208f4a9ab2e94f758574a04c51e492aa58f91a3ed7cbbcb/ruff-0.11.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6fbb2aed66fe742a6a3a0075ed467a459b7cedc5ae01008340075909d819df1e", size = 13884167, upload-time = "2025-03-14T13:52:15.528Z" },
- { url = "https://files.pythonhosted.org/packages/9f/5e/42ffbb0a5d4b07bbc642b7d58357b4e19a0f4774275ca6ca7d1f7b5452cd/ruff-0.11.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92c0c1ff014351c0b0cdfdb1e35fa83b780f1e065667167bb9502d47ca41e6db", size = 11348311, upload-time = "2025-03-14T13:52:18.088Z" },
- { url = "https://files.pythonhosted.org/packages/c8/51/dc3ce0c5ce1a586727a3444a32f98b83ba99599bb1ebca29d9302886e87f/ruff-0.11.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e4fd5ff5de5f83e0458a138e8a869c7c5e907541aec32b707f57cf9a5e124445", size = 10305039, upload-time = "2025-03-14T13:52:20.476Z" },
- { url = "https://files.pythonhosted.org/packages/60/e0/475f0c2f26280f46f2d6d1df1ba96b3399e0234cf368cc4c88e6ad10dcd9/ruff-0.11.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:96bc89a5c5fd21a04939773f9e0e276308be0935de06845110f43fd5c2e4ead7", size = 9937939, upload-time = "2025-03-14T13:52:22.798Z" },
- { url = "https://files.pythonhosted.org/packages/e2/d3/3e61b7fd3e9cdd1e5b8c7ac188bec12975c824e51c5cd3d64caf81b0331e/ruff-0.11.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a9352b9d767889ec5df1483f94870564e8102d4d7e99da52ebf564b882cdc2c7", size = 10923259, upload-time = "2025-03-14T13:52:24.89Z" },
- { url = "https://files.pythonhosted.org/packages/30/32/cd74149ebb40b62ddd14bd2d1842149aeb7f74191fb0f49bd45c76909ff2/ruff-0.11.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:049a191969a10897fe052ef9cc7491b3ef6de79acd7790af7d7897b7a9bfbcb6", size = 11406212, upload-time = "2025-03-14T13:52:27.493Z" },
- { url = "https://files.pythonhosted.org/packages/00/ef/033022a6b104be32e899b00de704d7c6d1723a54d4c9e09d147368f14b62/ruff-0.11.0-py3-none-win32.whl", hash = "sha256:3191e9116b6b5bbe187447656f0c8526f0d36b6fd89ad78ccaad6bdc2fad7df2", size = 10310905, upload-time = "2025-03-14T13:52:30.46Z" },
- { url = "https://files.pythonhosted.org/packages/ed/8a/163f2e78c37757d035bd56cd60c8d96312904ca4a6deeab8442d7b3cbf89/ruff-0.11.0-py3-none-win_amd64.whl", hash = "sha256:c58bfa00e740ca0a6c43d41fb004cd22d165302f360aaa56f7126d544db31a21", size = 11411730, upload-time = "2025-03-14T13:52:32.508Z" },
- { url = "https://files.pythonhosted.org/packages/4e/f7/096f6efabe69b49d7ca61052fc70289c05d8d35735c137ef5ba5ef423662/ruff-0.11.0-py3-none-win_arm64.whl", hash = "sha256:868364fc23f5aa122b00c6f794211e85f7e78f5dffdf7c590ab90b8c4e69b657", size = 10538956, upload-time = "2025-03-14T13:52:34.491Z" },
+version = "0.14.5"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/82/fa/fbb67a5780ae0f704876cb8ac92d6d76da41da4dc72b7ed3565ab18f2f52/ruff-0.14.5.tar.gz", hash = "sha256:8d3b48d7d8aad423d3137af7ab6c8b1e38e4de104800f0d596990f6ada1a9fc1", size = 5615944, upload-time = "2025-11-13T19:58:51.155Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/68/31/c07e9c535248d10836a94e4f4e8c5a31a1beed6f169b31405b227872d4f4/ruff-0.14.5-py3-none-linux_armv6l.whl", hash = "sha256:f3b8248123b586de44a8018bcc9fefe31d23dda57a34e6f0e1e53bd51fd63594", size = 13171630, upload-time = "2025-11-13T19:57:54.894Z" },
+ { url = "https://files.pythonhosted.org/packages/8e/5c/283c62516dca697cd604c2796d1487396b7a436b2f0ecc3fd412aca470e0/ruff-0.14.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f7a75236570318c7a30edd7f5491945f0169de738d945ca8784500b517163a72", size = 13413925, upload-time = "2025-11-13T19:57:59.181Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/f3/aa319f4afc22cb6fcba2b9cdfc0f03bbf747e59ab7a8c5e90173857a1361/ruff-0.14.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6d146132d1ee115f8802356a2dc9a634dbf58184c51bff21f313e8cd1c74899a", size = 12574040, upload-time = "2025-11-13T19:58:02.056Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/7f/cb5845fcc7c7e88ed57f58670189fc2ff517fe2134c3821e77e29fd3b0c8/ruff-0.14.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2380596653dcd20b057794d55681571a257a42327da8894b93bbd6111aa801f", size = 13009755, upload-time = "2025-11-13T19:58:05.172Z" },
+ { url = "https://files.pythonhosted.org/packages/21/d2/bcbedbb6bcb9253085981730687ddc0cc7b2e18e8dc13cf4453de905d7a0/ruff-0.14.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d1fa985a42b1f075a098fa1ab9d472b712bdb17ad87a8ec86e45e7fa6273e68", size = 12937641, upload-time = "2025-11-13T19:58:08.345Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/58/e25de28a572bdd60ffc6bb71fc7fd25a94ec6a076942e372437649cbb02a/ruff-0.14.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88f0770d42b7fa02bbefddde15d235ca3aa24e2f0137388cc15b2dcbb1f7c7a7", size = 13610854, upload-time = "2025-11-13T19:58:11.419Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/24/43bb3fd23ecee9861970978ea1a7a63e12a204d319248a7e8af539984280/ruff-0.14.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3676cb02b9061fee7294661071c4709fa21419ea9176087cb77e64410926eb78", size = 15061088, upload-time = "2025-11-13T19:58:14.551Z" },
+ { url = "https://files.pythonhosted.org/packages/23/44/a022f288d61c2f8c8645b24c364b719aee293ffc7d633a2ca4d116b9c716/ruff-0.14.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b595bedf6bc9cab647c4a173a61acf4f1ac5f2b545203ba82f30fcb10b0318fb", size = 14734717, upload-time = "2025-11-13T19:58:17.518Z" },
+ { url = "https://files.pythonhosted.org/packages/58/81/5c6ba44de7e44c91f68073e0658109d8373b0590940efe5bd7753a2585a3/ruff-0.14.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f55382725ad0bdb2e8ee2babcbbfb16f124f5a59496a2f6a46f1d9d99d93e6e2", size = 14028812, upload-time = "2025-11-13T19:58:20.533Z" },
+ { url = "https://files.pythonhosted.org/packages/ad/ef/41a8b60f8462cb320f68615b00299ebb12660097c952c600c762078420f8/ruff-0.14.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7497d19dce23976bdaca24345ae131a1d38dcfe1b0850ad8e9e6e4fa321a6e19", size = 13825656, upload-time = "2025-11-13T19:58:23.345Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/00/207e5de737fdb59b39eb1fac806904fe05681981b46d6a6db9468501062e/ruff-0.14.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:410e781f1122d6be4f446981dd479470af86537fb0b8857f27a6e872f65a38e4", size = 13959922, upload-time = "2025-11-13T19:58:26.537Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/7e/fa1f5c2776db4be405040293618846a2dece5c70b050874c2d1f10f24776/ruff-0.14.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c01be527ef4c91a6d55e53b337bfe2c0f82af024cc1a33c44792d6844e2331e1", size = 12932501, upload-time = "2025-11-13T19:58:29.822Z" },
+ { url = "https://files.pythonhosted.org/packages/67/d8/d86bf784d693a764b59479a6bbdc9515ae42c340a5dc5ab1dabef847bfaa/ruff-0.14.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f66e9bb762e68d66e48550b59c74314168ebb46199886c5c5aa0b0fbcc81b151", size = 12927319, upload-time = "2025-11-13T19:58:32.923Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/de/ee0b304d450ae007ce0cb3e455fe24fbcaaedae4ebaad6c23831c6663651/ruff-0.14.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d93be8f1fa01022337f1f8f3bcaa7ffee2d0b03f00922c45c2207954f351f465", size = 13206209, upload-time = "2025-11-13T19:58:35.952Z" },
+ { url = "https://files.pythonhosted.org/packages/33/aa/193ca7e3a92d74f17d9d5771a765965d2cf42c86e6f0fd95b13969115723/ruff-0.14.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c135d4b681f7401fe0e7312017e41aba9b3160861105726b76cfa14bc25aa367", size = 13953709, upload-time = "2025-11-13T19:58:39.002Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/f1/7119e42aa1d3bf036ffc9478885c2e248812b7de9abea4eae89163d2929d/ruff-0.14.5-py3-none-win32.whl", hash = "sha256:c83642e6fccfb6dea8b785eb9f456800dcd6a63f362238af5fc0c83d027dd08b", size = 12925808, upload-time = "2025-11-13T19:58:42.779Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/9d/7c0a255d21e0912114784e4a96bf62af0618e2190cae468cd82b13625ad2/ruff-0.14.5-py3-none-win_amd64.whl", hash = "sha256:9d55d7af7166f143c94eae1db3312f9ea8f95a4defef1979ed516dbb38c27621", size = 14331546, upload-time = "2025-11-13T19:58:45.691Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/80/69756670caedcf3b9be597a6e12276a6cf6197076eb62aad0c608f8efce0/ruff-0.14.5-py3-none-win_arm64.whl", hash = "sha256:4b700459d4649e2594b31f20a9de33bc7c19976d4746d8d0798ad959621d64a4", size = 13433331, upload-time = "2025-11-13T19:58:48.434Z" },
]
[[package]]
@@ -3268,8 +2565,6 @@ version = "25.8.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
- { name = "importlib-metadata", marker = "python_full_version < '3.10'" },
- { name = "importlib-resources", marker = "python_full_version < '3.10'" },
{ name = "jinja2" },
{ name = "tomli", marker = "python_full_version < '3.11'" },
]
@@ -3421,17 +2716,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d8/50/8856e24bec5e2fc7f775d867aeb7a3f137359356200ac44658f1f2c834b2/ujson-5.11.0-cp313-cp313-win32.whl", hash = "sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241", size = 39753, upload-time = "2025-08-20T11:56:01.345Z" },
{ url = "https://files.pythonhosted.org/packages/5b/d8/1baee0f4179a4d0f5ce086832147b6cc9b7731c24ca08e14a3fdb8d39c32/ujson-5.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0", size = 43866, upload-time = "2025-08-20T11:56:02.552Z" },
{ url = "https://files.pythonhosted.org/packages/a9/8c/6d85ef5be82c6d66adced3ec5ef23353ed710a11f70b0b6a836878396334/ujson-5.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9", size = 38363, upload-time = "2025-08-20T11:56:03.688Z" },
- { url = "https://files.pythonhosted.org/packages/39/bf/c6f59cdf74ce70bd937b97c31c42fd04a5ed1a9222d0197e77e4bd899841/ujson-5.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694", size = 55283, upload-time = "2025-08-20T11:56:33.947Z" },
- { url = "https://files.pythonhosted.org/packages/8d/c1/a52d55638c0c644b8a63059f95ad5ffcb4ad8f60d8bc3e8680f78e77cc75/ujson-5.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac", size = 53168, upload-time = "2025-08-20T11:56:35.141Z" },
- { url = "https://files.pythonhosted.org/packages/75/6c/e64e19a01d59c8187d01ffc752ee3792a09f5edaaac2a0402de004459dd7/ujson-5.11.0-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a", size = 57809, upload-time = "2025-08-20T11:56:36.293Z" },
- { url = "https://files.pythonhosted.org/packages/9f/36/910117b7a8a1c188396f6194ca7bc8fd75e376d8f7e3cf5eb6219fc8b09d/ujson-5.11.0-cp39-cp39-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02", size = 59797, upload-time = "2025-08-20T11:56:37.746Z" },
- { url = "https://files.pythonhosted.org/packages/c7/17/bcc85d282ee2f4cdef5f577e0a43533eedcae29cc6405edf8c62a7a50368/ujson-5.11.0-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c", size = 57378, upload-time = "2025-08-20T11:56:39.123Z" },
- { url = "https://files.pythonhosted.org/packages/ef/39/120bb76441bf835f3c3f42db9c206f31ba875711637a52a8209949ab04b0/ujson-5.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a", size = 1036515, upload-time = "2025-08-20T11:56:40.848Z" },
- { url = "https://files.pythonhosted.org/packages/b6/ae/fe1b4ff6388f681f6710e9494656957725b1e73ae50421ec04567df9fb75/ujson-5.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052", size = 1195753, upload-time = "2025-08-20T11:56:42.341Z" },
- { url = "https://files.pythonhosted.org/packages/92/20/005b93f2cf846ae50b46812fcf24bbdd127521197e5f1e1a82e3b3e730a1/ujson-5.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596", size = 1088844, upload-time = "2025-08-20T11:56:43.777Z" },
- { url = "https://files.pythonhosted.org/packages/41/9e/3142023c30008e2b24d7368a389b26d28d62fcd3f596d3d898a72dd09173/ujson-5.11.0-cp39-cp39-win32.whl", hash = "sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547", size = 39652, upload-time = "2025-08-20T11:56:45.034Z" },
- { url = "https://files.pythonhosted.org/packages/ca/89/f4de0a3c485d0163f85f552886251876645fb62cbbe24fcdc0874b9fae03/ujson-5.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b", size = 43783, upload-time = "2025-08-20T11:56:46.156Z" },
- { url = "https://files.pythonhosted.org/packages/48/b1/2d50987a7b7cccb5c1fbe9ae7b184211106237b32c7039118c41d79632ea/ujson-5.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9", size = 38430, upload-time = "2025-08-20T11:56:47.653Z" },
{ url = "https://files.pythonhosted.org/packages/50/17/30275aa2933430d8c0c4ead951cc4fdb922f575a349aa0b48a6f35449e97/ujson-5.11.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362", size = 51206, upload-time = "2025-08-20T11:56:48.797Z" },
{ url = "https://files.pythonhosted.org/packages/c3/15/42b3924258eac2551f8f33fa4e35da20a06a53857ccf3d4deb5e5d7c0b6c/ujson-5.11.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39", size = 48907, upload-time = "2025-08-20T11:56:50.136Z" },
{ url = "https://files.pythonhosted.org/packages/94/7e/0519ff7955aba581d1fe1fb1ca0e452471250455d182f686db5ac9e46119/ujson-5.11.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc", size = 50319, upload-time = "2025-08-20T11:56:51.63Z" },
@@ -3469,10 +2753,8 @@ version = "20.35.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "distlib" },
- { name = "filelock", version = "3.19.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "filelock", version = "3.20.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
- { name = "platformdirs", version = "4.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "platformdirs", version = "4.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "filelock" },
+ { name = "platformdirs" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a4/d5/b0ccd381d55c8f45d46f77df6ae59fbc23d19e901e2d523395598e5f4c93/virtualenv-20.35.3.tar.gz", hash = "sha256:4f1a845d131133bdff10590489610c98c168ff99dc75d6c96853801f7f67af44", size = 6002907, upload-time = "2025-10-10T21:23:33.178Z" }
@@ -3539,29 +2821,12 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" },
{ url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" },
{ url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" },
- { url = "https://files.pythonhosted.org/packages/36/db/3fff0bcbe339a6fa6a3b9e3fbc2bfb321ec2f4cd233692272c5a8d6cf801/websockets-15.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f4c04ead5aed67c8a1a20491d54cdfba5884507a48dd798ecaf13c74c4489f5", size = 175424, upload-time = "2025-03-05T20:02:56.505Z" },
- { url = "https://files.pythonhosted.org/packages/46/e6/519054c2f477def4165b0ec060ad664ed174e140b0d1cbb9fafa4a54f6db/websockets-15.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abdc0c6c8c648b4805c5eacd131910d2a7f6455dfd3becab248ef108e89ab16a", size = 173077, upload-time = "2025-03-05T20:02:58.37Z" },
- { url = "https://files.pythonhosted.org/packages/1a/21/c0712e382df64c93a0d16449ecbf87b647163485ca1cc3f6cbadb36d2b03/websockets-15.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a625e06551975f4b7ea7102bc43895b90742746797e2e14b70ed61c43a90f09b", size = 173324, upload-time = "2025-03-05T20:02:59.773Z" },
- { url = "https://files.pythonhosted.org/packages/1c/cb/51ba82e59b3a664df54beed8ad95517c1b4dc1a913730e7a7db778f21291/websockets-15.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d591f8de75824cbb7acad4e05d2d710484f15f29d4a915092675ad3456f11770", size = 182094, upload-time = "2025-03-05T20:03:01.827Z" },
- { url = "https://files.pythonhosted.org/packages/fb/0f/bf3788c03fec679bcdaef787518dbe60d12fe5615a544a6d4cf82f045193/websockets-15.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47819cea040f31d670cc8d324bb6435c6f133b8c7a19ec3d61634e62f8d8f9eb", size = 181094, upload-time = "2025-03-05T20:03:03.123Z" },
- { url = "https://files.pythonhosted.org/packages/5e/da/9fb8c21edbc719b66763a571afbaf206cb6d3736d28255a46fc2fe20f902/websockets-15.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac017dd64572e5c3bd01939121e4d16cf30e5d7e110a119399cf3133b63ad054", size = 181397, upload-time = "2025-03-05T20:03:04.443Z" },
- { url = "https://files.pythonhosted.org/packages/2e/65/65f379525a2719e91d9d90c38fe8b8bc62bd3c702ac651b7278609b696c4/websockets-15.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4a9fac8e469d04ce6c25bb2610dc535235bd4aa14996b4e6dbebf5e007eba5ee", size = 181794, upload-time = "2025-03-05T20:03:06.708Z" },
- { url = "https://files.pythonhosted.org/packages/d9/26/31ac2d08f8e9304d81a1a7ed2851c0300f636019a57cbaa91342015c72cc/websockets-15.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363c6f671b761efcb30608d24925a382497c12c506b51661883c3e22337265ed", size = 181194, upload-time = "2025-03-05T20:03:08.844Z" },
- { url = "https://files.pythonhosted.org/packages/98/72/1090de20d6c91994cd4b357c3f75a4f25ee231b63e03adea89671cc12a3f/websockets-15.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2034693ad3097d5355bfdacfffcbd3ef5694f9718ab7f29c29689a9eae841880", size = 181164, upload-time = "2025-03-05T20:03:10.242Z" },
- { url = "https://files.pythonhosted.org/packages/2d/37/098f2e1c103ae8ed79b0e77f08d83b0ec0b241cf4b7f2f10edd0126472e1/websockets-15.0.1-cp39-cp39-win32.whl", hash = "sha256:3b1ac0d3e594bf121308112697cf4b32be538fb1444468fb0a6ae4feebc83411", size = 176381, upload-time = "2025-03-05T20:03:12.77Z" },
- { url = "https://files.pythonhosted.org/packages/75/8b/a32978a3ab42cebb2ebdd5b05df0696a09f4d436ce69def11893afa301f0/websockets-15.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7643a03db5c95c799b89b31c036d5f27eeb4d259c798e878d6937d71832b1e4", size = 176841, upload-time = "2025-03-05T20:03:14.367Z" },
{ url = "https://files.pythonhosted.org/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109, upload-time = "2025-03-05T20:03:17.769Z" },
{ url = "https://files.pythonhosted.org/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343, upload-time = "2025-03-05T20:03:19.094Z" },
{ url = "https://files.pythonhosted.org/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599, upload-time = "2025-03-05T20:03:21.1Z" },
{ url = "https://files.pythonhosted.org/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207, upload-time = "2025-03-05T20:03:23.221Z" },
{ url = "https://files.pythonhosted.org/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155, upload-time = "2025-03-05T20:03:25.321Z" },
{ url = "https://files.pythonhosted.org/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884, upload-time = "2025-03-05T20:03:27.934Z" },
- { url = "https://files.pythonhosted.org/packages/b7/48/4b67623bac4d79beb3a6bb27b803ba75c1bdedc06bd827e465803690a4b2/websockets-15.0.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7f493881579c90fc262d9cdbaa05a6b54b3811c2f300766748db79f098db9940", size = 173106, upload-time = "2025-03-05T20:03:29.404Z" },
- { url = "https://files.pythonhosted.org/packages/ed/f0/adb07514a49fe5728192764e04295be78859e4a537ab8fcc518a3dbb3281/websockets-15.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:47b099e1f4fbc95b701b6e85768e1fcdaf1630f3cbe4765fa216596f12310e2e", size = 173339, upload-time = "2025-03-05T20:03:30.755Z" },
- { url = "https://files.pythonhosted.org/packages/87/28/bd23c6344b18fb43df40d0700f6d3fffcd7cef14a6995b4f976978b52e62/websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67f2b6de947f8c757db2db9c71527933ad0019737ec374a8a6be9a956786aaf9", size = 174597, upload-time = "2025-03-05T20:03:32.247Z" },
- { url = "https://files.pythonhosted.org/packages/6d/79/ca288495863d0f23a60f546f0905ae8f3ed467ad87f8b6aceb65f4c013e4/websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d08eb4c2b7d6c41da6ca0600c077e93f5adcfd979cd777d747e9ee624556da4b", size = 174205, upload-time = "2025-03-05T20:03:33.731Z" },
- { url = "https://files.pythonhosted.org/packages/04/e4/120ff3180b0872b1fe6637f6f995bcb009fb5c87d597c1fc21456f50c848/websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b826973a4a2ae47ba357e4e82fa44a463b8f168e1ca775ac64521442b19e87f", size = 174150, upload-time = "2025-03-05T20:03:35.757Z" },
- { url = "https://files.pythonhosted.org/packages/cb/c3/30e2f9c539b8da8b1d76f64012f3b19253271a63413b2d3adb94b143407f/websockets-15.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:21c1fa28a6a7e3cbdc171c694398b6df4744613ce9b36b1a498e816787e28123", size = 176877, upload-time = "2025-03-05T20:03:37.199Z" },
{ url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" },
]
@@ -3630,20 +2895,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/c8/54/8928a1733bab2cb94e19a5815d1077bc18b7e7d463a026232192bad8ce36/whenever-0.7.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b28e08e9b2b2c11c047f7a87ce8867a8739eca0c77fa4c552861a87767f7025b", size = 590513, upload-time = "2025-03-19T14:40:47.87Z" },
{ url = "https://files.pythonhosted.org/packages/d6/c9/91f71eff32540e5991820b4eddb0fe3886c45a47432ac4ac00ca75ad6723/whenever-0.7.3-cp313-cp313-win32.whl", hash = "sha256:2991d491badcdd9da357d156f9e17426f2feda7da9f186dabea6d759f8920225", size = 295029, upload-time = "2025-03-19T14:41:09.146Z" },
{ url = "https://files.pythonhosted.org/packages/74/46/e3b3f9ccd27958652fea2d94442a1f1e82deaf0721bb4afa72b3d0fee476/whenever-0.7.3-cp313-cp313-win_amd64.whl", hash = "sha256:1a340f71c0b8a059ecf34948f2c59b8995abd84b2b69fff576a3818162fb3056", size = 280568, upload-time = "2025-03-19T14:41:15.979Z" },
- { url = "https://files.pythonhosted.org/packages/ed/f3/5979d3948194123d198c4f5c41b7166bcd46446c353b9ca30df66cd63073/whenever-0.7.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:d9b95e378780826e70328008413d69486ea69b35e5179efb47734d786f2427d0", size = 375845, upload-time = "2025-03-19T14:41:03.565Z" },
- { url = "https://files.pythonhosted.org/packages/ae/ba/de38f233945bc54637e47cac105f3ce5813657d0a7a414227a6b75e914d8/whenever-0.7.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:088b1bf5709fabd47bddc9f7a03c044e9d8ff787c8572422969504713df55f8e", size = 370201, upload-time = "2025-03-19T14:40:56.251Z" },
- { url = "https://files.pythonhosted.org/packages/2d/41/5a275dab1195ed8ce82951c8e69f2b54da7a15f354c1777cdfb3837a9830/whenever-0.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c617caa073450dec2efe9a282c1cdfb45bfb4e1ba523f1e5f16a448724b4463", size = 426843, upload-time = "2025-03-19T14:39:40.908Z" },
- { url = "https://files.pythonhosted.org/packages/62/c8/753fa3c0c39dbaf9d456f12022e93de25bc26cc3f062f0c008829db08836/whenever-0.7.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:706913571cb617f07283b4c6818225c71e65ecb46fd138884f40b5cf3f29948c", size = 461878, upload-time = "2025-03-19T14:39:58.038Z" },
- { url = "https://files.pythonhosted.org/packages/c4/5a/dfff567399ddcb23b606cd95a98f3a495b8d2d9988fbc8dc365645a3aa08/whenever-0.7.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaa401743c6f7e1f259cc88eac9d0f5b05099e7cb1c5f8a3cd9bd0d475cfd963", size = 456709, upload-time = "2025-03-19T14:40:12.353Z" },
- { url = "https://files.pythonhosted.org/packages/0f/55/1aed27b9781e10f7ffa2f0ce3f7b4770a78ca2005d7e03371ae3fd0e18fe/whenever-0.7.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c129a5dc3e91d1505b571e837e2b1c4cd6cc4f734afa29e0da62de3dd5c42e01", size = 487571, upload-time = "2025-03-19T14:40:20.71Z" },
- { url = "https://files.pythonhosted.org/packages/fe/98/4f311137313686d3c6d42314ecfe18f972d87d38a5a2672a0b7da18bd3ef/whenever-0.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb7376d92caa45af197eab53844e3c1c066bc928eb325994ca5d30656cba3c55", size = 419018, upload-time = "2025-03-19T14:40:41.48Z" },
- { url = "https://files.pythonhosted.org/packages/fb/a4/991f89a86838c87298d1cf5f139d804ad4a4b1adddcb316f8f6370cc7014/whenever-0.7.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:08635676f5c1939c5222bba8965a05f7a95b81a4ae08029f145ec61d21eba9a9", size = 464994, upload-time = "2025-03-19T14:40:27.732Z" },
- { url = "https://files.pythonhosted.org/packages/b8/d3/05bb2ada0c31bd489a9849d3dd38d18572f979cf4c1e23389aa6f2a0d101/whenever-0.7.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5dcede079202312df5740c71a41184980eb687c6308cf03b729fea2f4e1a4b77", size = 606371, upload-time = "2025-03-19T14:39:49.379Z" },
- { url = "https://files.pythonhosted.org/packages/06/61/49104937221347a7b4d3563ab9cdd217b17cd9d8fb9fbd625f2d35ec852b/whenever-0.7.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:6df141b41e0e2e3fd4e4411388075b37c01827dca485f89668dd4b59a2b879d8", size = 724081, upload-time = "2025-03-19T14:40:05.296Z" },
- { url = "https://files.pythonhosted.org/packages/ef/cc/08b866dcd6345e213082407078a6e305c4612ea6638da57aba75d8b14a18/whenever-0.7.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:05384546288bb080a21599362dd7caee7de297eea92823b45db45f13f3ce4d7e", size = 630750, upload-time = "2025-03-19T14:40:34.369Z" },
- { url = "https://files.pythonhosted.org/packages/f7/79/40ca2837bc1688b1e2697b1db74198af5259db3cf69e909e788e31de4354/whenever-0.7.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:af9a49abf8fb9d8717d3d7e444ed367d947bd152c5e91e6b3c9986a9111acd20", size = 589560, upload-time = "2025-03-19T14:40:49.309Z" },
- { url = "https://files.pythonhosted.org/packages/9f/cf/df3f771b6fa01470ffd44ec4d5c6d14336f0857991277fcb36548da99966/whenever-0.7.3-cp39-cp39-win32.whl", hash = "sha256:c69ca4d7e83130b7ee2cf592cb188057eeaf28b16cb8e1cb0a03af649b8e8a3e", size = 293749, upload-time = "2025-03-19T14:41:10.459Z" },
- { url = "https://files.pythonhosted.org/packages/7f/cc/a1130a5019f374423c75cb490cfa6ff2d8d7078eac2feb111f1c6b7171ce/whenever-0.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:9f1c0219bc0d7f933d11891585d118bd5c7b2c97568dc7eff14a434375761da1", size = 279038, upload-time = "2025-03-19T14:41:17.884Z" },
]
[[package]]
@@ -3712,18 +2963,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/bb/b6/20ffcf2558596a7f58a2e69c89597128781f0b88e124bf5a4cadc05b8139/wrapt-2.0.1-cp313-cp313t-win32.whl", hash = "sha256:e76e3f91f864e89db8b8d2a8311d57df93f01ad6bb1e9b9976d1f2e83e18315c", size = 59943, upload-time = "2025-11-07T00:44:33.211Z" },
{ url = "https://files.pythonhosted.org/packages/87/6a/0e56111cbb3320151eed5d3821ee1373be13e05b376ea0870711f18810c3/wrapt-2.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:83ce30937f0ba0d28818807b303a412440c4b63e39d3d8fc036a94764b728c92", size = 63240, upload-time = "2025-11-07T00:44:30.935Z" },
{ url = "https://files.pythonhosted.org/packages/1d/54/5ab4c53ea1f7f7e5c3e7c1095db92932cc32fd62359d285486d00c2884c3/wrapt-2.0.1-cp313-cp313t-win_arm64.whl", hash = "sha256:4b55cacc57e1dc2d0991dbe74c6419ffd415fb66474a02335cb10efd1aa3f84f", size = 60416, upload-time = "2025-11-07T00:44:32.002Z" },
- { url = "https://files.pythonhosted.org/packages/c6/1f/5af0ae22368ec69067a577f9e07a0dd2619a1f63aabc2851263679942667/wrapt-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:68424221a2dc00d634b54f92441914929c5ffb1c30b3b837343978343a3512a3", size = 77478, upload-time = "2025-11-07T00:45:16.65Z" },
- { url = "https://files.pythonhosted.org/packages/8c/b7/fd6b563aada859baabc55db6aa71b8afb4a3ceb8bc33d1053e4c7b5e0109/wrapt-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6bd1a18f5a797fe740cb3d7a0e853a8ce6461cc62023b630caec80171a6b8097", size = 60687, upload-time = "2025-11-07T00:45:17.896Z" },
- { url = "https://files.pythonhosted.org/packages/0f/8c/9ededfff478af396bcd081076986904bdca336d9664d247094150c877dcb/wrapt-2.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fb3a86e703868561c5cad155a15c36c716e1ab513b7065bd2ac8ed353c503333", size = 61563, upload-time = "2025-11-07T00:45:19.109Z" },
- { url = "https://files.pythonhosted.org/packages/ab/a7/d795a1aa2b6ab20ca21157fe03cbfc6aa7e870a88ac3b4ea189e2f6c79f0/wrapt-2.0.1-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5dc1b852337c6792aa111ca8becff5bacf576bf4a0255b0f05eb749da6a1643e", size = 113395, upload-time = "2025-11-07T00:45:21.551Z" },
- { url = "https://files.pythonhosted.org/packages/61/32/56cde2bbf95f2d5698a1850a765520aa86bc7ae0f95b8ec80b6f2e2049bb/wrapt-2.0.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c046781d422f0830de6329fa4b16796096f28a92c8aef3850674442cdcb87b7f", size = 115362, upload-time = "2025-11-07T00:45:22.809Z" },
- { url = "https://files.pythonhosted.org/packages/cf/53/8d3cc433847c219212c133a3e8305bd087b386ef44442ff39189e8fa62ac/wrapt-2.0.1-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f73f9f7a0ebd0db139253d27e5fc8d2866ceaeef19c30ab5d69dcbe35e1a6981", size = 111766, upload-time = "2025-11-07T00:45:20.294Z" },
- { url = "https://files.pythonhosted.org/packages/b8/d3/14b50c2d0463c0dcef8f388cb1527ed7bbdf0972b9fd9976905f36c77ebf/wrapt-2.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b667189cf8efe008f55bbda321890bef628a67ab4147ebf90d182f2dadc78790", size = 114560, upload-time = "2025-11-07T00:45:24.054Z" },
- { url = "https://files.pythonhosted.org/packages/3a/b8/4f731ff178f77ae55385586de9ff4b4261e872cf2ced4875e6c976fbcb8b/wrapt-2.0.1-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:a9a83618c4f0757557c077ef71d708ddd9847ed66b7cc63416632af70d3e2308", size = 110999, upload-time = "2025-11-07T00:45:25.596Z" },
- { url = "https://files.pythonhosted.org/packages/fe/bb/5f1bb0f9ae9d12e19f1d71993d052082062603e83fe3e978377f918f054d/wrapt-2.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e9b121e9aeb15df416c2c960b8255a49d44b4038016ee17af03975992d03931", size = 113164, upload-time = "2025-11-07T00:45:26.8Z" },
- { url = "https://files.pythonhosted.org/packages/ad/f6/f3a3c623d3065c7bf292ee0b73566236b562d5ed894891bd8e435762b618/wrapt-2.0.1-cp39-cp39-win32.whl", hash = "sha256:1f186e26ea0a55f809f232e92cc8556a0977e00183c3ebda039a807a42be1494", size = 58028, upload-time = "2025-11-07T00:45:30.943Z" },
- { url = "https://files.pythonhosted.org/packages/24/78/647c609dfa18063a7fcd5c23f762dd006be401cc9206314d29c9b0b12078/wrapt-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:bf4cb76f36be5de950ce13e22e7fdf462b35b04665a12b64f3ac5c1bbbcf3728", size = 60380, upload-time = "2025-11-07T00:45:28.341Z" },
- { url = "https://files.pythonhosted.org/packages/07/90/0c14b241d18d80ddf4c847a5f52071e126e8a6a9e5a8a7952add8ef0d766/wrapt-2.0.1-cp39-cp39-win_arm64.whl", hash = "sha256:d6cc985b9c8b235bd933990cdbf0f891f8e010b65a3911f7a55179cd7b0fc57b", size = 58895, upload-time = "2025-11-07T00:45:29.527Z" },
{ url = "https://files.pythonhosted.org/packages/15/d1/b51471c11592ff9c012bd3e2f7334a6ff2f42a7aed2caffcf0bdddc9cb89/wrapt-2.0.1-py3-none-any.whl", hash = "sha256:4d2ce1bf1a48c5277d7969259232b57645aae5686dba1eaeade39442277afbca", size = 44046, upload-time = "2025-11-07T00:45:32.116Z" },
]