-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathdescriptors.py
More file actions
76 lines (67 loc) · 2.14 KB
/
descriptors.py
File metadata and controls
76 lines (67 loc) · 2.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import typing as t
from dataclasses import (
InitVar,
dataclass,
field,
)
from .container import (
DIContext,
get_di_container,
)
from .errors import (
ConfigError,
DIErrors,
)
@dataclass(frozen=True)
class Inject:
"""
A class that can serve as:
* a descriptor for a `Component` class
* a default value of a function argument
that should be used to mark a place for injecting dependencies as an attribute or an argument
of a function.
"""
context: DIContext = field(init=False)
name: InitVar[str] = None
interface: InitVar[t.Type] = None
qualifier: InitVar[t.Any] = None
get_qualifier: InitVar[t.Callable[[t.Any], t.Any]] = None
label: str = None
annotation: t.Type = None
def __post_init__(
self,
name: str,
interface: t.Type,
qualifier: t.Any,
get_qualifier: t.Callable[[t.Any], t.Any] = None,
):
object.__setattr__(
self,
"context",
DIContext(
name=name, interface=interface, qualifier=qualifier, get_qualifier=get_qualifier
),
)
def __set_name__(self, owner, name: str) -> None:
annotation = owner.__annotations__.get(name) if hasattr(owner, "__annotations__") else None
# supporting object's immutability
object.__setattr__(self, "label", name)
if annotation:
object.__setattr__(self.context, "interface", annotation)
def __get__(self, instance: t.Any, owner: t.Type) -> t.Any:
if instance is None:
return self
container = get_di_container(instance)
if not container:
raise DIErrors.NO_CONTAINER_PROVIDED.with_params(
class_name=instance.__class__.__qualname__, attribute=self.label
)
context = self.context.determine(instance)
try:
return context.get(container=container)
except ConfigError as e:
raise e.with_params(
class_name=instance.__class__.__qualname__,
attribute=self.label,
context=e.params.get("context"),
)