forked from MODFLOW-ORG/modflow-devtools
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path__init__.py
More file actions
74 lines (58 loc) · 2.02 KB
/
__init__.py
File metadata and controls
74 lines (58 loc) · 2.02 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
"""Utilities for accessing the program database"""
from csv import DictReader
from dataclasses import dataclass
from os import PathLike
from pathlib import Path
from modflow_devtools.misc import try_literal_eval
DB_NAME = "programs.csv"
DB_PATH = Path(__file__).parent / DB_NAME
@dataclass
class Program:
target: str
version: str
current: bool
url: str
dirname: str
srcdir: str
standard_switch: bool
double_switch: bool
shared_object: bool
@classmethod
def from_dict(cls, d: dict, strict: bool = False) -> "Program":
"""
Create a Program instance from a dictionary.
Parameters
----------
d : dict
Dictionary containing program data
strict : bool, optional
If True, raise ValueError if dict contains unrecognized keys.
If False (default), ignore unrecognized keys.
"""
keys = set(cls.__annotations__.keys())
if strict:
dkeys = {k.strip() for k in d.keys()}
if extra_keys := dkeys - keys:
raise ValueError(f"Unrecognized keys in program data: {extra_keys}")
return cls(
**{
k.strip(): try_literal_eval(v.strip())
for k, v in d.items()
if k.strip() in keys
}
)
def load_programs(path: str | PathLike, strict: bool = False) -> dict[str, Program]:
"""Load the program database from the CSV file."""
path = Path(path).expanduser().resolve()
with path.open() as csvfile:
# assumes the first row is the header!
reader = DictReader(csvfile, skipinitialspace=True)
programs = [Program.from_dict(row, strict) for row in reader]
return {program.target: program for program in programs}
PROGRAMS = load_programs(DB_PATH, strict=True)
def get_programs() -> dict[str, Program]:
"""Get the program database."""
return PROGRAMS
def get_program(name: str) -> Program:
"""Get a specific program by name."""
return PROGRAMS[name]