|
8 | 8 | AsyncIterator, |
9 | 9 | Awaitable, |
10 | 10 | Callable, |
| 11 | + Container, |
11 | 12 | Generator, |
12 | 13 | Iterable, |
13 | 14 | Iterator, |
|
18 | 19 | from enum import StrEnum |
19 | 20 | from functools import partial, partialmethod, singledispatchmethod, update_wrapper |
20 | 21 | from inspect import ( |
| 22 | + BoundArguments, |
21 | 23 | Signature, |
22 | 24 | isasyncgenfunction, |
23 | 25 | isclass, |
@@ -739,28 +741,32 @@ def mod(name: str | None = None, /) -> Module: |
739 | 741 | class Dependencies: |
740 | 742 | lazy_mapping: Lazy[Mapping[str, Injectable[Any]]] |
741 | 743 |
|
742 | | - def __iter__(self) -> Iterator[tuple[str, Any]]: |
743 | | - for name, injectable in self.items(): |
| 744 | + def iter(self, exclude: Container[str]) -> Iterator[tuple[str, Any]]: |
| 745 | + for name, injectable in self.items(exclude): |
744 | 746 | with suppress(SkipInjectable): |
745 | 747 | yield name, injectable.get_instance() |
746 | 748 |
|
747 | | - async def __aiter__(self) -> AsyncIterator[tuple[str, Any]]: |
748 | | - for name, injectable in self.items(): |
| 749 | + async def aiter(self, exclude: Container[str]) -> AsyncIterator[tuple[str, Any]]: |
| 750 | + for name, injectable in self.items(exclude): |
749 | 751 | with suppress(SkipInjectable): |
750 | 752 | yield name, await injectable.aget_instance() |
751 | 753 |
|
752 | 754 | @property |
753 | 755 | def are_resolved(self) -> bool: |
754 | 756 | return self.lazy_mapping.is_set |
755 | 757 |
|
756 | | - async def aget_arguments(self) -> dict[str, Any]: |
757 | | - return {key: value async for key, value in self} |
| 758 | + async def aget_arguments(self, *, exclude: Container[str]) -> dict[str, Any]: |
| 759 | + return {key: value async for key, value in self.aiter(exclude)} |
758 | 760 |
|
759 | | - def get_arguments(self) -> dict[str, Any]: |
760 | | - return dict(self) |
| 761 | + def get_arguments(self, *, exclude: Container[str]) -> dict[str, Any]: |
| 762 | + return dict(self.iter(exclude)) |
761 | 763 |
|
762 | | - def items(self) -> Iterator[tuple[str, Injectable[Any]]]: |
763 | | - return iter((~self.lazy_mapping).items()) |
| 764 | + def items(self, exclude: Container[str]) -> Iterator[tuple[str, Injectable[Any]]]: |
| 765 | + return ( |
| 766 | + (name, injectable) |
| 767 | + for name, injectable in (~self.lazy_mapping).items() |
| 768 | + if name not in exclude |
| 769 | + ) |
764 | 770 |
|
765 | 771 | @classmethod |
766 | 772 | def from_iterable(cls, iterable: Iterable[tuple[str, Injectable[Any]]]) -> Self: |
@@ -858,21 +864,21 @@ def signature(self) -> Signature: |
858 | 864 | def wrapped(self) -> Callable[P, T]: |
859 | 865 | return self.__wrapped |
860 | 866 |
|
861 | | - async def abind( |
862 | | - self, |
863 | | - args: Iterable[Any] = (), |
864 | | - kwargs: Mapping[str, Any] | None = None, |
865 | | - ) -> Arguments: |
866 | | - additional_arguments = await self.__dependencies.aget_arguments() |
867 | | - return self.__bind(args, kwargs, additional_arguments) |
| 867 | + async def abind(self, args: Iterable[Any], kwargs: Mapping[str, Any]) -> Arguments: |
| 868 | + arguments = self.__get_arguments(args, kwargs) |
| 869 | + dependencies = await self.__dependencies.aget_arguments(exclude=arguments) |
| 870 | + if dependencies: |
| 871 | + return self.__merge_arguments(arguments, dependencies) |
868 | 872 |
|
869 | | - def bind( |
870 | | - self, |
871 | | - args: Iterable[Any] = (), |
872 | | - kwargs: Mapping[str, Any] | None = None, |
873 | | - ) -> Arguments: |
874 | | - additional_arguments = self.__dependencies.get_arguments() |
875 | | - return self.__bind(args, kwargs, additional_arguments) |
| 873 | + return Arguments(args, kwargs) |
| 874 | + |
| 875 | + def bind(self, args: Iterable[Any], kwargs: Mapping[str, Any]) -> Arguments: |
| 876 | + arguments = self.__get_arguments(args, kwargs) |
| 877 | + dependencies = self.__dependencies.get_arguments(exclude=arguments) |
| 878 | + if dependencies: |
| 879 | + return self.__merge_arguments(arguments, dependencies) |
| 880 | + |
| 881 | + return Arguments(args, kwargs) |
876 | 882 |
|
877 | 883 | async def acall(self, /, *args: P.args, **kwargs: P.kwargs) -> T: |
878 | 884 | with self.__lock: |
@@ -921,20 +927,20 @@ def _(self, event: ModuleEvent, /) -> Iterator[None]: |
921 | 927 | yield |
922 | 928 | self.update(event.module) |
923 | 929 |
|
924 | | - def __bind( |
| 930 | + def __get_arguments( |
925 | 931 | self, |
926 | 932 | args: Iterable[Any], |
927 | | - kwargs: Mapping[str, Any] | None, |
928 | | - additional_arguments: dict[str, Any] | None, |
929 | | - ) -> Arguments: |
930 | | - if kwargs is None: |
931 | | - kwargs = {} |
932 | | - |
933 | | - if not additional_arguments: |
934 | | - return Arguments(args, kwargs) |
935 | | - |
| 933 | + kwargs: Mapping[str, Any], |
| 934 | + ) -> dict[str, Any]: |
936 | 935 | bound = self.signature.bind_partial(*args, **kwargs) |
937 | | - bound.arguments = bound.arguments | additional_arguments | bound.arguments |
| 936 | + return bound.arguments |
| 937 | + |
| 938 | + def __merge_arguments( |
| 939 | + self, |
| 940 | + arguments: dict[str, Any], |
| 941 | + additional_arguments: dict[str, Any], |
| 942 | + ) -> Arguments: |
| 943 | + bound = BoundArguments(self.signature, additional_arguments | arguments) # type: ignore[arg-type] |
938 | 944 | return Arguments(bound.args, bound.kwargs) |
939 | 945 |
|
940 | 946 | def __run_tasks(self) -> None: |
|
0 commit comments