-
-
Notifications
You must be signed in to change notification settings - Fork 288
/
boxing.py
81 lines (65 loc) · 2.5 KB
/
boxing.py
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
77
78
79
80
81
from __future__ import annotations
import inspect
from functools import wraps
from dynaconf.utils import find_the_correct_casing
from dynaconf.utils import recursively_evaluate_lazy_format
from dynaconf.utils.functional import empty
from dynaconf.vendor.box import Box
def evaluate_lazy_format(f):
"""Marks a method on Dynabox instance to
lazily evaluate LazyFormat objects upon access."""
@wraps(f)
def evaluate(dynabox, item, *args, **kwargs):
value = f(dynabox, item, *args, **kwargs)
settings = dynabox._box_config["box_settings"]
if getattr(value, "_dynaconf_lazy_format", None):
dynabox._box_config[
f"raw_{item.lower()}"
] = f"@{value.formatter.token} {value.value}"
return recursively_evaluate_lazy_format(value, settings)
return evaluate
class DynaBox(Box):
"""Specialized Box for dynaconf
it allows items/attrs to be found both in upper or lower case"""
@evaluate_lazy_format
def __getattr__(self, item, *args, **kwargs):
try:
return super().__getattr__(item, *args, **kwargs)
except (AttributeError, KeyError):
n_item = find_the_correct_casing(item, self) or item
return super().__getattr__(n_item, *args, **kwargs)
@evaluate_lazy_format
def __getitem__(self, item, *args, **kwargs):
try:
return super().__getitem__(item, *args, **kwargs)
except (AttributeError, KeyError):
n_item = find_the_correct_casing(item, self) or item
return super().__getitem__(n_item, *args, **kwargs)
def __copy__(self):
return self.__class__(
super(Box, self).copy(),
box_settings=self._box_config.get("box_settings"),
)
def copy(self):
return self.__class__(
super(Box, self).copy(),
box_settings=self._box_config.get("box_settings"),
)
@evaluate_lazy_format
def get(self, item, default=None, *args, **kwargs):
n_item = find_the_correct_casing(item, self) or item
value = super().get(n_item, empty, *args, **kwargs)
return value if value is not empty else default
def __dir__(self):
keys = list(self.keys())
reserved = [
item[0]
for item in inspect.getmembers(DynaBox)
if not item[0].startswith("__")
]
return (
keys
+ [k.lower() for k in keys]
+ [k.upper() for k in keys]
+ reserved
)