python-injection 0.12.0__tar.gz → 0.12.1.post0__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. {python_injection-0.12.0 → python_injection-0.12.1.post0}/PKG-INFO +1 -1
  2. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/common/asynchronous.py +1 -6
  3. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/common/invertible.py +1 -2
  4. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/common/lazy.py +0 -5
  5. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/injectables.py +1 -9
  6. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/module.py +23 -55
  7. {python_injection-0.12.0 → python_injection-0.12.1.post0}/pyproject.toml +1 -1
  8. {python_injection-0.12.0 → python_injection-0.12.1.post0}/README.md +0 -0
  9. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/__init__.py +0 -0
  10. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/__init__.pyi +0 -0
  11. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/__init__.py +0 -0
  12. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/common/__init__.py +0 -0
  13. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/common/event.py +0 -0
  14. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/common/threading.py +0 -0
  15. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/common/type.py +0 -0
  16. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/descriptors.py +0 -0
  17. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/_core/hook.py +0 -0
  18. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/exceptions.py +0 -0
  19. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/integrations/__init__.py +0 -0
  20. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/integrations/fastapi.py +0 -0
  21. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/py.typed +0 -0
  22. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/testing/__init__.py +0 -0
  23. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/testing/__init__.pyi +0 -0
  24. {python_injection-0.12.0 → python_injection-0.12.1.post0}/injection/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: python-injection
3
- Version: 0.12.0
3
+ Version: 0.12.1.post0
4
4
  Summary: Fast and easy dependency injection framework.
5
5
  Home-page: https://github.com/100nm/python-injection
6
6
  License: MIT
@@ -1,14 +1,13 @@
1
1
  from abc import abstractmethod
2
2
  from collections.abc import Awaitable, Callable, Generator
3
3
  from dataclasses import dataclass
4
- from typing import Any, NoReturn, Protocol, override, runtime_checkable
4
+ from typing import Any, NoReturn, Protocol, runtime_checkable
5
5
 
6
6
 
7
7
  @dataclass(repr=False, eq=False, frozen=True, slots=True)
8
8
  class SimpleAwaitable[T](Awaitable[T]):
9
9
  callable: Callable[..., Awaitable[T]]
10
10
 
11
- @override
12
11
  def __await__(self) -> Generator[Any, Any, T]:
13
12
  return self.callable().__await__()
14
13
 
@@ -30,11 +29,9 @@ class Caller[**P, T](Protocol):
30
29
  class AsyncCaller[**P, T](Caller[P, T]):
31
30
  callable: Callable[P, Awaitable[T]]
32
31
 
