python-injection 0.12.0__tar.gz → 0.12.1__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}/PKG-INFO +1 -1
  2. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/common/asynchronous.py +1 -6
  3. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/common/invertible.py +1 -2
  4. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/common/lazy.py +0 -5
  5. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/injectables.py +1 -9
  6. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/module.py +8 -42
  7. {python_injection-0.12.0 → python_injection-0.12.1}/pyproject.toml +1 -1
  8. {python_injection-0.12.0 → python_injection-0.12.1}/README.md +0 -0
  9. {python_injection-0.12.0 → python_injection-0.12.1}/injection/__init__.py +0 -0
  10. {python_injection-0.12.0 → python_injection-0.12.1}/injection/__init__.pyi +0 -0
  11. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/__init__.py +0 -0
  12. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/common/__init__.py +0 -0
  13. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/common/event.py +0 -0
  14. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/common/threading.py +0 -0
  15. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/common/type.py +0 -0
  16. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/descriptors.py +0 -0
  17. {python_injection-0.12.0 → python_injection-0.12.1}/injection/_core/hook.py +0 -0
  18. {python_injection-0.12.0 → python_injection-0.12.1}/injection/exceptions.py +0 -0
  19. {python_injection-0.12.0 → python_injection-0.12.1}/injection/integrations/__init__.py +0 -0
  20. {python_injection-0.12.0 → python_injection-0.12.1}/injection/integrations/fastapi.py +0 -0
  21. {python_injection-0.12.0 → python_injection-0.12.1}/injection/py.typed +0 -0
  22. {python_injection-0.12.0 → python_injection-0.12.1}/injection/testing/__init__.py +0 -0
  23. {python_injection-0.12.0 → python_injection-0.12.1}/injection/testing/__init__.pyi +0 -0
  24. {python_injection-0.12.0 → python_injection-0.12.1}/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
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}` "
@@ -242,7 +235,6 @@ class Locator(Broker):
242
235
 
243
236
  static_hooks: ClassVar[LocatorHooks[Any]] = LocatorHooks.default()
244
237
 
245
- @override
246
238
  def __getitem__[T](self, cls: InputType[T], /) -> Injectable[T]:
247
239
  for input_class in self.__standardize_inputs((cls,)):
248
240
  try:
@@ -254,7 +246,6 @@ class Locator(Broker):
254
246
 
255
247
  raise NoInjectable(cls)
256
248
 
257
- @override
258
249
  def __contains__(self, cls: InputType[Any], /) -> bool:
259
250
  return any(
260
251
  input_class in self.__records
@@ -262,7 +253,6 @@ class Locator(Broker):
262
253
  )
263
254
 
264
255
  @property
265
- @override
266
256
  def is_locked(self) -> bool:
267
257
  return any(injectable.is_locked for injectable in self.__injectables)
268
258
 
@@ -284,7 +274,6 @@ class Locator(Broker):
284
274
 
285
275
  return self
286
276
 
287
- @override
288
277
  @synchronized()
289
278
  def unlock(self) -> Self:
290
279
  for injectable in self.__injectables:
@@ -292,7 +281,6 @@ class Locator(Broker):
292
281
 
293
282
  return self
294
283
 
295
- @override
296
284
  async def all_ready(self) -> None:
297
285
  for injectable in self.__injectables:
298
286
  await injectable.aget_instance()
@@ -387,7 +375,6 @@ class Module(Broker, EventListener):
387
375
  def __post_init__(self) -> None:
388
376
  self.__locator.add_listener(self)
389
377
 
390
- @override
391
378
  def __getitem__[T](self, cls: InputType[T], /) -> Injectable[T]:
392
379
  for broker in self.__brokers:
393
380
  with suppress(KeyError):
@@ -395,12 +382,10 @@ class Module(Broker, EventListener):
395
382
 
396
383
  raise NoInjectable(cls)
397
384
 
398
- @override
399
385
  def __contains__(self, cls: InputType[Any], /) -> bool:
400
386
  return any(cls in broker for broker in self.__brokers)
401
387
 
402
388
  @property
403
- @override
404
389
  def is_locked(self) -> bool:
405
390
  return any(broker.is_locked for broker in self.__brokers)
406
391
 
@@ -695,7 +680,6 @@ class Module(Broker, EventListener):
695
680
 
696
681
  return self
697
682
 
698
- @override
699
683
  @synchronized()
700
684
  def unlock(self) -> Self:
701
685
  for broker in self.__brokers:
@@ -703,7 +687,6 @@ class Module(Broker, EventListener):
703
687
 
704
688
  return self
705
689
 
706
- @override
707
690
  async def all_ready(self) -> None:
708
691
  for broker in self.__brokers:
709
692
  await broker.all_ready()
@@ -720,7 +703,6 @@ class Module(Broker, EventListener):
720
703
  self.__channel.remove_listener(listener)
721
704
  return self
722
705
 
723
- @override
724
706
  def on_event(self, event: Event, /) -> ContextManager[None] | None:
725
707
  self_event = ModuleEventProxy(self, event)
726
708
  return self.dispatch(self_event)
@@ -890,7 +872,7 @@ class InjectMetadata[**P, T](Caller[P, T], EventListener):
890
872
  return self.__signature
891
873
 
892
874
  with synchronized():
893
- signature = inspect.signature(self.wrapped, eval_str=True)
875
+ signature = inspect_signature(self.wrapped, eval_str=True)
894
876
  self.__signature = signature
895
877
 
896
878
  return signature
@@ -915,13 +897,11 @@ class InjectMetadata[**P, T](Caller[P, T], EventListener):
915
897
  additional_arguments = self.__dependencies.get_arguments()
916
898
  return self.__bind(args, kwargs, additional_arguments)
917
899
 
918
- @override
919
900
  async def acall(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
920
901
  self.__setup()
921
902
  arguments = await self.abind(args, kwargs)
922
903
  return self.wrapped(*arguments.args, **arguments.kwargs)
923
904
 
924
- @override
925
905
  def call(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
926
906
  self.__setup()
927
907
  arguments = self.bind(args, kwargs)
@@ -957,7 +937,6 @@ class InjectMetadata[**P, T](Caller[P, T], EventListener):
957
937
  return decorator(wrapped) if wrapped else decorator
958
938
 
959
939
  @singledispatchmethod
960
- @override
961
940
  def on_event(self, event: Event, /) -> ContextManager[None] | None: # type: ignore[override]
962
941
  return None
963
942
 
@@ -1014,11 +993,9 @@ class InjectedFunction[**P, T](ABC):
1014
993
  update_wrapper(self, metadata.wrapped)
1015
994
  self.__inject_metadata__ = metadata
1016
995
 
1017
- @override
1018
996
  def __repr__(self) -> str: # pragma: no cover
1019
997
  return repr(self.__inject_metadata__.wrapped)
1020
998
 
1021
- @override
1022
999
  def __str__(self) -> str: # pragma: no cover
1023
1000
  return str(self.__inject_metadata__.wrapped)
1024
1001
 
@@ -1043,7 +1020,10 @@ class InjectedFunction[**P, T](ABC):
1043
1020
  class AsyncInjectedFunction[**P, T](InjectedFunction[P, Awaitable[T]]):
1044
1021
  __slots__ = ()
1045
1022
 
1046
- @override
1023
+ def __init__(self, metadata: InjectMetadata[P, Awaitable[T]]) -> None:
1024
+ super().__init__(metadata)
1025
+ markcoroutinefunction(self)
1026
+
1047
1027
  async def __call__(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
1048
1028
  return await (await self.__inject_metadata__.acall(*args, **kwargs))
1049
1029
 
@@ -1051,26 +1031,12 @@ class AsyncInjectedFunction[**P, T](InjectedFunction[P, Awaitable[T]]):
1051
1031
  class SyncInjectedFunction[**P, T](InjectedFunction[P, T]):
1052
1032
  __slots__ = ()
1053
1033
 
1054
- @override
1055
1034
  def __call__(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
1056
1035
  return self.__inject_metadata__.call(*args, **kwargs)
1057
1036
 
1058
1037
 
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
1038
  def _get_caller[**P, T](function: Callable[P, T]) -> Caller[P, T]:
1073
- if _is_coroutine_function(function):
1039
+ if iscoroutinefunction(function):
1074
1040
  return AsyncCaller(function)
1075
1041
 
1076
1042
  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"
4
4
  description = "Fast and easy dependency injection framework."
5
5
  license = "MIT"
6
6
  readme = "README.md"