|
1 | 1 | from abc import ABC, abstractmethod |
| 2 | +from concurrent.futures import Future, ThreadPoolExecutor |
2 | 3 | from dataclasses import dataclass |
3 | 4 | from typing import Annotated, Any, Optional, TypeVar, Union |
4 | 5 |
|
| 6 | +import anyio |
5 | 7 | import pytest |
6 | 8 |
|
7 | 9 | from injection import inject, injectable |
@@ -294,3 +296,43 @@ def function(a: A): ... |
294 | 296 |
|
295 | 297 | function() |
296 | 298 | assert module.is_locked |
| 299 | + |
| 300 | + async def test_inject_with_async_singleton(self, module): |
| 301 | + class Dependency: ... |
| 302 | + |
| 303 | + @module.singleton |
| 304 | + async def dependency_factory() -> Dependency: |
| 305 | + await anyio.sleep(0) |
| 306 | + return Dependency() |
| 307 | + |
| 308 | + instances = [] |
| 309 | + |
| 310 | + @module.inject |
| 311 | + async def append_dependency(dependency: Dependency): |
| 312 | + instances.append(dependency) |
| 313 | + |
| 314 | + async with anyio.create_task_group() as task_group: |
| 315 | + for _ in range(100): |
| 316 | + task_group.start_soon(append_dependency) |
| 317 | + |
| 318 | + reference = instances[0] |
| 319 | + for instance in instances: |
| 320 | + assert instance is reference |
| 321 | + |
| 322 | + def test_inject_with_threadsafe(self, module): |
| 323 | + @module.singleton |
| 324 | + class Dependency: ... |
| 325 | + |
| 326 | + @module.inject(threadsafe=True) |
| 327 | + def get_dependency(dependency: Dependency) -> Dependency: |
| 328 | + return dependency |
| 329 | + |
| 330 | + futures: list[Future[Dependency]] = [] |
| 331 | + |
| 332 | + with ThreadPoolExecutor() as executor: |
| 333 | + for _ in range(100): |
| 334 | + futures.append(executor.submit(get_dependency)) |
| 335 | + |
| 336 | + reference = futures[0].result() |
| 337 | + for future in futures: |
| 338 | + assert future.result() is reference |
0 commit comments