anemoi-utils 0.4.29__py3-none-any.whl → 0.4.30__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of anemoi-utils might be problematic. Click here for more details.
- anemoi/utils/_version.py +2 -2
- anemoi/utils/caching.py +4 -5
- anemoi/utils/checkpoints.py +1 -1
- anemoi/utils/cli.py +2 -3
- anemoi/utils/commands/metadata.py +1 -2
- anemoi/utils/compatibility.py +2 -6
- anemoi/utils/config.py +47 -21
- anemoi/utils/dates.py +17 -24
- anemoi/utils/grib.py +4 -6
- anemoi/utils/grids.py +2 -5
- anemoi/utils/hindcasts.py +3 -5
- anemoi/utils/humanize.py +33 -40
- anemoi/utils/mars/__init__.py +4 -7
- anemoi/utils/mars/requests.py +1 -2
- anemoi/utils/provenance.py +13 -18
- anemoi/utils/registry.py +6 -11
- anemoi/utils/remote/__init__.py +2 -3
- anemoi/utils/remote/s3.py +1 -1
- anemoi/utils/rules.py +10 -14
- anemoi/utils/s3.py +2 -3
- anemoi/utils/text.py +6 -9
- {anemoi_utils-0.4.29.dist-info → anemoi_utils-0.4.30.dist-info}/METADATA +2 -3
- anemoi_utils-0.4.30.dist-info/RECORD +47 -0
- anemoi_utils-0.4.29.dist-info/RECORD +0 -47
- {anemoi_utils-0.4.29.dist-info → anemoi_utils-0.4.30.dist-info}/WHEEL +0 -0
- {anemoi_utils-0.4.29.dist-info → anemoi_utils-0.4.30.dist-info}/entry_points.txt +0 -0
- {anemoi_utils-0.4.29.dist-info → anemoi_utils-0.4.30.dist-info}/licenses/LICENSE +0 -0
- {anemoi_utils-0.4.29.dist-info → anemoi_utils-0.4.30.dist-info}/top_level.txt +0 -0
anemoi/utils/humanize.py
CHANGED
|
@@ -15,14 +15,9 @@ import json
|
|
|
15
15
|
import re
|
|
16
16
|
import warnings
|
|
17
17
|
from collections import defaultdict
|
|
18
|
+
from collections.abc import Callable
|
|
19
|
+
from collections.abc import Generator
|
|
18
20
|
from typing import Any
|
|
19
|
-
from typing import Callable
|
|
20
|
-
from typing import Dict
|
|
21
|
-
from typing import Generator
|
|
22
|
-
from typing import List
|
|
23
|
-
from typing import Optional
|
|
24
|
-
from typing import Tuple
|
|
25
|
-
from typing import Union
|
|
26
21
|
|
|
27
22
|
from anemoi.utils.dates import as_datetime
|
|
28
23
|
|
|
@@ -57,7 +52,7 @@ def bytes_to_human(n: float) -> str:
|
|
|
57
52
|
while n >= 1024:
|
|
58
53
|
n /= 1024.0
|
|
59
54
|
i += 1
|
|
60
|
-
return "
|
|
55
|
+
return f"{sign}{int(n * 10 + 0.5) / 10.0:g}{u[i]}"
|
|
61
56
|
|
|
62
57
|
|
|
63
58
|
def bytes(n: float) -> str:
|
|
@@ -99,7 +94,7 @@ def base2_to_human(n: float) -> str:
|
|
|
99
94
|
while n >= 1024:
|
|
100
95
|
n /= 1024.0
|
|
101
96
|
i += 1
|
|
102
|
-
return "
|
|
97
|
+
return f"{int(n * 10 + 0.5) / 10.0:g}{u[i]}"
|
|
103
98
|
|
|
104
99
|
|
|
105
100
|
def base2(n: float) -> str:
|
|
@@ -151,7 +146,7 @@ def _plural(count: int) -> str:
|
|
|
151
146
|
return ""
|
|
152
147
|
|
|
153
148
|
|
|
154
|
-
def seconds_to_human(seconds:
|
|
149
|
+
def seconds_to_human(seconds: float | datetime.timedelta) -> str:
|
|
155
150
|
"""Convert a number of seconds to a human readable string.
|
|
156
151
|
|
|
157
152
|
>>> seconds_to_human(4000)
|
|
@@ -205,7 +200,7 @@ def seconds_to_human(seconds: Union[float, datetime.timedelta]) -> str:
|
|
|
205
200
|
|
|
206
201
|
if not s:
|
|
207
202
|
seconds = round(seconds * 10) / 10
|
|
208
|
-
s.append("
|
|
203
|
+
s.append(f"{seconds:g} second{_plural(seconds)}")
|
|
209
204
|
return " ".join(s)
|
|
210
205
|
|
|
211
206
|
|
|
@@ -303,7 +298,7 @@ def __(n: int) -> str:
|
|
|
303
298
|
|
|
304
299
|
|
|
305
300
|
def when(
|
|
306
|
-
then: datetime.datetime, now:
|
|
301
|
+
then: datetime.datetime, now: datetime.datetime | None = None, short: bool = True, use_utc: bool = False
|
|
307
302
|
) -> str:
|
|
308
303
|
"""Generate a human readable string for a date, relative to now.
|
|
309
304
|
|
|
@@ -359,23 +354,23 @@ def when(
|
|
|
359
354
|
|
|
360
355
|
def _(x):
|
|
361
356
|
if last == "last":
|
|
362
|
-
return "
|
|
357
|
+
return f"{x} ago"
|
|
363
358
|
else:
|
|
364
|
-
return "in
|
|
359
|
+
return f"in {x}"
|
|
365
360
|
|
|
366
361
|
if diff < 60:
|
|
367
362
|
diff = int(diff + 0.5)
|
|
368
|
-
return _("
|
|
363
|
+
return _(f"{diff} second{_plural(diff)}")
|
|
369
364
|
|
|
370
365
|
if diff < 60 * 60:
|
|
371
366
|
diff /= 60
|
|
372
367
|
diff = int(diff + 0.5)
|
|
373
|
-
return _("
|
|
368
|
+
return _(f"{diff} minute{_plural(diff)}")
|
|
374
369
|
|
|
375
370
|
if diff < 60 * 60 * 6:
|
|
376
371
|
diff /= 60 * 60
|
|
377
372
|
diff = int(diff + 0.5)
|
|
378
|
-
return _("
|
|
373
|
+
return _(f"{diff} hour{_plural(diff)}")
|
|
379
374
|
|
|
380
375
|
jnow = now.toordinal()
|
|
381
376
|
jthen = then.toordinal()
|
|
@@ -392,7 +387,7 @@ def when(
|
|
|
392
387
|
if abs(jnow - jthen) <= 7:
|
|
393
388
|
if last == "next":
|
|
394
389
|
last = "this"
|
|
395
|
-
return "
|
|
390
|
+
return "{} {}".format(
|
|
396
391
|
last,
|
|
397
392
|
DOW[then.weekday()],
|
|
398
393
|
)
|
|
@@ -462,7 +457,7 @@ def string_distance(s: str, t: str) -> int:
|
|
|
462
457
|
return d[m, n]
|
|
463
458
|
|
|
464
459
|
|
|
465
|
-
def did_you_mean(word: str, vocabulary:
|
|
460
|
+
def did_you_mean(word: str, vocabulary: list[str]) -> str:
|
|
466
461
|
"""Pick the closest word in a vocabulary.
|
|
467
462
|
|
|
468
463
|
>>> did_you_mean("aple", ["banana", "lemon", "apple", "orange"])
|
|
@@ -485,7 +480,7 @@ def did_you_mean(word: str, vocabulary: List[str]) -> str:
|
|
|
485
480
|
return best
|
|
486
481
|
|
|
487
482
|
|
|
488
|
-
def dict_to_human(query:
|
|
483
|
+
def dict_to_human(query: dict[str, Any]) -> str:
|
|
489
484
|
"""Convert a dictionary to a human readable string.
|
|
490
485
|
|
|
491
486
|
Parameters
|
|
@@ -503,7 +498,7 @@ def dict_to_human(query: Dict[str, Any]) -> str:
|
|
|
503
498
|
return list_to_human(lst)
|
|
504
499
|
|
|
505
500
|
|
|
506
|
-
def list_to_human(lst:
|
|
501
|
+
def list_to_human(lst: list[str], conjunction: str = "and") -> str:
|
|
507
502
|
"""Convert a list of strings to a human readable string.
|
|
508
503
|
|
|
509
504
|
>>> list_to_human(["banana", "lemon", "apple", "orange"])
|
|
@@ -530,7 +525,7 @@ def list_to_human(lst: List[str], conjunction: str = "and") -> str:
|
|
|
530
525
|
return f" {conjunction} ".join(lst)
|
|
531
526
|
|
|
532
527
|
|
|
533
|
-
def human_to_number(value:
|
|
528
|
+
def human_to_number(value: str | int, name: str, units: dict[str, int], none_ok: bool) -> int | None:
|
|
534
529
|
"""Convert a human readable string to a number.
|
|
535
530
|
|
|
536
531
|
Parameters
|
|
@@ -568,8 +563,8 @@ def human_to_number(value: Union[str, int], name: str, units: Dict[str, int], no
|
|
|
568
563
|
|
|
569
564
|
|
|
570
565
|
def as_number(
|
|
571
|
-
value:
|
|
572
|
-
) ->
|
|
566
|
+
value: str | int, name: str | None = None, units: dict[str, int] | None = None, none_ok: bool = False
|
|
567
|
+
) -> int | None:
|
|
573
568
|
"""Deprecated function to convert a human readable string to a number.
|
|
574
569
|
|
|
575
570
|
Parameters
|
|
@@ -596,7 +591,7 @@ def as_number(
|
|
|
596
591
|
return human_to_number(value, name, units, none_ok)
|
|
597
592
|
|
|
598
593
|
|
|
599
|
-
def human_seconds(value:
|
|
594
|
+
def human_seconds(value: str | int, name: str | None = None, none_ok: bool = False) -> int | None:
|
|
600
595
|
"""Convert a human readable string to seconds.
|
|
601
596
|
|
|
602
597
|
Parameters
|
|
@@ -617,7 +612,7 @@ def human_seconds(value: Union[str, int], name: Optional[str] = None, none_ok: b
|
|
|
617
612
|
return human_to_number(value, name, units, none_ok)
|
|
618
613
|
|
|
619
614
|
|
|
620
|
-
def as_seconds(value:
|
|
615
|
+
def as_seconds(value: str | int, name: str | None = None, none_ok: bool = False) -> int | None:
|
|
621
616
|
"""Deprecated function to convert a human readable string to seconds.
|
|
622
617
|
|
|
623
618
|
Parameters
|
|
@@ -642,7 +637,7 @@ def as_seconds(value: Union[str, int], name: Optional[str] = None, none_ok: bool
|
|
|
642
637
|
return human_seconds(value, name, none_ok)
|
|
643
638
|
|
|
644
639
|
|
|
645
|
-
def human_to_percent(value:
|
|
640
|
+
def human_to_percent(value: str | int, name: str | None = None, none_ok: bool = False) -> int | None:
|
|
646
641
|
"""Convert a human readable string to a percentage.
|
|
647
642
|
|
|
648
643
|
Parameters
|
|
@@ -663,7 +658,7 @@ def human_to_percent(value: Union[str, int], name: Optional[str] = None, none_ok
|
|
|
663
658
|
return human_to_number(value, name, units, none_ok)
|
|
664
659
|
|
|
665
660
|
|
|
666
|
-
def as_percent(value:
|
|
661
|
+
def as_percent(value: str | int, name: str | None = None, none_ok: bool = False) -> int | None:
|
|
667
662
|
"""Deprecated function to convert a human readable string to a percentage.
|
|
668
663
|
|
|
669
664
|
Parameters
|
|
@@ -688,7 +683,7 @@ def as_percent(value: Union[str, int], name: Optional[str] = None, none_ok: bool
|
|
|
688
683
|
return human_to_percent(value, name, none_ok)
|
|
689
684
|
|
|
690
685
|
|
|
691
|
-
def human_to_bytes(value:
|
|
686
|
+
def human_to_bytes(value: str | int, name: str | None = None, none_ok: bool = False) -> int | None:
|
|
692
687
|
"""Convert a human readable string to bytes.
|
|
693
688
|
|
|
694
689
|
Parameters
|
|
@@ -715,7 +710,7 @@ def human_to_bytes(value: Union[str, int], name: Optional[str] = None, none_ok:
|
|
|
715
710
|
return human_to_number(value, name, units, none_ok)
|
|
716
711
|
|
|
717
712
|
|
|
718
|
-
def as_bytes(value:
|
|
713
|
+
def as_bytes(value: str | int, name: str | None = None, none_ok: bool = False) -> int | None:
|
|
719
714
|
"""Deprecated function to convert a human readable string to bytes.
|
|
720
715
|
|
|
721
716
|
Parameters
|
|
@@ -740,7 +735,7 @@ def as_bytes(value: Union[str, int], name: Optional[str] = None, none_ok: bool =
|
|
|
740
735
|
return human_to_bytes(value, name, none_ok)
|
|
741
736
|
|
|
742
737
|
|
|
743
|
-
def human_to_timedelta(value: str, name:
|
|
738
|
+
def human_to_timedelta(value: str, name: str | None = None, none_ok: bool = False) -> datetime.timedelta:
|
|
744
739
|
"""Convert a human readable string to a timedelta.
|
|
745
740
|
|
|
746
741
|
Parameters
|
|
@@ -792,7 +787,7 @@ def human_to_timedelta(value: str, name: Optional[str] = None, none_ok: bool = F
|
|
|
792
787
|
)
|
|
793
788
|
|
|
794
789
|
|
|
795
|
-
def as_timedelta(value: str, name:
|
|
790
|
+
def as_timedelta(value: str, name: str | None = None, none_ok: bool = False) -> datetime.timedelta:
|
|
796
791
|
"""Deprecated function to convert a human readable string to a timedelta.
|
|
797
792
|
|
|
798
793
|
Parameters
|
|
@@ -892,7 +887,7 @@ def json_pretty_dump(obj: Any, max_line_length: int = 120, default: Callable = s
|
|
|
892
887
|
return _format_json(obj)
|
|
893
888
|
|
|
894
889
|
|
|
895
|
-
def shorten_list(lst:
|
|
890
|
+
def shorten_list(lst: list[Any] | tuple[Any], max_length: int = 5) -> list[Any] | tuple[Any]:
|
|
896
891
|
"""Shorten a list to a maximum length.
|
|
897
892
|
|
|
898
893
|
Parameters
|
|
@@ -918,10 +913,8 @@ def shorten_list(lst: Union[List[Any], Tuple[Any]], max_length: int = 5) -> Unio
|
|
|
918
913
|
|
|
919
914
|
|
|
920
915
|
def _compress_dates(
|
|
921
|
-
dates:
|
|
922
|
-
) -> Generator[
|
|
923
|
-
Union[List[datetime.datetime], Tuple[datetime.datetime, datetime.datetime, datetime.timedelta]], None, None
|
|
924
|
-
]:
|
|
916
|
+
dates: list[datetime.datetime],
|
|
917
|
+
) -> Generator[list[datetime.datetime] | tuple[datetime.datetime, datetime.datetime, datetime.timedelta], None, None]:
|
|
925
918
|
"""Compress a list of dates into a more compact representation.
|
|
926
919
|
|
|
927
920
|
Parameters
|
|
@@ -953,7 +946,7 @@ def _compress_dates(
|
|
|
953
946
|
yield from _compress_dates([curr] + dates)
|
|
954
947
|
|
|
955
948
|
|
|
956
|
-
def compress_dates(dates:
|
|
949
|
+
def compress_dates(dates: list[datetime.datetime | str]) -> str:
|
|
957
950
|
"""Compress a list of dates into a human-readable format.
|
|
958
951
|
|
|
959
952
|
Parameters
|
|
@@ -979,7 +972,7 @@ def compress_dates(dates: List[Union[datetime.datetime, str]]) -> str:
|
|
|
979
972
|
return result
|
|
980
973
|
|
|
981
974
|
|
|
982
|
-
def print_dates(dates:
|
|
975
|
+
def print_dates(dates: list[datetime.datetime | str]) -> None:
|
|
983
976
|
"""Print a list of dates in a human-readable format.
|
|
984
977
|
|
|
985
978
|
Parameters
|
|
@@ -990,7 +983,7 @@ def print_dates(dates: List[Union[datetime.datetime, str]]) -> None:
|
|
|
990
983
|
print(compress_dates(dates))
|
|
991
984
|
|
|
992
985
|
|
|
993
|
-
def make_list_int(value:
|
|
986
|
+
def make_list_int(value: str | list[int] | tuple[int] | int) -> list[int]:
|
|
994
987
|
"""Convert a string like "1/2/3" or "1/to/3" or "1/to/10/by/2" to a list of integers.
|
|
995
988
|
|
|
996
989
|
Parameters
|
anemoi/utils/mars/__init__.py
CHANGED
|
@@ -17,9 +17,6 @@ import datetime
|
|
|
17
17
|
import logging
|
|
18
18
|
import os
|
|
19
19
|
from typing import Any
|
|
20
|
-
from typing import Dict
|
|
21
|
-
from typing import Optional
|
|
22
|
-
from typing import Tuple
|
|
23
20
|
|
|
24
21
|
import yaml
|
|
25
22
|
|
|
@@ -33,7 +30,7 @@ DEFAULT_MARS_LABELLING = {
|
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
|
|
36
|
-
def _expand_mars_labelling(request:
|
|
33
|
+
def _expand_mars_labelling(request: dict[str, Any]) -> dict[str, Any]:
|
|
37
34
|
"""Expand the request with the default Mars labelling.
|
|
38
35
|
|
|
39
36
|
Parameters
|
|
@@ -54,7 +51,7 @@ def _expand_mars_labelling(request: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
54
51
|
STREAMS = None
|
|
55
52
|
|
|
56
53
|
|
|
57
|
-
def _lookup_mars_stream(request:
|
|
54
|
+
def _lookup_mars_stream(request: dict[str, Any]) -> dict[str, Any] | None:
|
|
58
55
|
"""Look up the Mars stream information for a given request.
|
|
59
56
|
|
|
60
57
|
Parameters
|
|
@@ -82,8 +79,8 @@ def _lookup_mars_stream(request: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
|
82
79
|
|
|
83
80
|
|
|
84
81
|
def recenter(
|
|
85
|
-
date: datetime.datetime, center:
|
|
86
|
-
) ->
|
|
82
|
+
date: datetime.datetime, center: dict[str, Any], members: dict[str, Any]
|
|
83
|
+
) -> tuple[dict[str, Any] | None, dict[str, Any] | None]:
|
|
87
84
|
"""Recenter the given date with the specified center and members.
|
|
88
85
|
|
|
89
86
|
Parameters
|
anemoi/utils/mars/requests.py
CHANGED
|
@@ -7,11 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
import sys
|
|
9
9
|
from typing import Any
|
|
10
|
-
from typing import Dict
|
|
11
10
|
from typing import TextIO
|
|
12
11
|
|
|
13
12
|
|
|
14
|
-
def print_request(verb: str, request:
|
|
13
|
+
def print_request(verb: str, request: dict[str, Any], file: TextIO = sys.stdout) -> None:
|
|
15
14
|
"""Prints a formatted request.
|
|
16
15
|
|
|
17
16
|
Parameters
|
anemoi/utils/provenance.py
CHANGED
|
@@ -25,16 +25,11 @@ import sys
|
|
|
25
25
|
import sysconfig
|
|
26
26
|
from functools import cache
|
|
27
27
|
from typing import Any
|
|
28
|
-
from typing import Dict
|
|
29
|
-
from typing import List
|
|
30
|
-
from typing import Optional
|
|
31
|
-
from typing import Tuple
|
|
32
|
-
from typing import Union
|
|
33
28
|
|
|
34
29
|
LOG = logging.getLogger(__name__)
|
|
35
30
|
|
|
36
31
|
|
|
37
|
-
def lookup_git_repo(path: str) ->
|
|
32
|
+
def lookup_git_repo(path: str) -> Any | None:
|
|
38
33
|
"""Lookup the git repository for a given path.
|
|
39
34
|
|
|
40
35
|
Parameters
|
|
@@ -62,7 +57,7 @@ def lookup_git_repo(path: str) -> Optional[Any]:
|
|
|
62
57
|
return None
|
|
63
58
|
|
|
64
59
|
|
|
65
|
-
def _check_for_git(paths:
|
|
60
|
+
def _check_for_git(paths: list[tuple[str, str]], full: bool) -> dict[str, Any]:
|
|
66
61
|
"""Check for git information for the given paths.
|
|
67
62
|
|
|
68
63
|
Parameters
|
|
@@ -112,7 +107,7 @@ def _check_for_git(paths: List[Tuple[str, str]], full: bool) -> Dict[str, Any]:
|
|
|
112
107
|
|
|
113
108
|
|
|
114
109
|
def version(
|
|
115
|
-
versions:
|
|
110
|
+
versions: dict[str, Any], name: str, module: Any, roots: dict[str, str], namespaces: set, paths: set, full: bool
|
|
116
111
|
) -> None:
|
|
117
112
|
"""Collect version information for a module.
|
|
118
113
|
|
|
@@ -174,7 +169,7 @@ def version(
|
|
|
174
169
|
versions[name] = str(module)
|
|
175
170
|
|
|
176
171
|
|
|
177
|
-
def _module_versions(full: bool) ->
|
|
172
|
+
def _module_versions(full: bool) -> tuple[dict[str, Any], set]:
|
|
178
173
|
"""Collect version information for all loaded modules.
|
|
179
174
|
|
|
180
175
|
Parameters
|
|
@@ -216,7 +211,7 @@ def _module_versions(full: bool) -> Tuple[Dict[str, Any], set]:
|
|
|
216
211
|
|
|
217
212
|
|
|
218
213
|
@cache
|
|
219
|
-
def package_distributions() ->
|
|
214
|
+
def package_distributions() -> dict[str, list[str]]:
|
|
220
215
|
"""Get the package distributions.
|
|
221
216
|
|
|
222
217
|
Returns
|
|
@@ -235,7 +230,7 @@ def package_distributions() -> Dict[str, List[str]]:
|
|
|
235
230
|
return metadata.packages_distributions()
|
|
236
231
|
|
|
237
232
|
|
|
238
|
-
def import_name_to_distribution_name(packages:
|
|
233
|
+
def import_name_to_distribution_name(packages: list[str]) -> dict[str, str]:
|
|
239
234
|
"""Convert import names to distribution names.
|
|
240
235
|
|
|
241
236
|
Parameters
|
|
@@ -266,7 +261,7 @@ def import_name_to_distribution_name(packages: List[str]) -> Dict[str, str]:
|
|
|
266
261
|
return distribution_names
|
|
267
262
|
|
|
268
263
|
|
|
269
|
-
def module_versions(full: bool) ->
|
|
264
|
+
def module_versions(full: bool) -> tuple[dict[str, Any], dict[str, Any]]:
|
|
270
265
|
"""Collect version information for all loaded modules and their git information.
|
|
271
266
|
|
|
272
267
|
Parameters
|
|
@@ -306,7 +301,7 @@ def _name(obj: Any) -> str:
|
|
|
306
301
|
return str(obj)
|
|
307
302
|
|
|
308
303
|
|
|
309
|
-
def _paths(path_or_object:
|
|
304
|
+
def _paths(path_or_object: None | str | list[str] | tuple[str] | Any) -> list[tuple[str, str]]:
|
|
310
305
|
"""Get the paths for a given path or object.
|
|
311
306
|
|
|
312
307
|
Parameters
|
|
@@ -357,7 +352,7 @@ def _paths(path_or_object: Union[None, str, List[str], Tuple[str], Any]) -> List
|
|
|
357
352
|
return paths
|
|
358
353
|
|
|
359
354
|
|
|
360
|
-
def git_check(*args: Any) ->
|
|
355
|
+
def git_check(*args: Any) -> dict[str, Any]:
|
|
361
356
|
"""Return the git information for the given arguments.
|
|
362
357
|
|
|
363
358
|
Arguments can be:
|
|
@@ -400,7 +395,7 @@ def git_check(*args: Any) -> Dict[str, Any]:
|
|
|
400
395
|
return result
|
|
401
396
|
|
|
402
397
|
|
|
403
|
-
def platform_info() ->
|
|
398
|
+
def platform_info() -> dict[str, Any]:
|
|
404
399
|
"""Get the platform information.
|
|
405
400
|
|
|
406
401
|
Returns
|
|
@@ -429,7 +424,7 @@ def platform_info() -> Dict[str, Any]:
|
|
|
429
424
|
return r
|
|
430
425
|
|
|
431
426
|
|
|
432
|
-
def gpu_info() ->
|
|
427
|
+
def gpu_info() -> str | list[dict[str, Any]]:
|
|
433
428
|
"""Get the GPU information.
|
|
434
429
|
|
|
435
430
|
Returns
|
|
@@ -470,7 +465,7 @@ def path_md5(path: str) -> str:
|
|
|
470
465
|
return hash.hexdigest()
|
|
471
466
|
|
|
472
467
|
|
|
473
|
-
def assets_info(paths:
|
|
468
|
+
def assets_info(paths: list[str]) -> dict[str, Any]:
|
|
474
469
|
"""Get information about the given assets.
|
|
475
470
|
|
|
476
471
|
Parameters
|
|
@@ -511,7 +506,7 @@ def assets_info(paths: List[str]) -> Dict[str, Any]:
|
|
|
511
506
|
return result
|
|
512
507
|
|
|
513
508
|
|
|
514
|
-
def gather_provenance_info(assets:
|
|
509
|
+
def gather_provenance_info(assets: list[str] = [], full: bool = False) -> dict[str, Any]:
|
|
515
510
|
"""Gather information about the current environment.
|
|
516
511
|
|
|
517
512
|
Parameters
|
anemoi/utils/registry.py
CHANGED
|
@@ -13,15 +13,12 @@ import logging
|
|
|
13
13
|
import os
|
|
14
14
|
import sys
|
|
15
15
|
import warnings
|
|
16
|
+
from collections.abc import Callable
|
|
16
17
|
from functools import cached_property
|
|
17
18
|
from typing import Any
|
|
18
|
-
from typing import Callable
|
|
19
|
-
from typing import Dict
|
|
20
19
|
from typing import Generic
|
|
21
|
-
from typing import List
|
|
22
20
|
from typing import Optional
|
|
23
21
|
from typing import TypeVar
|
|
24
|
-
from typing import Union
|
|
25
22
|
|
|
26
23
|
import entrypoints
|
|
27
24
|
|
|
@@ -121,9 +118,7 @@ class Registry(Generic[T]):
|
|
|
121
118
|
"""
|
|
122
119
|
return _BY_KIND.get(kind)
|
|
123
120
|
|
|
124
|
-
def register(
|
|
125
|
-
self, name: str, factory: Optional[Callable] = None, source: Optional[Any] = None
|
|
126
|
-
) -> Optional[Wrapper]:
|
|
121
|
+
def register(self, name: str, factory: Callable | None = None, source: Any | None = None) -> Wrapper | None:
|
|
127
122
|
"""Register a factory with the registry.
|
|
128
123
|
|
|
129
124
|
Parameters
|
|
@@ -201,7 +196,7 @@ class Registry(Generic[T]):
|
|
|
201
196
|
LOG.info(f"Registered: {e} ({self._sources.get(e)})")
|
|
202
197
|
return ok
|
|
203
198
|
|
|
204
|
-
def lookup(self, name: str, *, return_none: bool = False) ->
|
|
199
|
+
def lookup(self, name: str, *, return_none: bool = False) -> Callable | None:
|
|
205
200
|
"""Lookup a factory by name.
|
|
206
201
|
|
|
207
202
|
Parameters
|
|
@@ -234,7 +229,7 @@ class Registry(Generic[T]):
|
|
|
234
229
|
return factory
|
|
235
230
|
|
|
236
231
|
@cached_property
|
|
237
|
-
def factories(self) ->
|
|
232
|
+
def factories(self) -> dict[str, Callable]:
|
|
238
233
|
|
|
239
234
|
directory = sys.modules[self.package].__path__[0]
|
|
240
235
|
|
|
@@ -286,7 +281,7 @@ class Registry(Generic[T]):
|
|
|
286
281
|
return self.__registered
|
|
287
282
|
|
|
288
283
|
@property
|
|
289
|
-
def registered(self) ->
|
|
284
|
+
def registered(self) -> list[str]:
|
|
290
285
|
"""Get the registered factories."""
|
|
291
286
|
|
|
292
287
|
return sorted(self.factories.keys())
|
|
@@ -314,7 +309,7 @@ class Registry(Generic[T]):
|
|
|
314
309
|
factory = self.lookup(name)
|
|
315
310
|
return factory(*args, **kwargs)
|
|
316
311
|
|
|
317
|
-
def from_config(self, config:
|
|
312
|
+
def from_config(self, config: str | dict[str, Any], *args: Any, **kwargs: Any) -> T:
|
|
318
313
|
"""Create an instance from a configuration.
|
|
319
314
|
|
|
320
315
|
Parameters
|
anemoi/utils/remote/__init__.py
CHANGED
|
@@ -10,9 +10,8 @@ import logging
|
|
|
10
10
|
import os
|
|
11
11
|
import shutil
|
|
12
12
|
from abc import abstractmethod
|
|
13
|
+
from collections.abc import Iterable
|
|
13
14
|
from typing import Any
|
|
14
|
-
from typing import Dict
|
|
15
|
-
from typing import Iterable
|
|
16
15
|
|
|
17
16
|
import tqdm
|
|
18
17
|
|
|
@@ -496,7 +495,7 @@ class Transfer:
|
|
|
496
495
|
if not target:
|
|
497
496
|
target = os.path.basename(os.path.dirname(source))
|
|
498
497
|
|
|
499
|
-
temporary_target:
|
|
498
|
+
temporary_target: dict[Any, Any] = {
|
|
500
499
|
False: None,
|
|
501
500
|
True: "{dirname}-downloading/{basename}",
|
|
502
501
|
"-tmp/*": "{dirname}-tmp/{basename}",
|
anemoi/utils/remote/s3.py
CHANGED
anemoi/utils/rules.py
CHANGED
|
@@ -7,17 +7,13 @@
|
|
|
7
7
|
# granted to it by virtue of its status as an intergovernmental organisation
|
|
8
8
|
# nor does it submit to any jurisdiction.
|
|
9
9
|
|
|
10
|
+
from collections.abc import Mapping
|
|
10
11
|
from typing import Any
|
|
11
|
-
from typing import Dict
|
|
12
|
-
from typing import List
|
|
13
|
-
from typing import Mapping
|
|
14
|
-
from typing import Optional
|
|
15
|
-
from typing import Union
|
|
16
12
|
|
|
17
13
|
|
|
18
14
|
class Rule:
|
|
19
15
|
|
|
20
|
-
def __init__(self, match:
|
|
16
|
+
def __init__(self, match: dict[str, Any], result: Any):
|
|
21
17
|
"""Initialize a Rule object.
|
|
22
18
|
|
|
23
19
|
Parameters
|
|
@@ -55,14 +51,14 @@ class Rule:
|
|
|
55
51
|
return self._result
|
|
56
52
|
|
|
57
53
|
@property
|
|
58
|
-
def condition(self) ->
|
|
54
|
+
def condition(self) -> dict[str, Any]:
|
|
59
55
|
"""The conditions that define the rule."""
|
|
60
56
|
return self._match
|
|
61
57
|
|
|
62
58
|
|
|
63
59
|
class RuleSet:
|
|
64
60
|
|
|
65
|
-
def __init__(self, rules:
|
|
61
|
+
def __init__(self, rules: list[Rule | dict[str, Any] | list[Any]]):
|
|
66
62
|
"""Initialize a RuleSet object.
|
|
67
63
|
|
|
68
64
|
Parameters
|
|
@@ -73,7 +69,7 @@ class RuleSet:
|
|
|
73
69
|
"""
|
|
74
70
|
assert isinstance(rules, list), "rules must be a list"
|
|
75
71
|
|
|
76
|
-
self.rules:
|
|
72
|
+
self.rules: list[Rule] = []
|
|
77
73
|
|
|
78
74
|
for rule in rules:
|
|
79
75
|
if isinstance(rule, Rule):
|
|
@@ -107,7 +103,7 @@ class RuleSet:
|
|
|
107
103
|
)
|
|
108
104
|
|
|
109
105
|
@classmethod
|
|
110
|
-
def from_list(cls, rules:
|
|
106
|
+
def from_list(cls, rules: list[Any]) -> "RuleSet":
|
|
111
107
|
"""Create a RuleSet from a list of rules.
|
|
112
108
|
|
|
113
109
|
Parameters
|
|
@@ -144,19 +140,19 @@ class RuleSet:
|
|
|
144
140
|
if path.endswith(".json"):
|
|
145
141
|
import json
|
|
146
142
|
|
|
147
|
-
with open(path
|
|
143
|
+
with open(path) as f:
|
|
148
144
|
return cls.from_list(json.load(f))
|
|
149
145
|
|
|
150
146
|
if path.endswith(".yaml") or path.endswith(".yml"):
|
|
151
147
|
import yaml
|
|
152
148
|
|
|
153
|
-
with open(path
|
|
149
|
+
with open(path) as f:
|
|
154
150
|
return cls.from_list(yaml.safe_load(f))
|
|
155
151
|
|
|
156
152
|
raise ValueError("Unsupported file format. Supported formats are .json and .yaml/.yml.")
|
|
157
153
|
|
|
158
154
|
@classmethod
|
|
159
|
-
def from_any(cls, rules:
|
|
155
|
+
def from_any(cls, rules: str | list[Any]) -> "RuleSet":
|
|
160
156
|
"""Create a RuleSet from a list or a file path.
|
|
161
157
|
|
|
162
158
|
Parameters
|
|
@@ -182,7 +178,7 @@ class RuleSet:
|
|
|
182
178
|
|
|
183
179
|
raise ValueError("Unsupported rules format. Must be a list or a file path.")
|
|
184
180
|
|
|
185
|
-
def match(self, obj: Mapping[str, Any], strategy: str = "first-match") ->
|
|
181
|
+
def match(self, obj: Mapping[str, Any], strategy: str = "first-match") -> Rule | None:
|
|
186
182
|
"""Match an object against the rules in the RuleSet.
|
|
187
183
|
|
|
188
184
|
Parameters
|
anemoi/utils/s3.py
CHANGED
|
@@ -8,9 +8,8 @@
|
|
|
8
8
|
# nor does it submit to any jurisdiction.
|
|
9
9
|
|
|
10
10
|
import warnings
|
|
11
|
+
from collections.abc import Callable
|
|
11
12
|
from typing import Any
|
|
12
|
-
from typing import Callable
|
|
13
|
-
from typing import Optional
|
|
14
13
|
|
|
15
14
|
from .remote import transfer
|
|
16
15
|
from .remote.s3 import delete as delete_
|
|
@@ -55,7 +54,7 @@ def upload(
|
|
|
55
54
|
overwrite: bool = False,
|
|
56
55
|
resume: bool = False,
|
|
57
56
|
verbosity: int = 1,
|
|
58
|
-
progress:
|
|
57
|
+
progress: Callable | None = None,
|
|
59
58
|
threads: int = 1,
|
|
60
59
|
) -> None:
|
|
61
60
|
"""Upload a file to S3.
|