anydi 0.67.0__py3-none-any.whl → 0.67.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 +40 -55
- anydi/_resolver.py +2 -0
- {anydi-0.67.0.dist-info → anydi-0.67.1.dist-info}/METADATA +1 -1
- {anydi-0.67.0.dist-info → anydi-0.67.1.dist-info}/RECORD +6 -6
- {anydi-0.67.0.dist-info → anydi-0.67.1.dist-info}/WHEEL +0 -0
- {anydi-0.67.0.dist-info → anydi-0.67.1.dist-info}/entry_points.txt +0 -0
anydi/_container.py
CHANGED
|
@@ -390,28 +390,27 @@ class Container:
|
|
|
390
390
|
name = type_repr(call)
|
|
391
391
|
kind = ProviderKind.from_call(call)
|
|
392
392
|
is_class = kind == ProviderKind.CLASS
|
|
393
|
-
|
|
393
|
+
is_coroutine = kind == ProviderKind.COROUTINE
|
|
394
|
+
is_generator = kind == ProviderKind.GENERATOR
|
|
395
|
+
is_async_generator = kind == ProviderKind.ASYNC_GENERATOR
|
|
396
|
+
is_resource = is_generator or is_async_generator
|
|
394
397
|
|
|
395
|
-
# Validate scope
|
|
398
|
+
# Validate scope
|
|
396
399
|
self._validate_provider_scope(scope, name, is_resource)
|
|
397
400
|
|
|
398
|
-
# Get
|
|
401
|
+
# Get signature and detect interface
|
|
399
402
|
signature = inspect.signature(call, eval_str=True)
|
|
400
403
|
|
|
401
|
-
# Detect the interface
|
|
402
404
|
if interface is NOT_SET:
|
|
403
|
-
if is_class
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
interface = signature.return_annotation
|
|
407
|
-
if interface is inspect.Signature.empty:
|
|
408
|
-
interface = None
|
|
405
|
+
interface = call if is_class else signature.return_annotation
|
|
406
|
+
if interface is inspect.Signature.empty:
|
|
407
|
+
interface = None
|
|
409
408
|
|
|
410
|
-
#
|
|
411
|
-
|
|
409
|
+
# Handle iterator types for resources
|
|
410
|
+
interface_origin = get_origin(interface)
|
|
411
|
+
if is_iterator_type(interface) or is_iterator_type(interface_origin):
|
|
412
412
|
if args := get_args(interface):
|
|
413
413
|
interface = args[0]
|
|
414
|
-
# If the callable is a generator, return the resource type
|
|
415
414
|
if is_none_type(interface):
|
|
416
415
|
interface = type(f"Event_{uuid.uuid4().hex}", (Event,), {})
|
|
417
416
|
else:
|
|
@@ -420,24 +419,22 @@ class Container:
|
|
|
420
419
|
"without actual type argument."
|
|
421
420
|
)
|
|
422
421
|
|
|
423
|
-
#
|
|
422
|
+
# Validate interface
|
|
424
423
|
if is_none_type(interface):
|
|
425
424
|
raise TypeError(f"Missing `{name}` provider return annotation.")
|
|
426
425
|
|
|
427
|
-
# Check for existing provider
|
|
428
426
|
if interface in self._providers and not override:
|
|
429
427
|
raise LookupError(
|
|
430
428
|
f"The provider interface `{type_repr(interface)}` already registered."
|
|
431
429
|
)
|
|
432
430
|
|
|
433
|
-
|
|
434
|
-
unresolved_exc: LookupError | None = None
|
|
431
|
+
# Process parameters
|
|
435
432
|
parameters: list[ProviderParameter] = []
|
|
436
433
|
scope_provider: dict[Scope, Provider] = {}
|
|
437
|
-
|
|
438
|
-
|
|
434
|
+
unresolved_parameter = None
|
|
435
|
+
unresolved_exc: LookupError | None = None
|
|
439
436
|
is_scoped = scope not in ("singleton", "transient")
|
|
440
|
-
|
|
437
|
+
scope_hierarchy = self._scopes.get(scope, ()) if scope != "transient" else ()
|
|
441
438
|
|
|
442
439
|
for parameter in signature.parameters.values():
|
|
443
440
|
if parameter.annotation is inspect.Parameter.empty:
|
|
@@ -451,20 +448,15 @@ class Container:
|
|
|
451
448
|
f"are not allowed in the provider `{name}`."
|
|
452
449
|
)
|
|
453
450
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
if parameter.default is not inspect.Parameter.empty
|
|
457
|
-
else NOT_SET
|
|
458
|
-
)
|
|
459
|
-
has_default = default is not NOT_SET
|
|
451
|
+
has_default = parameter.default is not inspect.Parameter.empty
|
|
452
|
+
default = parameter.default if has_default else NOT_SET
|
|
460
453
|
|
|
461
454
|
try:
|
|
462
455
|
sub_provider = self._get_or_register_provider(parameter.annotation)
|
|
463
456
|
except LookupError as exc:
|
|
464
|
-
if (
|
|
457
|
+
if (defaults and parameter.name in defaults) or has_default:
|
|
465
458
|
continue
|
|
466
|
-
# For scoped
|
|
467
|
-
# that will be provided via context.set()
|
|
459
|
+
# For scoped dependencies, allow unresolved parameters via context.set()
|
|
468
460
|
if is_scoped:
|
|
469
461
|
self._resolver.add_unresolved(parameter.annotation)
|
|
470
462
|
parameters.append(
|
|
@@ -482,12 +474,11 @@ class Container:
|
|
|
482
474
|
unresolved_exc = exc
|
|
483
475
|
continue
|
|
484
476
|
|
|
485
|
-
#
|
|
486
|
-
|
|
487
|
-
scope_provider[sub_provider.scope] = sub_provider
|
|
477
|
+
# Track scope providers for validation
|
|
478
|
+
scope_provider.setdefault(sub_provider.scope, sub_provider)
|
|
488
479
|
|
|
489
|
-
# For scoped dependencies with same scope
|
|
490
|
-
#
|
|
480
|
+
# For scoped dependencies with same scope having unresolved params,
|
|
481
|
+
# defer to context.set() instead
|
|
491
482
|
if (
|
|
492
483
|
is_scoped
|
|
493
484
|
and sub_provider.scope == scope
|
|
@@ -506,6 +497,15 @@ class Container:
|
|
|
506
497
|
)
|
|
507
498
|
continue
|
|
508
499
|
|
|
500
|
+
# Validate scope compatibility inline
|
|
501
|
+
if scope_hierarchy and sub_provider.scope not in scope_hierarchy:
|
|
502
|
+
raise ValueError(
|
|
503
|
+
f"The provider `{name}` with a `{scope}` scope "
|
|
504
|
+
f"cannot depend on `{sub_provider}` with a "
|
|
505
|
+
f"`{sub_provider.scope}` scope. Please ensure all "
|
|
506
|
+
"providers are registered with matching scopes."
|
|
507
|
+
)
|
|
508
|
+
|
|
509
509
|
parameters.append(
|
|
510
510
|
ProviderParameter(
|
|
511
511
|
name=parameter.name,
|
|
@@ -517,21 +517,11 @@ class Container:
|
|
|
517
517
|
)
|
|
518
518
|
)
|
|
519
519
|
|
|
520
|
-
#
|
|
521
|
-
# Transient scope can use any scoped dependencies
|
|
522
|
-
if scope != "transient":
|
|
523
|
-
for sub_provider in scope_provider.values():
|
|
524
|
-
if sub_provider.scope not in self._scopes.get(scope, []):
|
|
525
|
-
raise ValueError(
|
|
526
|
-
f"The provider `{name}` with a `{scope}` scope "
|
|
527
|
-
f"cannot depend on `{sub_provider}` with a "
|
|
528
|
-
f"`{sub_provider.scope}` scope. Please ensure all "
|
|
529
|
-
"providers are registered with matching scopes."
|
|
530
|
-
)
|
|
531
|
-
|
|
532
|
-
# Check for unresolved parameters
|
|
520
|
+
# Handle unresolved parameters
|
|
533
521
|
if unresolved_parameter:
|
|
534
|
-
if
|
|
522
|
+
if is_scoped: # pragma: no cover
|
|
523
|
+
# Note: This branch is currently unreachable because
|
|
524
|
+
# unresolved_parameter is only set when is_scoped=False
|
|
535
525
|
self._resolver.add_unresolved(interface)
|
|
536
526
|
else:
|
|
537
527
|
raise LookupError(
|
|
@@ -542,11 +532,7 @@ class Container:
|
|
|
542
532
|
f"attempting to use it."
|
|
543
533
|
) from unresolved_exc
|
|
544
534
|
|
|
545
|
-
|
|
546
|
-
is_generator = kind == ProviderKind.GENERATOR
|
|
547
|
-
is_async_generator = kind == ProviderKind.ASYNC_GENERATOR
|
|
548
|
-
is_async = is_coroutine or is_async_generator
|
|
549
|
-
|
|
535
|
+
# Create and register provider
|
|
550
536
|
provider = Provider(
|
|
551
537
|
call=call,
|
|
552
538
|
scope=scope,
|
|
@@ -557,13 +543,12 @@ class Container:
|
|
|
557
543
|
is_coroutine=is_coroutine,
|
|
558
544
|
is_generator=is_generator,
|
|
559
545
|
is_async_generator=is_async_generator,
|
|
560
|
-
is_async=
|
|
546
|
+
is_async=is_coroutine or is_async_generator,
|
|
561
547
|
is_resource=is_resource,
|
|
562
548
|
)
|
|
563
549
|
|
|
564
550
|
self._set_provider(provider)
|
|
565
551
|
|
|
566
|
-
# Clear cached resolvers when overriding
|
|
567
552
|
if override:
|
|
568
553
|
self._resolver.clear_caches()
|
|
569
554
|
|
anydi/_resolver.py
CHANGED
|
@@ -672,6 +672,8 @@ class Resolver:
|
|
|
672
672
|
|
|
673
673
|
def _wrap_for_override(self, annotation: Any, value: Any) -> Any:
|
|
674
674
|
"""Hook for wrapping dependencies to enable override patching."""
|
|
675
|
+
if isinstance(value, InstanceProxy):
|
|
676
|
+
return value
|
|
675
677
|
return InstanceProxy(value, interface=annotation)
|
|
676
678
|
|
|
677
679
|
def _post_resolve_override(self, interface: Any, instance: Any) -> Any: # noqa: C901
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
anydi/__init__.py,sha256=KFX8OthKXwBuYDPCV61t-044DpJ88tAOzIxeUWRC5OA,633
|
|
2
2
|
anydi/_async_lock.py,sha256=3dwZr0KthXFYha0XKMyXf8jMmGb1lYoNC0O5w29V9ic,1104
|
|
3
|
-
anydi/_container.py,sha256=
|
|
3
|
+
anydi/_container.py,sha256=4bv3_fiDw6aPZ-bKjU5jmqeT66CvRnteHbosqMk5R0U,29408
|
|
4
4
|
anydi/_context.py,sha256=-9QqeMWo9OpZVXZxZCQgIsswggl3Ch7lgx1KiFX_ezc,3752
|
|
5
5
|
anydi/_decorators.py,sha256=J3W261ZAG7q4XKm4tbAv1wsWr9ysx9_5MUbUvSJB_MQ,2809
|
|
6
6
|
anydi/_injector.py,sha256=1Ux71DhGxu3dLwPJP8gU73olI0pcZ3_tVaVzwKH7100,4411
|
|
7
7
|
anydi/_marker.py,sha256=xVydjGdkxd_DqqwttnJZRkQbhpCTE9OnrhFmFJMlgvI,3415
|
|
8
8
|
anydi/_module.py,sha256=2kN5uEXLd2Dsc58gz5IWK43wJewr_QgIVGSO3iWp798,2609
|
|
9
9
|
anydi/_provider.py,sha256=OV1WFHTYv7W2U0XDk_Kql1r551Vhq8o-pUV5ep1HQcU,1574
|
|
10
|
-
anydi/_resolver.py,sha256=
|
|
10
|
+
anydi/_resolver.py,sha256=6pJS-9F0epCj7goVbc7GeGdpqe0woI3Blu-3dA3jeNs,31464
|
|
11
11
|
anydi/_scanner.py,sha256=rbRkHzyd2zMu7AFLffN6_tZJcMaW9gy7E-lVdHLHYrs,4294
|
|
12
12
|
anydi/_types.py,sha256=lsShY_-_CM2EFajeknAYXvLl-rHfopBT8udnK5_BtS4,1161
|
|
13
13
|
anydi/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -21,7 +21,7 @@ anydi/ext/starlette/middleware.py,sha256=n_JJ7BcG2Mg2M5HwM_SBboxZ-mnnD6WWJn4khq7
|
|
|
21
21
|
anydi/ext/typer.py,sha256=z-sDd3jZMPTE2CyEuJ0f9uIJB43FjoLWbjpnkOvqSKA,6236
|
|
22
22
|
anydi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
23
|
anydi/testing.py,sha256=cHg3mMScZbEep9smRqSNQ81BZMQOkyugHe8TvKdPnEg,1347
|
|
24
|
-
anydi-0.67.
|
|
25
|
-
anydi-0.67.
|
|
26
|
-
anydi-0.67.
|
|
27
|
-
anydi-0.67.
|
|
24
|
+
anydi-0.67.1.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
25
|
+
anydi-0.67.1.dist-info/entry_points.txt,sha256=AgOcQYM5KyS4D37QcYb00tiid0QA-pD1VrjHHq4QAps,44
|
|
26
|
+
anydi-0.67.1.dist-info/METADATA,sha256=lqtZFxSRc7ohAAkAAdjcgxQDy7q5FTNP2MtBPZo3c4o,8061
|
|
27
|
+
anydi-0.67.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|