anydi 0.68.0__py3-none-any.whl → 0.69.0__py3-none-any.whl

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.
@@ -3,34 +3,24 @@ from __future__ import annotations
3
3
  import importlib.util
4
4
  import inspect
5
5
  import logging
6
- from collections.abc import Callable, Iterator
7
- from typing import Any, cast
6
+ import warnings
7
+ from collections.abc import Generator
8
+ from typing import TYPE_CHECKING, Annotated, Any, cast, get_args, get_origin
8
9
 
9
10
  import pytest
10
11
  from anyio.pytest_plugin import extract_backend_and_options, get_runner
11
12
  from typing_extensions import get_annotations
12
13
 
13
14
  from anydi import Container, import_container
15
+ from anydi._marker import is_marker
14
16
 
15
- logger = logging.getLogger(__name__)
17
+ if TYPE_CHECKING:
18
+ from _pytest.fixtures import SubRequest
16
19
 
17
- # Storage for fixtures with inject markers
18
- _INJECTED_FIXTURES: dict[str, dict[str, Any]] = {}
20
+ logger = logging.getLogger(__name__)
19
21
 
20
22
 
21
23
  def pytest_addoption(parser: pytest.Parser) -> None:
22
- parser.addini(
23
- "anydi_autoinject",
24
- help="Automatically inject dependencies into all test functions",
25
- type="bool",
26
- default=False,
27
- )
28
- parser.addini(
29
- "anydi_inject_all",
30
- help="Deprecated: use 'anydi_autoinject' instead",
31
- type="bool",
32
- default=False,
33
- )
34
24
  parser.addini(
35
25
  "anydi_container",
36
26
  help=(
@@ -41,266 +31,165 @@ def pytest_addoption(parser: pytest.Parser) -> None:
41
31
  default=None,
42
32
  )
43
33
  parser.addini(
44
- "anydi_fixture_inject_enabled",
45
- help=(
46
- "Enable dependency injection into fixtures marked with @pytest.mark.inject"
47
- ),
34
+ "anydi_autoinject",
35
+ help="Automatically inject dependencies into all test functions",
48
36
  type="bool",
49
- default=False,
37
+ default=True,
50
38
  )
51
39
 
52
40
 
53
41
  def pytest_configure(config: pytest.Config) -> None:
54
42
  config.addinivalue_line(
55
43
  "markers",
56
- "inject: mark test as needing dependency injection",
44
+ "inject: mark test as needing dependency injection (deprecated)",
57
45
  )
58
46
 
59
- # Enable fixture injection if configured
60
- inject_fixtures_enabled = cast(bool, config.getini("anydi_fixture_inject_enabled"))
61
- if inject_fixtures_enabled:
62
- autoinject = cast(bool, config.getini("anydi_autoinject"))
63
- inject_all = cast(bool, config.getini("anydi_inject_all"))
64
- _patch_pytest_fixtures(autoinject=autoinject or inject_all)
65
- logger.debug(
66
- "Fixture injection enabled via anydi_fixture_inject_enabled config"
67
- )
68
-
69
47
 
70
48
  @pytest.hookimpl(hookwrapper=True)
71
- def pytest_fixture_setup( # noqa: C901
72
- fixturedef: pytest.FixtureDef[Any],
73
- request: pytest.FixtureRequest,
74
- ) -> Iterator[None]:
75
- """Inject dependencies into fixtures marked with @pytest.mark.inject."""
76
- # Check if this fixture has injection metadata
77
- fixture_name = fixturedef.argname
78
- if fixture_name not in _INJECTED_FIXTURES:
79
- yield
80
- return
81
-
82
- # Get the metadata
83
- fixture_info = _INJECTED_FIXTURES[fixture_name]
84
- original_func = fixture_info["func"]
85
- parameters: list[tuple[str, Any]] = fixture_info["parameters"]
86
-
87
- # Get the container
88
- try:
89
- container = cast(Container, request.getfixturevalue("container"))
90
- except pytest.FixtureLookupError:
91
- yield
92
- return
93
-
94
- resolvable_params = _select_resolvable_parameters(container, parameters)
95
-
96
- if not resolvable_params:
97
- yield
98
- return
99
-
100
- target_name = f"fixture '{fixture_name}'"
101
-
102
- def _prepare_sync_call_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]:
103
- combined_kwargs = dict(kwargs)
104
- combined_kwargs.update(
105
- _resolve_dependencies_sync(container, resolvable_params, target=target_name)
106
- )
107
- return combined_kwargs
108
-
109
- async def _prepare_async_call_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]:
110
- combined_kwargs = dict(kwargs)
111
- combined_kwargs.update(
112
- await _resolve_dependencies_async(
113
- container, resolvable_params, target=target_name
114
- )
115
- )
116
- return combined_kwargs
117
-
118
- def _ensure_anyio_backend() -> tuple[str, dict[str, Any]]:
119
- try:
120
- backend = request.getfixturevalue("anyio_backend")
121
- except pytest.FixtureLookupError as exc: # pragma: no cover - defensive
122
- msg = (
123
- "To run async fixtures with AnyDI, please configure the `anyio` pytest "
124
- "plugin (provide the `anyio_backend` fixture)."
125
- )
126
- pytest.fail(msg, pytrace=False)
127
- raise RuntimeError from exc # Unreachable but satisfies type checkers
128
-
129
- return extract_backend_and_options(backend)
130
-
131
- # Replace the fixture function with one that mirrors the original's type and
132
- # injects dependencies before delegating to the user-defined function.
133
- original_fixture_func = fixturedef.func
134
-
135
- if inspect.isasyncgenfunction(original_func):
136
-
137
- def asyncgen_wrapper(*args: Any, **kwargs: Any) -> Iterator[Any]:
138
- backend_name, backend_options = _ensure_anyio_backend()
139
-
140
- async def _fixture() -> Any:
141
- call_kwargs = await _prepare_async_call_kwargs(kwargs)
142
- async for value in original_func(**call_kwargs):
143
- yield value
144
-
145
- with get_runner(backend_name, backend_options) as runner:
146
- yield from runner.run_asyncgen_fixture(_fixture, {}) # type: ignore
147
-
148
- fixturedef.func = asyncgen_wrapper # type: ignore[misc]
149
- elif inspect.iscoroutinefunction(original_func):
150
-
151
- def async_wrapper(*args: Any, **kwargs: Any) -> Any:
152
- backend_name, backend_options = _ensure_anyio_backend()
153
-
154
- async def _fixture() -> Any:
155
- call_kwargs = await _prepare_async_call_kwargs(kwargs)
156
- return await original_func(**call_kwargs)
157
-
158
- with get_runner(backend_name, backend_options) as runner:
159
- return runner.run_fixture(_fixture, {})
160
-
161
- fixturedef.func = async_wrapper # type: ignore[misc]
162
- elif inspect.isgeneratorfunction(original_func):
163
-
164
- def generator_wrapper(*args: Any, **kwargs: Any) -> Iterator[Any]:
165
- call_kwargs = _prepare_sync_call_kwargs(kwargs)
166
- yield from original_func(**call_kwargs)
167
-
168
- fixturedef.func = generator_wrapper # type: ignore[misc]
169
- else:
170
-
171
- def sync_wrapper(*args: Any, **kwargs: Any) -> Any:
172
- call_kwargs = _prepare_sync_call_kwargs(kwargs)
173
- return original_func(**call_kwargs)
174
-
175
- fixturedef.func = sync_wrapper # type: ignore[misc]
176
-
177
- # Let pytest execute the modified fixture
49
+ def pytest_fixture_setup(
50
+ fixturedef: pytest.FixtureDef[Any], request: SubRequest
51
+ ) -> Generator[None]:
52
+ """Automatically enable test mode on the container fixture."""
178
53
  yield
