anydi 0.65.0__py3-none-any.whl → 0.67.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.
anydi/_container.py CHANGED
@@ -458,21 +458,14 @@ class Container:
458
458
  )
459
459
  has_default = default is not NOT_SET
460
460
 
461
- # Check if provider exists before attempting to register (for scoped only)
462
- was_auto_registered = (
463
- is_scoped and parameter.annotation not in self._providers
464
- )
465
-
466
461
  try:
467
462
  sub_provider = self._get_or_register_provider(parameter.annotation)
468
463
  except LookupError as exc:
469
464
  if (has_defaults and parameter.name in defaults) or has_default:
470
465
  continue
471
- # For request/custom scopes, allow unregistered dependencies
472
- # They might be provided via context.set()
466
+ # For scoped (request/custom) dependencies, allow unresolved parameters
467
+ # that will be provided via context.set()
473
468
  if is_scoped:
474
- # Add to unresolved list to provide better error messages
475
- # and prevent infinite recursion
476
469
  self._resolver.add_unresolved(parameter.annotation)
477
470
  parameters.append(
478
471
  ProviderParameter(
@@ -480,8 +473,8 @@ class Container:
480
473
  annotation=parameter.annotation,
481
474
  default=default,
482
475
  has_default=has_default,
483
- provider=None, # Will check context at runtime
484
- shared_scope=True, # Same scope, check context
476
+ provider=None,
477
+ shared_scope=True,
485
478
  )
486
479
  )
487
480
  continue
@@ -493,9 +486,25 @@ class Container:
493
486
  if sub_provider.scope not in scope_provider:
494
487
  scope_provider[sub_provider.scope] = sub_provider
495
488
 
496
- # If provider was auto-registered and has same scope, mark as unresolved
497
- if was_auto_registered and sub_provider.scope == scope:
489
+ # For scoped dependencies with same scope: if auto-registered provider
490
+ # has unresolved parameters, defer to context.set() instead
491
+ if (
492
+ is_scoped
493
+ and sub_provider.scope == scope
494
+ and any(p.provider is None for p in sub_provider.parameters)
495
+ ):
498
496
  self._resolver.add_unresolved(parameter.annotation)
497
+ parameters.append(
498
+ ProviderParameter(
499
+ name=parameter.name,
500
+ annotation=parameter.annotation,
501
+ default=default,
502
+ has_default=has_default,
503
+ provider=None,
504
+ shared_scope=True,
505
+ )
506
+ )
507
+ continue
499
508
 
