This commit is contained in:
2026-01-10 16:52:32 -06:00
parent b547d69d48
commit 4216e833e5
10 changed files with 90 additions and 133 deletions

View File

@@ -6,10 +6,9 @@ readme = "README.md"
authors = [{ name = "Christian Camper", email = "ccamper7@gmail.com" }]
requires-python = ">=3.13"
dependencies = [
"basedpyright>=1.37.0",
"basedpyright>=1.37.1",
"pyyaml>=6.0.3",
"ruff>=0.14.10",
"ty>=0.0.10",
"ruff>=0.14.11",
]
[project.scripts]
@@ -19,6 +18,6 @@ docker_compose = "docker_compose:main"
requires = ["uv_build>=0.9.17,<0.10.0"]
build-backend = "uv_build"
[tool.pyright]
analysis.diagnosticMode = "workspace"
#reportExplicitAny = false
[tools.pyright]
analysis.diagnosticMode = 'workspace'

View File

@@ -1,3 +0,0 @@
{
"basedpyright.analysis.diagnosticMode": "workspace"
}

View File

@@ -1,8 +1,10 @@
from collections.abc import Iterator
from typing import cast
from docker_compose.cfg import CFG_ROOT, TRAEFIK_PATH
from docker_compose.compose.net_yaml import NetArgsYaml
from docker_compose.compose.rendered import Rendered
from docker_compose.util.Ts import TypeYamlCompatableDict
from docker_compose.util.yaml_util import to_yaml
@@ -29,6 +31,7 @@ if __name__ == "__main__":
data["networks"] = {net: NetArgsYaml(name=f"{net}_proxy") for net in nets}
cfg = traefik.cfg
data["services"]["traefik"]["networks"] = nets
data = cast(TypeYamlCompatableDict, cast(object, data))
template = cfg.pre_render(to_yaml(data))
cfg.src_paths.compose_file.write(template)
cfg.dest_paths.compose_file.write(cfg.render(template))

View File

@@ -9,7 +9,7 @@ from docker_compose.cfg.org import App, Org
from docker_compose.cfg.replace import ReplaceDynamic, ReplaceStatic, ReplaceUnique
from docker_compose.compose.services_yaml import ServiceYamlRead
from docker_compose.compose.volume_yaml import VolYaml
from docker_compose.util.Ts import T_YamlRW
from docker_compose.util.Ts import TypeYamlDict
from docker_compose.util.yaml_util import path_to_typed, read_yaml
@@ -46,12 +46,12 @@ class ServicePath:
data_str = f.read()
for func in self.pre_render_funcs:
data_str = func(data_str)
data_dict: T_YamlRW = yaml.safe_load(data_str) # pyright: ignore[reportAny]
data_dict: TypeYamlDict = yaml.safe_load(data_str) # pyright: ignore[reportAny]
if not isinstance(data_dict, MutableMapping):
raise TypeError
path_to_typed(ServiceYamlRead, data_dict, self.path)
return cast(ServiceYamlRead, cast(object, data_dict))
@property
def pre_render_funcs(self) -> Iterator[Callable[[str], str]]:
yield self.fqdn

View File

@@ -5,14 +5,14 @@ from typing import Self, cast, final
from docker_compose.cfg.compose_paths import ServicePath, VolumePath
from docker_compose.cfg.org_yaml import OrgYaml
from docker_compose.util.Ts import T_YamlDict, T_YamlRW
from docker_compose.util.Ts import TypeYamlCompatableDict, TypeYamlCompatableRes
from docker_compose.util.yaml_util import read_yaml, write_yaml
YAML_EXTS = frozenset((".yml", ".yaml"))
class ComposeFileTemplate(Path):
def write_dict(self, data: T_YamlDict) -> None:
def write_dict(self, data: TypeYamlCompatableDict) -> None:
write_yaml(data, self)
def write(self, data: str) -> None:
@@ -68,7 +68,7 @@ class VolumesDir(YamlDir):
class VolumeData(Path):
def write(self, data: T_YamlRW) -> None:
def write(self, data: TypeYamlCompatableRes) -> None:
write_yaml(data, self)

View File

@@ -1,7 +1,7 @@
from collections.abc import Iterator
from dataclasses import dataclass
from pathlib import Path
from typing import Self
from typing import Self, cast
from docker_compose.cfg.cfg_paths import CfgData
from docker_compose.cfg.org import OrgData
@@ -10,6 +10,7 @@ from docker_compose.compose.compose_yaml import ComposeYaml
from docker_compose.compose.net import Net
from docker_compose.compose.services import Service
from docker_compose.compose.volume_yaml import VolYaml
from docker_compose.util.Ts import TypeYamlCompatableDict
from docker_compose.util.yaml_util import to_yaml
@@ -53,17 +54,18 @@ class Compose:
@property
def as_dict(self) -> ComposeYaml:
return ComposeYaml(
name=str(OrgData.org_app),
name=str(OrgData.org_app.dest),
services={
service.service_name: service.as_dict for service in self.services
},
networks=self.networks.as_dict,
volumes=self.volumes,
)
@property
def as_template(self) -> str:
return self.cfg.pre_render(to_yaml(self.as_dict))
data = cast(TypeYamlCompatableDict, cast(object, self.as_dict))
return self.cfg.pre_render(to_yaml(data))
def write_template(self):
self.cfg.src_paths.compose_file.write(self.as_template)

