1
+ import itertools
1
2
import os
2
3
import uuid
3
4
from pathlib import Path
4
5
from typing import Any , Optional
6
+ from warnings import warn
5
7
6
8
import yaml
7
- from pydantic import BaseModel
9
+ from pydantic import BaseModel , ValidationError
8
10
9
11
from midi_app_controller .config import Config
10
12
from midi_app_controller .gui .utils import is_subpath
@@ -19,6 +21,11 @@ def _path_representer(dumper, data):
19
21
yaml .SafeDumper .add_multi_representer (Path , _path_representer )
20
22
21
23
24
+ def _abs_listdir (d : Path ) -> list [Path ]:
25
+ """List the contents of directory as absolute paths."""
26
+ return [d / p for p in os .listdir (d )]
27
+
28
+
22
29
class YamlBaseModel (BaseModel ):
23
30
@classmethod
24
31
def load_from (cls , path : Path ) -> "YamlBaseModel" :
@@ -43,8 +50,9 @@ def load_from(cls, path: Path) -> "YamlBaseModel":
43
50
def load_all_from (
44
51
cls , directories : list [Path ]
45
52
) -> list [tuple ["YamlBaseModel" , Path ]]:
46
- """Creates models initialized with data from all YAML files in
47
- multiple directories.
53
+ """Return models with data from all YAML files in multiple directories.
54
+
55
+ If a yaml file fails to load, it is skipped and a warning is emitted.
48
56
49
57
Parameters
50
58
----------
@@ -56,16 +64,21 @@ def load_all_from(
56
64
list[tuple[cls, Path]]
57
65
List of created models with paths to corresponding YAML files.
58
66
"""
59
- return [
60
- (
61
- cls .load_from (directory / filename ),
62
- directory / filename ,
63
- )
64
- for directory in directories
65
- if directory .exists ()
66
- for filename in os .listdir (directory )
67
- if filename .lower ().endswith ((".yaml" , ".yml" ))
68
- ]
67
+ all_models = []
68
+ real_directories = filter (os .path .exists , directories )
69
+ fns = itertools .chain (* map (_abs_listdir , real_directories ))
70
+ yamls = (fn for fn in fns if fn .suffix in {".yaml" , ".yml" })
71
+ for fn in yamls :
72
+ try :
73
+ model = cls .load_from (fn )
74
+ all_models .append ((model , fn ))
75
+ except (ValidationError , Exception ) as e :
76
+ warn (
77
+ f"Unable to load model from file { fn } ; got error:\n "
78
+ f"{ e .__class__ } : { e } " ,
79
+ stacklevel = 2 ,
80
+ )
81
+ return all_models
69
82
70
83
def save_to (self , path : Path ) -> None :
71
84
"""Saves the model's data to a YAML file.
0 commit comments