179
-
180
- # Restore the original function
181
- fixturedef.func = original_fixture_func # type: ignore[misc]
54
+ if fixturedef.argname == "container" and fixturedef.cached_result is not None:
55
+ container = fixturedef.cached_result[0]
56
+ if isinstance(container, Container):
57
+ container.enable_test_mode()
182
58
 
183
59
 
184
60
  @pytest.fixture(scope="session")
185
61
  def container(request: pytest.FixtureRequest) -> Container:
186
- """Container fixture with testing mode enabled."""
187
- container = _find_container(request)
188
- container.enable_test_mode()
189
- return container
190
-
191
-
192
- @pytest.fixture
193
- def _anydi_should_inject(request: pytest.FixtureRequest) -> bool:
194
- marker = request.node.get_closest_marker("inject")
195
-
196
- # Check new config option first
197
- autoinject = cast(bool, request.config.getini("anydi_autoinject"))
198
-
199
- # Check deprecated option for backward compatibility
200
- inject_all = cast(bool, request.config.getini("anydi_inject_all"))
201
- if inject_all:
202
- logger.warning(
203
- "Configuration option 'anydi_inject_all' is deprecated. "
204
- "Please use 'anydi_autoinject' instead."
205
- )
206
-
207
- return marker is not None or autoinject or inject_all
208
-
209
-
210
- @pytest.fixture
211
- def _anydi_injected_parameter_iterator(
212
- request: pytest.FixtureRequest,
213
- ) -> Callable[[], Iterator[tuple[str, Any]]]:
214
- fixturenames = set(request.node._fixtureinfo.initialnames) - set(
215
- request.node._fixtureinfo.name2fixturedefs.keys()
216
- )
217
-
218
- def _iterator() -> Iterator[tuple[str, Any]]:
219
- for name, annotation in _iter_injectable_parameters(request.function):
220
- if name not in fixturenames:
221
- continue
222
- yield name, annotation
223
-
224
- return _iterator
62
+ """Container fixture."""
63
+ return _find_container(request)
225
64
 