View File

@@ -1,3 +1,3 @@
from docker_compose.util.Ts import T_YamlDict
from docker_compose.util.Ts import TypeYamlDict
type VolYaml = dict[str, T_YamlDict]
type VolYaml = dict[str, TypeYamlDict]

View File

@@ -1,4 +1,4 @@
from collections.abc import ItemsView, Iterator, KeysView, MutableMapping, Set
from collections.abc import ItemsView, Iterator, KeysView, MutableMapping, Sequence, Set
from types import GenericAlias, UnionType
from typing import (
ClassVar,
@@ -9,61 +9,44 @@ from typing import (
get_origin,
)
#generic nested data
type T_Primitive = None | bool | int | str
type _PrimIters = Sequence[TypePrim] | Set[TypePrim] | Iterator[TypePrim]
type TypePrimDict = MutableMapping[T_Primitive, TypePrim]
type TypePrim = T_Primitive | _PrimIters | TypePrimDict
# type T_TDict = MutableMapping[T_Primitive, T_Prim]
type T_TIters = list[T_Prim]
type T_T = T_Primitive | T_TIters | TypedYamlDict
class TypedYamlDict(Protocol):
def __getitem__(self, key: str, /) -> T_T: ...
# data going to and from yaml
type TypeYaml = T_Primitive | TypeYamlRes
type TypeYamlRes = list[TypeYaml] | TypeYamlDict
class TypeYamlDict(Protocol):
def __getitem__(self, key: str, /) -> object: ...
# def __setitem__(self, key: str, value: V, /) -> V: ...
# def __delitem__(self, key: Never | K, /) -> None: ...
def __contains__(self, key: str, /) -> bool: ...
def __iter__(self) -> Iterator[str]: ...
def __len__(self) -> int: ...
def keys(self) -> KeysView[str]: ...
def items(self) -> ItemsView[str, T_T]: ...
def items(self) -> ItemsView[str, object]: ...
# def pop(self, key: Never | K, /) -> V: ...
# def popitem(self) -> tuple[K, V]: ...
# def clear(self) -> None: ...
__required_keys__: ClassVar[frozenset[str]]
__optional_keys__: ClassVar[frozenset[str]]
# class Test(TypedDict):
# var: str
#
#
# x = Test(var="test")
#
#
# def is_typed_dict_test(obj: TypedYamlDict[object, object]) -> None:
# print(obj)
# pass
#
#
# is_typed_dict_test(x)
#yaml compatible data
type TypeYamlCompatableIters = Sequence[TypeYamlCompatable] | Set[TypeYamlCompatable] | Iterator[TypeYamlCompatable]
type TypeYamlCompatableDict = MutableMapping[str, TypeYamlCompatable]
type TypeYamlCompatableRes = TypeYamlCompatableIters | TypeYamlCompatableDict
type TypeYamlCompatable = T_Primitive | TypeYamlCompatableRes
type T_PrimIters = tuple[T_Prim, ...] | list[T_Prim] | Set[T_Prim] | Iterator[T_Prim]
type T_PrimDict = MutableMapping[T_Primitive, T_Prim]
type T_Prim = T_Primitive | T_PrimIters | T_PrimDict
type T_YamlIters = tuple[T_Yaml, ...] | list[T_Yaml] | Set[T_Yaml] | Iterator[T_Yaml]
type T_YamlDict = MutableMapping[str, T_Yaml]
type T_YamlRW = T_YamlIters | T_YamlDict
type T_Yaml = T_Primitive | T_YamlRW
type T_YamlPostDict = MutableMapping[str, T_YamlPost]
type T_YamlPostRes = tuple[T_YamlPost, ...] | T_YamlPostDict
type T_YamlPost = T_Primitive | T_YamlPostRes
# type T_YamlPostDict = MutableMapping[str, T_YamlPost]
# type T_YamlPostRes = Sequence[T_YamlPost] | T_YamlPostDict
# type T_YamlPost = T_Primitive | T_YamlPostRes
def get_union_types(annotations: UnionType) -> Iterator[type]:

View File

@@ -1,5 +1,5 @@
import re
from collections.abc import Iterator, MutableMapping, Set
from collections.abc import Iterator, MutableMapping, Sequence, Set
from pathlib import Path
from typing import (
cast,
@@ -11,13 +11,12 @@ from typing import (
import yaml
from docker_compose.util.Ts import (
T_YamlDict,
T_YamlIters,
T_YamlPost,
T_YamlPostDict,
T_YamlPostRes,
T_YamlRW,
TypedYamlDict,
TypeYamlCompatable,
TypeYamlCompatableDict,
TypeYamlCompatableIters,
TypeYamlCompatableRes,
TypeYamlDict,
TypeYamlRes,
get_types,
)
@@ -46,10 +45,10 @@ class VerboseSafeDumper(yaml.SafeDumper):
return True
def yaml_prep(data: T_YamlRW) -> T_YamlPostRes:
def yaml_prep(data: TypeYamlCompatableRes) -> TypeYamlCompatableRes:
if isinstance(data, MutableMapping):
return dict_prep(data)
if isinstance(data, (tuple, list)):
if isinstance(data, Sequence):
return tuple(list_prep(data))
res = tuple(list_prep(data))
try:
@@ -58,7 +57,7 @@ def yaml_prep(data: T_YamlRW) -> T_YamlPostRes:
return res
def list_prep(data: T_YamlIters) -> Iterator[T_YamlPost]:
def list_prep(data: TypeYamlCompatableIters) -> Iterator[TypeYamlCompatable]:
for v in data:
if isinstance(v, (MutableMapping, tuple, list, Set, Iterator)):
yield yaml_prep(v)
@@ -71,22 +70,22 @@ def list_prep(data: T_YamlIters) -> Iterator[T_YamlPost]:
continue
def dict_prep(data: T_YamlDict) -> T_YamlPostDict:
def dict_prep(data: TypeYamlCompatableDict) -> TypeYamlCompatableDict:
keys = tuple(data.keys())
for k in keys:
v = data[k]
if isinstance(v, (MutableMapping, tuple, list, Set, Iterator)):
data[k] = v = yaml_prep(v) # pyright: ignore[reportArgumentType]
data[k] = v = yaml_prep(v)
if v:
continue
if isinstance(v, bool):
continue
del data[k]
return cast(T_YamlPostDict, cast(object, data))
return data
def to_yaml(data: T_YamlRW) -> str:
def to_yaml(data: TypeYamlCompatableRes) -> str:
dict_ = yaml_prep(data)
res = yaml.dump(dict_, Dumper=VerboseSafeDumper)
res = re.sub(r"(^\s?-)", r" \g<1>", res, flags=re.MULTILINE)
@@ -94,31 +93,31 @@ def to_yaml(data: T_YamlRW) -> str:
def write_yaml(
data: T_YamlRW,
data: TypeYamlCompatableRes,
path: Path,
) -> None:
with path.open("wt") as f:
_ = f.write(to_yaml(data))
def read_yaml(path: Path) -> T_YamlPostRes:
def read_yaml(path: Path) -> TypeYamlRes:
with path.open("rt") as f:
return yaml.safe_load(f) # pyright: ignore[reportAny]
def read_typed_yaml[T: TypedYamlDict](
def read_typed_yaml[T: TypeYamlDict](
type_: type[T],
path: Path,
) -> T:
with path.open("rt") as f:
data: T_YamlDict = yaml.safe_load(f) # pyright: ignore[reportAny]
data: TypeYamlDict = yaml.safe_load(f) # pyright: ignore[reportAny]
path_to_typed(type_, data, path)
return cast(T, data) # pyright: ignore[reportInvalidCast]
return cast(T, data)
def path_to_typed(
type_: type[TypedYamlDict],
data: T_YamlDict,
type_: type[TypeYamlDict],
data: TypeYamlDict,
path: Path,
) -> None:
try:
@@ -129,8 +128,8 @@ def path_to_typed(
def validate_typed_dict(
t: type[TypedYamlDict],
data: T_YamlDict,
t: type[TypeYamlDict],
data: TypeYamlDict,
) -> None:
keys = frozenset(data.keys())
missing = t.__required_keys__.difference(keys)
@@ -143,7 +142,7 @@ def validate_typed_dict(
for key, val in data.items():
t2 = cast(type, cast(object, hints[key]))
if is_typeddict(t2):
validate_typed_dict(t2, cast(T_YamlDict, val))
validate_typed_dict(t2, cast(TypeYamlDict, val))
continue
# try:

76
uv.lock generated
View File

@@ -4,14 +4,14 @@ requires-python = ">=3.13"
[[package]]
name = "basedpyright"
version = "1.37.0"
version = "1.37.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "nodejs-wheel-binaries" },
]
sdist = { url = "https://files.pythonhosted.org/packages/60/d7/9476af6f45a70e8d23045ec59d99c2698513b7395283cadc75caeeea2b83/basedpyright-1.37.0.tar.gz", hash = "sha256:affbffced97a04a08bfc44aef2da43951a5ab5e2e55921a144ed786c4fd2c6ad", size = 22837441, upload-time = "2026-01-04T09:59:32.652Z" }
sdist = { url = "https://files.pythonhosted.org/packages/0c/b0/fbba81ea29eed1274e965cd0445f0d6020b467ff4d3393791e4d6ae02e64/basedpyright-1.37.1.tar.gz", hash = "sha256:1f47bc6f45cbcc5d6f8619d60aa42128e4b38942f5118dcd4bc20c3466c5e02f", size = 25235384, upload-time = "2026-01-08T14:42:46.447Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e8/63/753918f0bad07a1b24755a540b64bca1388322615025d4c954e3740fcdbe/basedpyright-1.37.0-py3-none-any.whl", hash = "sha256:261a02a8732a19f3f585e2940582147560058626a062a2320724de84fb2dc41b", size = 11884509, upload-time = "2026-01-04T09:59:35.997Z" },
{ url = "https://files.pythonhosted.org/packages/ad/d6/6b33bb49f08d761d7c958a1e3cecfb3ffbdcf4ba6bbed65b23ab47516b75/basedpyright-1.37.1-py3-none-any.whl", hash = "sha256:caf3adfe54f51623241712f8b4367adb51ef8a8c2288e3e1ec4118319661340d", size = 12297397, upload-time = "2026-01-08T14:42:50.306Z" },
]
[[package]]
@@ -22,15 +22,13 @@ dependencies = [
{ name = "basedpyright" },
{ name = "pyyaml" },
{ name = "ruff" },
{ name = "ty" },
]
[package.metadata]
requires-dist = [
{ name = "basedpyright", specifier = ">=1.37.0" },
{ name = "basedpyright", specifier = ">=1.37.1" },
{ name = "pyyaml", specifier = ">=6.0.3" },
{ name = "ruff", specifier = ">=0.14.10" },
{ name = "ty", specifier = ">=0.0.10" },
{ name = "ruff", specifier = ">=0.14.11" },
]
[[package]]
@@ -87,50 +85,26 @@ wheels = [
[[package]]
name = "ruff"
version = "0.14.10"
version = "0.14.11"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/57/08/52232a877978dd8f9cf2aeddce3e611b40a63287dfca29b6b8da791f5e8d/ruff-0.14.10.tar.gz", hash = "sha256:9a2e830f075d1a42cd28420d7809ace390832a490ed0966fe373ba288e77aaf4", size = 5859763, upload-time = "2025-12-18T19:28:57.98Z" }
sdist = { url = "https://files.pythonhosted.org/packages/d4/77/9a7fe084d268f8855d493e5031ea03fa0af8cc05887f638bf1c4e3363eb8/ruff-0.14.11.tar.gz", hash = "sha256:f6dc463bfa5c07a59b1ff2c3b9767373e541346ea105503b4c0369c520a66958", size = 5993417, upload-time = "2026-01-08T19:11:58.322Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/60/01/933704d69f3f05ee16ef11406b78881733c186fe14b6a46b05cfcaf6d3b2/ruff-0.14.10-py3-none-linux_armv6l.whl", hash = "sha256:7a3ce585f2ade3e1f29ec1b92df13e3da262178df8c8bdf876f48fa0e8316c49", size = 13527080, upload-time = "2025-12-18T19:29:25.642Z" },
{ url = "https://files.pythonhosted.org/packages/df/58/a0349197a7dfa603ffb7f5b0470391efa79ddc327c1e29c4851e85b09cc5/ruff-0.14.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:674f9be9372907f7257c51f1d4fc902cb7cf014b9980152b802794317941f08f", size = 13797320, upload-time = "2025-12-18T19:29:02.571Z" },
{ url = "https://files.pythonhosted.org/packages/7b/82/36be59f00a6082e38c23536df4e71cdbc6af8d7c707eade97fcad5c98235/ruff-0.14.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d85713d522348837ef9df8efca33ccb8bd6fcfc86a2cde3ccb4bc9d28a18003d", size = 12918434, upload-time = "2025-12-18T19:28:51.202Z" },
{ url = "https://files.pythonhosted.org/packages/a6/00/45c62a7f7e34da92a25804f813ebe05c88aa9e0c25e5cb5a7d23dd7450e3/ruff-0.14.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6987ebe0501ae4f4308d7d24e2d0fe3d7a98430f5adfd0f1fead050a740a3a77", size = 13371961, upload-time = "2025-12-18T19:29:04.991Z" },
{ url = "https://files.pythonhosted.org/packages/40/31/a5906d60f0405f7e57045a70f2d57084a93ca7425f22e1d66904769d1628/ruff-0.14.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16a01dfb7b9e4eee556fbfd5392806b1b8550c9b4a9f6acd3dbe6812b193c70a", size = 13275629, upload-time = "2025-12-18T19:29:21.381Z" },
{ url = "https://files.pythonhosted.org/packages/3e/60/61c0087df21894cf9d928dc04bcd4fb10e8b2e8dca7b1a276ba2155b2002/ruff-0.14.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7165d31a925b7a294465fa81be8c12a0e9b60fb02bf177e79067c867e71f8b1f", size = 14029234, upload-time = "2025-12-18T19:29:00.132Z" },
{ url = "https://files.pythonhosted.org/packages/44/84/77d911bee3b92348b6e5dab5a0c898d87084ea03ac5dc708f46d88407def/ruff-0.14.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c561695675b972effb0c0a45db233f2c816ff3da8dcfbe7dfc7eed625f218935", size = 15449890, upload-time = "2025-12-18T19:28:53.573Z" },
{ url = "https://files.pythonhosted.org/packages/e9/36/480206eaefa24a7ec321582dda580443a8f0671fdbf6b1c80e9c3e93a16a/ruff-0.14.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bb98fcbbc61725968893682fd4df8966a34611239c9fd07a1f6a07e7103d08e", size = 15123172, upload-time = "2025-12-18T19:29:23.453Z" },
{ url = "https://files.pythonhosted.org/packages/5c/38/68e414156015ba80cef5473d57919d27dfb62ec804b96180bafdeaf0e090/ruff-0.14.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f24b47993a9d8cb858429e97bdf8544c78029f09b520af615c1d261bf827001d", size = 14460260, upload-time = "2025-12-18T19:29:27.808Z" },
{ url = "https://files.pythonhosted.org/packages/b3/19/9e050c0dca8aba824d67cc0db69fb459c28d8cd3f6855b1405b3f29cc91d/ruff-0.14.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59aabd2e2c4fd614d2862e7939c34a532c04f1084476d6833dddef4afab87e9f", size = 14229978, upload-time = "2025-12-18T19:29:11.32Z" },
{ url = "https://files.pythonhosted.org/packages/51/eb/e8dd1dd6e05b9e695aa9dd420f4577debdd0f87a5ff2fedda33c09e9be8c/ruff-0.14.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:213db2b2e44be8625002dbea33bb9c60c66ea2c07c084a00d55732689d697a7f", size = 14338036, upload-time = "2025-12-18T19:29:09.184Z" },
{ url = "https://files.pythonhosted.org/packages/6a/12/f3e3a505db7c19303b70af370d137795fcfec136d670d5de5391e295c134/ruff-0.14.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b914c40ab64865a17a9a5b67911d14df72346a634527240039eb3bd650e5979d", size = 13264051, upload-time = "2025-12-18T19:29:13.431Z" },
{ url = "https://files.pythonhosted.org/packages/08/64/8c3a47eaccfef8ac20e0484e68e0772013eb85802f8a9f7603ca751eb166/ruff-0.14.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1484983559f026788e3a5c07c81ef7d1e97c1c78ed03041a18f75df104c45405", size = 13283998, upload-time = "2025-12-18T19:29:06.994Z" },
{ url = "https://files.pythonhosted.org/packages/12/84/534a5506f4074e5cc0529e5cd96cfc01bb480e460c7edf5af70d2bcae55e/ruff-0.14.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c70427132db492d25f982fffc8d6c7535cc2fd2c83fc8888f05caaa248521e60", size = 13601891, upload-time = "2025-12-18T19:28:55.811Z" },
{ url = "https://files.pythonhosted.org/packages/0d/1e/14c916087d8598917dbad9b2921d340f7884824ad6e9c55de948a93b106d/ruff-0.14.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5bcf45b681e9f1ee6445d317ce1fa9d6cba9a6049542d1c3d5b5958986be8830", size = 14336660, upload-time = "2025-12-18T19:29:16.531Z" },
{ url = "https://files.pythonhosted.org/packages/f2/1c/d7b67ab43f30013b47c12b42d1acd354c195351a3f7a1d67f59e54227ede/ruff-0.14.10-py3-none-win32.whl", hash = "sha256:104c49fc7ab73f3f3a758039adea978869a918f31b73280db175b43a2d9b51d6", size = 13196187, upload-time = "2025-12-18T19:29:19.006Z" },
{ url = "https://files.pythonhosted.org/packages/fb/9c/896c862e13886fae2af961bef3e6312db9ebc6adc2b156fe95e615dee8c1/ruff-0.14.10-py3-none-win_amd64.whl", hash = "sha256:466297bd73638c6bdf06485683e812db1c00c7ac96d4ddd0294a338c62fdc154", size = 14661283, upload-time = "2025-12-18T19:29:30.16Z" },
{ url = "https://files.pythonhosted.org/packages/74/31/b0e29d572670dca3674eeee78e418f20bdf97fa8aa9ea71380885e175ca0/ruff-0.14.10-py3-none-win_arm64.whl", hash = "sha256:e51d046cf6dda98a4633b8a8a771451107413b0f07183b2bef03f075599e44e6", size = 13729839, upload-time = "2025-12-18T19:28:48.636Z" },
]
[[package]]
name = "ty"
version = "0.0.10"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b7/85/97b5276baa217e05db2fe3d5c61e4dfd35d1d3d0ec95bfca1986820114e0/ty-0.0.10.tar.gz", hash = "sha256:0a1f9f7577e56cd508a8f93d0be2a502fdf33de6a7d65a328a4c80b784f4ac5f", size = 4892892, upload-time = "2026-01-07T23:00:23.572Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0c/7a/5a7147ce5231c3ccc55d6f945dabd7412e233e755d28093bfdec988ba595/ty-0.0.10-py3-none-linux_armv6l.whl", hash = "sha256:406a8ea4e648551f885629b75dc3f070427de6ed099af45e52051d4c68224829", size = 9835881, upload-time = "2026-01-07T22:08:17.492Z" },
{ url = "https://files.pythonhosted.org/packages/3e/7d/89f4d2277c938332d047237b47b11b82a330dbff4fff0de8574cba992128/ty-0.0.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d6e0a733e3d6d3bce56d6766bc61923e8b130241088dc2c05e3c549487190096", size = 9696404, upload-time = "2026-01-07T22:08:37.965Z" },
{ url = "https://files.pythonhosted.org/packages/e8/cd/9dd49e6d40e54d4b7d563f9e2a432c4ec002c0673a81266e269c4bc194ce/ty-0.0.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e4832f8879cb95fc725f7e7fcab4f22be0cf2550f3a50641d5f4409ee04176d4", size = 9181195, upload-time = "2026-01-07T22:59:07.187Z" },
{ url = "https://files.pythonhosted.org/packages/d2/b8/3e7c556654ba0569ed5207138d318faf8633d87e194760fc030543817c26/ty-0.0.10-py3-none-manylinux_2_24_aarch64.whl", hash = "sha256:6b58cc78e5865bc908f053559a80bb77cab0dc168aaad2e88f2b47955694b138", size = 9665002, upload-time = "2026-01-07T22:08:30.782Z" },
{ url = "https://files.pythonhosted.org/packages/98/96/410a483321406c932c4e3aa1581d1072b72cdcde3ae83cd0664a65c7b254/ty-0.0.10-py3-none-manylinux_2_24_armv7l.whl", hash = "sha256:83c6a514bb86f05005fa93e3b173ae3fde94d291d994bed6fe1f1d2e5c7331cf", size = 9664948, upload-time = "2026-01-07T23:04:14.655Z" },
{ url = "https://files.pythonhosted.org/packages/1f/5d/cba2ab3e2f660763a72ad12620d0739db012e047eaa0ceaa252bf5e94ebb/ty-0.0.10-py3-none-manylinux_2_24_i686.whl", hash = "sha256:2e43f71e357f8a4f7fc75e4753b37beb2d0f297498055b1673a9306aa3e21897", size = 10125401, upload-time = "2026-01-07T22:08:28.171Z" },
{ url = "https://files.pythonhosted.org/packages/a7/67/29536e0d97f204a2933122239298e754db4564f4ed7f34e2153012b954be/ty-0.0.10-py3-none-manylinux_2_24_ppc64le.whl", hash = "sha256:18be3c679965c23944c8e574be0635504398c64c55f3f0c46259464e10c0a1c7", size = 10714052, upload-time = "2026-01-07T22:08:20.098Z" },
{ url = "https://files.pythonhosted.org/packages/63/c8/82ac83b79a71c940c5dcacb644f526f0c8fdf4b5e9664065ab7ee7c0e4ec/ty-0.0.10-py3-none-manylinux_2_24_s390x.whl", hash = "sha256:5477981681440a35acdf9b95c3097410c547abaa32b893f61553dbc3b0096fff", size = 10395924, upload-time = "2026-01-07T22:08:22.839Z" },
{ url = "https://files.pythonhosted.org/packages/9e/4c/2f9ac5edbd0e67bf82f5cd04275c4e87cbbf69a78f43e5dcf90c1573d44e/ty-0.0.10-py3-none-manylinux_2_24_x86_64.whl", hash = "sha256:e206a23bd887574302138b33383ae1edfcc39d33a06a12a5a00803b3f0287a45", size = 10220096, upload-time = "2026-01-07T22:08:13.171Z" },
{ url = "https://files.pythonhosted.org/packages/04/13/3be2b7bfd53b9952b39b6f2c2ef55edeb1a2fea3bf0285962736ee26731c/ty-0.0.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4e09ddb0d3396bd59f645b85eab20f9a72989aa8b736b34338dcb5ffecfe77b6", size = 9649120, upload-time = "2026-01-07T22:08:34.003Z" },
{ url = "https://files.pythonhosted.org/packages/93/e3/edd58547d9fd01e4e584cec9dced4f6f283506b422cdd953e946f6a8e9f0/ty-0.0.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:139d2a741579ad86a044233b5d7e189bb81f427eebce3464202f49c3ec0eba3b", size = 9686033, upload-time = "2026-01-07T22:08:40.967Z" },
{ url = "https://files.pythonhosted.org/packages/cc/bc/9d2f5fec925977446d577fb9b322d0e7b1b1758709f23a6cfc10231e9b84/ty-0.0.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6bae10420c0abfe4601fbbc6ce637b67d0b87a44fa520283131a26da98f2e74c", size = 9841905, upload-time = "2026-01-07T23:04:21.694Z" },
{ url = "https://files.pythonhosted.org/packages/7c/b8/5acd3492b6a4ef255ace24fcff0d4b1471a05b7f3758d8910a681543f899/ty-0.0.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7358bbc5d037b9c59c3a48895206058bcd583985316c4125a74dd87fd1767adb", size = 10320058, upload-time = "2026-01-07T22:08:25.645Z" },
{ url = "https://files.pythonhosted.org/packages/35/67/5b6906fccef654c7e801d6ac8dcbe0d493e1f04c38127f82a5e6d7e0aa0e/ty-0.0.10-py3-none-win32.whl", hash = "sha256:f51b6fd485bc695d0fdf555e69e6a87d1c50f14daef6cb980c9c941e12d6bcba", size = 9271806, upload-time = "2026-01-07T22:08:10.08Z" },
{ url = "https://files.pythonhosted.org/packages/42/36/82e66b9753a76964d26fd9bc3514ea0abce0a5ba5ad7d5f084070c6981da/ty-0.0.10-py3-none-win_amd64.whl", hash = "sha256:16deb77a72cf93b89b4d29577829613eda535fbe030513dfd9fba70fe38bc9f5", size = 10130520, upload-time = "2026-01-07T23:04:11.759Z" },
{ url = "https://files.pythonhosted.org/packages/63/52/89da123f370e80b587d2db8551ff31562c882d87b32b0e92b59504b709ae/ty-0.0.10-py3-none-win_arm64.whl", hash = "sha256:7495288bca7afba9a4488c9906466d648ffd3ccb6902bc3578a6dbd91a8f05f0", size = 9626026, upload-time = "2026-01-07T23:04:17.91Z" },
{ url = "https://files.pythonhosted.org/packages/f0/a6/a4c40a5aaa7e331f245d2dc1ac8ece306681f52b636b40ef87c88b9f7afd/ruff-0.14.11-py3-none-linux_armv6l.whl", hash = "sha256:f6ff2d95cbd335841a7217bdfd9c1d2e44eac2c584197ab1385579d55ff8830e", size = 12951208, upload-time = "2026-01-08T19:12:09.218Z" },
{ url = "https://files.pythonhosted.org/packages/5c/5c/360a35cb7204b328b685d3129c08aca24765ff92b5a7efedbdd6c150d555/ruff-0.14.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f6eb5c1c8033680f4172ea9c8d3706c156223010b8b97b05e82c59bdc774ee6", size = 13330075, upload-time = "2026-01-08T19:12:02.549Z" },
{ url = "https://files.pythonhosted.org/packages/1b/9e/0cc2f1be7a7d33cae541824cf3f95b4ff40d03557b575912b5b70273c9ec/ruff-0.14.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f2fc34cc896f90080fca01259f96c566f74069a04b25b6205d55379d12a6855e", size = 12257809, upload-time = "2026-01-08T19:12:00.366Z" },
{ url = "https://files.pythonhosted.org/packages/a7/e5/5faab97c15bb75228d9f74637e775d26ac703cc2b4898564c01ab3637c02/ruff-0.14.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53386375001773ae812b43205d6064dae49ff0968774e6befe16a994fc233caa", size = 12678447, upload-time = "2026-01-08T19:12:13.899Z" },
{ url = "https://files.pythonhosted.org/packages/1b/33/e9767f60a2bef779fb5855cab0af76c488e0ce90f7bb7b8a45c8a2ba4178/ruff-0.14.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a697737dce1ca97a0a55b5ff0434ee7205943d4874d638fe3ae66166ff46edbe", size = 12758560, upload-time = "2026-01-08T19:11:42.55Z" },
{ url = "https://files.pythonhosted.org/packages/eb/84/4c6cf627a21462bb5102f7be2a320b084228ff26e105510cd2255ea868e5/ruff-0.14.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6845ca1da8ab81ab1dce755a32ad13f1db72e7fba27c486d5d90d65e04d17b8f", size = 13599296, upload-time = "2026-01-08T19:11:30.371Z" },
{ url = "https://files.pythonhosted.org/packages/88/e1/92b5ed7ea66d849f6157e695dc23d5d6d982bd6aa8d077895652c38a7cae/ruff-0.14.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e36ce2fd31b54065ec6f76cb08d60159e1b32bdf08507862e32f47e6dde8bcbf", size = 15048981, upload-time = "2026-01-08T19:12:04.742Z" },
{ url = "https://files.pythonhosted.org/packages/61/df/c1bd30992615ac17c2fb64b8a7376ca22c04a70555b5d05b8f717163cf9f/ruff-0.14.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:590bcc0e2097ecf74e62a5c10a6b71f008ad82eb97b0a0079e85defe19fe74d9", size = 14633183, upload-time = "2026-01-08T19:11:40.069Z" },
{ url = "https://files.pythonhosted.org/packages/04/e9/fe552902f25013dd28a5428a42347d9ad20c4b534834a325a28305747d64/ruff-0.14.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:53fe71125fc158210d57fe4da26e622c9c294022988d08d9347ec1cf782adafe", size = 14050453, upload-time = "2026-01-08T19:11:37.555Z" },
{ url = "https://files.pythonhosted.org/packages/ae/93/f36d89fa021543187f98991609ce6e47e24f35f008dfe1af01379d248a41/ruff-0.14.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a35c9da08562f1598ded8470fcfef2afb5cf881996e6c0a502ceb61f4bc9c8a3", size = 13757889, upload-time = "2026-01-08T19:12:07.094Z" },
{ url = "https://files.pythonhosted.org/packages/b7/9f/c7fb6ecf554f28709a6a1f2a7f74750d400979e8cd47ed29feeaa1bd4db8/ruff-0.14.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0f3727189a52179393ecf92ec7057c2210203e6af2676f08d92140d3e1ee72c1", size = 13955832, upload-time = "2026-01-08T19:11:55.064Z" },
{ url = "https://files.pythonhosted.org/packages/db/a0/153315310f250f76900a98278cf878c64dfb6d044e184491dd3289796734/ruff-0.14.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:eb09f849bd37147a789b85995ff734a6c4a095bed5fd1608c4f56afc3634cde2", size = 12586522, upload-time = "2026-01-08T19:11:35.356Z" },
{ url = "https://files.pythonhosted.org/packages/2f/2b/a73a2b6e6d2df1d74bf2b78098be1572191e54bec0e59e29382d13c3adc5/ruff-0.14.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:c61782543c1231bf71041461c1f28c64b961d457d0f238ac388e2ab173d7ecb7", size = 12724637, upload-time = "2026-01-08T19:11:47.796Z" },
{ url = "https://files.pythonhosted.org/packages/f0/41/09100590320394401cd3c48fc718a8ba71c7ddb1ffd07e0ad6576b3a3df2/ruff-0.14.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82ff352ea68fb6766140381748e1f67f83c39860b6446966cff48a315c3e2491", size = 13145837, upload-time = "2026-01-08T19:11:32.87Z" },
{ url = "https://files.pythonhosted.org/packages/3b/d8/e035db859d1d3edf909381eb8ff3e89a672d6572e9454093538fe6f164b0/ruff-0.14.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:728e56879df4ca5b62a9dde2dd0eb0edda2a55160c0ea28c4025f18c03f86984", size = 13850469, upload-time = "2026-01-08T19:12:11.694Z" },
{ url = "https://files.pythonhosted.org/packages/4e/02/bb3ff8b6e6d02ce9e3740f4c17dfbbfb55f34c789c139e9cd91985f356c7/ruff-0.14.11-py3-none-win32.whl", hash = "sha256:337c5dd11f16ee52ae217757d9b82a26400be7efac883e9e852646f1557ed841", size = 12851094, upload-time = "2026-01-08T19:11:45.163Z" },
{ url = "https://files.pythonhosted.org/packages/58/f1/90ddc533918d3a2ad628bc3044cdfc094949e6d4b929220c3f0eb8a1c998/ruff-0.14.11-py3-none-win_amd64.whl", hash = "sha256:f981cea63d08456b2c070e64b79cb62f951aa1305282974d4d5216e6e0178ae6", size = 14001379, upload-time = "2026-01-08T19:11:52.591Z" },
{ url = "https://files.pythonhosted.org/packages/c4/1c/1dbe51782c0e1e9cfce1d1004752672d2d4629ea46945d19d731ad772b3b/ruff-0.14.11-py3-none-win_arm64.whl", hash = "sha256:649fb6c9edd7f751db276ef42df1f3df41c38d67d199570ae2a7bd6cbc3590f0", size = 12938644, upload-time = "2026-01-08T19:11:50.027Z" },
]