Skip to content

Commit

Permalink
fix(binaryfile): accommodate windows drives for in-place reversal (#2312
Browse files Browse the repository at this point in the history
)

The reverse() methods on HeadFile and CellBudgetFile would fail on an in-place reversal if the system temp dir occupied a different drive than the original file. Use shutil.move() instead of Path.replace() to accommodate the cross-drive move.
  • Loading branch information
wpbonelli authored Sep 16, 2024
1 parent 693f01a commit 181e101
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 35 deletions.
66 changes: 35 additions & 31 deletions flopy/utils/binaryfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import tempfile
import warnings
from pathlib import Path
from shutil import move
from typing import List, Optional, Union

import numpy as np
Expand Down Expand Up @@ -460,9 +461,9 @@ class BinaryLayerFile(LayerFile):
"""

def __init__(
self, filename: Union[str, os.PathLike], precision, verbose, kwargs
self, filename: Union[str, os.PathLike], precision, verbose, **kwargs
):
super().__init__(filename, precision, verbose, kwargs)
super().__init__(filename, precision, verbose, **kwargs)

def _build_index(self):
"""
Expand Down Expand Up @@ -661,7 +662,7 @@ def __init__(
self.header_dtype = BinaryHeader.set_dtype(
bintype="Head", precision=precision
)
super().__init__(filename, precision, verbose, kwargs)
super().__init__(filename, precision, verbose, **kwargs)

def reverse(self, filename: Optional[os.PathLike] = None):
"""
Expand Down Expand Up @@ -733,10 +734,18 @@ def reverse_header(header):
header["pertim"] = perlen - header["pertim"]
return header

# reverse record order and write to temporary file
temp_dir_path = Path(tempfile.gettempdir())
temp_file_path = temp_dir_path / filename.name
with open(temp_file_path, "wb") as f:
target = filename

# if rewriting the same file, write
# temp file then copy it into place
inplace = filename == self.filename
if inplace:
temp_dir_path = Path(tempfile.gettempdir())
temp_file_path = temp_dir_path / filename.name
target = temp_file_path

# reverse record order
with open(target, "wb") as f:
for i in range(len(self) - 1, -1, -1):
header = self.recordarray[i].copy()
header = reverse_header(header)
Expand All @@ -752,16 +761,10 @@ def reverse_header(header):
ilay=ilay,
)

# if we're rewriting the original file, close it first
if filename == self.filename:
self.close()

# move temp file to destination
temp_file_path.replace(filename)

# if we rewrote the original file, reinitialize
if filename == self.filename:
super().__init__(self.filename, self.precision, self.verbose, {})
if inplace:
move(target, filename)
super().__init__(filename, self.precision, self.verbose)


class UcnFile(BinaryLayerFile):
Expand Down Expand Up @@ -828,7 +831,7 @@ def __init__(
self.header_dtype = BinaryHeader.set_dtype(
bintype="Ucn", precision=precision
)
super().__init__(filename, precision, verbose, kwargs)
super().__init__(filename, precision, verbose, **kwargs)
return


Expand Down Expand Up @@ -898,7 +901,7 @@ def __init__(
self.header_dtype = BinaryHeader.set_dtype(
bintype="Head", precision=precision
)
super().__init__(filename, precision, verbose, kwargs)
super().__init__(filename, precision, verbose, **kwargs)

def _get_data_array(self, totim=0.0):
"""
Expand Down Expand Up @@ -2325,10 +2328,17 @@ def reverse(self, filename: Optional[os.PathLike] = None):
# get number of records
nrecords = len(self)

# open backward budget file
temp_dir_path = Path(tempfile.gettempdir())
temp_file_path = temp_dir_path / filename.name
with open(temp_file_path, "wb") as f:
target = filename

# if rewriting the same file, write
# temp file then copy it into place
inplace = filename == self.filename
if inplace:
temp_dir_path = Path(tempfile.gettempdir())
temp_file_path = temp_dir_path / filename.name
target = temp_file_path

with open(target, "wb") as f:
# loop over budget file records in reverse order
for idx in range(nrecords - 1, -1, -1):
# load header array
Expand Down Expand Up @@ -2415,13 +2425,7 @@ def reverse(self, filename: Optional[os.PathLike] = None):
# Write data
data.tofile(f)

# if we're rewriting the original file, close it first
if filename == self.filename:
self.close()

# move temp file to destination
temp_file_path.replace(filename)

# if we rewrote the original file, reinitialize
if filename == self.filename:
self.__init__(self.filename, self.precision, self.verbose)
if inplace:
move(target, filename)
self.__init__(filename, self.precision, self.verbose)
2 changes: 1 addition & 1 deletion flopy/utils/datafile.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class LayerFile:
"""

def __init__(
self, filename: Union[str, os.PathLike], precision, verbose, kwargs
self, filename: Union[str, os.PathLike], precision, verbose, **kwargs
):
from ..discretization.structuredgrid import StructuredGrid

Expand Down
6 changes: 3 additions & 3 deletions flopy/utils/formattedfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ class FormattedLayerFile(LayerFile):
"""

def __init__(self, filename, precision, verbose, kwargs):
super().__init__(filename, precision, verbose, kwargs)
def __init__(self, filename, precision, verbose, **kwargs):
super().__init__(filename, precision, verbose, **kwargs)

def _build_index(self):
"""
Expand Down Expand Up @@ -376,7 +376,7 @@ def __init__(
**kwargs,
):
self.text = text
super().__init__(filename, precision, verbose, kwargs)
super().__init__(filename, precision, verbose, **kwargs)

def _get_text_header(self):
"""
Expand Down

0 comments on commit 181e101

Please sign in to comment.