226
65
 
227
66
  @pytest.fixture(autouse=True)
228
- def _anydi_inject(
229
- request: pytest.FixtureRequest,
230
- _anydi_should_inject: bool,
231
- _anydi_injected_parameter_iterator: Callable[[], Iterator[tuple[str, Any]]],
232
- ) -> None:
233
- """Inject dependencies into the test function."""
234
-
235
- if inspect.iscoroutinefunction(request.function) or not _anydi_should_inject:
67
+ def _anydi_inject(request: pytest.FixtureRequest) -> None:
68
+ """Inject dependencies into sync test functions."""
69
+ if inspect.iscoroutinefunction(request.function):
236
70
  return
237
71
 
238
- parameters = list(_anydi_injected_parameter_iterator())
72
+ parameters, uses_deprecated = _get_injectable_params(request)
239
73
  if not parameters:
240
74
  return
241
75
 
242
76
  container = cast(Container, request.getfixturevalue("container"))
243
- resolvable = _select_resolvable_parameters(container, parameters)
244
- if not resolvable:
245
- return
246
77
 
247
- resolved = _resolve_dependencies_sync(
248
- container, resolvable, target=request.node.nodeid
249
- )
250
- for argname, value in resolved.items():
251
- request.node.funcargs[argname] = value
78
+ warned = False
79
+ for name, dependency_type in parameters:
80
+ if not container.has_provider_for(dependency_type):
81
+ continue
82
+ if uses_deprecated and not warned:
83
+ _warn_deprecated_marker(request.node.name)
84
+ warned = True
85
+ try:
86
+ request.node.funcargs[name] = container.resolve(dependency_type)
87
+ except Exception: # pragma: no cover
88
+ logger.warning("Failed to resolve '%s' for %s", name, request.node.nodeid)
252
89
 
253
90
 
254
91
  @pytest.fixture(autouse=True)
255
- def _anydi_ainject(
256
- request: pytest.FixtureRequest,
257
- _anydi_should_inject: bool,
258
- _anydi_injected_parameter_iterator: Callable[[], Iterator[tuple[str, Any]]],
259
- ) -> None:
260
- """Inject dependencies into the test function."""
261
- if (
262
- not inspect.iscoroutinefunction(request.function)
263
- and not inspect.isasyncgenfunction(request.function)
264
- or not _anydi_should_inject
265
- ):
92
+ def _anydi_ainject(request: pytest.FixtureRequest) -> None:
93
+ """Inject dependencies into async test functions."""
94
+ if not inspect.iscoroutinefunction(
95
+ request.function
96
+ ) and not inspect.isasyncgenfunction(request.function):
97
+ return
98
+
99
+ parameters, uses_deprecated = _get_injectable_params(request)
100
+ if not parameters:
266
101
  return
267
102
 
268
- # Skip if the anyio backend is not available
269
103
  if "anyio_backend" not in request.fixturenames:
