Skip to content

Commit

Permalink
revisions
Browse files Browse the repository at this point in the history
  • Loading branch information
wpbonelli committed Nov 4, 2024
1 parent 23b2a30 commit acf1b7c
Show file tree
Hide file tree
Showing 14 changed files with 385 additions and 411 deletions.
64 changes: 40 additions & 24 deletions flopy/mf6/utils/codegen/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,53 @@
from os import PathLike
from pathlib import Path

from flopy.utils import import_optional_dependency

__all__ = ["make_targets", "make_all"]
__jinja = import_optional_dependency("jinja2", errors="ignore")


def make_targets(dfn, outdir: Path, verbose: bool = False):
"""Generate Python source file(s) from the given input definition."""
def _get_template_env():
from flopy.mf6.utils.codegen.jinja import Filters

jinja = import_optional_dependency("jinja2")
loader = jinja.PackageLoader("flopy", "mf6/utils/codegen/templates/")
env = jinja.Environment(loader=loader)
env.filters["parent"] = Filters.parent
env.filters["prefix"] = Filters.prefix
env.filters["skip"] = Filters.skip
return env

if not __jinja:
raise RuntimeError("Jinja2 not installed, can't make targets")

def make_init(dfns: dict, outdir: PathLike, verbose: bool = False):
"""Generate a Python __init__.py file for the given input definitions."""

from flopy.mf6.utils.codegen.context import Context

loader = __jinja.PackageLoader("flopy", "mf6/utils/codegen/templates/")
env = __jinja.Environment(loader=loader)
env = _get_template_env()
outdir = Path(outdir).expanduser()
contexts = [
c
for cc in [
[ctx for ctx in Context.from_dfn(dfn)] for dfn in dfns.values()
]
for c in cc
] # ugly, but it's the fastest way to flatten the list
target_name = "__init__.py"
target = outdir / target_name
template = env.get_template(f"{target_name}.jinja")
with open(target, "w") as f:
f.write(template.render(contexts=contexts))
if verbose:
print(f"Wrote {target}")


def make_targets(dfn, outdir: PathLike, verbose: bool = False):
"""Generate Python source file(s) from the given input definition."""

from flopy.mf6.utils.codegen.context import Context

env = _get_template_env()
outdir = Path(outdir).expanduser()
for context in Context.from_dfn(dfn):
name = context.name
target = outdir / name.target
Expand All @@ -29,25 +61,9 @@ def make_targets(dfn, outdir: Path, verbose: bool = False):
def make_all(dfndir: Path, outdir: Path, verbose: bool = False):
"""Generate Python source files from the DFN files in the given location."""

if not __jinja:
raise RuntimeError("Jinja2 not installed, can't make targets")

from flopy.mf6.utils.codegen.context import Context
from flopy.mf6.utils.codegen.dfn import Dfn

# load dfns
dfns = Dfn.load_all(dfndir)

# make target files
make_init(dfns, outdir, verbose)
for dfn in dfns.values():
make_targets(dfn, outdir, verbose)

# make __init__.py file
init_path = outdir / "__init__.py"
with open(init_path, "w") as f:
for dfn in dfns.values():
for name in Context.Name.from_dfn(dfn):
prefix = "MF" if name.base == "MFSimulationBase" else "Modflow"
f.write(
f"from .mf{name.title} import {prefix}{name.title.title()}\n"
)
23 changes: 23 additions & 0 deletions flopy/mf6/utils/codegen/dfn.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,29 @@
}


def try_literal_eval(value: str) -> Any:
"""
Try to parse a string as a literal. If this fails,
return the value unaltered.
"""
try:
return literal_eval(value)
except (SyntaxError, ValueError):
return value


def try_parse_bool(value: Any) -> Any:
"""
Try to parse a boolean from a string as represented
in a DFN file, otherwise return the value unaltered.
"""
if isinstance(value, str):
value = value.lower()
if value in ["true", "false"]:
return value == "true"
return value


Vars = Dict[str, "Var"]
Refs = Dict[str, "Ref"]
Dfns = Dict[str, "Dfn"]
Expand Down
9 changes: 2 additions & 7 deletions flopy/mf6/utils/codegen/dfn2toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,13 @@
_DFN_PATH = _MF6_PATH / "data" / "dfn"
_TOML_PATH = _MF6_PATH / "data" / "toml"

__tomlkit = import_optional_dependency("tomlkit")


if __name__ == "__main__":
"""Convert DFN files to TOML."""

if not __tomlkit:
raise RuntimeError("tomlkit not installed, can't convert DFNs to TOML")

from flopy.mf6.utils.codegen.dfn import Dfn

tomlkit = import_optional_dependency("tomlkit")
parser = argparse.ArgumentParser(description="Convert DFN files to TOML.")
parser.add_argument(
"--dfndir",
Expand All @@ -30,11 +26,10 @@
default=_TOML_PATH,
help="Output directory.",
)

args = parser.parse_args()
dfndir = Path(args.dfndir)
outdir = Path(args.outdir)
outdir.mkdir(exist_ok=True, parents=True)
for dfn in Dfn.load_all(dfndir).values():
with open(Path(outdir) / f"{'-'.join(dfn.name)}.toml", "w") as f:
__tomlkit.dump(dfn.render(), f)
tomlkit.dump(dfn.render(), f)
Loading

0 comments on commit acf1b7c

Please sign in to comment.