wt-task 0.1.2__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {wt_task-0.1.2 → wt_task-0.1.3}/CHANGELOG.md +4 -0
  2. {wt_task-0.1.2/src/wt_task.egg-info → wt_task-0.1.3}/PKG-INFO +1 -1
  3. {wt_task-0.1.2 → wt_task-0.1.3}/pyproject.toml +47 -11
  4. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/__init__.py +9 -13
  5. wt_task-0.1.3/src/wt_task/_version.py +24 -0
  6. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/async_task.py +7 -2
  7. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/base.py +5 -4
  8. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/exceptions.py +1 -1
  9. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/executors/base.py +4 -4
  10. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/skip.py +4 -4
  11. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/sync_task.py +9 -9
  12. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/testing.py +14 -11
  13. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/tracing/_config.py +2 -5
  14. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/tracing/_decorator.py +1 -1
  15. {wt_task-0.1.2 → wt_task-0.1.3/src/wt_task.egg-info}/PKG-INFO +1 -1
  16. {wt_task-0.1.2 → wt_task-0.1.3}/tests/test_testing.py +10 -5
  17. {wt_task-0.1.2 → wt_task-0.1.3}/tests/test_tracing.py +4 -2
  18. {wt_task-0.1.2 → wt_task-0.1.3}/uv.lock +178 -1
  19. wt_task-0.1.2/src/wt_task/_version.py +0 -34
  20. {wt_task-0.1.2 → wt_task-0.1.3}/README.md +0 -0
  21. {wt_task-0.1.2 → wt_task-0.1.3}/setup.cfg +0 -0
  22. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/decorator.py +0 -0
  23. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/executors/__init__.py +1 -1
  24. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/executors/python.py +0 -0
  25. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/py.typed +0 -0
  26. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task/tracing/__init__.py +1 -1
  27. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task.egg-info/SOURCES.txt +0 -0
  28. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task.egg-info/dependency_links.txt +0 -0
  29. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task.egg-info/requires.txt +0 -0
  30. {wt_task-0.1.2 → wt_task-0.1.3}/src/wt_task.egg-info/top_level.txt +0 -0
  31. {wt_task-0.1.2 → wt_task-0.1.3}/tests/test_decorator.py +0 -0
  32. {wt_task-0.1.2 → wt_task-0.1.3}/tests/test_exceptions.py +0 -0
  33. {wt_task-0.1.2 → wt_task-0.1.3}/tests/test_executors.py +0 -0
  34. {wt_task-0.1.2 → wt_task-0.1.3}/tests/test_map.py +0 -0
  35. {wt_task-0.1.2 → wt_task-0.1.3}/tests/test_mapvalues.py +0 -0
  36. {wt_task-0.1.2 → wt_task-0.1.3}/tests/test_partial.py +0 -0
  37. {wt_task-0.1.2 → wt_task-0.1.3}/tests/test_skip.py +0 -0
  38. {wt_task-0.1.2 → wt_task-0.1.3}/tests/test_validation.py +0 -0
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.1.3 — 2026-05-13
4
+
5
+ - Standardize ruff lint config to enforce type annotations and Google-style docstrings; convert module/class/function docstrings accordingly ([#155](https://github.com/wildlife-dynamics/wt/pull/155))
6
+
3
7
  ## v0.1.2 — 2026-03-13
4
8
 
5
9
  - `configure_tracer()` and `attach_context()` now warn instead of raising `ImportError` when tracing deps are missing ([#60](https://github.com/wildlife-dynamics/wt/pull/60))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wt-task
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Task decorator and execution features for wt ecosystem
5
5
  Author: Ecoscope Workflows Team
6
6
  License: BSD-3-Clause
@@ -101,21 +101,57 @@ line-length = 100
101
101
  target-version = "py310"
102
102
 
103
103
  [tool.ruff.lint]
104
- select = [
105
- "E", # pycodestyle errors
106
- "W", # pycodestyle warnings
107
- "F", # pyflakes
108
- "I", # isort
109
- "B", # flake8-bugbear
110
- "C4", # flake8-comprehensions
111
- "UP", # pyupgrade
104
+ extend-select = [
105
+ # already-explicit families (kept; F dropped — it's a default)
106
+ "E", # pycodestyle errors (extends defaults E4/E7/E9 with E1/E2/E5)
107
+ "W", # pycodestyle warnings
108
+ "I", # isort
109
+ "B", # flake8-bugbear
110
+ "C4", # flake8-comprehensions
111
+ "UP", # pyupgrade
112
+ "N", # pep8-naming
113
+ "RUF", # ruff-specific
114
+ "PLC0415", # import-outside-top-level (mandatory per CLAUDE.md)
115
+
116
+ # CLAUDE.md mandates, now enforced
117
+ "ANN", # flake8-annotations (require complete type annotations)
118
+ "D", # pydocstyle (require docstrings on public API)
119
+
120
+ # high-value / low-noise modernizers
121
+ "SIM", # flake8-simplify
122
+ "RET", # flake8-return
123
+ "PIE", # flake8-pie
124
+ "PTH", # flake8-use-pathlib
125
+ "ICN", # flake8-import-conventions
126
+ "TID", # flake8-tidy-imports
127
+ "TC", # flake8-type-checking
128
+ "ISC", # flake8-implicit-str-concat
129
+ "YTT", # flake8-2020
130
+ "PERF", # Perflint
131
+ "FURB", # refurb
132
+ "LOG", # flake8-logging
133
+ "G", # flake8-logging-format
134
+ "PT", # flake8-pytest-style
135
+ "ASYNC", # flake8-async
136
+
137
+ # security / strictness (require per-file-ignores)
138
+ "S", # flake8-bandit
139
+ "ARG", # flake8-unused-arguments
140
+ "BLE", # flake8-blind-except
141
+ "PLE", # Pylint errors
142
+ "PLW", # Pylint warnings
112
143
  ]
113
144
  ignore = [
114
- "E501", # line too long (handled by formatter)
145
+ "E501", # line length — handled by formatter
146
+ "ISC001", # conflicts with formatter (ruff docs recommend disabling)
115
147
  ]
116
148
 
149
+ [tool.ruff.lint.pydocstyle]
150
+ convention = "google"
151
+
117
152
  [tool.ruff.lint.per-file-ignores]
118
- "__init__.py" = ["F401"] # unused imports in __init__.py are often intentional
153
+ "__init__.py" = ["F401", "D104"] # re-exports + missing module docstring
154
+ "tests/**/*.py" = ["D", "S101", "ANN", "ARG", "PT011"] # tests don't need docstrings/annotations; assert OK
119
155
 
120
156
  # ============================================================================
121
157
  # Pixi Build Configuration (conda package building)
@@ -123,7 +159,7 @@ ignore = [
123
159
 
124
160
  [tool.pixi.package]
125
161
  name = "wt-task"
126
- version = "0.1.2"
162
+ version = "0.1.3"
127
163
 
128
164
  [tool.pixi.package.build]
129
165
  backend = { name = "pixi-build-python", version = "*", channels = ["conda-forge", "https://prefix.dev/pixi-build-backends"] }
@@ -24,25 +24,21 @@ from .skip import (
24
24
  from .sync_task import SyncTask
25
25
 
26
26
  __all__ = [
27
- # Main decorator and task types
28
- "task",
29
- "Task",
30
- "SyncTask",
31
- "AsyncTask",
32
- # Exceptions
33
- "TaskInstanceError",
34
- "handle_errors",
35
- # Executors
36
- "SyncExecutor",
27
+ "SKIP_SENTINEL",
37
28
  "AsyncExecutor",
38
- "PythonExecutor",
29
+ "AsyncTask",
39
30
  "Future",
40
31
  "FutureSequence",
41
- # Skip utilities
32
+ "PythonExecutor",
42
33
  "SkipSentinel",
43
- "SKIP_SENTINEL",
44
34
  "SkippedDependencyFallback",
35
+ "SyncExecutor",
36
+ "SyncTask",
37
+ "Task",
38
+ "TaskInstanceError",
39
+ "handle_errors",
45
40
  "skipif",
41
+ "task",
46
42
  "unpack_listlike",
47
43
  ]
48
44
 
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.1.3'
22
+ __version_tuple__ = version_tuple = (0, 1, 3)
23
+
24
+ __commit_id__ = commit_id = 'g5f0f25f'
@@ -6,7 +6,6 @@ returns Future objects.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- from collections.abc import Sequence
10
9
  from dataclasses import dataclass
11
10
 
12
11
  try:
@@ -16,8 +15,9 @@ try:
16
15
  except ImportError:
17
16
  TRACING_AVAILABLE = False
18
17
 
18
+ from typing import TYPE_CHECKING
19
+
19
20
  from .base import K, P, R, V, _Task
20
- from .executors import AsyncExecutor, Future, FutureSequence
21
21
  from .sync_task import (
22
22
  _create_kwargs_iterable,
23
23
  _create_mapvalues_kwargs_iterable,
@@ -25,6 +25,11 @@ from .sync_task import (
25
25
  _wrap_for_mapvalues,
26
26
  )
27
27
 
28
+ if TYPE_CHECKING:
29
+ from collections.abc import Sequence
30
+
31
+ from .executors import AsyncExecutor, Future, FutureSequence
32
+
28
33
 
29
34
  @dataclass(frozen=True)
30
35
  class AsyncTask(_Task[P, R, K, V]):
@@ -9,7 +9,6 @@ from __future__ import annotations
9
9
  import functools
10
10
  import sys
11
11
  import warnings
12
- from collections.abc import Callable
13
12
  from dataclasses import dataclass, replace
14
13
  from typing import TYPE_CHECKING, Generic, Literal, ParamSpec, TypeVar, overload
15
14
 
@@ -19,6 +18,8 @@ else:
19
18
  from typing_extensions import Self
20
19
 
21
20
  if TYPE_CHECKING:
21
+ from collections.abc import Callable
22
+
22
23
  from .async_task import AsyncTask
23
24
  from .sync_task import SyncTask
24
25
 
@@ -290,9 +291,9 @@ class _Task(Generic[P, R, K, V]):
290
291
  >>> type(custom.executor).__name__
291
292
  'PythonExecutor'
292
293
  """
293
- # Import here to avoid circular imports
294
- from .async_task import AsyncTask
295
- from .sync_task import SyncTask
294
+ # circular import: AsyncTask/SyncTask subclass _Task defined here
295
+ from .async_task import AsyncTask # noqa: PLC0415
296
+ from .sync_task import SyncTask # noqa: PLC0415
296
297
 
297
298
  match name_or_executor:
298
299
  case "python":
@@ -88,7 +88,7 @@ def handle_errors(func: Callable[..., Any], *, task_instance_id: str) -> Callabl
88
88
  """
89
89
 
90
90
  @wraps(func)
91
- def wrapper(*args: Any, **kwargs: Any) -> Any:
91
+ def wrapper(*args: Any, **kwargs: Any) -> Any: # noqa: ANN401 # generic wrapper passes args through
92
92
  try:
93
93
  return func(*args, **kwargs)
94
94
  except Exception as e:
@@ -6,7 +6,7 @@ task execution, along with Future types for async results.
6
6
 
7
7
  from abc import ABC, abstractmethod
8
8
  from collections.abc import Callable, Iterable, Sequence
9
- from typing import Generic, ParamSpec, TypeVar
9
+ from typing import Any, Generic, ParamSpec, TypeVar
10
10
 
11
11
  P = ParamSpec("P")
12
12
  R = TypeVar("R")
@@ -79,7 +79,7 @@ class Future(ABC, Generic[R]):
79
79
  """
80
80
 
81
81
  @abstractmethod
82
- def gather(self, *args, **kwargs) -> R: # type: ignore[no-untyped-def]
82
+ def gather(self, *args: Any, **kwargs: Any) -> R: # noqa: ANN401 # implementation-specific args
83
83
  """Block until result is available and return it.
84
84
 
85
85
  Args:
@@ -110,7 +110,7 @@ class FutureSequence(ABC, Generic[R]):
110
110
  """
111
111
 
112
112
  @abstractmethod
113
- def gather(self, *args, **kwargs) -> Sequence[R]: # type: ignore[no-untyped-def]
113
+ def gather(self, *args: Any, **kwargs: Any) -> Sequence[R]: # noqa: ANN401 # implementation-specific args
114
114
  """Block until all results are available and return them.
115
115
 
116
116
  Args:
@@ -180,7 +180,7 @@ class AsyncExecutor(ABC, Generic[P, R]):
180
180
  ...
181
181
 
182
182
 
183
- class mapvalues_wrapper(Generic[K, V, R]):
183
+ class mapvalues_wrapper(Generic[K, V, R]): # noqa: N801 # public API; renaming would break callers
184
184
  """Wrapper for mapvalues operations that preserves keys.
185
185
 
186
186
  This wrapper takes a function that accepts keyword arguments and wraps it
@@ -41,13 +41,14 @@ class SkipSentinel:
41
41
  def __get_pydantic_core_schema__(
42
42
  cls, source_type: type, handler: GetCoreSchemaHandler
43
43
  ) -> cs.CoreSchema:
44
+ """Return a Pydantic core schema that matches instances of this class."""
44
45
  return cs.is_instance_schema(cls)
45
46
 
46
47
  @classmethod
47
48
  def __get_pydantic_json_schema__(
48
49
  cls, core_schema: cs.CoreSchema, handler: GetJsonSchemaHandler
49
50
  ) -> JsonSchemaValue:
50
- # SkipSentinel represents "skipped/no value" - maps to null in JSON Schema
51
+ """Map this sentinel to JSON Schema null since it represents an absent value."""
51
52
  return {"type": "null", "title": "SkipSentinel"}
52
53
 
53
54
 
@@ -136,12 +137,11 @@ def skipif(
136
137
  """
137
138
 
138
139
  @wraps(func)
139
- def wrapper(*args: Any, **kwargs: Any) -> Any:
140
+ def wrapper(*args: Any, **kwargs: Any) -> Any: # noqa: ANN401 # generic wrapper passes args through
140
141
  argvalues = list(args) + list(kwargs.values())
141
142
  to_evaluate = unpack_listlike(argvalues, unpack_depth)
142
143
  if any(condition(*to_evaluate) for condition in conditions):
143
144
  return SKIP_SENTINEL
144
- else:
145
- return func(*args, **kwargs)
145
+ return func(*args, **kwargs)
146
146
 
147
147
  return wrapper
@@ -5,10 +5,10 @@ This module provides the SyncTask class for synchronous task execution.
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
+ import functools
8
9
  import inspect
9
- from collections.abc import Callable, Sequence
10
10
  from dataclasses import dataclass, field
11
- from typing import Any, cast, overload
11
+ from typing import TYPE_CHECKING, Any, cast, overload
12
12
 
13
13
  try:
14
14
  from opentelemetry import trace
@@ -22,6 +22,9 @@ from .executors import SyncExecutor, mapvalues_wrapper
22
22
  from .executors.python import PythonExecutor
23
23
  from .skip import SkipSentinel
24
24
 
25
+ if TYPE_CHECKING:
26
+ from collections.abc import Callable, Sequence
27
+
25
28
  # Helper functions
26
29
 
27
30
 
@@ -67,11 +70,10 @@ def _create_kwargs_iterable(
67
70
  argvalues_list: list[tuple[Any, ...]] = (
68
71
  [(v,) for v in argvalues]
69
72
  if not isinstance(argvalues[0], tuple)
70
- else cast(list[tuple[Any, ...]], argvalues)
71
- )
72
- assert all(len(v) == len(argnames) for v in argvalues_list), (
73
- "All values in `argvalues` must have the same length as `argnames`."
73
+ else cast("list[tuple[Any, ...]]", argvalues)
74
74
  )
75
+ if not all(len(v) == len(argnames) for v in argvalues_list):
76
+ raise ValueError("All values in `argvalues` must have the same length as `argnames`.")
75
77
  return [
76
78
  defaults | {argnames[i]: argvalues_list[j][i] for i in range(len(argnames))}
77
79
  for j in range(len(argvalues_list))
@@ -105,7 +107,7 @@ def _create_mapvalues_kwargs_iterable(
105
107
  kwargs_iterable: list[tuple[K, dict[str, Any]]] = []
106
108
  for argvalue in argvalues:
107
109
  key = argvalue[0]
108
- values = [argvalue[1]] if len(argnames) == 1 else cast(list[Any], argvalue[1])
110
+ values = [argvalue[1]] if len(argnames) == 1 else cast("list[Any]", argvalue[1])
109
111
 
110
112
  if len(values) != len(argnames):
111
113
  raise ValueError(
@@ -128,8 +130,6 @@ def _wrap_for_mapvalues(
128
130
  Returns:
129
131
  Wrapped function that accepts (key, kwargs) and returns (key, result)
130
132
  """
131
- import functools
132
-
133
133
  wrapper: mapvalues_wrapper[Any, dict[str, Any], R] = mapvalues_wrapper(func)
134
134
  functools.update_wrapper(wrapper, func)
135
135
  return wrapper
@@ -17,11 +17,13 @@ import importlib.resources
17
17
  import inspect
18
18
  import json
19
19
  import os
20
- from collections.abc import Callable
21
20
  from pathlib import Path
22
- from typing import Any, cast
21
+ from typing import TYPE_CHECKING, Any, cast
23
22
  from unittest.mock import MagicMock
24
23
 
24
+ if TYPE_CHECKING:
25
+ from collections.abc import Callable
26
+
25
27
 
26
28
  def _import_func(anchor: str, func_name: str) -> Callable[..., Any]:
27
29
  """Import a registered function from a module.
@@ -42,8 +44,8 @@ def _import_func(anchor: str, func_name: str) -> Callable[..., Any]:
42
44
  """
43
45
  module = importlib.import_module(anchor)
44
46
  attr = getattr(module, func_name)
45
- assert callable(attr), f"{anchor}.{func_name} is {type(attr).__name__}, expected callable"
46
- return cast(Callable[..., Any], attr)
47
+ assert callable(attr), f"{anchor}.{func_name} is {type(attr).__name__}, expected callable" # noqa: S101 # internal invariant; callers test for AssertionError
48
+ return cast("Callable[..., Any]", attr)
47
49
 
48
50
 
49
51
  def _env_var_name(anchor: str, func_name: str) -> str:
@@ -107,15 +109,16 @@ def _find_example_return_path(anchor: str, func_name: str) -> Path:
107
109
  for p in importlib.resources.files(anchor).iterdir()
108
110
  if hasattr(p, "name") and Path(p.name).stem == expected_stem
109
111
  ]
110
- assert len(matches) == 1, (
111
- f"Expected exactly 1 example-return file matching '{expected_stem}.*' "
112
- f"in {anchor}, found {len(matches)}: {[m.name for m in matches]}"
113
- )
112
+ if len(matches) != 1:
113
+ raise FileNotFoundError(
114
+ f"Expected exactly 1 example-return file matching '{expected_stem}.*' "
115
+ f"in {anchor}, found {len(matches)}: {[m.name for m in matches]}"
116
+ )
114
117
  # importlib.resources traversables may not be real Paths; resolve via str
115
118
  return Path(str(matches[0]))
116
119
 
117
120
 
118
- def _load_json(path: Path) -> Any:
121
+ def _load_json(path: Path) -> Any: # noqa: ANN401 # JSON content is dynamic
119
122
  """Load a JSON file.
120
123
 
121
124
  Args:
@@ -124,7 +127,7 @@ def _load_json(path: Path) -> Any:
124
127
  Returns:
125
128
  Parsed JSON content.
126
129
  """
127
- with open(path) as f:
130
+ with path.open() as f:
128
131
  return json.load(f)
129
132
 
130
133
 
@@ -156,7 +159,7 @@ def _discover_loaders() -> dict[str, Callable[[Path], Any]]:
156
159
  return loaders
157
160
 
158
161
 
159
- def _load_example_return(path: Path) -> Any:
162
+ def _load_example_return(path: Path) -> Any: # noqa: ANN401 # loaded data is dynamic
160
163
  """Load example-return data by dispatching on file extension.
161
164
 
162
165
  Args:
@@ -7,6 +7,7 @@ Note: This is adapted from https://github.com/PADAS/cdip-routing.
7
7
  """
8
8
 
9
9
  import os
10
+ import warnings
10
11
  from pathlib import Path
11
12
  from typing import Literal
12
13
 
@@ -68,7 +69,7 @@ def make_otel_console_exporter_file_dst_kws(target_dir: Path) -> dict[str, objec
68
69
  """
69
70
  if target_dir.exists() and not target_dir.is_dir():
70
71
  raise ValueError(f"Target dir {target_dir} exists but is not a directory")
71
- elif not target_dir.exists():
72
+ if not target_dir.exists():
72
73
  target_dir.mkdir(parents=True, exist_ok=True)
73
74
  traces_outpath = target_dir / "otel_traces.jsonl"
74
75
  return {
@@ -110,8 +111,6 @@ def configure_tracer(
110
111
  >>> configure_tracer("my-service", "1.0.0", "console", kws)
111
112
  """
112
113
  if not TRACING_AVAILABLE:
113
- import warnings
114
-
115
114
  warnings.warn(
116
115
  "OpenTelemetry dependencies not installed. Tracing is disabled. "
117
116
  "Install with: pip install wt-task[gcp]",
@@ -194,8 +193,6 @@ def attach_context(traceparent: str, tracestate: str | None = None) -> None:
194
193
  ... )
195
194
  """
196
195
  if not TRACING_AVAILABLE:
197
- import warnings
198
-
199
196
  warnings.warn(
200
197
  "OpenTelemetry dependencies not installed. Cannot attach trace context. "
201
198
  "Install with: pip install wt-task[gcp]",
@@ -44,7 +44,7 @@ def with_tracing(func: F) -> F:
44
44
  return func
45
45
 
46
46
  @wraps(func)
47
- def wrapper(*args: Any, **kwargs: Any) -> Any:
47
+ def wrapper(*args: Any, **kwargs: Any) -> Any: # noqa: ANN401 # generic wrapper passes args through
48
48
  tracer = get_tracer(__name__)
49
49
  with tracer.start_as_current_span(
50
50
  func.__name__,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wt-task
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Task decorator and execution features for wt ecosystem
5
5
  Author: Ecoscope Workflows Team
6
6
  License: BSD-3-Clause
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import importlib.metadata
6
6
  import json
7
7
  import types
8
- from pathlib import Path
8
+ from typing import TYPE_CHECKING
9
9
  from unittest.mock import MagicMock, patch
10
10
 
11
11
  import pytest
@@ -20,6 +20,9 @@ from wt_task.testing import (
20
20
  create_func_magicmock,
21
21
  )
22
22
 
23
+ if TYPE_CHECKING:
24
+ from pathlib import Path
25
+
23
26
  # ---------------------------------------------------------------------------
24
27
  # Fixtures
25
28
  # ---------------------------------------------------------------------------
@@ -52,9 +55,11 @@ def test_import_func_not_callable():
52
55
  fake_module = types.ModuleType("fake_module_bad")
53
56
  fake_module.not_a_func = "just a string" # type: ignore[attr-defined]
54
57
 
55
- with patch.dict("sys.modules", {"fake_module_bad": fake_module}):
56
- with pytest.raises(AssertionError, match="expected callable"):
57
- _import_func("fake_module_bad", "not_a_func")
58
+ with (
59
+ patch.dict("sys.modules", {"fake_module_bad": fake_module}),
60
+ pytest.raises(AssertionError, match="expected callable"),
61
+ ):
62
+ _import_func("fake_module_bad", "not_a_func")
58
63
 
59
64
 
60
65
  # ---------------------------------------------------------------------------
@@ -111,7 +116,7 @@ def test_load_example_return_unknown_extension(tmp_path: Path):
111
116
  fixture = tmp_path / "data.xyz"
112
117
  fixture.write_text("stuff")
113
118
 
114
- with pytest.raises(ValueError, match="No loader registered for extension '.xyz'"):
119
+ with pytest.raises(ValueError, match=r"No loader registered for extension '\.xyz'"):
115
120
  _load_example_return(fixture)
116
121
 
117
122
 
@@ -6,7 +6,8 @@ import pytest
6
6
  def test_tracing_available_with_gcp_extra():
7
7
  """TRACING_AVAILABLE is True when gcp extra is installed."""
8
8
  pytest.importorskip("opentelemetry")
9
- from wt_task.tracing._config import TRACING_AVAILABLE
9
+ # optional-dep presence test
10
+ from wt_task.tracing._config import TRACING_AVAILABLE # noqa: PLC0415
10
11
 
11
12
  assert TRACING_AVAILABLE is True
12
13
 
@@ -14,6 +15,7 @@ def test_tracing_available_with_gcp_extra():
14
15
  def test_cloud_trace_exporter_importable():
15
16
  """CloudTraceSpanExporter can be imported when gcp extra is installed."""
16
17
  pytest.importorskip("opentelemetry.exporter.cloud_trace")
17
- from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
18
+ # optional-dep presence test
19
+ from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter # noqa: PLC0415
18
20
 
19
21
  assert CloudTraceSpanExporter is not None
@@ -17,6 +17,15 @@ wheels = [
17
17
  { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
18
18
  ]
19
19
 
20
+ [[package]]
21
+ name = "attrs"
22
+ version = "26.1.0"
23
+ source = { registry = "https://pypi.org/simple" }
24
+ sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" }
25
+ wheels = [
26
+ { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" },
27
+ ]
28
+
20
29
  [[package]]
21
30
  name = "backports-asyncio-runner"
22
31
  version = "1.2.0"
@@ -427,6 +436,33 @@ wheels = [
427
436
  { 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" },
428
437
  ]
429
438
 
439
+ [[package]]
440
+ name = "jsonschema"
441
+ version = "4.26.0"
442
+ source = { registry = "https://pypi.org/simple" }
443
+ dependencies = [
444
+ { name = "attrs" },
445
+ { name = "jsonschema-specifications" },
446
+ { name = "referencing" },
447
+ { name = "rpds-py" },
448
+ ]
449
+ sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" }
450
+ wheels = [
451
+ { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" },
452
+ ]
453
+
454
+ [[package]]
455
+ name = "jsonschema-specifications"
456
+ version = "2025.9.1"
457
+ source = { registry = "https://pypi.org/simple" }
458
+ dependencies = [
459
+ { name = "referencing" },
460
+ ]
461
+ 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" }
462
+ wheels = [
463
+ { 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" },
464
+ ]
465
+
430
466
  [[package]]
431
467
  name = "librt"
432
468
  version = "0.7.4"
@@ -888,6 +924,20 @@ wheels = [
888
924
  { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" },
889
925
  ]
890
926
 
927
+ [[package]]
928
+ name = "referencing"
929
+ version = "0.37.0"
930
+ source = { registry = "https://pypi.org/simple" }
931
+ dependencies = [
932
+ { name = "attrs" },
933
+ { name = "rpds-py" },
934
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
935
+ ]
936
+ 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" }
937
+ wheels = [
938
+ { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" },
939
+ ]
940
+
891
941
  [[package]]
892
942
  name = "requests"
893
943
  version = "2.32.5"
@@ -903,6 +953,128 @@ wheels = [
903
953
  { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" },
904
954
  ]
905
955
 
956
+ [[package]]
957
+ name = "rpds-py"
958
+ version = "0.30.0"
959
+ source = { registry = "https://pypi.org/simple" }
960
+ sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" }
961
+ wheels = [
962
+ { url = "https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288", size = 370490, upload-time = "2025-11-30T20:21:33.256Z" },
963
+ { url = "https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00", size = 359751, upload-time = "2025-11-30T20:21:34.591Z" },
964
+ { url = "https://files.pythonhosted.org/packages/cd/7c/e4933565ef7f7a0818985d87c15d9d273f1a649afa6a52ea35ad011195ea/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6", size = 389696, upload-time = "2025-11-30T20:21:36.122Z" },
965
+ { url = "https://files.pythonhosted.org/packages/5e/01/6271a2511ad0815f00f7ed4390cf2567bec1d4b1da39e2c27a41e6e3b4de/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7", size = 403136, upload-time = "2025-11-30T20:21:37.728Z" },
966
+ { url = "https://files.pythonhosted.org/packages/55/64/c857eb7cd7541e9b4eee9d49c196e833128a55b89a9850a9c9ac33ccf897/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324", size = 524699, upload-time = "2025-11-30T20:21:38.92Z" },
967
+ { url = "https://files.pythonhosted.org/packages/9c/ed/94816543404078af9ab26159c44f9e98e20fe47e2126d5d32c9d9948d10a/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df", size = 412022, upload-time = "2025-11-30T20:21:40.407Z" },
968
+ { url = "https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3", size = 390522, upload-time = "2025-11-30T20:21:42.17Z" },
969
+ { url = "https://files.pythonhosted.org/packages/13/4e/57a85fda37a229ff4226f8cbcf09f2a455d1ed20e802ce5b2b4a7f5ed053/rpds_py-0.30.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221", size = 404579, upload-time = "2025-11-30T20:21:43.769Z" },
970
+ { url = "https://files.pythonhosted.org/packages/f9/da/c9339293513ec680a721e0e16bf2bac3db6e5d7e922488de471308349bba/rpds_py-0.30.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7", size = 421305, upload-time = "2025-11-30T20:21:44.994Z" },
971
+ { url = "https://files.pythonhosted.org/packages/f9/be/522cb84751114f4ad9d822ff5a1aa3c98006341895d5f084779b99596e5c/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff", size = 572503, upload-time = "2025-11-30T20:21:46.91Z" },
972
+ { url = "https://files.pythonhosted.org/packages/a2/9b/de879f7e7ceddc973ea6e4629e9b380213a6938a249e94b0cdbcc325bb66/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7", size = 598322, upload-time = "2025-11-30T20:21:48.709Z" },
973
+ { url = "https://files.pythonhosted.org/packages/48/ac/f01fc22efec3f37d8a914fc1b2fb9bcafd56a299edbe96406f3053edea5a/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139", size = 560792, upload-time = "2025-11-30T20:21:50.024Z" },
974
+ { url = "https://files.pythonhosted.org/packages/e2/da/4e2b19d0f131f35b6146425f846563d0ce036763e38913d917187307a671/rpds_py-0.30.0-cp310-cp310-win32.whl", hash = "sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464", size = 221901, upload-time = "2025-11-30T20:21:51.32Z" },
975
+ { url = "https://files.pythonhosted.org/packages/96/cb/156d7a5cf4f78a7cc571465d8aec7a3c447c94f6749c5123f08438bcf7bc/rpds_py-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169", size = 235823, upload-time = "2025-11-30T20:21:52.505Z" },
976
+ { url = "https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425", size = 370157, upload-time = "2025-11-30T20:21:53.789Z" },
977
+ { url = "https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d", size = 359676, upload-time = "2025-11-30T20:21:55.475Z" },
978
+ { url = "https://files.pythonhosted.org/packages/84/86/04dbba1b087227747d64d80c3b74df946b986c57af0a9f0c98726d4d7a3b/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4", size = 389938, upload-time = "2025-11-30T20:21:57.079Z" },
979
+ { url = "https://files.pythonhosted.org/packages/42/bb/1463f0b1722b7f45431bdd468301991d1328b16cffe0b1c2918eba2c4eee/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f", size = 402932, upload-time = "2025-11-30T20:21:58.47Z" },
980
+ { url = "https://files.pythonhosted.org/packages/99/ee/2520700a5c1f2d76631f948b0736cdf9b0acb25abd0ca8e889b5c62ac2e3/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4", size = 525830, upload-time = "2025-11-30T20:21:59.699Z" },
981
+ { url = "https://files.pythonhosted.org/packages/e0/ad/bd0331f740f5705cc555a5e17fdf334671262160270962e69a2bdef3bf76/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97", size = 412033, upload-time = "2025-11-30T20:22:00.991Z" },
982
+ { url = "https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89", size = 390828, upload-time = "2025-11-30T20:22:02.723Z" },
983
+ { url = "https://files.pythonhosted.org/packages/ab/2b/d88bb33294e3e0c76bc8f351a3721212713629ffca1700fa94979cb3eae8/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d", size = 404683, upload-time = "2025-11-30T20:22:04.367Z" },
984
+ { url = "https://files.pythonhosted.org/packages/50/32/c759a8d42bcb5289c1fac697cd92f6fe01a018dd937e62ae77e0e7f15702/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038", size = 421583, upload-time = "2025-11-30T20:22:05.814Z" },
985
+ { url = "https://files.pythonhosted.org/packages/2b/81/e729761dbd55ddf5d84ec4ff1f47857f4374b0f19bdabfcf929164da3e24/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7", size = 572496, upload-time = "2025-11-30T20:22:07.713Z" },
986
+ { url = "https://files.pythonhosted.org/packages/14/f6/69066a924c3557c9c30baa6ec3a0aa07526305684c6f86c696b08860726c/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed", size = 598669, upload-time = "2025-11-30T20:22:09.312Z" },
987
+ { url = "https://files.pythonhosted.org/packages/5f/48/905896b1eb8a05630d20333d1d8ffd162394127b74ce0b0784ae04498d32/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85", size = 561011, upload-time = "2025-11-30T20:22:11.309Z" },
988
+ { url = "https://files.pythonhosted.org/packages/22/16/cd3027c7e279d22e5eb431dd3c0fbc677bed58797fe7581e148f3f68818b/rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c", size = 221406, upload-time = "2025-11-30T20:22:13.101Z" },
989
+ { url = "https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825", size = 236024, upload-time = "2025-11-30T20:22:14.853Z" },
990
+ { url = "https://files.pythonhosted.org/packages/14/a6/364bba985e4c13658edb156640608f2c9e1d3ea3c81b27aa9d889fff0e31/rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229", size = 229069, upload-time = "2025-11-30T20:22:16.577Z" },
991
+ { url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad", size = 375086, upload-time = "2025-11-30T20:22:17.93Z" },
992
+ { url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05", size = 359053, upload-time = "2025-11-30T20:22:19.297Z" },
993
+ { url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28", size = 390763, upload-time = "2025-11-30T20:22:21.661Z" },
994
+ { url = "https://files.pythonhosted.org/packages/d4/36/eb2eb8515e2ad24c0bd43c3ee9cd74c33f7ca6430755ccdb240fd3144c44/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd", size = 408951, upload-time = "2025-11-30T20:22:23.408Z" },
995
+ { url = "https://files.pythonhosted.org/packages/d6/65/ad8dc1784a331fabbd740ef6f71ce2198c7ed0890dab595adb9ea2d775a1/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f", size = 514622, upload-time = "2025-11-30T20:22:25.16Z" },
996
+ { url = "https://files.pythonhosted.org/packages/63/8e/0cfa7ae158e15e143fe03993b5bcd743a59f541f5952e1546b1ac1b5fd45/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1", size = 414492, upload-time = "2025-11-30T20:22:26.505Z" },
997
+ { url = "https://files.pythonhosted.org/packages/60/1b/6f8f29f3f995c7ffdde46a626ddccd7c63aefc0efae881dc13b6e5d5bb16/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23", size = 394080, upload-time = "2025-11-30T20:22:27.934Z" },
998
+ { url = "https://files.pythonhosted.org/packages/6d/d5/a266341051a7a3ca2f4b750a3aa4abc986378431fc2da508c5034d081b70/rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6", size = 408680, upload-time = "2025-11-30T20:22:29.341Z" },
999
+ { url = "https://files.pythonhosted.org/packages/10/3b/71b725851df9ab7a7a4e33cf36d241933da66040d195a84781f49c50490c/rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51", size = 423589, upload-time = "2025-11-30T20:22:31.469Z" },
1000
+ { url = "https://files.pythonhosted.org/packages/00/2b/e59e58c544dc9bd8bd8384ecdb8ea91f6727f0e37a7131baeff8d6f51661/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5", size = 573289, upload-time = "2025-11-30T20:22:32.997Z" },
1001
+ { url = "https://files.pythonhosted.org/packages/da/3e/a18e6f5b460893172a7d6a680e86d3b6bc87a54c1f0b03446a3c8c7b588f/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e", size = 599737, upload-time = "2025-11-30T20:22:34.419Z" },
1002
+ { url = "https://files.pythonhosted.org/packages/5c/e2/714694e4b87b85a18e2c243614974413c60aa107fd815b8cbc42b873d1d7/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394", size = 563120, upload-time = "2025-11-30T20:22:35.903Z" },
1003
+ { url = "https://files.pythonhosted.org/packages/6f/ab/d5d5e3bcedb0a77f4f613706b750e50a5a3ba1c15ccd3665ecc636c968fd/rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf", size = 223782, upload-time = "2025-11-30T20:22:37.271Z" },
1004
+ { url = "https://files.pythonhosted.org/packages/39/3b/f786af9957306fdc38a74cef405b7b93180f481fb48453a114bb6465744a/rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b", size = 240463, upload-time = "2025-11-30T20:22:39.021Z" },
1005
+ { url = "https://files.pythonhosted.org/packages/f3/d2/b91dc748126c1559042cfe41990deb92c4ee3e2b415f6b5234969ffaf0cc/rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e", size = 230868, upload-time = "2025-11-30T20:22:40.493Z" },
1006
+ { url = "https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2", size = 374887, upload-time = "2025-11-30T20:22:41.812Z" },
1007
+ { url = "https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8", size = 358904, upload-time = "2025-11-30T20:22:43.479Z" },
1008
+ { url = "https://files.pythonhosted.org/packages/58/70/faed8186300e3b9bdd138d0273109784eea2396c68458ed580f885dfe7ad/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4", size = 389945, upload-time = "2025-11-30T20:22:44.819Z" },
1009
+ { url = "https://files.pythonhosted.org/packages/bd/a8/073cac3ed2c6387df38f71296d002ab43496a96b92c823e76f46b8af0543/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136", size = 407783, upload-time = "2025-11-30T20:22:46.103Z" },
1010
+ { url = "https://files.pythonhosted.org/packages/77/57/5999eb8c58671f1c11eba084115e77a8899d6e694d2a18f69f0ba471ec8b/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7", size = 515021, upload-time = "2025-11-30T20:22:47.458Z" },
1011
+ { url = "https://files.pythonhosted.org/packages/e0/af/5ab4833eadc36c0a8ed2bc5c0de0493c04f6c06de223170bd0798ff98ced/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2", size = 414589, upload-time = "2025-11-30T20:22:48.872Z" },
1012
+ { url = "https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6", size = 394025, upload-time = "2025-11-30T20:22:50.196Z" },
1013
+ { url = "https://files.pythonhosted.org/packages/91/c4/fc70cd0249496493500e7cc2de87504f5aa6509de1e88623431fec76d4b6/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e", size = 408895, upload-time = "2025-11-30T20:22:51.87Z" },
1014
+ { url = "https://files.pythonhosted.org/packages/58/95/d9275b05ab96556fefff73a385813eb66032e4c99f411d0795372d9abcea/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d", size = 422799, upload-time = "2025-11-30T20:22:53.341Z" },
1015
+ { url = "https://files.pythonhosted.org/packages/06/c1/3088fc04b6624eb12a57eb814f0d4997a44b0d208d6cace713033ff1a6ba/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7", size = 572731, upload-time = "2025-11-30T20:22:54.778Z" },
1016
+ { url = "https://files.pythonhosted.org/packages/d8/42/c612a833183b39774e8ac8fecae81263a68b9583ee343db33ab571a7ce55/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31", size = 599027, upload-time = "2025-11-30T20:22:56.212Z" },
1017
+ { url = "https://files.pythonhosted.org/packages/5f/60/525a50f45b01d70005403ae0e25f43c0384369ad24ffe46e8d9068b50086/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95", size = 563020, upload-time = "2025-11-30T20:22:58.2Z" },
1018
+ { url = "https://files.pythonhosted.org/packages/0b/5d/47c4655e9bcd5ca907148535c10e7d489044243cc9941c16ed7cd53be91d/rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d", size = 223139, upload-time = "2025-11-30T20:23:00.209Z" },
1019
+ { url = "https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15", size = 240224, upload-time = "2025-11-30T20:23:02.008Z" },
1020
+ { url = "https://files.pythonhosted.org/packages/24/95/ffd128ed1146a153d928617b0ef673960130be0009c77d8fbf0abe306713/rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1", size = 230645, upload-time = "2025-11-30T20:23:03.43Z" },
1021
+ { url = "https://files.pythonhosted.org/packages/ff/1b/b10de890a0def2a319a2626334a7f0ae388215eb60914dbac8a3bae54435/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a", size = 364443, upload-time = "2025-11-30T20:23:04.878Z" },
1022
+ { url = "https://files.pythonhosted.org/packages/0d/bf/27e39f5971dc4f305a4fb9c672ca06f290f7c4e261c568f3dea16a410d47/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e", size = 353375, upload-time = "2025-11-30T20:23:06.342Z" },
1023
+ { url = "https://files.pythonhosted.org/packages/40/58/442ada3bba6e8e6615fc00483135c14a7538d2ffac30e2d933ccf6852232/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000", size = 383850, upload-time = "2025-11-30T20:23:07.825Z" },
1024
+ { url = "https://files.pythonhosted.org/packages/14/14/f59b0127409a33c6ef6f5c1ebd5ad8e32d7861c9c7adfa9a624fc3889f6c/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db", size = 392812, upload-time = "2025-11-30T20:23:09.228Z" },
1025
+ { url = "https://files.pythonhosted.org/packages/b3/66/e0be3e162ac299b3a22527e8913767d869e6cc75c46bd844aa43fb81ab62/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2", size = 517841, upload-time = "2025-11-30T20:23:11.186Z" },
1026
+ { url = "https://files.pythonhosted.org/packages/3d/55/fa3b9cf31d0c963ecf1ba777f7cf4b2a2c976795ac430d24a1f43d25a6ba/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa", size = 408149, upload-time = "2025-11-30T20:23:12.864Z" },
1027
+ { url = "https://files.pythonhosted.org/packages/60/ca/780cf3b1a32b18c0f05c441958d3758f02544f1d613abf9488cd78876378/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083", size = 383843, upload-time = "2025-11-30T20:23:14.638Z" },
1028
+ { url = "https://files.pythonhosted.org/packages/82/86/d5f2e04f2aa6247c613da0c1dd87fcd08fa17107e858193566048a1e2f0a/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9", size = 396507, upload-time = "2025-11-30T20:23:16.105Z" },
1029
+ { url = "https://files.pythonhosted.org/packages/4b/9a/453255d2f769fe44e07ea9785c8347edaf867f7026872e76c1ad9f7bed92/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0", size = 414949, upload-time = "2025-11-30T20:23:17.539Z" },
1030
+ { url = "https://files.pythonhosted.org/packages/a3/31/622a86cdc0c45d6df0e9ccb6becdba5074735e7033c20e401a6d9d0e2ca0/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94", size = 565790, upload-time = "2025-11-30T20:23:19.029Z" },
1031
+ { url = "https://files.pythonhosted.org/packages/1c/5d/15bbf0fb4a3f58a3b1c67855ec1efcc4ceaef4e86644665fff03e1b66d8d/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08", size = 590217, upload-time = "2025-11-30T20:23:20.885Z" },
1032
+ { url = "https://files.pythonhosted.org/packages/6d/61/21b8c41f68e60c8cc3b2e25644f0e3681926020f11d06ab0b78e3c6bbff1/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27", size = 555806, upload-time = "2025-11-30T20:23:22.488Z" },
1033
+ { url = "https://files.pythonhosted.org/packages/f9/39/7e067bb06c31de48de3eb200f9fc7c58982a4d3db44b07e73963e10d3be9/rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6", size = 211341, upload-time = "2025-11-30T20:23:24.449Z" },
1034
+ { url = "https://files.pythonhosted.org/packages/0a/4d/222ef0b46443cf4cf46764d9c630f3fe4abaa7245be9417e56e9f52b8f65/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d", size = 225768, upload-time = "2025-11-30T20:23:25.908Z" },
1035
+ { url = "https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0", size = 362099, upload-time = "2025-11-30T20:23:27.316Z" },
1036
+ { url = "https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be", size = 353192, upload-time = "2025-11-30T20:23:29.151Z" },
1037
+ { url = "https://files.pythonhosted.org/packages/bf/c4/76eb0e1e72d1a9c4703c69607cec123c29028bff28ce41588792417098ac/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f", size = 384080, upload-time = "2025-11-30T20:23:30.785Z" },
1038
+ { url = "https://files.pythonhosted.org/packages/72/87/87ea665e92f3298d1b26d78814721dc39ed8d2c74b86e83348d6b48a6f31/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f", size = 394841, upload-time = "2025-11-30T20:23:32.209Z" },
1039
+ { url = "https://files.pythonhosted.org/packages/77/ad/7783a89ca0587c15dcbf139b4a8364a872a25f861bdb88ed99f9b0dec985/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87", size = 516670, upload-time = "2025-11-30T20:23:33.742Z" },
1040
+ { url = "https://files.pythonhosted.org/packages/5b/3c/2882bdac942bd2172f3da574eab16f309ae10a3925644e969536553cb4ee/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18", size = 408005, upload-time = "2025-11-30T20:23:35.253Z" },
1041
+ { url = "https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad", size = 382112, upload-time = "2025-11-30T20:23:36.842Z" },
1042
+ { url = "https://files.pythonhosted.org/packages/cf/8e/1da49d4a107027e5fbc64daeab96a0706361a2918da10cb41769244b805d/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07", size = 399049, upload-time = "2025-11-30T20:23:38.343Z" },
1043
+ { url = "https://files.pythonhosted.org/packages/df/5a/7ee239b1aa48a127570ec03becbb29c9d5a9eb092febbd1699d567cae859/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f", size = 415661, upload-time = "2025-11-30T20:23:40.263Z" },
1044
+ { url = "https://files.pythonhosted.org/packages/70/ea/caa143cf6b772f823bc7929a45da1fa83569ee49b11d18d0ada7f5ee6fd6/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65", size = 565606, upload-time = "2025-11-30T20:23:42.186Z" },
1045
+ { url = "https://files.pythonhosted.org/packages/64/91/ac20ba2d69303f961ad8cf55bf7dbdb4763f627291ba3d0d7d67333cced9/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f", size = 591126, upload-time = "2025-11-30T20:23:44.086Z" },
1046
+ { url = "https://files.pythonhosted.org/packages/21/20/7ff5f3c8b00c8a95f75985128c26ba44503fb35b8e0259d812766ea966c7/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53", size = 553371, upload-time = "2025-11-30T20:23:46.004Z" },
1047
+ { url = "https://files.pythonhosted.org/packages/72/c7/81dadd7b27c8ee391c132a6b192111ca58d866577ce2d9b0ca157552cce0/rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed", size = 215298, upload-time = "2025-11-30T20:23:47.696Z" },
1048
+ { url = "https://files.pythonhosted.org/packages/3e/d2/1aaac33287e8cfb07aab2e6b8ac1deca62f6f65411344f1433c55e6f3eb8/rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950", size = 228604, upload-time = "2025-11-30T20:23:49.501Z" },
1049
+ { url = "https://files.pythonhosted.org/packages/e8/95/ab005315818cc519ad074cb7784dae60d939163108bd2b394e60dc7b5461/rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6", size = 222391, upload-time = "2025-11-30T20:23:50.96Z" },
1050
+ { url = "https://files.pythonhosted.org/packages/9e/68/154fe0194d83b973cdedcdcc88947a2752411165930182ae41d983dcefa6/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb", size = 364868, upload-time = "2025-11-30T20:23:52.494Z" },
1051
+ { url = "https://files.pythonhosted.org/packages/83/69/8bbc8b07ec854d92a8b75668c24d2abcb1719ebf890f5604c61c9369a16f/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8", size = 353747, upload-time = "2025-11-30T20:23:54.036Z" },
1052
+ { url = "https://files.pythonhosted.org/packages/ab/00/ba2e50183dbd9abcce9497fa5149c62b4ff3e22d338a30d690f9af970561/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7", size = 383795, upload-time = "2025-11-30T20:23:55.556Z" },
1053
+ { url = "https://files.pythonhosted.org/packages/05/6f/86f0272b84926bcb0e4c972262f54223e8ecc556b3224d281e6598fc9268/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898", size = 393330, upload-time = "2025-11-30T20:23:57.033Z" },
1054
+ { url = "https://files.pythonhosted.org/packages/cb/e9/0e02bb2e6dc63d212641da45df2b0bf29699d01715913e0d0f017ee29438/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e", size = 518194, upload-time = "2025-11-30T20:23:58.637Z" },
1055
+ { url = "https://files.pythonhosted.org/packages/ee/ca/be7bca14cf21513bdf9c0606aba17d1f389ea2b6987035eb4f62bd923f25/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419", size = 408340, upload-time = "2025-11-30T20:24:00.2Z" },
1056
+ { url = "https://files.pythonhosted.org/packages/c2/c7/736e00ebf39ed81d75544c0da6ef7b0998f8201b369acf842f9a90dc8fce/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551", size = 383765, upload-time = "2025-11-30T20:24:01.759Z" },
1057
+ { url = "https://files.pythonhosted.org/packages/4a/3f/da50dfde9956aaf365c4adc9533b100008ed31aea635f2b8d7b627e25b49/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8", size = 396834, upload-time = "2025-11-30T20:24:03.687Z" },
1058
+ { url = "https://files.pythonhosted.org/packages/4e/00/34bcc2565b6020eab2623349efbdec810676ad571995911f1abdae62a3a0/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5", size = 415470, upload-time = "2025-11-30T20:24:05.232Z" },
1059
+ { url = "https://files.pythonhosted.org/packages/8c/28/882e72b5b3e6f718d5453bd4d0d9cf8df36fddeb4ddbbab17869d5868616/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404", size = 565630, upload-time = "2025-11-30T20:24:06.878Z" },
1060
+ { url = "https://files.pythonhosted.org/packages/3b/97/04a65539c17692de5b85c6e293520fd01317fd878ea1995f0367d4532fb1/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856", size = 591148, upload-time = "2025-11-30T20:24:08.445Z" },
1061
+ { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030, upload-time = "2025-11-30T20:24:10.956Z" },
1062
+ { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570, upload-time = "2025-11-30T20:24:12.735Z" },
1063
+ { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532, upload-time = "2025-11-30T20:24:14.634Z" },
1064
+ { url = "https://files.pythonhosted.org/packages/69/71/3f34339ee70521864411f8b6992e7ab13ac30d8e4e3309e07c7361767d91/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58", size = 372292, upload-time = "2025-11-30T20:24:16.537Z" },
1065
+ { url = "https://files.pythonhosted.org/packages/57/09/f183df9b8f2d66720d2ef71075c59f7e1b336bec7ee4c48f0a2b06857653/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a", size = 362128, upload-time = "2025-11-30T20:24:18.086Z" },
1066
+ { url = "https://files.pythonhosted.org/packages/7a/68/5c2594e937253457342e078f0cc1ded3dd7b2ad59afdbf2d354869110a02/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb", size = 391542, upload-time = "2025-11-30T20:24:20.092Z" },
1067
+ { url = "https://files.pythonhosted.org/packages/49/5c/31ef1afd70b4b4fbdb2800249f34c57c64beb687495b10aec0365f53dfc4/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c", size = 404004, upload-time = "2025-11-30T20:24:22.231Z" },
1068
+ { url = "https://files.pythonhosted.org/packages/e3/63/0cfbea38d05756f3440ce6534d51a491d26176ac045e2707adc99bb6e60a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3", size = 527063, upload-time = "2025-11-30T20:24:24.302Z" },
1069
+ { url = "https://files.pythonhosted.org/packages/42/e6/01e1f72a2456678b0f618fc9a1a13f882061690893c192fcad9f2926553a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5", size = 413099, upload-time = "2025-11-30T20:24:25.916Z" },
1070
+ { url = "https://files.pythonhosted.org/packages/b8/25/8df56677f209003dcbb180765520c544525e3ef21ea72279c98b9aa7c7fb/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738", size = 392177, upload-time = "2025-11-30T20:24:27.834Z" },
1071
+ { url = "https://files.pythonhosted.org/packages/4a/b4/0a771378c5f16f8115f796d1f437950158679bcd2a7c68cf251cfb00ed5b/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f", size = 406015, upload-time = "2025-11-30T20:24:29.457Z" },
1072
+ { url = "https://files.pythonhosted.org/packages/36/d8/456dbba0af75049dc6f63ff295a2f92766b9d521fa00de67a2bd6427d57a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877", size = 423736, upload-time = "2025-11-30T20:24:31.22Z" },
1073
+ { url = "https://files.pythonhosted.org/packages/13/64/b4d76f227d5c45a7e0b796c674fd81b0a6c4fbd48dc29271857d8219571c/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a", size = 573981, upload-time = "2025-11-30T20:24:32.934Z" },
1074
+ { url = "https://files.pythonhosted.org/packages/20/91/092bacadeda3edf92bf743cc96a7be133e13a39cdbfd7b5082e7ab638406/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4", size = 599782, upload-time = "2025-11-30T20:24:35.169Z" },
1075
+ { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" },
1076
+ ]
1077
+
906
1078
  [[package]]
907
1079
  name = "rsa"
908
1080
  version = "4.9.1"
@@ -1024,11 +1196,15 @@ wheels = [
1024
1196
  name = "wt-contracts"
1025
1197
  source = { editable = "../wt-contracts" }
1026
1198
  dependencies = [
1199
+ { name = "jsonschema" },
1027
1200
  { name = "pydantic" },
1028
1201
  ]
1029
1202
 
1030
1203
  [package.metadata]
1031
- requires-dist = [{ name = "pydantic", specifier = ">=2.0.0,<3.0.0" }]
1204
+ requires-dist = [
1205
+ { name = "jsonschema", specifier = ">=4.0.0,<5.0.0" },
1206
+ { name = "pydantic", specifier = ">=2.0.0,<3.0.0" },
1207
+ ]
1032
1208
 
1033
1209
  [package.metadata.requires-dev]
1034
1210
  dev = [
@@ -1036,6 +1212,7 @@ dev = [
1036
1212
  { name = "pytest", specifier = ">=7.0.0" },
1037
1213
  { name = "pytest-cov", specifier = ">=4.0.0" },
1038
1214
  { name = "ruff", specifier = ">=0.1.0" },
1215
+ { name = "types-jsonschema" },
1039
1216
  ]
1040
1217
 
1041
1218
  [[package]]
@@ -1,34 +0,0 @@
1
- # file generated by setuptools-scm
2
- # don't change, don't track in version control
3
-
4
- __all__ = [
5
- "__version__",
6
- "__version_tuple__",
7
- "version",
8
- "version_tuple",
9
- "__commit_id__",
10
- "commit_id",
11
- ]
12
-
13
- TYPE_CHECKING = False
14
- if TYPE_CHECKING:
15
- from typing import Tuple
16
- from typing import Union
17
-
18
- VERSION_TUPLE = Tuple[Union[int, str], ...]
19
- COMMIT_ID = Union[str, None]
20
- else:
21
- VERSION_TUPLE = object
22
- COMMIT_ID = object
23
-
24
- version: str
25
- __version__: str
26
- __version_tuple__: VERSION_TUPLE
27
- version_tuple: VERSION_TUPLE
28
- commit_id: COMMIT_ID
29
- __commit_id__: COMMIT_ID
30
-
31
- __version__ = version = '0.1.2'
32
- __version_tuple__ = version_tuple = (0, 1, 2)
33
-
34
- __commit_id__ = commit_id = 'geecefd3'
File without changes
File without changes
@@ -10,7 +10,7 @@ __all__ = [
10
10
  "AsyncExecutor",
11
11
  "Future",
12
12
  "FutureSequence",
13
+ "PythonExecutor",
13
14
  "SyncExecutor",
14
15
  "mapvalues_wrapper",
15
- "PythonExecutor",
16
16
  ]
File without changes
@@ -15,8 +15,8 @@ from ._config import (
15
15
  from ._decorator import with_tracing
16
16
 
17
17
  __all__ = [
18
- "OtelExporterChoice",
19
18
  "OTelConsoleExporterDst",
19
+ "OtelExporterChoice",
20
20
  "attach_context",
21
21
  "configure_tracer",
22
22
  "make_otel_console_exporter_file_dst_kws",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes