anydi 0.47.0rc0__py3-none-any.whl → 0.48.1__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.
- anydi/_container.py +34 -48
- anydi/_typing.py +0 -6
- anydi/ext/django/apps.py +10 -2
- anydi/testing.py +1 -7
- {anydi-0.47.0rc0.dist-info → anydi-0.48.1.dist-info}/METADATA +17 -17
- {anydi-0.47.0rc0.dist-info → anydi-0.48.1.dist-info}/RECORD +13 -14
- anydi-0.48.1.dist-info/WHEEL +4 -0
- {anydi-0.47.0rc0.dist-info → anydi-0.48.1.dist-info}/entry_points.txt +1 -0
- anydi-0.47.0rc0.dist-info/WHEEL +0 -4
- anydi-0.47.0rc0.dist-info/licenses/LICENSE +0 -21
anydi/_container.py
CHANGED
|
@@ -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__", {})
|
|
@@ -315,6 +305,7 @@ class Container:
|
|
|
315
305
|
)
|
|
316
306
|
|
|
317
307
|
unresolved_parameter = None
|
|
308
|
+
unresolved_exc: LookupError | None = None
|
|
318
309
|
parameters: list[inspect.Parameter] = []
|
|
319
310
|
scopes: dict[Scope, Provider] = {}
|
|
320
311
|
|
|
@@ -335,13 +326,12 @@ class Container:
|
|
|
335
326
|
)
|
|
336
327
|
|
|
337
328
|
try:
|
|
338
|
-
sub_provider = self._get_or_register_provider(
|
|
339
|
-
|
|
340
|
-
)
|
|
341
|
-
except LookupError:
|
|
329
|
+
sub_provider = self._get_or_register_provider(parameter.annotation)
|
|
330
|
+
except LookupError as exc:
|
|
342
331
|
if self._parameter_has_default(parameter, **defaults):
|
|
343
332
|
continue
|
|
344
333
|
unresolved_parameter = parameter
|
|
334
|
+
unresolved_exc = exc
|
|
345
335
|
continue
|
|
346
336
|
|
|
347
337
|
# Store first provider for each scope
|
|
@@ -350,24 +340,9 @@ class Container:
|
|
|
350
340
|
|
|
351
341
|
parameters.append(parameter)
|
|
352
342
|
|
|
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
343
|
# Check for unresolved parameters
|
|
369
344
|
if unresolved_parameter:
|
|
370
|
-
if
|
|
345
|
+
if scope not in ("singleton", "transient"):
|
|
371
346
|
self._unresolved_interfaces.add(interface)
|
|
372
347
|
else:
|
|
373
348
|
raise LookupError(
|
|
@@ -376,20 +351,20 @@ class Container:
|
|
|
376
351
|
"which has not been registered or set. To resolve this, ensure "
|
|
377
352
|
f"that `{unresolved_parameter.name}` is registered before "
|
|
378
353
|
f"attempting to use it."
|
|
379
|
-
) from
|
|
354
|
+
) from unresolved_exc
|
|
380
355
|
|
|
381
356
|
# Check scope compatibility
|
|
382
357
|
for sub_provider in scopes.values():
|
|
383
|
-
if sub_provider.scope not in ALLOWED_SCOPES.get(
|
|
358
|
+
if sub_provider.scope not in ALLOWED_SCOPES.get(scope, []):
|
|
384
359
|
raise ValueError(
|
|
385
|
-
f"The provider `{name}` with a `{
|
|
360
|
+
f"The provider `{name}` with a `{scope}` scope cannot "
|
|
386
361
|
f"depend on `{sub_provider}` with a `{sub_provider.scope}` scope. "
|
|
387
362
|
"Please ensure all providers are registered with matching scopes."
|
|
388
363
|
)
|
|
389
364
|
|
|
390
365
|
provider = Provider(
|
|
391
366
|
call=call,
|
|
392
|
-
scope=
|
|
367
|
+
scope=scope,
|
|
393
368
|
interface=interface,
|
|
394
369
|
name=name,
|
|
395
370
|
kind=kind,
|
|
@@ -425,20 +400,18 @@ class Container:
|
|
|
425
400
|
"properly registered before attempting to use it."
|
|
426
401
|
) from exc
|
|
427
402
|
|
|
428
|
-
def _get_or_register_provider(
|
|
429
|
-
self, interface: Any, parent_scope: Scope | None, /, **defaults: Any
|
|
430
|
-
) -> Provider:
|
|
403
|
+
def _get_or_register_provider(self, interface: Any, /, **defaults: Any) -> Provider:
|
|
431
404
|
"""Get or register a provider by interface."""
|
|
432
405
|
try:
|
|
433
406
|
return self._providers[interface]
|
|
434
407
|
except KeyError:
|
|
435
|
-
if inspect.isclass(interface) and
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
408
|
+
if inspect.isclass(interface) and is_provided(interface):
|
|
409
|
+
return self._register_provider(
|
|
410
|
+
interface,
|
|
411
|
+
interface.__provided__["scope"],
|
|
412
|
+
NOT_SET,
|
|
413
|
+
**defaults,
|
|
414
|
+
)
|
|
442
415
|
raise LookupError(
|
|
443
416
|
f"The provider interface `{type_repr(interface)}` is either not "
|
|
444
417
|
"registered, not provided, or not set in the scoped context. "
|
|
@@ -533,7 +506,7 @@ class Container:
|
|
|
533
506
|
self, interface: Any, create: bool, /, **defaults: Any
|
|
534
507
|
) -> Any:
|
|
535
508
|
"""Internal method to handle instance resolution and creation."""
|
|
536
|
-
provider = self._get_or_register_provider(interface,
|
|
509
|
+
provider = self._get_or_register_provider(interface, **defaults)
|
|
537
510
|
if provider.scope == "transient":
|
|
538
511
|
return self._create_instance(provider, None, **defaults)
|
|
539
512
|
context = self._get_instance_context(provider.scope)
|
|
@@ -548,7 +521,7 @@ class Container:
|
|
|
548
521
|
self, interface: Any, create: bool, /, **defaults: Any
|
|
549
522
|
) -> Any:
|
|
550
523
|
"""Internal method to handle instance resolution and creation asynchronously."""
|
|
551
|
-
provider = self._get_or_register_provider(interface,
|
|
524
|
+
provider = self._get_or_register_provider(interface, **defaults)
|
|
552
525
|
if provider.scope == "transient":
|
|
553
526
|
return await self._acreate_instance(provider, None, **defaults)
|
|
554
527
|
context = self._get_instance_context(provider.scope)
|
|
@@ -884,3 +857,16 @@ class Container:
|
|
|
884
857
|
self, /, packages: PackageOrIterable, *, tags: Iterable[str] | None = None
|
|
885
858
|
) -> None:
|
|
886
859
|
self._scanner.scan(packages=packages, tags=tags)
|
|
860
|
+
|
|
861
|
+
############################
|
|
862
|
+
# Testing
|
|
863
|
+
############################
|
|
864
|
+
|
|
865
|
+
@contextlib.contextmanager
|
|
866
|
+
def override(self, interface: Any, instance: Any) -> Iterator[None]:
|
|
867
|
+
raise RuntimeError(
|
|
868
|
+
"Dependency overriding is not supported in this container.\n"
|
|
869
|
+
"Wrap your container with `anydi.testing.Container` instead.\n"
|
|
870
|
+
"Example:\n\n"
|
|
871
|
+
" container = TestContainer.from_container(container)"
|
|
872
|
+
)
|
anydi/_typing.py
CHANGED
|
@@ -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__")
|
anydi/ext/django/apps.py
CHANGED
|
@@ -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
|
anydi/testing.py
CHANGED
|
@@ -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,36 +1,36 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: anydi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.48.1
|
|
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
|
|
@@ -1,33 +1,32 @@
|
|
|
1
1
|
anydi/__init__.py,sha256=KjjYm-1yAFxiPYaMs1WRJMtxE0q_vdX7ZRLQR1fFGs8,567
|
|
2
2
|
anydi/_async.py,sha256=KhRd3RmZFcwNDzrMm8ctA1gwrg-6m_7laECTYsZdF5k,1445
|
|
3
|
-
anydi/_container.py,sha256=
|
|
3
|
+
anydi/_container.py,sha256=fELFvxMrsrO2MQhAtnMmLKFxkvsaySx5ZwFGHy5KcOw,31860
|
|
4
4
|
anydi/_context.py,sha256=_Xy8cTpRskb4cxTd-Fe-5NnIZyBe1DnovkofhdeUfmw,3020
|
|
5
5
|
anydi/_decorators.py,sha256=F3yBeGQSz1EsulZaEvYn3cd6FEjJRMoyA6u1QCbEwcs,2813
|
|
6
6
|
anydi/_module.py,sha256=QPvP27JndZkwl-FYUZWscJm6yfkNzjwoFGURyDhb6Pc,2582
|
|
7
7
|
anydi/_provider.py,sha256=ig2ecn-STmFGcpkLE5A5OM35XHtU2NsxFVrGp2CvuvM,2123
|
|
8
8
|
anydi/_scan.py,sha256=nOpspmceVucdwf8nUv1QVFsz2sRVWCVUb0QTH9EbWr4,3653
|
|
9
9
|
anydi/_scope.py,sha256=PFHjPb2-n0vhRo9mvD_craTFfoJBzR3y-N3_0apL5Q0,258
|
|
10
|
-
anydi/_typing.py,sha256=
|
|
11
|
-
anydi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
anydi/testing.py,sha256=ex9grqKpQmmJWwhIVnzq6aHaUAGLu2-7fwLyYTUuKHE,5678
|
|
10
|
+
anydi/_typing.py,sha256=cYsEnv_QpI8B1DIZ8zPZwywEmZjtx0otJjj6vTLLk_E,3895
|
|
13
11
|
anydi/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
anydi/ext/fastapi.py,sha256=L9VGPHGy23se1sflmJqTE7LNfQuElVdYEogoT1f5-4A,2324
|
|
15
|
-
anydi/ext/faststream.py,sha256=Dy81Vf34CP6pEIbZ-41vh_-Dn6Qc-rcf14U5poebjxI,1905
|
|
16
|
-
anydi/ext/pydantic_settings.py,sha256=8IXXLuG_OvKbvKlBkBRQUHcXgbTpgQUxeWyoMcRIUQM,1488
|
|
17
|
-
anydi/ext/pytest_plugin.py,sha256=IoP6XKuGLGLd2Xlpfttc3mI4pxCm2WQLE7x_a7asbv4,4732
|
|
18
12
|
anydi/ext/django/__init__.py,sha256=QI1IABCVgSDTUoh7M9WMECKXwB3xvh04HfQ9TOWw1Mk,223
|
|
19
13
|
anydi/ext/django/_container.py,sha256=cxVoYQG16WP0S_Yv4TnLwuaaT7NVEOhLWO-YdALJUb4,418
|
|
20
14
|
anydi/ext/django/_settings.py,sha256=NsYbFBeslqw_tcXCn2b2gKnSp7eb64DM4dRc4tn_eiw,808
|
|
21
15
|
anydi/ext/django/_utils.py,sha256=sYfUgBV9azddWYB4vNaZadDXcv_MiU-wSfVKV-TZDrE,2695
|
|
22
|
-
anydi/ext/django/apps.py,sha256=
|
|
16
|
+
anydi/ext/django/apps.py,sha256=kGqTUZK55OPtaG5lktavSr88_quDm9GNFUE94eQh6zQ,2965
|
|
23
17
|
anydi/ext/django/middleware.py,sha256=5OUdp0OWRozyW338Sq04BDhacaFlyUTTOduS_7EwCTA,854
|
|
24
18
|
anydi/ext/django/ninja/__init__.py,sha256=4J0zoHPK9itbTVrjjvLX6Ftrsb2ND8bITqNDIJzEhks,520
|
|
25
19
|
anydi/ext/django/ninja/_operation.py,sha256=wk5EOjLY3KVIHk9jMCGsFsja9-dQmMOpLpHXciqxQdk,2680
|
|
26
20
|
anydi/ext/django/ninja/_signature.py,sha256=p7JtyMdFhX4fWQOvAhvZNss6iURNERcdsTsQADTHkMY,2358
|
|
21
|
+
anydi/ext/fastapi.py,sha256=L9VGPHGy23se1sflmJqTE7LNfQuElVdYEogoT1f5-4A,2324
|
|
22
|
+
anydi/ext/faststream.py,sha256=Dy81Vf34CP6pEIbZ-41vh_-Dn6Qc-rcf14U5poebjxI,1905
|
|
23
|
+
anydi/ext/pydantic_settings.py,sha256=8IXXLuG_OvKbvKlBkBRQUHcXgbTpgQUxeWyoMcRIUQM,1488
|
|
24
|
+
anydi/ext/pytest_plugin.py,sha256=IoP6XKuGLGLd2Xlpfttc3mI4pxCm2WQLE7x_a7asbv4,4732
|
|
27
25
|
anydi/ext/starlette/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
26
|
anydi/ext/starlette/middleware.py,sha256=MxnzshAs-CMvjJp0r457k52MzBL8O4KAuClnF6exBdU,803
|
|
29
|
-
anydi
|
|
30
|
-
anydi
|
|
31
|
-
anydi-0.
|
|
32
|
-
anydi-0.
|
|
33
|
-
anydi-0.
|
|
27
|
+
anydi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
+
anydi/testing.py,sha256=waz0nO-MnfPGQLnPuDT0bdEdfqfmgkbsuFuxWfct6kw,5539
|
|
29
|
+
anydi-0.48.1.dist-info/WHEEL,sha256=Pi5uDq5Fdo_Rr-HD5h9BiPn9Et29Y9Sh8NhcJNnFU1c,79
|
|
30
|
+
anydi-0.48.1.dist-info/entry_points.txt,sha256=AgOcQYM5KyS4D37QcYb00tiid0QA-pD1VrjHHq4QAps,44
|
|
31
|
+
anydi-0.48.1.dist-info/METADATA,sha256=X9swcb7pHvqntskN44YfhEJlCnR6wCGJWGwARHAPWfM,4956
|
|
32
|
+
anydi-0.48.1.dist-info/RECORD,,
|
anydi-0.47.0rc0.dist-info/WHEEL
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.
|