anydi 0.47.0rc0__tar.gz → 0.48.0__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.
- {anydi-0.47.0rc0 → anydi-0.48.0}/PKG-INFO +17 -17
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/_container.py +30 -46
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/_typing.py +0 -6
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/django/apps.py +10 -2
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/testing.py +1 -7
- {anydi-0.47.0rc0 → anydi-0.48.0}/pyproject.toml +12 -7
- anydi-0.47.0rc0/.editorconfig +0 -26
- anydi-0.47.0rc0/.github/workflows/ci.yml +0 -61
- anydi-0.47.0rc0/.gitignore +0 -83
- anydi-0.47.0rc0/.readthedocs.yaml +0 -20
- anydi-0.47.0rc0/LICENSE +0 -21
- anydi-0.47.0rc0/Makefile +0 -18
- anydi-0.47.0rc0/docs/examples/basic.md +0 -184
- anydi-0.47.0rc0/docs/extensions/django.md +0 -171
- anydi-0.47.0rc0/docs/extensions/fastapi.md +0 -193
- anydi-0.47.0rc0/docs/extensions/faststream.md +0 -45
- anydi-0.47.0rc0/docs/extensions/pydantic_settings.md +0 -45
- anydi-0.47.0rc0/docs/index.md +0 -154
- anydi-0.47.0rc0/docs/usage.md +0 -829
- anydi-0.47.0rc0/mkdocs.yml +0 -38
- anydi-0.47.0rc0/tests/__init__.py +0 -0
- anydi-0.47.0rc0/tests/conftest.py +0 -6
- anydi-0.47.0rc0/tests/ext/__init__.py +0 -0
- anydi-0.47.0rc0/tests/ext/django/__init__.py +0 -0
- anydi-0.47.0rc0/tests/ext/django/api/__init__.py +0 -0
- anydi-0.47.0rc0/tests/ext/django/api/router.py +0 -30
- anydi-0.47.0rc0/tests/ext/django/api/test_router.py +0 -15
- anydi-0.47.0rc0/tests/ext/django/api/urls.py +0 -11
- anydi-0.47.0rc0/tests/ext/django/conftest.py +0 -12
- anydi-0.47.0rc0/tests/ext/django/container.py +0 -26
- anydi-0.47.0rc0/tests/ext/django/scan/__init__.py +0 -0
- anydi-0.47.0rc0/tests/ext/django/services.py +0 -28
- anydi-0.47.0rc0/tests/ext/django/settings.py +0 -22
- anydi-0.47.0rc0/tests/ext/django/test_views.py +0 -50
- anydi-0.47.0rc0/tests/ext/django/urls.py +0 -18
- anydi-0.47.0rc0/tests/ext/django/views.py +0 -40
- anydi-0.47.0rc0/tests/ext/fastapi/__init__.py +0 -0
- anydi-0.47.0rc0/tests/ext/fastapi/app.py +0 -86
- anydi-0.47.0rc0/tests/ext/fastapi/conftest.py +0 -24
- anydi-0.47.0rc0/tests/ext/fastapi/test_ext.py +0 -53
- anydi-0.47.0rc0/tests/ext/fastapi/test_routes.py +0 -80
- anydi-0.47.0rc0/tests/ext/faststream/__init__.py +0 -0
- anydi-0.47.0rc0/tests/ext/faststream/test_ext.py +0 -53
- anydi-0.47.0rc0/tests/ext/faststream/test_subscribers.py +0 -54
- anydi-0.47.0rc0/tests/ext/fixtures.py +0 -36
- anydi-0.47.0rc0/tests/ext/starlette/__init__.py +0 -0
- anydi-0.47.0rc0/tests/ext/starlette/app.py +0 -53
- anydi-0.47.0rc0/tests/ext/starlette/conftest.py +0 -24
- anydi-0.47.0rc0/tests/ext/starlette/test_routes.py +0 -56
- anydi-0.47.0rc0/tests/ext/test_pydantic.py +0 -43
- anydi-0.47.0rc0/tests/ext/test_pytest_plugin.py +0 -65
- anydi-0.47.0rc0/tests/fixtures.py +0 -77
- anydi-0.47.0rc0/tests/scan_app/__init__.py +0 -17
- anydi-0.47.0rc0/tests/scan_app/a/__init__.py +0 -0
- anydi-0.47.0rc0/tests/scan_app/a/a1/__init__.py +0 -2
- anydi-0.47.0rc0/tests/scan_app/a/a1/handlers.py +0 -6
- anydi-0.47.0rc0/tests/scan_app/a/a2/__init__.py +0 -0
- anydi-0.47.0rc0/tests/scan_app/a/a2/a21/__init__.py +0 -0
- anydi-0.47.0rc0/tests/scan_app/a/a2/a21/handlers.py +0 -6
- anydi-0.47.0rc0/tests/scan_app/a/a3/__init__.py +0 -0
- anydi-0.47.0rc0/tests/scan_app/a/a3/handlers.py +0 -12
- anydi-0.47.0rc0/tests/scan_app/b/__init__.py +0 -0
- anydi-0.47.0rc0/tests/scan_app/b/handlers.py +0 -20
- anydi-0.47.0rc0/tests/test_container.py +0 -1553
- anydi-0.47.0rc0/tests/test_decorators.py +0 -76
- anydi-0.47.0rc0/tests/test_module.py +0 -74
- anydi-0.47.0rc0/tests/test_scan.py +0 -68
- anydi-0.47.0rc0/tests/test_testing.py +0 -221
- anydi-0.47.0rc0/tests/test_utils.py +0 -61
- anydi-0.47.0rc0/uv.lock +0 -1517
- {anydi-0.47.0rc0 → anydi-0.48.0}/README.md +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/__init__.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/_async.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/_context.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/_decorators.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/_module.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/_provider.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/_scan.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/_scope.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/__init__.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/django/__init__.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/django/_container.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/django/_settings.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/django/_utils.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/django/middleware.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/django/ninja/__init__.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/django/ninja/_operation.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/django/ninja/_signature.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/fastapi.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/faststream.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/pydantic_settings.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/pytest_plugin.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/starlette/__init__.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/ext/starlette/middleware.py +0 -0
- {anydi-0.47.0rc0 → anydi-0.48.0}/anydi/py.typed +0 -0
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: anydi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.48.0
|
|
4
4
|
Summary: Dependency Injection library
|
|
5
|
-
|
|
5
|
+
Keywords: dependency injection,dependencies,di,async,asyncio,application
|
|
6
|
+
Author: Anton Ruhlov
|
|
6
7
|
Author-email: Anton Ruhlov <antonruhlov@gmail.com>
|
|
7
8
|
License-Expression: MIT
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
Classifier: Intended Audience :: Information Technology
|
|
10
|
+
Classifier: Intended Audience :: System Administrators
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
10
12
|
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Topic :: Internet
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
17
|
+
Classifier: Topic :: Software Development
|
|
18
|
+
Classifier: Typing :: Typed
|
|
11
19
|
Classifier: Environment :: Web Environment
|
|
12
20
|
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: Intended Audience :: Information Technology
|
|
14
|
-
Classifier: Intended Audience :: System Administrators
|
|
15
21
|
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
-
Classifier: Operating System :: OS Independent
|
|
17
22
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
23
|
Classifier: Programming Language :: Python :: 3.9
|
|
20
24
|
Classifier: Programming Language :: Python :: 3.10
|
|
21
25
|
Classifier: Programming Language :: Python :: 3.11
|
|
22
26
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
27
|
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
-
Classifier:
|
|
25
|
-
|
|
26
|
-
Classifier: Topic :: Software Development :: Libraries
|
|
27
|
-
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
28
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
29
|
-
Classifier: Typing :: Typed
|
|
30
|
-
Requires-Python: ~=3.9
|
|
28
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
29
|
+
Requires-Dist: typing-extensions>=4.15.0,<5
|
|
31
30
|
Requires-Dist: anyio>=3.7.1
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-
|
|
31
|
+
Requires-Dist: wrapt>=1.17.0,<2
|
|
32
|
+
Requires-Python: ~=3.9
|
|
33
|
+
Project-URL: Repository, https://github.com/antonrh/anydi
|
|
34
34
|
Description-Content-Type: text/markdown
|
|
35
35
|
|
|
36
36
|
# AnyDI
|
|
@@ -28,7 +28,6 @@ from ._typing import (
|
|
|
28
28
|
get_typed_annotation,
|
|
29
29
|
get_typed_parameters,
|
|
30
30
|
is_async_context_manager,
|
|
31
|
-
is_builtin_type,
|
|
32
31
|
is_context_manager,
|
|
33
32
|
is_event_type,
|
|
34
33
|
is_inject_marker,
|
|
@@ -49,11 +48,9 @@ class Container:
|
|
|
49
48
|
*,
|
|
50
49
|
providers: Iterable[ProviderDef] | None = None,
|
|
51
50
|
modules: Iterable[ModuleDef] | None = None,
|
|
52
|
-
default_scope: Scope = "transient",
|
|
53
51
|
logger: logging.Logger | None = None,
|
|
54
52
|
) -> None:
|
|
55
53
|
self._providers: dict[Any, Provider] = {}
|
|
56
|
-
self._default_scope: Scope = default_scope
|
|
57
54
|
self._logger = logger or logging.getLogger(__name__)
|
|
58
55
|
self._resources: dict[str, list[Any]] = defaultdict(list)
|
|
59
56
|
self._singleton_context = InstanceContext()
|
|
@@ -85,11 +82,6 @@ class Container:
|
|
|
85
82
|
# Properties
|
|
86
83
|
############################
|
|
87
84
|
|
|
88
|
-
@property
|
|
89
|
-
def default_scope(self) -> Scope:
|
|
90
|
-
"""Get the default scope."""
|
|
91
|
-
return self._default_scope
|
|
92
|
-
|
|
93
85
|
@property
|
|
94
86
|
def providers(self) -> dict[type[Any], Provider]:
|
|
95
87
|
"""Get the registered providers."""
|
|
@@ -259,7 +251,7 @@ class Container:
|
|
|
259
251
|
def _register_provider( # noqa: C901
|
|
260
252
|
self,
|
|
261
253
|
call: Callable[..., Any],
|
|
262
|
-
scope: Scope
|
|
254
|
+
scope: Scope,
|
|
263
255
|
interface: Any = NOT_SET,
|
|
264
256
|
override: bool = False,
|
|
265
257
|
/,
|
|
@@ -268,11 +260,9 @@ class Container:
|
|
|
268
260
|
"""Register a provider with the specified scope."""
|
|
269
261
|
name = type_repr(call)
|
|
270
262
|
kind = ProviderKind.from_call(call)
|
|
271
|
-
detected_scope = scope
|
|
272
263
|
|
|
273
264
|
# Validate scope if it provided
|
|
274
|
-
|
|
275
|
-
self._validate_provider_scope(scope, name, kind)
|
|
265
|
+
self._validate_provider_scope(scope, name, kind)
|
|
276
266
|
|
|
277
267
|
# Get the signature
|
|
278
268
|
globalns = getattr(call, "__globals__", {})
|
|
@@ -335,9 +325,7 @@ class Container:
|
|
|
335
325
|
)
|
|
336
326
|
|
|
337
327
|
try:
|
|
338
|
-
sub_provider = self._get_or_register_provider(
|
|
339
|
-
parameter.annotation, scope
|
|
340
|
-
)
|
|
328
|
+
sub_provider = self._get_or_register_provider(parameter.annotation)
|
|
341
329
|
except LookupError:
|
|
342
330
|
if self._parameter_has_default(parameter, **defaults):
|
|
343
331
|
continue
|
|
@@ -350,24 +338,9 @@ class Container:
|
|
|
350
338
|
|
|
351
339
|
parameters.append(parameter)
|
|
352
340
|
|
|
353
|
-
# Set detected scope
|
|
354
|
-
if detected_scope is None:
|
|
355
|
-
if "transient" in scopes:
|
|
356
|
-
detected_scope = "transient"
|
|
357
|
-
elif "request" in scopes:
|
|
358
|
-
detected_scope = "request"
|
|
359
|
-
elif "singleton" in scopes:
|
|
360
|
-
detected_scope = "singleton"
|
|
361
|
-
else:
|
|
362
|
-
detected_scope = self.default_scope
|
|
363
|
-
|
|
364
|
-
# Validate the provider scope after detection
|
|
365
|
-
if scope is None:
|
|
366
|
-
self._validate_provider_scope(detected_scope, name, kind)
|
|
367
|
-
|
|
368
341
|
# Check for unresolved parameters
|
|
369
342
|
if unresolved_parameter:
|
|
370
|
-
if
|
|
343
|
+
if scope not in ("singleton", "transient"):
|
|
371
344
|
self._unresolved_interfaces.add(interface)
|
|
372
345
|
else:
|
|
373
346
|
raise LookupError(
|
|
@@ -380,16 +353,16 @@ class Container:
|
|
|
380
353
|
|
|
381
354
|
# Check scope compatibility
|
|
382
355
|
for sub_provider in scopes.values():
|
|
383
|
-
if sub_provider.scope not in ALLOWED_SCOPES.get(
|
|
356
|
+
if sub_provider.scope not in ALLOWED_SCOPES.get(scope, []):
|
|
384
357
|
raise ValueError(
|
|
385
|
-
f"The provider `{name}` with a `{
|
|
358
|
+
f"The provider `{name}` with a `{scope}` scope cannot "
|
|
386
359
|
f"depend on `{sub_provider}` with a `{sub_provider.scope}` scope. "
|
|
387
360
|
"Please ensure all providers are registered with matching scopes."
|
|
388
361
|
)
|
|
389
362
|
|
|
390
363
|
provider = Provider(
|
|
391
364
|
call=call,
|
|
392
|
-
scope=
|
|
365
|
+
scope=scope,
|
|
393
366
|
interface=interface,
|
|
394
367
|
name=name,
|
|
395
368
|
kind=kind,
|
|
@@ -425,20 +398,18 @@ class Container:
|
|
|
425
398
|
"properly registered before attempting to use it."
|
|
426
399
|
) from exc
|
|
427
400
|
|
|
428
|
-
def _get_or_register_provider(
|
|
429
|
-
self, interface: Any, parent_scope: Scope | None, /, **defaults: Any
|
|
430
|
-
) -> Provider:
|
|
401
|
+
def _get_or_register_provider(self, interface: Any, /, **defaults: Any) -> Provider:
|
|
431
402
|
"""Get or register a provider by interface."""
|
|
432
403
|
try:
|
|
433
404
|
return self._providers[interface]
|
|
434
405
|
except KeyError:
|
|
435
|
-
if inspect.isclass(interface) and
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
406
|
+
if inspect.isclass(interface) and is_provided(interface):
|
|
407
|
+
return self._register_provider(
|
|
408
|
+
interface,
|
|
409
|
+
interface.__provided__["scope"],
|
|
410
|
+
NOT_SET,
|
|
411
|
+
**defaults,
|
|
412
|
+
)
|
|
442
413
|
raise LookupError(
|
|
443
414
|
f"The provider interface `{type_repr(interface)}` is either not "
|
|
444
415
|
"registered, not provided, or not set in the scoped context. "
|
|
@@ -533,7 +504,7 @@ class Container:
|
|
|
533
504
|
self, interface: Any, create: bool, /, **defaults: Any
|
|
534
505
|
) -> Any:
|
|
535
506
|
"""Internal method to handle instance resolution and creation."""
|
|
536
|
-
provider = self._get_or_register_provider(interface,
|
|
507
|
+
provider = self._get_or_register_provider(interface, **defaults)
|
|
537
508
|
if provider.scope == "transient":
|
|
538
509
|
return self._create_instance(provider, None, **defaults)
|
|
539
510
|
context = self._get_instance_context(provider.scope)
|
|
@@ -548,7 +519,7 @@ class Container:
|
|
|
548
519
|
self, interface: Any, create: bool, /, **defaults: Any
|
|
549
520
|
) -> Any:
|
|
550
521
|
"""Internal method to handle instance resolution and creation asynchronously."""
|
|
551
|
-
provider = self._get_or_register_provider(interface,
|
|
522
|
+
provider = self._get_or_register_provider(interface, **defaults)
|
|
552
523
|
if provider.scope == "transient":
|
|
553
524
|
return await self._acreate_instance(provider, None, **defaults)
|
|
554
525
|
context = self._get_instance_context(provider.scope)
|
|
@@ -884,3 +855,16 @@ class Container:
|
|
|
884
855
|
self, /, packages: PackageOrIterable, *, tags: Iterable[str] | None = None
|
|
885
856
|
) -> None:
|
|
886
857
|
self._scanner.scan(packages=packages, tags=tags)
|
|
858
|
+
|
|
859
|
+
############################
|
|
860
|
+
# Testing
|
|
861
|
+
############################
|
|
862
|
+
|
|
863
|
+
@contextlib.contextmanager
|
|
864
|
+
def override(self, interface: Any, instance: Any) -> Iterator[None]:
|
|
865
|
+
raise RuntimeError(
|
|
866
|
+
"Dependency overriding is not supported in this container.\n"
|
|
867
|
+
"Wrap your container with `anydi.testing.Container` instead.\n"
|
|
868
|
+
"Example:\n\n"
|
|
869
|
+
" container = TestContainer.from_container(container)"
|
|
870
|
+
)
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import builtins
|
|
6
5
|
import inspect
|
|
7
6
|
import re
|
|
8
7
|
import sys
|
|
@@ -44,11 +43,6 @@ def type_repr(obj: Any) -> str:
|
|
|
44
43
|
)
|
|
45
44
|
|
|
46
45
|
|
|
47
|
-
def is_builtin_type(tp: type[Any]) -> bool:
|
|
48
|
-
"""Check if the given type is a built-in type."""
|
|
49
|
-
return tp.__module__ == builtins.__name__
|
|
50
|
-
|
|
51
|
-
|
|
52
46
|
def is_context_manager(obj: Any) -> bool:
|
|
53
47
|
"""Check if the given object is a context manager."""
|
|
54
48
|
return hasattr(obj, "__enter__") and hasattr(obj, "__exit__")
|
|
@@ -9,6 +9,7 @@ from django.core.exceptions import ImproperlyConfigured
|
|
|
9
9
|
from django.utils.module_loading import import_string
|
|
10
10
|
|
|
11
11
|
import anydi
|
|
12
|
+
from anydi.testing import TestContainer
|
|
12
13
|
|
|
13
14
|
from ._settings import get_settings
|
|
14
15
|
from ._utils import inject_urlpatterns, register_components, register_settings
|
|
@@ -32,9 +33,16 @@ class ContainerConfig(AppConfig):
|
|
|
32
33
|
raise ImproperlyConfigured(
|
|
33
34
|
f"Cannot import container factory '{container_factory_path}'."
|
|
34
35
|
) from exc
|
|
35
|
-
|
|
36
|
+
container = container_factory()
|
|
36
37
|
else:
|
|
37
|
-
|
|
38
|
+
container = anydi.Container()
|
|
39
|
+
|
|
40
|
+
# Use test container
|
|
41
|
+
testing = getattr(settings, "ANYDI_TESTING", False)
|
|
42
|
+
if testing:
|
|
43
|
+
container = TestContainer.from_container(container)
|
|
44
|
+
|
|
45
|
+
self.container = container
|
|
38
46
|
|
|
39
47
|
def ready(self) -> None: # noqa: C901
|
|
40
48
|
# Register Django settings
|
|
@@ -28,12 +28,7 @@ class TestContainer(Container):
|
|
|
28
28
|
default_scope: Scope = "transient",
|
|
29
29
|
logger: logging.Logger | None = None,
|
|
30
30
|
) -> None:
|
|
31
|
-
super().__init__(
|
|
32
|
-
providers=providers,
|
|
33
|
-
modules=modules,
|
|
34
|
-
default_scope=default_scope,
|
|
35
|
-
logger=logger,
|
|
36
|
-
)
|
|
31
|
+
super().__init__(providers=providers, modules=modules, logger=logger)
|
|
37
32
|
self._override_instances: dict[Any, Any] = {}
|
|
38
33
|
|
|
39
34
|
@classmethod
|
|
@@ -47,7 +42,6 @@ class TestContainer(Container):
|
|
|
47
42
|
)
|
|
48
43
|
for provider in container.providers.values()
|
|
49
44
|
],
|
|
50
|
-
default_scope=container.default_scope,
|
|
51
45
|
logger=container.logger,
|
|
52
46
|
)
|
|
53
47
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "anydi"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.48.0"
|
|
4
4
|
description = "Dependency Injection library"
|
|
5
5
|
authors = [{ name = "Anton Ruhlov", email = "antonruhlov@gmail.com" }]
|
|
6
6
|
requires-python = "~=3.9"
|
|
@@ -37,7 +37,7 @@ classifiers = [
|
|
|
37
37
|
"Programming Language :: Python :: 3 :: Only",
|
|
38
38
|
]
|
|
39
39
|
dependencies = [
|
|
40
|
-
"typing-extensions>=4.
|
|
40
|
+
"typing-extensions>=4.15.0,<5",
|
|
41
41
|
"anyio>=3.7.1",
|
|
42
42
|
"wrapt>=1.17.0,<2",
|
|
43
43
|
]
|
|
@@ -50,7 +50,7 @@ anydi = "anydi.ext.pytest_plugin"
|
|
|
50
50
|
|
|
51
51
|
[dependency-groups]
|
|
52
52
|
dev = [
|
|
53
|
-
"ruff>=0.
|
|
53
|
+
"ruff>=0.13.0",
|
|
54
54
|
"pytest>=8.4.0,<9",
|
|
55
55
|
"pytest-cov>=6.0.0,<7",
|
|
56
56
|
"starlette>=0.37.2",
|
|
@@ -64,7 +64,7 @@ dev = [
|
|
|
64
64
|
"redis>=5.0.4,<6",
|
|
65
65
|
"pydantic-settings>=2.4.0,<3",
|
|
66
66
|
"bump-my-version>=1.1.4",
|
|
67
|
-
"pyright>=1.1.
|
|
67
|
+
"pyright>=1.1.405",
|
|
68
68
|
"pytest-mock>=3.14.1",
|
|
69
69
|
]
|
|
70
70
|
docs = [
|
|
@@ -73,8 +73,12 @@ docs = [
|
|
|
73
73
|
]
|
|
74
74
|
|
|
75
75
|
[build-system]
|
|
76
|
-
requires = ["
|
|
77
|
-
build-backend = "
|
|
76
|
+
requires = ["uv_build>=0.8.17,<0.9.0"]
|
|
77
|
+
build-backend = "uv_build"
|
|
78
|
+
|
|
79
|
+
[tool.uv.build-backend]
|
|
80
|
+
module-name = "anydi"
|
|
81
|
+
module-root = "."
|
|
78
82
|
|
|
79
83
|
[tool.ruff]
|
|
80
84
|
line-length = 88
|
|
@@ -137,7 +141,7 @@ omit = [
|
|
|
137
141
|
]
|
|
138
142
|
|
|
139
143
|
[tool.bumpversion]
|
|
140
|
-
current_version = "0.
|
|
144
|
+
current_version = "0.48.0"
|
|
141
145
|
parse = """(?x)
|
|
142
146
|
(?P<major>0|[1-9]\\d*)\\.
|
|
143
147
|
(?P<minor>0|[1-9]\\d*)\\.
|
|
@@ -164,3 +168,4 @@ replace = "version = \"{new_version}\""
|
|
|
164
168
|
[tool.bumpversion.parts.pre_l]
|
|
165
169
|
values = ["rc", "final"]
|
|
166
170
|
optional_value = "final"
|
|
171
|
+
|
anydi-0.47.0rc0/.editorconfig
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# https://editorconfig.org/
|
|
2
|
-
|
|
3
|
-
root = true
|
|
4
|
-
|
|
5
|
-
[*]
|
|
6
|
-
indent_style = space
|
|
7
|
-
indent_size = 4
|
|
8
|
-
insert_final_newline = true
|
|
9
|
-
trim_trailing_whitespace = true
|
|
10
|
-
end_of_line = lf
|
|
11
|
-
charset = utf-8
|
|
12
|
-
|
|
13
|
-
# Docstrings and comments use max_line_length = 88
|
|
14
|
-
[*.py]
|
|
15
|
-
max_line_length = 88
|
|
16
|
-
|
|
17
|
-
[Makefile]
|
|
18
|
-
indent_style = tab
|
|
19
|
-
|
|
20
|
-
# Use 2 spaces for the HTML files
|
|
21
|
-
[*.html]
|
|
22
|
-
indent_size = 2
|
|
23
|
-
|
|
24
|
-
# The JSON/YAML files contain newlines inconsistently
|
|
25
|
-
[*.{json,yml,yaml}]
|
|
26
|
-
indent_size = 2
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
pull_request:
|
|
8
|
-
branches:
|
|
9
|
-
- main
|
|
10
|
-
|
|
11
|
-
jobs:
|
|
12
|
-
lint:
|
|
13
|
-
name: Code quality
|
|
14
|
-
runs-on: ubuntu-latest
|
|
15
|
-
steps:
|
|
16
|
-
- name: Checkout
|
|
17
|
-
uses: actions/checkout@v4
|
|
18
|
-
- name: Install uv
|
|
19
|
-
uses: astral-sh/setup-uv@v5
|
|
20
|
-
with:
|
|
21
|
-
python-version: '3.10'
|
|
22
|
-
enable-cache: true
|
|
23
|
-
- name: Set up Python
|
|
24
|
-
run: uv python install
|
|
25
|
-
- name: Install dependencies
|
|
26
|
-
run: uv sync --all-extras --dev
|
|
27
|
-
- name: Static type checking
|
|
28
|
-
run: uv run pyright
|
|
29
|
-
- name: Code formatting
|
|
30
|
-
run: uv run ruff check && uv run ruff format --check
|
|
31
|
-
|
|
32
|
-
tests:
|
|
33
|
-
name: Run unit tests ${{ matrix.name }}
|
|
34
|
-
runs-on: ${{ matrix.os }}
|
|
35
|
-
strategy:
|
|
36
|
-
fail-fast: false
|
|
37
|
-
matrix:
|
|
38
|
-
include:
|
|
39
|
-
- {name: '3.13', python: '3.13', os: ubuntu-latest}
|
|
40
|
-
- {name: '3.12', python: '3.12', os: ubuntu-latest}
|
|
41
|
-
- {name: '3.11', python: '3.11', os: ubuntu-latest}
|
|
42
|
-
- {name: '3.10', python: '3.10', os: ubuntu-latest}
|
|
43
|
-
- {name: '3.9', python: '3.9', os: ubuntu-latest}
|
|
44
|
-
|
|
45
|
-
steps:
|
|
46
|
-
- name: Checkout
|
|
47
|
-
uses: actions/checkout@v4
|
|
48
|
-
- name: Install uv and set the python version
|
|
49
|
-
uses: astral-sh/setup-uv@v5
|
|
50
|
-
with:
|
|
51
|
-
python-version: ${{ matrix.python-version }}
|
|
52
|
-
enable-cache: true
|
|
53
|
-
- name: Install dependencies
|
|
54
|
-
run: uv sync --all-extras --dev
|
|
55
|
-
- name: Run tests
|
|
56
|
-
run: |
|
|
57
|
-
uv run pytest -vv tests --ignore=tests/ext/test_pytest_plugin.py --cov=anydi -p no:anydi
|
|
58
|
-
uv run pytest -vv tests/ext/test_pytest_plugin.py --cov=anydi --cov-append --cov-report=xml
|
|
59
|
-
- name: Upload coverage to Codecov
|
|
60
|
-
uses: codecov/codecov-action@v3
|
|
61
|
-
if: matrix.python == '3.10'
|
anydi-0.47.0rc0/.gitignore
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# Byte-compiled / optimized / DLL files
|
|
2
|
-
__pycache__/
|
|
3
|
-
*.py[cod]
|
|
4
|
-
*$py.class
|
|
5
|
-
.pytest_cache
|
|
6
|
-
.mypy_cache
|
|
7
|
-
.ruff_cache
|
|
8
|
-
|
|
9
|
-
# C extensions
|
|
10
|
-
*.so
|
|
11
|
-
|
|
12
|
-
# Distribution / packaging
|
|
13
|
-
.Python
|
|
14
|
-
env/
|
|
15
|
-
.venv
|
|
16
|
-
build/
|
|
17
|
-
develop-eggs/
|
|
18
|
-
dist/
|
|
19
|
-
downloads/
|
|
20
|
-
eggs/
|
|
21
|
-
.eggs/
|
|
22
|
-
lib/
|
|
23
|
-
lib64/
|
|
24
|
-
parts/
|
|
25
|
-
sdist/
|
|
26
|
-
var/
|
|
27
|
-
*.egg-info/
|
|
28
|
-
.installed.cfg
|
|
29
|
-
*.egg
|
|
30
|
-
|
|
31
|
-
# PyInstaller
|
|
32
|
-
# Usually these files are written by a python script from a template
|
|
33
|
-
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
34
|
-
*.manifest
|
|
35
|
-
*.spec
|
|
36
|
-
|
|
37
|
-
# Installer logs
|
|
38
|
-
pip-log.txt
|
|
39
|
-
pip-delete-this-directory.txt
|
|
40
|
-
|
|
41
|
-
# Unit test / coverage reports
|
|
42
|
-
htmlcov/
|
|
43
|
-
.tox/
|
|
44
|
-
.coverage
|
|
45
|
-
.coverage.*
|
|
46
|
-
.cache
|
|
47
|
-
nosetests.xml
|
|
48
|
-
coverage.xml
|
|
49
|
-
*,cover
|
|
50
|
-
.hypothesis/
|
|
51
|
-
pyunit.xml
|
|
52
|
-
|
|
53
|
-
# Translations
|
|
54
|
-
*.mo
|
|
55
|
-
*.pot
|
|
56
|
-
|
|
57
|
-
# Django stuff:
|
|
58
|
-
*.log
|
|
59
|
-
|
|
60
|
-
# Sphinx documentation
|
|
61
|
-
docs/_build/
|
|
62
|
-
|
|
63
|
-
# PyBuilder
|
|
64
|
-
target/
|
|
65
|
-
|
|
66
|
-
#Ipython Notebook
|
|
67
|
-
.ipynb_checkpoints
|
|
68
|
-
*.ipynb
|
|
69
|
-
|
|
70
|
-
# OS-X thumbnails
|
|
71
|
-
.DS_Store
|
|
72
|
-
|
|
73
|
-
# vi swap files
|
|
74
|
-
*.swp
|
|
75
|
-
|
|
76
|
-
# PyCharm project settings
|
|
77
|
-
.idea
|
|
78
|
-
|
|
79
|
-
# dotenv file
|
|
80
|
-
.env
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
/app
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
version: 2
|
|
2
|
-
|
|
3
|
-
build:
|
|
4
|
-
os: ubuntu-24.04
|
|
5
|
-
tools:
|
|
6
|
-
python: "3.13"
|
|
7
|
-
jobs:
|
|
8
|
-
create_environment:
|
|
9
|
-
- asdf plugin add uv
|
|
10
|
-
- asdf install uv latest
|
|
11
|
-
- asdf global uv latest
|
|
12
|
-
- uv venv
|
|
13
|
-
install:
|
|
14
|
-
- uv sync --frozen --group docs
|
|
15
|
-
build:
|
|
16
|
-
html:
|
|
17
|
-
- NO_COLOR=1 uv run mkdocs build --strict --site-dir $READTHEDOCS_OUTPUT/html
|
|
18
|
-
|
|
19
|
-
mkdocs:
|
|
20
|
-
configuration: mkdocs.yml
|
anydi-0.47.0rc0/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2023 Anton Ruhlov
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
anydi-0.47.0rc0/Makefile
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
.PHONY: help lint fmt test
|
|
2
|
-
.DEFAULT_GOAL := help
|
|
3
|
-
|
|
4
|
-
help:
|
|
5
|
-
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
|
6
|
-
|
|
7
|
-
lint: ## Run code linters
|
|
8
|
-
uv run pyright
|
|
9
|
-
uv run ruff format --check
|
|
10
|
-
uv run ruff check
|
|
11
|
-
|
|
12
|
-
fmt: ## Run code formatters
|
|
13
|
-
uv run ruff format
|
|
14
|
-
uv run ruff check --fix
|
|
15
|
-
|
|
16
|
-
test: ## Run unit tests
|
|
17
|
-
uv run pytest -vv tests --ignore=tests/ext/test_pytest_plugin.py --cov=anydi -p no:anydi -p no:testanydi
|
|
18
|
-
uv run pytest -vv tests/ext/test_pytest_plugin.py --cov=anydi --cov-append
|