Skip to content

Commit 2e102e5

Browse files
authored
Merge pull request #255 from MODFLOW-ORG/v1.8.0
Release 1.8.0
2 parents 355b0be + a4422f0 commit 2e102e5

File tree

17 files changed

+835
-659
lines changed

17 files changed

+835
-659
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ jobs:
7979
strategy:
8080
fail-fast: false
8181
matrix:
82-
os: [ ubuntu-22.04, macos-13, windows-2022 ]
82+
os: [ ubuntu-22.04, macos-14, windows-2022 ]
8383
python: [ "3.10", "3.11", "3.12", "3.13" ]
8484
env:
8585
GCC_V: 11

HISTORY.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
### Version 1.8.0
2+
3+
#### New features
4+
5+
* [feat(programs)](https://github.com/MODFLOW-ORG/modflow-devtools/commit/7424efa236c67365889081f857127cb2ccfa19c3): Add programs module and database (#243). Committed by wpbonelli on 2025-10-15.
6+
7+
#### Refactoring
8+
9+
* [refactor](https://github.com/MODFLOW-ORG/modflow-devtools/commit/98215fd29a46cd63c964613dba14fbacfed26721): Move drop_none_or_empty to misc module. Committed by w-bonelli on 2025-10-29.
10+
* [refactor](https://github.com/MODFLOW-ORG/modflow-devtools/commit/e1264de9eef2f63b030cb75584e91d9cb1422d2f): Update programs database (#254). Committed by wpbonelli on 2025-10-29.
11+
112
### Version 1.7.0
213

314
#### New features

MANIFEST.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include modflow_devtools/programs/*.csv
2+
include modflow_devtools/registry/*.toml

autotest/test_programs.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import pytest
2+
3+
from modflow_devtools.programs import get_program, get_programs, load_programs
4+
5+
6+
def test_load_programs():
7+
programs = get_programs()
8+
assert isinstance(programs, dict)
9+
assert "mf6" in programs
10+
mf6 = get_program("mf6")
11+
assert mf6 == programs["mf6"]
12+
assert isinstance(mf6.version, str)
13+
assert isinstance(mf6.current, bool)
14+
assert isinstance(mf6.url, str)
15+
assert isinstance(mf6.dirname, str)
16+
assert isinstance(mf6.srcdir, str)
17+
assert isinstance(mf6.standard_switch, bool)
18+
assert isinstance(mf6.double_switch, bool)
19+
assert isinstance(mf6.shared_object, bool)
20+
21+
22+
def test_strict_unrecognized_keys(function_tmpdir):
23+
tmp_path = function_tmpdir / "programs.csv"
24+
with tmp_path.open("w") as f:
25+
f.write(
26+
"target,version,current,url,dirname,srcdir,standard_switch,double_switch,shared_object,garbage\n"
27+
)
28+
f.write(
29+
"mf6,6.6.3,True,https://github.com/MODFLOW-ORG/modflow6/releases/download/6.6.3/mf6.6.3_linux.zip,mf6.6.3_linux,src,True,False,False,garbage\n"
30+
)
31+
32+
with pytest.raises(ValueError) as e:
33+
load_programs(tmp_path, strict=True)
34+
assert "Unrecognized keys in program data: {'unrecognized_key'}" in e.message

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
project = "modflow-devtools"
1010
author = "MODFLOW Team"
11-
release = "1.7.0"
11+
release = "1.8.0"
1212

1313
# -- General configuration ---------------------------------------------------
1414
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

docs/md/models.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ For example, to create the "default" registry of models in the MF6 examples and
110110

111111
```shell
112112
python -m modflow_devtools.make_registry -p ../modflow6-examples/examples --url https://github.com/MODFLOW-ORG/modflow6-examples/releases/download/current/mf6examples.zip --model-name-prefix mf6/example
113-
python -m modflow_devtools.make_registry -p ../modflow6-testmodels/mf6 --append --url https://github.com/MODFLOW-ORG/modflow6-testmodels/raw/master/mf6 --model-name-prefix mf6/test
114-
python -m modflow_devtools.make_registry -p ../modflow6-largetestmodels --append --url https://github.com/MODFLOW-ORG/modflow6-largetestmodels/raw/master --model-name-prefix mf6/large
115-
python -m modflow_devtools.make_registry -p ../modflow6-testmodels/mf5to6 --append --url https://github.com/MODFLOW-ORG/modflow6-testmodels/raw/master/mf5to6 --model-name-prefix mf2005 --namefile "*.nam"
113+
python -m modflow_devtools.make_registry -p ../modflow6-testmodels/mf6 --url https://github.com/MODFLOW-ORG/modflow6-testmodels/raw/master/mf6 --model-name-prefix mf6/test
114+
python -m modflow_devtools.make_registry -p ../modflow6-largetestmodels --url https://github.com/MODFLOW-ORG/modflow6-largetestmodels/raw/master --model-name-prefix mf6/large
115+
python -m modflow_devtools.make_registry -p ../modflow6-testmodels/mf5to6 --url https://github.com/MODFLOW-ORG/modflow6-testmodels/raw/master/mf5to6 --model-name-prefix mf2005 --namefile "*.nam"
116116
```
117117

118118
As a shortcut to create the default registry, the script can be run with no arguments: `python -m modflow_devtools.make_registry`.

docs/md/programs.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# MODFLOW and related programs
2+
3+
The `modflow_devtools.programs` module provides a database of programs in the MODFLOW ecosystem. This has previously been housed in [`pymake`](https://github.com/modflowpy/pymake).
4+
5+
The database is accessible as a dictionary of programs:
6+
7+
```python
8+
from modflow_devtools.programs import get_programs, get_program
9+
10+
programs = get_programs()
11+
mf6 = programs["mf6"]
12+
mf6 = get_program("mf6") # equivalent
13+
```

modflow_devtools/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
__author__ = "Joseph D. Hughes"
2-
__date__ = "Jun 23, 2025"
3-
__version__ = "1.7.0"
2+
__date__ = "Oct 29, 2025"
3+
__version__ = "1.8.0"
44
__maintainer__ = "Joseph D. Hughes"
55
__email__ = "[email protected]"
66
__status__ = "Production"

modflow_devtools/misc.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import traceback
55
from _warnings import warn
66
from ast import literal_eval
7+
from collections.abc import Iterable
78
from contextlib import contextmanager
89
from enum import Enum
910
from functools import wraps
@@ -565,3 +566,24 @@ def try_get_enum_value(v: Any) -> Any:
565566
of an enumeration, otherwise return it unaltered.
566567
"""
567568
return v.value if isinstance(v, Enum) else v
569+
570+
571+
def try_literal_eval(value: str) -> Any:
572+
"""
573+
Try to parse a string as a literal. If this fails,
574+
return the value unaltered.
575+
"""
576+
try:
577+
return literal_eval(value)
578+
except (SyntaxError, ValueError):
579+
return value
580+
581+
582+
def drop_none_or_empty(path, key, value):
583+
"""
584+
Drop dictionary items with None or empty values.
585+
For use with `boltons.iterutils.remap`.
586+
"""
587+
if value is None or (isinstance(value, Iterable) and not any(value)):
588+
return False
589+
return True

modflow_devtools/models.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,7 @@
2121
from pooch import Pooch
2222

2323
import modflow_devtools
24-
from modflow_devtools.misc import get_model_paths
25-
26-
27-
def _drop_none_or_empty(path, key, value):
28-
if value is None or value == "":
29-
return False
30-
return True
24+
from modflow_devtools.misc import drop_none_or_empty, get_model_paths
3125

3226

3327
def _model_sort_key(k) -> int:
@@ -421,7 +415,7 @@ def index(
421415

422416
with self._registry_file_path.open("ab+") as registry_file:
423417
tomli_w.dump(
424-
remap(dict(sorted(files.items())), visit=_drop_none_or_empty),
418+
remap(dict(sorted(files.items())), visit=drop_none_or_empty),
425419
registry_file,
426420
)
427421

0 commit comments

Comments
 (0)