Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions autotest/test_mbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,8 @@ def test_run_model_exe_rel_path(mf6_model_path, function_tmpdir, use_ext):

bin_dir = function_tmpdir / "bin"
bin_dir.mkdir()
inner_dir = function_tmpdir / "inner"
inner_dir.mkdir()

with set_dir(inner_dir):
with set_dir(ws):
# copy exe to relative dir
copy(mf6, bin_dir / "mf6")
assert (bin_dir / "mf6").is_file()
Expand Down
52 changes: 26 additions & 26 deletions flopy/mbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,31 +64,31 @@ def resolve_exe(exe_name: Union[str, os.PathLike], forgive: bool = False) -> str
str: absolute path to the executable
"""

def _resolve(exe_name):
exe = which(exe_name)
if exe is not None:
# if which() returned a relative path, resolve it
exe = which(str(Path(exe).resolve()))
else:
if exe_name.lower().endswith(".exe"):
# try removing .exe suffix
exe = which(exe_name[:-4])
if exe is not None:
# in case which() returned a relative path, resolve it
exe = which(str(Path(exe).resolve()))
else:
# try tilde-expanded abspath
exe = which(Path(exe_name).expanduser().absolute())
if exe is None and exe_name.lower().endswith(".exe"):
# try tilde-expanded abspath without .exe suffix
exe = which(Path(exe_name[:-4]).expanduser().absolute())
return exe

name = str(exe_name)
exe_path = _resolve(name)
if exe_path is None and on_windows and Path(name).suffix == "":
# try adding .exe suffix on windows (for portability from other OS)
exe_path = _resolve(f"{name}.exe")
def _resolve(exe_name, checked=set()):
# Prevent infinite recursion by checking if exe_name has been checked
if exe_name in checked:
return None
checked.add(exe_name)

# exe_name is found (not None), ensure absolute path is returned
if exe := which(str(exe_name)):
return which(str(Path(exe).resolve()))

# exe_name is relative path
if not Path(exe_name).is_absolute() and (
exe := which(str(Path(exe_name).expanduser().resolve()), mode=0)
):
# expanduser() in case of ~ in path
# mode=0 effectively allows which() to find exe without suffix in windows
return exe

# try adding/removing .exe suffix
if exe_name.lower().endswith(".exe"):
return _resolve(exe_name[:-4], checked)
elif on_windows and "." not in Path(exe_name).stem:
return _resolve(f"{exe_name}.exe", checked)

exe_path = _resolve(exe_name)

# raise if we are unforgiving, otherwise return None
if exe_path is None:
Expand All @@ -103,7 +103,7 @@ def _resolve(exe_name):
f"The program {exe_name} does not exist or is not executable."
)

return exe_path
return str(exe_path)


# external exceptions for users
Expand Down
Loading