Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #847 +/- ##
==========================================
+ Coverage 83.46% 83.56% +0.09%
==========================================
Files 49 49
Lines 7293 7294 +1
==========================================
+ Hits 6087 6095 +8
+ Misses 1206 1199 -7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR refactors and modernizes the restartthinner module by improving code quality, replacing deprecated patterns, and enhancing maintainability.
Changes:
- Replaced
os.system()calls withsubprocess.run()for better error handling and portability - Refactored
find_resdata_app()to useshutil.which()instead of manual PATH traversal - Simplified
date_slicer()to return a list directly instead of a dict, improving clarity
Comments suppressed due to low confidence (1)
src/subscript/restartthinner/restartthinner.py:69
- There are two spelling errors in this comment: "dont't" should be "don't" and "remainding" should be "remaining".
First unpacking a UNRST file, then deleting dates the dont't want, then
pack the remainding files into a new UNRST file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -41,30 +42,27 @@ def find_resdata_app(toolname: str) -> str: | |||
| Raises: | |||
| IOError: if tool can't be found | |||
There was a problem hiding this comment.
The docstring states "IOError: if tool can't be found" but the function raises OSError. While IOError is an alias for OSError in Python 3, the docstring should be updated to match the actual exception being raised for consistency.
| IOError: if tool can't be found | |
| OSError: if tool can't be found |
| def date_slicer( | ||
| slicedates: list, restartdates: list, restartindices: list | ||
| ) -> list[int]: | ||
| """Make a dict that maps a chosen restart date to a report index""" |
There was a problem hiding this comment.
The docstring still mentions "Make a dict that maps a chosen restart date to a report index" but the function now returns a list instead of a dict. The docstring should be updated to reflect that it returns a list of restart indices.
| """Make a dict that maps a chosen restart date to a report index""" | |
| """Return a list of restart indices closest to the requested slice dates.""" |
56537b7 to
1b28dbe
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| with _working_directory(rstdir): | ||
| tempdir = Path(tempfile.mkdtemp(dir=".")) | ||
| try: | ||
| # Move UNRST into temp directory and work there | ||
| shutil.move(rstname, tempdir / rstname) | ||
|
|
||
| with _working_directory(tempdir): | ||
| subprocess.run( | ||
| [rd_unpack, rstname], | ||
| capture_output=quiet, | ||
| check=True, | ||
| ) | ||
|
|
||
| for file in Path(".").glob("*.X*"): | ||
| index = int(file.suffix.lstrip(".X")) | ||
| if index not in slicerstindices: | ||
| file.unlink() | ||
|
|
||
| remaining_files = sorted(Path(".").glob("*.X*")) | ||
| subprocess.run( | ||
| [rd_pack, *[str(f) for f in remaining_files]], | ||
| capture_output=quiet, | ||
| check=True, | ||
| ) | ||
|
|
||
| # Move result back up | ||
| shutil.move(rstname, f"../{rstname}") | ||
| finally: | ||
| shutil.rmtree(tempdir) |
There was a problem hiding this comment.
If an error occurs in rd_repacker after moving the original file into the temp directory but before successfully moving it back, the original file could be lost when the temp directory is cleaned up in the finally block. This is especially problematic when keep=False. Consider creating a temporary backup inside rd_repacker or ensuring the original file is only moved after successful processing, using a different approach like working on a copy.
| subprocess.run( | ||
| [rd_unpack, rstname], | ||
| capture_output=quiet, | ||
| check=True, | ||
| ) | ||
|
|
||
| for file in Path(".").glob("*.X*"): | ||
| index = int(file.suffix.lstrip(".X")) | ||
| if index not in slicerstindices: | ||
| file.unlink() | ||
|
|
||
| remaining_files = sorted(Path(".").glob("*.X*")) | ||
| subprocess.run( | ||
| [rd_pack, *[str(f) for f in remaining_files]], | ||
| capture_output=quiet, | ||
| check=True, | ||
| ) |
There was a problem hiding this comment.
The subprocess.run calls use capture_output=quiet which will be either True or False. When True, both stdout and stderr are captured and discarded. When False, they are not captured. However, this means error messages from the subprocess will be hidden when quiet=True, making debugging difficult if the subprocess fails. Consider using stdout=subprocess.DEVNULL if quiet else None and always showing stderr for better error visibility, or at least including stderr in the exception message when check=True fails.
1b28dbe to
925b484
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
925b484 to
633967e
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if numberofslices > 1: | ||
| slicedates = pandas.DatetimeIndex( | ||
| numpy.linspace( | ||
| pandas.Timestamp(restart_dates[0]).value, | ||
| pandas.Timestamp(restart_dates[-1]).value, | ||
| slicedates = pd.DatetimeIndex( | ||
| np.linspace( | ||
| pd.Timestamp(restart_dates[0]).value, | ||
| pd.Timestamp(restart_dates[-1]).value, | ||
| int(numberofslices), | ||
| ) | ||
| ).to_list() | ||
| else: | ||
| slicedates = [restart_dates[-1]] # Only return last date if only one is wanted | ||
|
|
||
| slicerstindices = list( | ||
| date_slicer(slicedates, restart_dates, restart_indices).values() | ||
| ) | ||
| slicerstindices.sort() | ||
| slicerstindices = list(set(slicerstindices)) # uniquify | ||
| slicerstindices = date_slicer(slicedates, restart_dates, restart_indices) | ||
| slicerstindices = sorted(set(slicerstindices)) # uniquify |
There was a problem hiding this comment.
When numberofslices equals the number of existing restart points, the date_slicer logic may still try to calculate evenly-spaced dates which could theoretically select duplicates. The sorted(set(...)) on line 179 handles this, but it means the user might get fewer restart points than requested. Consider adding a check or warning when numberofslices >= len(restart_indices) to inform the user that all restart points are being kept.
633967e to
73c3fa3
Compare
73c3fa3 to
c172ddf
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
No description provided.