500
509
  parameters.append(
501
510
  ProviderParameter(
anydi/_resolver.py CHANGED
@@ -299,7 +299,7 @@ class Resolver:
299
299
  create_lines.append(" if compiled is None:")
300
300
  create_lines.append(
301
301
  " provider = "
302
- "container._get_or_register_provider(_param_annotations[{idx}])"
302
+ f"container._get_or_register_provider(_param_annotations[{idx}])"
303
303
  )
304
304
  create_lines.append(
305
305
  " compiled = "
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anydi
3
- Version: 0.65.0
3
+ Version: 0.67.0
4
4
  Summary: Dependency Injection library
5
5
  Keywords: dependency injection,dependencies,di,async,asyncio,application
6
6
  Author: Anton Ruhlov
@@ -37,11 +37,11 @@ Description-Content-Type: text/markdown
37
37
 
38
38
  <div style="text-align: center;">
39
39
 
40
- Modern, lightweight Dependency Injection library using type annotations.
40
+ Simple Dependency Injection library that uses Python type annotations.
41
41
 
42
42
  [![CI](https://github.com/antonrh/anydi/actions/workflows/ci.yml/badge.svg)](https://github.com/antonrh/anydi/actions/workflows/ci.yml)
43
43
  [![Coverage](https://codecov.io/gh/antonrh/anydi/branch/main/graph/badge.svg)](https://codecov.io/gh/antonrh/anydi)
44
- [![Documentation](https://readthedocs.org/projects/anydi/badge/?version=latest)](https://anydi.readthedocs.io/en/latest/)
44
+ [![Documentation](https://readthedocs.org/projects/anydi/badge/?version=latest)](https://anydi.readthedocs.io/en/stable/)
45
45
  [![CodSpeed](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json)](https://codspeed.io/antonrh/anydi?utm_source=badge)
46
46
 
47
47
  </div>
@@ -53,21 +53,21 @@ http://anydi.readthedocs.io/
53
53
 
54
54
  ---
55
55
 
56
- `AnyDI` is a modern, lightweight Dependency Injection library suitable for any synchronous or asynchronous applications with Python 3.10+, based on type annotations ([PEP 484](https://peps.python.org/pep-0484/)).
56
+ `AnyDI` is a simple Dependency Injection library for Python 3.10+. It works with sync and async applications and uses type annotations ([PEP 484](https://peps.python.org/pep-0484/)).
57
57
 
58
- The key features are:
58
+ Main features:
59
59
 
60
- * **Type-safe**: Dependency resolution is driven by type hints.
61
- * **Async-ready**: Works the same for sync and async providers or injections.
62
- * **Scoped**: Built-in singleton, transient, and request scopes, plus custom scopes.
63
- * **Simple**: Small surface area keeps boilerplate low.
64
- * **Fast**: Has minimal overhead and resolves dependencies quickly.
65
- * **Named**: `Annotated[...]` makes multiple bindings per type simple.
66
- * **Managed**: Providers can open/close resources via context managers.
67
- * **Modular**: Compose containers or modules for large apps.
68
- * **Scanning**: Auto-discovers injectable callables.
69
- * **Integrated**: Extensions for popular frameworks.
70
- * **Testable**: Override providers directly in tests.
60
+ * **Type-safe**: Uses type hints for dependency resolution.
61
+ * **Async support**: Works with both sync and async code.
62
+ * **Scopes**: Provides singleton, transient, and request scopes. Supports custom scope definitions.
63
+ * **Simple**: Minimal boilerplate with straightforward API.
64
+ * **Fast**: Low overhead dependency resolution.
65
+ * **Named providers**: Use `Annotated[...]` for multiple providers per type.
66
+ * **Resource management**: Context manager protocol support for lifecycle management.
67
+ * **Modular**: Container and module composition for large applications.
68
+ * **Auto-scan**: Automatic discovery of injectable callables.
69
+ * **Framework integrations**: Extensions for popular frameworks.
70
+ * **Testing**: Provider override mechanism for test isolation.
71
71
 
72
72
  ## Installation
73
73
 
@@ -266,23 +266,23 @@ urlpatterns = [
266
266
  ]
267
267
  ```
268
268
 
269
- ## What's Next?
269
+ ## Learn More
270
270
 
271
- Ready to learn more? Check out these resources:
271
+ Want to know more? Here are helpful resources:
272
272
 
273
273
  **Core Documentation:**
274
- - [Core Concepts](https://anydi.readthedocs.io/en/latest/concepts/) - Understand containers, providers, scopes, and dependency injection
275
- - [Providers](https://anydi.readthedocs.io/en/latest/usage/providers/) - Learn about registration, named providers, and resource management
276
- - [Scopes](https://anydi.readthedocs.io/en/latest/usage/scopes/) - Master lifecycle management with built-in and custom scopes
277
- - [Dependency Injection](https://anydi.readthedocs.io/en/latest/usage/injection/) - Explore injection patterns and techniques
278
- - [Testing](https://anydi.readthedocs.io/en/latest/usage/testing/) - Write testable code with provider overrides
274
+ - [Core Concepts](https://anydi.readthedocs.io/en/stable/concepts/) - Learn about containers, providers, scopes, and dependency injection
275
+ - [Providers](https://anydi.readthedocs.io/en/stable/usage/providers/) - How to register providers and manage resources
276
+ - [Scopes](https://anydi.readthedocs.io/en/stable/usage/scopes/) - How to use built-in and custom scopes
277
+ - [Dependency Injection](https://anydi.readthedocs.io/en/stable/usage/injection/) - Different ways to inject dependencies
278
+ - [Testing](https://anydi.readthedocs.io/en/stable/usage/testing/) - How to test your code with provider overrides
279
279
 
280
280
  **Framework Integrations:**
281
- - [FastAPI](https://anydi.readthedocs.io/en/latest/extensions/fastapi/) - Build modern APIs with automatic dependency injection
282
- - [Django](https://anydi.readthedocs.io/en/latest/extensions/django/) - Integrate with Django and Django Ninja
283
- - [FastStream](https://anydi.readthedocs.io/en/latest/extensions/faststream/) - Message broker applications
284
- - [Typer](https://anydi.readthedocs.io/en/latest/extensions/typer/) - CLI applications with async support
285
- - [Pydantic Settings](https://anydi.readthedocs.io/en/latest/extensions/pydantic_settings/) - Configuration management
281
+ - [FastAPI](https://anydi.readthedocs.io/en/stable/extensions/fastapi/) - How to use with FastAPI
282
+ - [Django](https://anydi.readthedocs.io/en/stable/extensions/django/) - How to use with Django and Django Ninja
283
+ - [FastStream](https://anydi.readthedocs.io/en/stable/extensions/faststream/) - How to use with message brokers
284
+ - [Typer](https://anydi.readthedocs.io/en/stable/extensions/typer/) - How to use in CLI applications
285
+ - [Pydantic Settings](https://anydi.readthedocs.io/en/stable/extensions/pydantic_settings/) - How to manage configuration
286
286
 
287
287
  **Full Documentation:**
288
- - [Read the Docs](https://anydi.readthedocs.io/) - Complete documentation with examples and guides
288
+ - [Read the Docs](https://anydi.readthedocs.io/) - All documentation with examples and guides
@@ -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=NFxrzJuWwc4DyT2Ffl0RUU3ecCCF4cl-tLp9LhgKnfQ,29675
3
+ anydi/_container.py,sha256=_gyNfAddQtp93tjCud2JZDvgoOAM2WuMx4qIvBs7IOs,29878
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=nKPuEI69ZBLdPubQlnlQTTkhMK15vG0YcW9jgitzIto,31393
10
+ anydi/_resolver.py,sha256=ask0W63w4fi1cZFd-3Bq9ael6rkTG01E05TTv81eSII,31394
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.65.0.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
25
- anydi-0.65.0.dist-info/entry_points.txt,sha256=AgOcQYM5KyS4D37QcYb00tiid0QA-pD1VrjHHq4QAps,44
26
- anydi-0.65.0.dist-info/METADATA,sha256=1_HiKQhF3W8pOnXHqMkAzLvhTOC7UiZX-0-fIbRVprY,8142
27
- anydi-0.65.0.dist-info/RECORD,,
24
+ anydi-0.67.0.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
25
+ anydi-0.67.0.dist-info/entry_points.txt,sha256=AgOcQYM5KyS4D37QcYb00tiid0QA-pD1VrjHHq4QAps,44
26
+ anydi-0.67.0.dist-info/METADATA,sha256=Ave4jzjegADI3S02BtmeX-n42cKFtT9ehXROCTepXYw,8061
27
+ anydi-0.67.0.dist-info/RECORD,,
File without changes