270
- msg = (
104
+ pytest.fail(
271
105
  "To run async test functions with `anyio`, "
272
106
  "please configure the `anyio` pytest plugin.\n"
273
- "See: https://anyio.readthedocs.io/en/stable/testing.html"
107
+ "See: https://anyio.readthedocs.io/en/stable/testing.html",
108
+ pytrace=False,
274
109
  )
275
- pytest.fail(msg, pytrace=False)
276
-
277
- parameters = list(_anydi_injected_parameter_iterator())
278
- if not parameters:
279
- return
280
110
 
281
111
  container = cast(Container, request.getfixturevalue("container"))
282
- resolvable = _select_resolvable_parameters(container, parameters)
283
- if not resolvable:
284
- return
285
112
 
286
- async def _awrapper() -> None:
287
- resolved = await _resolve_dependencies_async(
288
- container, resolvable, target=request.node.nodeid
289
- )
290
- for argname, value in resolved.items():
291
- request.node.funcargs[argname] = value
113
+ async def _resolve() -> None:
114
+ warned = False
115
+ for name, dependency_type in parameters:
116
+ if not container.has_provider_for(dependency_type):
117
+ continue
118
+ if uses_deprecated and not warned:
119
+ _warn_deprecated_marker(request.node.name)
120
+ warned = True
121
+ try:
122
+ request.node.funcargs[name] = await container.aresolve(dependency_type)
123
+ except Exception: # pragma: no cover
124
+ logger.warning(
125
+ "Failed to resolve '%s' for %s", name, request.node.nodeid
126
+ )
292
127
 
293
128
  anyio_backend = request.getfixturevalue("anyio_backend")
294
129
  backend_name, backend_options = extract_backend_and_options(anyio_backend)
295
130
 
296
131
  with get_runner(backend_name, backend_options) as runner:
297
- runner.run_fixture(_awrapper, {})
132
+ runner.run_fixture(_resolve, {})
298
133
 
299
134
 
300
- def _find_container(request: pytest.FixtureRequest) -> Container:
301
- """Find container."""
135
+ def _get_injectable_params(
136
+ request: pytest.FixtureRequest,
137
+ ) -> tuple[list[tuple[str, Any]], bool]:
138
+ """Get injectable parameters for a test function.
139
+
140
+ Returns (parameters, uses_deprecated_marker) tuple.
141
+ """
142
+ fixture_names = set(request.node._fixtureinfo.initialnames) - set(
143
+ request.node._fixtureinfo.name2fixturedefs.keys()
144
+ )
145
+
146
+ marker = request.node.get_closest_marker("inject")
147
+ autoinject = cast(bool, request.config.getini("anydi_autoinject"))
148
+
149
+ has_any_explicit = False
150
+ explicit_params: list[tuple[str, Any]] = []
151
+ all_params: list[tuple[str, Any]] = []
152
+
153
+ annotations = get_annotations(request.function, eval_str=True)
154
+
155
+ for name, annotation in annotations.items():
156
+ if name in ("request", "return"):
157
+ continue
158
+
159
+ dependency_type, is_explicit = _extract_dependency_type(annotation)
160
+
161
+ if is_explicit:
162
+ has_any_explicit = True
163
+ explicit_params.append((name, dependency_type))
164
+ elif name in fixture_names:
165
+ all_params.append((name, dependency_type))
166
+
167
+ # Priority: explicit markers > deprecated @pytest.mark.inject > autoinject
168
+ if has_any_explicit:
169
+ return explicit_params, False
170
+ if marker is not None:
171
+ return all_params, True
172
+ if autoinject:
173
+ return all_params, False
174
+ return [], False
175
+
176
+
177
+ def _extract_dependency_type(annotation: Any) -> tuple[Any, bool]:
178
+ """Extract the actual type and whether it has an explicit injection marker.
179
+
180
+ Handles Provide[T] and Annotated[T, Inject()].
181
+ Returns (unwrapped_type, is_explicit).
182
+ """
183
+ if get_origin(annotation) is Annotated:
184
+ args = get_args(annotation)
185
+ for arg in args[1:]:
186
+ if is_marker(arg):
187
+ return args[0], True
188
+ return annotation, False
302
189
 
303
- # Look for 'anydi_container' defined in pytest.ini (highest priority)
190
+
191
+ def _find_container(request: pytest.FixtureRequest) -> Container:
192
+ """Find container from config or auto-detection."""
304
193
  container_path = cast(str | None, request.config.getini("anydi_container"))
305
194
  if container_path:
306
195
  try:
@@ -311,12 +200,10 @@ def _find_container(request: pytest.FixtureRequest) -> Container:
311
200
  f"'anydi_container={container_path}': {exc}"
312
201
  ) from exc
313
202
 
314
- # Detect pytest-django + anydi_django availability
315
203
  pluginmanager = request.config.pluginmanager
316
204
  if pluginmanager.hasplugin("django") and importlib.util.find_spec("anydi_django"):
317
205
  return import_container("anydi_django.container")
