Skip to content

Commit 181e101

Browse files
authored
fix(binaryfile): accommodate windows drives for in-place reversal (#2312)
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.
1 parent 693f01a commit 181e101

File tree

3 files changed

+39
-35
lines changed

3 files changed

+39
-35
lines changed

flopy/utils/binaryfile.py

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import tempfile
1414
import warnings
1515
from pathlib import Path
16+
from shutil import move
1617
from typing import List, Optional, Union
1718

1819
import numpy as np
@@ -460,9 +461,9 @@ class BinaryLayerFile(LayerFile):
460461
"""
461462

462463
def __init__(
463-
self, filename: Union[str, os.PathLike], precision, verbose, kwargs
464+
self, filename: Union[str, os.PathLike], precision, verbose, **kwargs
464465
):
465-
super().__init__(filename, precision, verbose, kwargs)
466+
super().__init__(filename, precision, verbose, **kwargs)
466467

467468
def _build_index(self):
468469
"""
@@ -661,7 +662,7 @@ def __init__(
661662
self.header_dtype = BinaryHeader.set_dtype(
662663
bintype="Head", precision=precision
663664
)
664-
super().__init__(filename, precision, verbose, kwargs)
665+
super().__init__(filename, precision, verbose, **kwargs)
665666

666667
def reverse(self, filename: Optional[os.PathLike] = None):
667668
"""
@@ -733,10 +734,18 @@ def reverse_header(header):
733734
header["pertim"] = perlen - header["pertim"]
734735
return header
735736

736-
# reverse record order and write to temporary file
737-
temp_dir_path = Path(tempfile.gettempdir())
738-
temp_file_path = temp_dir_path / filename.name
739-
with open(temp_file_path, "wb") as f:
737+
target = filename
738+
739+
# if rewriting the same file, write
740+
# temp file then copy it into place
741+
inplace = filename == self.filename
742+
if inplace:
743+
temp_dir_path = Path(tempfile.gettempdir())
744+
temp_file_path = temp_dir_path / filename.name
745+
target = temp_file_path
746+
747+
# reverse record order
748+
with open(target, "wb") as f:
740749
for i in range(len(self) - 1, -1, -1):
741750
header = self.recordarray[i].copy()
742751
header = reverse_header(header)
@@ -752,16 +761,10 @@ def reverse_header(header):
752761
ilay=ilay,
753762
)
754763

755-
# if we're rewriting the original file, close it first
756-
if filename == self.filename:
757-
self.close()
758-
759-
# move temp file to destination
760-
temp_file_path.replace(filename)
761-
762764
# if we rewrote the original file, reinitialize
763-
if filename == self.filename:
764-
super().__init__(self.filename, self.precision, self.verbose, {})
765+
if inplace:
766+
move(target, filename)
767+
super().__init__(filename, self.precision, self.verbose)
765768

766769

767770
class UcnFile(BinaryLayerFile):
@@ -828,7 +831,7 @@ def __init__(
828831
self.header_dtype = BinaryHeader.set_dtype(
829832
bintype="Ucn", precision=precision
830833
)
831-
super().__init__(filename, precision, verbose, kwargs)
834+
super().__init__(filename, precision, verbose, **kwargs)
832835
return
833836

834837

@@ -898,7 +901,7 @@ def __init__(
898901
self.header_dtype = BinaryHeader.set_dtype(
899902
bintype="Head", precision=precision
900903
)
901-
super().__init__(filename, precision, verbose, kwargs)
904+
super().__init__(filename, precision, verbose, **kwargs)
902905

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

2328-
# open backward budget file
2329-
temp_dir_path = Path(tempfile.gettempdir())
2330-
temp_file_path = temp_dir_path / filename.name
2331-
with open(temp_file_path, "wb") as f:
2331+
target = filename
2332+
2333+
# if rewriting the same file, write
2334+
# temp file then copy it into place
2335+
inplace = filename == self.filename
2336+
if inplace:
2337+
temp_dir_path = Path(tempfile.gettempdir())
2338+
temp_file_path = temp_dir_path / filename.name
2339+
target = temp_file_path
2340+
2341+
with open(target, "wb") as f:
23322342
# loop over budget file records in reverse order
23332343
for idx in range(nrecords - 1, -1, -1):
23342344
# load header array
@@ -2415,13 +2425,7 @@ def reverse(self, filename: Optional[os.PathLike] = None):
24152425
# Write data
24162426
data.tofile(f)
24172427

2418-
# if we're rewriting the original file, close it first
2419-
if filename == self.filename:
2420-
self.close()
2421-
2422-
# move temp file to destination
2423-
temp_file_path.replace(filename)
2424-
24252428
# if we rewrote the original file, reinitialize
2426-
if filename == self.filename:
2427-
self.__init__(self.filename, self.precision, self.verbose)
2429+
if inplace:
2430+
move(target, filename)
2431+
self.__init__(filename, self.precision, self.verbose)

flopy/utils/datafile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class LayerFile:
157157
"""
158158

159159
def __init__(
160-
self, filename: Union[str, os.PathLike], precision, verbose, kwargs
160+
self, filename: Union[str, os.PathLike], precision, verbose, **kwargs
161161
):
162162
from ..discretization.structuredgrid import StructuredGrid
163163

flopy/utils/formattedfile.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ class FormattedLayerFile(LayerFile):
110110
111111
"""
112112

113-
def __init__(self, filename, precision, verbose, kwargs):
114-
super().__init__(filename, precision, verbose, kwargs)
113+
def __init__(self, filename, precision, verbose, **kwargs):
114+
super().__init__(filename, precision, verbose, **kwargs)
115115

116116
def _build_index(self):
117117
"""
@@ -376,7 +376,7 @@ def __init__(
376376
**kwargs,
377377
):
378378
self.text = text
379-
super().__init__(filename, precision, verbose, kwargs)
379+
super().__init__(filename, precision, verbose, **kwargs)
380380

381381
def _get_text_header(self):
382382
"""

0 commit comments

Comments
 (0)