generated from aws-samples/aws-cdk-project-structure-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cdk_props.py
67 lines (51 loc) · 2.21 KB
/
cdk_props.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
import importlib
from typing import Any, Dict, Optional, Sequence, cast
def merge(props: Sequence[Any], *, overrides: Optional[Any]) -> Any:
merged_props_dict: Dict[str, Any] = {}
overrides_props_dict = to_dict(overrides)
_check_type_match(props, overrides)
for index, props_obj in enumerate(props):
props_dict = to_dict(props_obj)
_check_conflicts(props_dict, index, merged_props_dict, overrides_props_dict)
merged_props_dict.update(props_dict)
merged_props_dict.update(overrides_props_dict)
props_module_name = _get_module_name(props[0])
props_class_name = _get_class_name(props[0])
props_module = importlib.import_module(props_module_name)
props_class = getattr(props_module, props_class_name)
merged_props_obj = props_class(**merged_props_dict)
return merged_props_obj
def to_dict(props: Any) -> Dict[str, Any]:
if props is None:
return {}
return cast(Dict[str, Any], vars(props).copy()["_values"])
def _check_type_match(props: Any, overrides: Optional[Any]) -> None:
if overrides is None:
props_types = {type(props_obj) for props_obj in props}
else:
props_types = {type(props_obj) for props_obj in props + [overrides]}
if len(props_types) > 1:
raise ValueError(f"type mismatch between props: {props_types}")
def _check_conflicts(
props_dict: Dict[str, Any],
index: int,
merged_props_dict: Dict[str, Any],
overrides_props_dict: Dict[str, Any],
) -> None:
for prop in props_dict:
if (
prop in merged_props_dict
and props_dict[prop] != merged_props_dict[prop]
and prop not in overrides_props_dict
):
raise ValueError(
f"Props object at index {index} includes '{prop}' prop with value "
f"'{props_dict[prop]}'. It was defined by previous props object(s) "
f"with value '{merged_props_dict[prop]}' and is not in overrides"
)
def _get_module_name(props: Any) -> str:
return type(props).__module__
def _get_class_name(props: Any) -> str:
return type(props).__name__
def _get_absolute_name(module_name: str, class_name: str) -> str:
return f"{module_name}.{class_name}"