318
206
 
319
- # Neither fixture nor config found
320
207
  raise pytest.FixtureLookupError(
321
208
  None,
322
209
  request,
@@ -326,156 +213,10 @@ def _find_container(request: pytest.FixtureRequest) -> Container:
326
213
  )
327
214
 
328
215
 
329
- def _patch_pytest_fixtures(*, autoinject: bool) -> None: # noqa: C901
330
- """Patch pytest.fixture decorator to intercept fixtures with inject markers."""
331
- from _pytest.fixtures import fixture as original_fixture_decorator
332
-
333
- def patched_fixture(*args: Any, **kwargs: Any) -> Any: # noqa: C901
334
- """Patched fixture decorator that handles inject markers."""
335
-
336
- def should_process(func: Callable[..., Any]) -> bool:
337
- has_inject_marker = False
338
- if hasattr(func, "pytestmark"):
339
- markers = getattr(func, "pytestmark", [])
340
- if not isinstance(markers, list):
341
- markers = [markers]
342
-
343
- has_inject_marker = any(
344
- marker.name == "inject"
345
- for marker in markers
346
- if hasattr(marker, "name")
347
- )
348
-
349
- return autoinject or has_inject_marker
350
-
351
- def register_fixture(func: Callable[..., Any]) -> Callable[..., Any] | None:
352
- if not should_process(func):
353
- return None
354
-
355
- parameters = list(_iter_injectable_parameters(func))
356
- if not parameters:
357
- return None
358
-
359
- sig = inspect.signature(func, eval_str=True)
360
- has_request_param = "request" in sig.parameters
361
-
362
- if has_request_param:
363
-
364
- def wrapper_with_request(request: Any) -> Any:
365
- return func
366
-
367
- wrapper_func = wrapper_with_request
368
- else:
369
-
370
- def wrapper_no_request() -> Any:
371
- return func
372
-
373
- wrapper_func = wrapper_no_request
374
-
375
- wrapper_func.__name__ = func.__name__
376
- wrapper_func.__annotations__ = {}
377
-
378
- fixture_name = func.__name__
379
- _INJECTED_FIXTURES[fixture_name] = {
380
- "func": func,
381
- "parameters": parameters,
382
- }
383
- logger.debug(
384
- "Registered injectable fixture '%s' with params: %s",
385
- fixture_name,
386
- [name for name, _ in parameters],
387
- )
388
-
389
- return wrapper_func
390
-
391
- # Handle both @pytest.fixture and @pytest.fixture() usage
392
- if len(args) == 1 and callable(args[0]) and not kwargs:
393
- func = args[0]
394
- wrapper_func = register_fixture(func)
395
- if wrapper_func:
396
- return original_fixture_decorator(wrapper_func)
397
-
398
- return original_fixture_decorator(func)
399
- else:
400
-
401
- def decorator(func: Callable[..., Any]) -> Any:
402
- wrapper_func = register_fixture(func)
403
- if wrapper_func:
404
- return original_fixture_decorator(*args, **kwargs)(wrapper_func)
405
-
406
- return original_fixture_decorator(*args, **kwargs)(func)
407
-
408
- return decorator
409
-
410
- # Replace pytest.fixture
411
- pytest.fixture = patched_fixture # type: ignore[assignment]
412
- # Also patch _pytest.fixtures.fixture
413
- import _pytest.fixtures
414
-
415
- _pytest.fixtures.fixture = patched_fixture # type: ignore[assignment]
416
-
417
-
418
- def _iter_injectable_parameters(
419
- func: Callable[..., Any], *, skip: tuple[str, ...] = ("request",)
420
- ) -> Iterator[tuple[str, Any]]:
421
- annotations = get_annotations(func, eval_str=True)
422
- skip_names = set(skip)
423
- for name, annotation in annotations.items():
424
- if name in skip_names or name == "return":
425
- continue
426
- yield name, annotation
427
-
428
-
429
- def _select_resolvable_parameters(
430
- container: Container,
431
- parameters: Iterator[tuple[str, Any]] | list[tuple[str, Any]],
432
- ) -> list[tuple[str, Any]]:
433
- return [
434
- (name, annotation)
435
- for name, annotation in parameters
436
- if container.has_provider_for(annotation)
437
- ]
438
-
439
-
440
- def _resolve_dependencies_sync(
441
- container: Container,
442
- parameters: list[tuple[str, Any]],
443
- *,
444
- target: str,
445
- ) -> dict[str, Any]:
446
- container.enable_test_mode()
447
- resolved: dict[str, Any] = {}
448
- for param_name, annotation in parameters:
449
- try:
450
- resolved[param_name] = container.resolve(annotation)
451
- logger.debug("Resolved %s=%s for %s", param_name, annotation, target)
452
- except Exception as exc: # pragma: no cover - defensive logging
453
- logger.warning(
454
- "Failed to resolve dependency for '%s' on %s.",
455
- param_name,
456
- target,
457
- exc_info=exc,
458
- )
459
- return resolved
460
-
461
-
462
- async def _resolve_dependencies_async(
463
- container: Container,
464
- parameters: list[tuple[str, Any]],
465
- *,
466
- target: str,
467
- ) -> dict[str, Any]:
468
- container.enable_test_mode()
469
- resolved: dict[str, Any] = {}
470
- for param_name, annotation in parameters:
471
- try:
472
- resolved[param_name] = await container.aresolve(annotation)
473
- logger.debug("Resolved %s=%s for async %s", param_name, annotation, target)
474
- except Exception as exc: # pragma: no cover - defensive logging
475
- logger.warning(
476
- "Failed to resolve async dependency for '%s' on %s.",
477
- param_name,
478
- target,
479
- exc_info=exc,
480
- )
481
- return resolved
216
+ def _warn_deprecated_marker(test_name: str) -> None:
217
+ warnings.warn(
218
+ f"Using @pytest.mark.inject on test '{test_name}' is deprecated. "
219
+ "Use Provide[T] instead.",
220
+ DeprecationWarning,
221
+ stacklevel=4,
222
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anydi
3
- Version: 0.68.0
3
+ Version: 0.69.0
4
4
  Summary: Dependency Injection library
5
5
  Keywords: dependency injection,dependencies,di,async,asyncio,application
6
6
  Author: Anton Ruhlov
@@ -17,13 +17,13 @@ anydi/ext/django/__init__.py,sha256=Ve8lncLU9dPY_Vjt4zihPgsSxwAtFHACn0XvBM5JG8k,
17
17
  anydi/ext/fastapi.py,sha256=NowHc-z_Sw069YDv9vP98Mehum5vHsIIcqvDkRmicmc,2964
18
18
  anydi/ext/faststream.py,sha256=_3FZ8vlgl1GVizVv_6ippvwSWu_Zor4qm6HaiAp24o4,2744
19
19
  anydi/ext/pydantic_settings.py,sha256=y6uz0MiLtqPvRO186bIdRZVQfezLvRUfT3KvvB5fCWk,1524
20
- anydi/ext/pytest_plugin.py,sha256=XoMy5nLY8jM-KyK7VuwDuF_3rE3ouxaR3jZ0S6A6mdw,16322
20
+ anydi/ext/pytest_plugin.py,sha256=rLZ6NZUYklSg1rYx0FPdSvVmEY-faZTYqEY5qUWqZXk,7336
21
21
  anydi/ext/starlette/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  anydi/ext/starlette/middleware.py,sha256=n_JJ7BcG2Mg2M5HwM_SBboxZ-mnnD6WWJn4khq7Bgbs,1860
23
23
  anydi/ext/typer.py,sha256=c7HapXQfKhnLJQcHNncJAGd8jZ3crX5it6-MRCJjyPM,6268
24
24
  anydi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  anydi/testing.py,sha256=cHg3mMScZbEep9smRqSNQ81BZMQOkyugHe8TvKdPnEg,1347
26
- anydi-0.68.0.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
27
- anydi-0.68.0.dist-info/entry_points.txt,sha256=oDl_yEX12KlWcDzsZBTg85GG1Jl1rpiYOG4C7EJvebs,87
28
- anydi-0.68.0.dist-info/METADATA,sha256=3gYwUfTF6a368Qhb8H-_-85cIze1H_054Wlt-ExFLz0,8061
29
- anydi-0.68.0.dist-info/RECORD,,
26
+ anydi-0.69.0.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
27
+ anydi-0.69.0.dist-info/entry_points.txt,sha256=oDl_yEX12KlWcDzsZBTg85GG1Jl1rpiYOG4C7EJvebs,87
28
+ anydi-0.69.0.dist-info/METADATA,sha256=h8I4S5WOovGNeSInAJUV_9ASebz1FClByn1Ds4DcNRg,8061
29
+ anydi-0.69.0.dist-info/RECORD,,
File without changes