|
4 | 4 | import shutil |
5 | 5 | import sys |
6 | 6 | from typing import Any |
7 | | -from typing import Callable |
8 | 7 |
|
9 | 8 | from pytask import hookimpl |
10 | 9 | from pytask_stata.shared import STATA_COMMANDS |
11 | 10 |
|
12 | 11 |
|
13 | 12 | @hookimpl |
14 | | -def pytask_parse_config( |
15 | | - config: dict[str, Any], |
16 | | - config_from_cli: dict[str, Any], |
17 | | - config_from_file: dict[str, Any], |
18 | | -) -> None: |
| 13 | +def pytask_parse_config(config: dict[str, Any]) -> None: |
19 | 14 | """Register the r marker.""" |
20 | 15 | config["markers"]["stata"] = "Tasks which are executed with Stata." |
21 | 16 | config["platform"] = sys.platform |
22 | 17 |
|
23 | | - if config_from_file.get("stata"): |
24 | | - config["stata"] = config_from_file["stata"] |
25 | | - else: |
| 18 | + if not config.get("stata"): |
26 | 19 | config["stata"] = next( |
27 | 20 | (executable for executable in STATA_COMMANDS if shutil.which(executable)), |
28 | 21 | None, |
29 | 22 | ) |
30 | | - |
31 | | - config["stata_keep_log"] = _get_first_non_none_value( |
32 | | - config_from_cli, |
33 | | - config_from_file, |
34 | | - key="stata_keep_log", |
35 | | - callback=_convert_truthy_or_falsy_to_bool, |
36 | | - default=False, |
37 | | - ) |
38 | | - |
39 | | - config["stata_check_log_lines"] = _get_first_non_none_value( |
40 | | - config_from_cli, |
41 | | - config_from_file, |
42 | | - key="stata_check_log_lines", |
43 | | - callback=_nonnegative_nonzero_integer, |
44 | | - default=10, |
45 | | - ) |
46 | | - |
47 | | - |
48 | | -def _nonnegative_nonzero_integer(x: Any) -> int: |
49 | | - """Check for nonnegative and nonzero integer.""" |
50 | | - if x is not None: |
51 | | - try: |
52 | | - x = int(x) |
53 | | - except ValueError: |
54 | | - raise ValueError( |
55 | | - "'stata_check_log_lines' must be a nonzero and nonnegative integer, " |
56 | | - f"but it is '{x}'." |
57 | | - ) |
58 | | - |
59 | | - if x <= 0: |
60 | | - raise ValueError("'stata_check_log_lines' must be greater than zero.") |
61 | | - |
62 | | - return x |
63 | | - |
64 | | - |
65 | | -def _get_first_non_none_value( |
66 | | - *configs: dict[str, Any], |
67 | | - key: str, |
68 | | - default: Any | None = None, |
69 | | - callback: Callable[..., Any] | None = None, |
70 | | -) -> Any: |
71 | | - """Get the first non-None value for a key from a list of dictionaries. |
72 | | -
|
73 | | - This function allows to prioritize information from many configurations by changing |
74 | | - the order of the inputs while also providing a default. |
75 | | -
|
76 | | - Examples |
77 | | - -------- |
78 | | - >>> _get_first_non_none_value({"a": None}, {"a": 1}, key="a") |
79 | | - 1 |
80 | | - >>> _get_first_non_none_value({"a": None}, {"a": None}, key="a", default="default") |
81 | | - 'default' |
82 | | - >>> _get_first_non_none_value({}, {}, key="a", default="default") |
83 | | - 'default' |
84 | | - >>> _get_first_non_none_value({"a": None}, {"a": "b"}, key="a") |
85 | | - 'b' |
86 | | -
|
87 | | - """ |
88 | | - callback = (lambda x: x) if callback is None else callback # noqa: E731 |
89 | | - processed_values = (callback(config.get(key)) for config in configs) |
90 | | - return next((value for value in processed_values if value is not None), default) |
91 | | - |
92 | | - |
93 | | -def _convert_truthy_or_falsy_to_bool(x: bool | str | None) -> bool: |
94 | | - """Convert truthy or falsy value in .ini to Python boolean.""" |
95 | | - if x in [True, "True", "true", "1"]: |
96 | | - out = True |
97 | | - elif x in [False, "False", "false", "0"]: |
98 | | - out = False |
99 | | - elif x in [None, "None", "none"]: |
100 | | - out = None |
101 | | - else: |
102 | | - raise ValueError( |
103 | | - f"Input {x!r} is neither truthy (True, true, 1) or falsy (False, false, 0)." |
104 | | - ) |
105 | | - return out |
0 commit comments