33
- @override
34
32
  async def acall(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
35
33
  return await self.callable(*args, **kwargs)
36
34
 
37
- @override
38
35
  def call(self, /, *args: P.args, **kwargs: P.kwargs) -> NoReturn:
39
36
  raise RuntimeError(
40
37
  "Synchronous call isn't supported for an asynchronous Callable."
@@ -45,10 +42,8 @@ class AsyncCaller[**P, T](Caller[P, T]):
45
42
  class SyncCaller[**P, T](Caller[P, T]):
46
43
  callable: Callable[P, T]
47
44
 
48
- @override
49
45
  async def acall(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
50
46
  return self.callable(*args, **kwargs)
51
47
 
52
- @override
53
48
  def call(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
54
49
  return self.callable(*args, **kwargs)
@@ -1,7 +1,7 @@
1
1
  from abc import abstractmethod
2
2
  from collections.abc import Callable
3
3
  from dataclasses import dataclass
4
- from typing import Protocol, override, runtime_checkable
4
+ from typing import Protocol, runtime_checkable
5
5
 
6
6
 
7
7
  @runtime_checkable
@@ -15,6 +15,5 @@ class Invertible[T](Protocol):
15
15
  class SimpleInvertible[T](Invertible[T]):
16
16
  callable: Callable[..., T]
17
17
 
18
- @override
19
18
  def __invert__(self) -> T:
20
19
  return self.callable()
@@ -1,6 +1,5 @@
1
1
  from collections.abc import Callable, Iterator, Mapping
2
2
  from types import MappingProxyType
3
- from typing import override
4
3
 
5
4
  from injection._core.common.invertible import Invertible
6
5
 
@@ -14,7 +13,6 @@ class Lazy[T](Invertible[T]):
14
13
  def __init__(self, factory: Callable[..., T]) -> None:
15
14
  self.__setup_cache(factory)
16
15
 
17
- @override
18
16
  def __invert__(self) -> T:
19
17
  return next(self.__iterator)
20
18
 
@@ -44,15 +42,12 @@ class LazyMapping[K, V](Mapping[K, V]):
44
42
  def __init__(self, iterator: Iterator[tuple[K, V]]) -> None:
45
43
  self.__lazy = Lazy(lambda: MappingProxyType(dict(iterator)))
46
44
 
47
- @override
48
45
  def __getitem__(self, key: K, /) -> V:
49
46
  return (~self.__lazy)[key]
50
47
 
51
- @override
52
48
  def __iter__(self) -> Iterator[K]:
53
49
  yield from ~self.__lazy
54
50
 
55
- @override
56
51
  def __len__(self) -> int:
57
52
  return len(~self.__lazy)
58
53
 
@@ -2,7 +2,7 @@ from abc import ABC, abstractmethod
2
2
  from collections.abc import MutableMapping
3
3
  from contextlib import suppress
4
4
  from dataclasses import dataclass
5
- from typing import Any, ClassVar, NoReturn, Protocol, override, runtime_checkable
5
+ from typing import Any, ClassVar, NoReturn, Protocol, runtime_checkable
6
6
 
7
7
  from injection._core.common.asynchronous import Caller
8
8
  from injection._core.common.threading import synchronized
@@ -37,11 +37,9 @@ class BaseInjectable[T](Injectable[T], ABC):
37
37
  class SimpleInjectable[T](BaseInjectable[T]):
38
38
  __slots__ = ()
39
39
 
40
- @override
41
40
  async def aget_instance(self) -> T:
42
41
  return await self.factory.acall()
43
42
 
44
- @override
45
43
  def get_instance(self) -> T:
46
44
  return self.factory.call()
47
45
 
@@ -56,15 +54,12 @@ class SingletonInjectable[T](BaseInjectable[T]):
56
54
  return self.__dict__
57
55
 
58
56
  @property
59
- @override
60
57
  def is_locked(self) -> bool:
61
58
  return self.__key in self.cache
62
59
 
63
- @override
64
60
  def unlock(self) -> None:
65
61
  self.cache.clear()
66
62
 
67
- @override
68
63
  async def aget_instance(self) -> T:
69
64
  with suppress(KeyError):
70
65
  return self.__check_instance()
@@ -75,7 +70,6 @@ class SingletonInjectable[T](BaseInjectable[T]):
75
70
 
76
71
  return instance
77
72
 
78
- @override
79
73
  def get_instance(self) -> T:
80
74
  with suppress(KeyError):
81
75
  return self.__check_instance()
@@ -97,10 +91,8 @@ class SingletonInjectable[T](BaseInjectable[T]):
97
91
  class ShouldBeInjectable[T](Injectable[T]):
98
92
  cls: type[T]
99
93
 
100
- @override
101
94
  async def aget_instance(self) -> T:
102
95
  return self.get_instance()
103
96
 
104
- @override
105
97
  def get_instance(self) -> NoReturn:
106
98
  raise InjectionError(f"`{self.cls}` should be an injectable.")
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- import inspect
5
4
  from abc import ABC, abstractmethod
6
5
  from collections import OrderedDict
7
6
  from collections.abc import (
@@ -17,7 +16,8 @@ from contextlib import contextmanager, suppress
17
16
  from dataclasses import dataclass, field
18
17
  from enum import StrEnum
19
18
  from functools import partialmethod, singledispatchmethod, update_wrapper
20
- from inspect import Signature, isclass, iscoroutinefunction
19
+ from inspect import Signature, isclass, iscoroutinefunction, markcoroutinefunction
20
+ from inspect import signature as inspect_signature
21
21
  from logging import Logger, getLogger
22
22
  from queue import Empty, Queue
23
23
  from types import MethodType
@@ -29,9 +29,7 @@ from typing import (
29
29
  NamedTuple,
30
30
  Protocol,
31
31
  Self,
32
- TypeGuard,
33
32
  overload,
34
- override,
35
33
  runtime_checkable,
36
34
  )
37
35
  from uuid import uuid4
@@ -76,7 +74,6 @@ class LocatorDependenciesUpdated[T](LocatorEvent):
76
74
  classes: Collection[InputType[T]]
77
75
  mode: Mode
78
76
 
79
- @override
80
77
  def __str__(self) -> str:
81
78
  length = len(self.classes)
82
79
  formatted_types = ", ".join(f"`{cls}`" for cls in self.classes)
@@ -95,7 +92,6 @@ class ModuleEvent(Event, ABC):
95
92
  class ModuleEventProxy(ModuleEvent):
96
93
  event: Event
97
94
 
98
- @override
99
95
  def __str__(self) -> str:
100
96
  return f"`{self.module}` has propagated an event: {self.origin}"
101
97
 
@@ -116,7 +112,6 @@ class ModuleAdded(ModuleEvent):
116
112
  module_added: Module
117
113
  priority: Priority
118
114
 
119
- @override
120
115
  def __str__(self) -> str:
121
116
  return f"`{self.module}` now uses `{self.module_added}`."
122
117
 
@@ -125,7 +120,6 @@ class ModuleAdded(ModuleEvent):
125
120
  class ModuleRemoved(ModuleEvent):
126
121
  module_removed: Module
127
122
 
128
- @override
129
123
  def __str__(self) -> str:
130
124
  return f"`{self.module}` no longer uses `{self.module_removed}`."
131
125
 
@@ -135,7 +129,6 @@ class ModulePriorityUpdated(ModuleEvent):
135
129
  module_updated: Module
136
130
  priority: Priority
137
131
 
138
- @override
139
132
  def __str__(self) -> str:
140
133
  return (
141
134
  f"In `{self.module}`, the priority `{self.priority}` "
@@ -215,18 +208,20 @@ class Updater[T]:
215
208
  return Record(injectable, self.mode)
216
209
 
217
210
 
218
- class LocatorHooks[T](NamedTuple):
219
- on_conflict: Hook[[Record[T], Record[T], InputType[T]], bool]
220
- on_input: Hook[[Iterable[InputType[T]]], Iterable[InputType[T]]]
221
- on_update: Hook[[Updater[T]], Updater[T]]
222
-
223
- @classmethod
224
- def default(cls) -> Self:
225
- return cls(
226
- on_conflict=Hook(),
227
- on_input=Hook(),
228
- on_update=Hook(),
229
- )
211
+ @dataclass(repr=False, eq=False, frozen=True, slots=True)
212
+ class LocatorHooks[T]:
213
+ on_conflict: Hook[[Record[T], Record[T], InputType[T]], bool] = field(
214
+ default_factory=Hook,
215
+ init=False,
216
+ )
217
+ on_input: Hook[[Iterable[InputType[T]]], Iterable[InputType[T]]] = field(
218
+ default_factory=Hook,
219
+ init=False,
220
+ )
221
+ on_update: Hook[[Updater[T]], Updater[T]] = field(
222
+ default_factory=Hook,
223
+ init=False,
224
+ )
230
225
 
231
226
 
232
227
  @dataclass(repr=False, frozen=True, slots=True)
@@ -240,9 +235,8 @@ class Locator(Broker):
240
235
  init=False,
241
236
  )
242
237
 
243
- static_hooks: ClassVar[LocatorHooks[Any]] = LocatorHooks.default()
238
+ static_hooks: ClassVar[LocatorHooks[Any]] = LocatorHooks()
244
239
 
245
- @override
246
240
  def __getitem__[T](self, cls: InputType[T], /) -> Injectable[T]:
247
241
  for input_class in self.__standardize_inputs((cls,)):
248
242
  try:
@@ -254,7 +248,6 @@ class Locator(Broker):
254
248
 
255
249
  raise NoInjectable(cls)
256
250
 
257
- @override
258
251
  def __contains__(self, cls: InputType[Any], /) -> bool:
259
252
  return any(
260
253
  input_class in self.__records
@@ -262,7 +255,6 @@ class Locator(Broker):
262
255
  )
263
256
 
264
257
  @property
265
- @override
266
258
  def is_locked(self) -> bool:
267
259
  return any(injectable.is_locked for injectable in self.__injectables)
268
260
 
@@ -284,7 +276,6 @@ class Locator(Broker):
284
276
 
285
277
  return self
286
278
 
287
- @override
288
279
  @synchronized()
289
280
  def unlock(self) -> Self:
290
281
  for injectable in self.__injectables:
@@ -292,7 +283,6 @@ class Locator(Broker):
292
283
 
293
284
  return self
294
285
 
295
- @override
296
286
  async def all_ready(self) -> None:
297
287
  for injectable in self.__injectables:
298
288
  await injectable.aget_instance()
@@ -387,7 +377,6 @@ class Module(Broker, EventListener):
387
377
  def __post_init__(self) -> None:
388
378
  self.__locator.add_listener(self)
389
379
 
390
- @override
391
380
  def __getitem__[T](self, cls: InputType[T], /) -> Injectable[T]:
392
381
  for broker in self.__brokers:
393
382
  with suppress(KeyError):
@@ -395,12 +384,10 @@ class Module(Broker, EventListener):
395
384
 
396
385
  raise NoInjectable(cls)
397
386
 
398
- @override
399
387
  def __contains__(self, cls: InputType[Any], /) -> bool:
400
388
  return any(cls in broker for broker in self.__brokers)
401
389
 
402
390
  @property
403
- @override
404
391
  def is_locked(self) -> bool:
405
392
  return any(broker.is_locked for broker in self.__brokers)
406
393
 
@@ -695,7 +682,6 @@ class Module(Broker, EventListener):
695
682
 
696
683
  return self
697
684
 
698
- @override
699
685
  @synchronized()
700
686
  def unlock(self) -> Self:
701
687
  for broker in self.__brokers:
@@ -703,7 +689,6 @@ class Module(Broker, EventListener):
703
689
 
704
690
  return self
705
691
 
706
- @override
707
692
  async def all_ready(self) -> None:
708
693
  for broker in self.__brokers:
709
694
  await broker.all_ready()
@@ -720,7 +705,6 @@ class Module(Broker, EventListener):
720
705
  self.__channel.remove_listener(listener)
721
706
  return self
722
707
 
723
- @override
724
708
  def on_event(self, event: Event, /) -> ContextManager[None] | None:
725
709
  self_event = ModuleEventProxy(self, event)
726
710
  return self.dispatch(self_event)
@@ -890,7 +874,7 @@ class InjectMetadata[**P, T](Caller[P, T], EventListener):
890
874
  return self.__signature
891
875
 
892
876
  with synchronized():
893
- signature = inspect.signature(self.wrapped, eval_str=True)
877
+ signature = inspect_signature(self.wrapped, eval_str=True)
894
878
  self.__signature = signature
895
879
 
896
880
  return signature
@@ -915,13 +899,11 @@ class InjectMetadata[**P, T](Caller[P, T], EventListener):
915
899
  additional_arguments = self.__dependencies.get_arguments()
916
900
  return self.__bind(args, kwargs, additional_arguments)
917
901
 
918
- @override
919
902
  async def acall(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
920
903
  self.__setup()
921
904
  arguments = await self.abind(args, kwargs)
922
905
  return self.wrapped(*arguments.args, **arguments.kwargs)
923
906
 
924
- @override
925
907
  def call(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
926
908
  self.__setup()
927
909
  arguments = self.bind(args, kwargs)
@@ -957,7 +939,6 @@ class InjectMetadata[**P, T](Caller[P, T], EventListener):
957
939
  return decorator(wrapped) if wrapped else decorator
958
940
 
959
941
  @singledispatchmethod
960
- @override
961
942
  def on_event(self, event: Event, /) -> ContextManager[None] | None: # type: ignore[override]
962
943
  return None
963
944
 
@@ -1014,11 +995,9 @@ class InjectedFunction[**P, T](ABC):
1014
995
  update_wrapper(self, metadata.wrapped)
1015
996
  self.__inject_metadata__ = metadata
1016
997
 
1017
- @override
1018
998
  def __repr__(self) -> str: # pragma: no cover
1019
999
  return repr(self.__inject_metadata__.wrapped)
1020
1000
 
1021
- @override
1022
1001
  def __str__(self) -> str: # pragma: no cover
1023
1002
  return str(self.__inject_metadata__.wrapped)
1024
1003
 
@@ -1043,7 +1022,10 @@ class InjectedFunction[**P, T](ABC):
1043
1022
  class AsyncInjectedFunction[**P, T](InjectedFunction[P, Awaitable[T]]):
1044
1023
  __slots__ = ()
1045
1024
 
1046
- @override
1025
+ def __init__(self, metadata: InjectMetadata[P, Awaitable[T]]) -> None:
1026
+ super().__init__(metadata)
1027
+ markcoroutinefunction(self)
1028
+
1047
1029
  async def __call__(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
1048
1030
  return await (await self.__inject_metadata__.acall(*args, **kwargs))
1049
1031
 
@@ -1051,26 +1033,12 @@ class AsyncInjectedFunction[**P, T](InjectedFunction[P, Awaitable[T]]):
1051
1033
  class SyncInjectedFunction[**P, T](InjectedFunction[P, T]):
1052
1034
  __slots__ = ()
1053
1035
 
1054
- @override
1055
1036
  def __call__(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
1056
1037
  return self.__inject_metadata__.call(*args, **kwargs)
1057
1038
 
1058
1039
 
1059
- def _is_coroutine_function[**P, T](
1060
- function: Callable[P, T] | Callable[P, Awaitable[T]],
1061
- ) -> TypeGuard[Callable[P, Awaitable[T]]]:
1062
- if iscoroutinefunction(function):
1063
- return True
1064
-
1065
- elif isclass(function):
1066
- return False
1067
-
1068
- call = getattr(function, "__call__", None)
1069
- return iscoroutinefunction(call)
1070
-
1071
-
1072
1040
  def _get_caller[**P, T](function: Callable[P, T]) -> Caller[P, T]:
1073
- if _is_coroutine_function(function):
1041
+ if iscoroutinefunction(function):
1074
1042
  return AsyncCaller(function)
1075
1043
 
1076
1044
  elif isinstance(function, InjectedFunction):
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "python-injection"
3
- version = "0.12.0"
3
+ version = "0.12.1.post0"
4
4
  description = "Fast and easy dependency injection framework."
5
5
  license = "MIT"
6
6
  readme = "README.md"