From 4e0906426ef70235a7546c31d263904fa3249a9d Mon Sep 17 00:00:00 2001 From: wpbonelli Date: Wed, 6 Nov 2024 15:41:42 -0500 Subject: [PATCH] refactor(mf6): deprecate mf6 checks (#2357) Deprecate the MF6 check mechanism. The sense after discussion is that the checks have limited utility at the moment, a few relevance/correctness issues, and see little use. Consider either reworking/replacing them in 3.x in a backwards-compatible way, or removing them and making the .check() methods on simulation model/package base classes no-ops, pending a 4.x rework. Deprecating should help to determine if anyone is relying on them while we investigate how deeply they are woven into the existing framework. --- flopy/mf6/mfmodel.py | 13 +++++++++++++ flopy/mf6/mfpackage.py | 29 +++++++++++++++++++++++++++-- flopy/mf6/mfsimbase.py | 15 +++++++++++++++ flopy/utils/check.py | 17 ++++++++++++++++- 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/flopy/mf6/mfmodel.py b/flopy/mf6/mfmodel.py index 044e61a2a8..76429bdec0 100644 --- a/flopy/mf6/mfmodel.py +++ b/flopy/mf6/mfmodel.py @@ -825,6 +825,12 @@ def check(self, f=None, verbose=True, level=1): """ Check model data for common errors. + Warning + ------- + The MF6 check mechanism is deprecated pending reimplementation + in a future release. While the checks API will remain in place + through 3.x, it may be unstable, and will likely change in 4.x. + Parameters ---------- f : str or file handle @@ -850,6 +856,7 @@ def check(self, f=None, verbose=True, level=1): >>> m = flopy.modflow.Modflow.load('model.nam') >>> m.check() """ + # check instance for model-level check chk = mf6check(self, f=f, verbose=verbose, level=level) @@ -1804,6 +1811,12 @@ def set_all_data_external( ): """Sets the model's list and array data to be stored externally. + Warning + ------- + The MF6 check mechanism is deprecated pending reimplementation + in a future release. While the checks API will remain in place + through 3.x, it may be unstable, and will likely change in 4.x. + Parameters ---------- check_data : bool diff --git a/flopy/mf6/mfpackage.py b/flopy/mf6/mfpackage.py index ebc3ac23f6..5bb69ec179 100644 --- a/flopy/mf6/mfpackage.py +++ b/flopy/mf6/mfpackage.py @@ -1332,6 +1332,12 @@ def set_all_data_external( base_name is external file name's prefix, check_data determines if data error checking is enabled during this process. + Warning + ------- + The MF6 check mechanism is deprecated pending reimplementation + in a future release. While the checks API will remain in place + through 3.x, it may be unstable, and will likely change in 4.x. + Parameters ---------- base_name : str @@ -1344,6 +1350,7 @@ def set_all_data_external( Whether file will be stored as binary """ + for key, dataset in self.datasets.items(): lst_data = isinstance(dataset, mfdatalist.MFList) or isinstance( dataset, mfdataplist.MFPandasList @@ -1397,12 +1404,19 @@ def set_all_data_internal(self, check_data=True): check_data determines if data error checking is enabled during this process. + Warning + ------- + The MF6 check mechanism is deprecated pending reimplementation + in a future release. While the checks API will remain in place + through 3.x, it may be unstable, and will likely change in 4.x. + Parameters ---------- check_data : bool Whether to do data error checking. """ + for key, dataset in self.datasets.items(): if ( isinstance(dataset, mfdataarray.MFArray) @@ -1644,7 +1658,9 @@ def is_allowed(self): return True def is_valid(self): - """Returns true of the block is valid.""" + """ + Returns true if the block is valid. + """ # check data sets for dataset in self.datasets.values(): # Non-optional datasets must be enabled @@ -2130,7 +2146,16 @@ def _boundnames_active(self): return False def check(self, f=None, verbose=True, level=1, checktype=None): - """Data check, returns True on success.""" + """ + Data check, returns True on success. + + Warning + ------- + The MF6 check mechanism is deprecated pending reimplementation + in a future release. While the checks API will remain in place + through 3.x, it may be unstable, and will likely change in 4.x. + """ + if checktype is None: checktype = mf6check # do general checks diff --git a/flopy/mf6/mfsimbase.py b/flopy/mf6/mfsimbase.py index 673cc858ef..6e1a960f8e 100644 --- a/flopy/mf6/mfsimbase.py +++ b/flopy/mf6/mfsimbase.py @@ -1094,6 +1094,12 @@ def check( """ Check model data for common errors. + Warning + ------- + The MF6 check mechanism is deprecated pending reimplementation + in a future release. While the checks API will remain in place + through 3.x, it may be unstable, and will likely change in 4.x. + Parameters ---------- f : str or PathLike, optional @@ -1120,6 +1126,7 @@ def check( >>> m = flopy.modflow.Modflow.load('model.nam') >>> m.check() """ + # check instance for simulation-level check chk_list = [] @@ -1586,6 +1593,12 @@ def set_all_data_external( ): """Sets the simulation's list and array data to be stored externally. + Warning + ------- + The MF6 check mechanism is deprecated pending reimplementation + in a future release. While the checks API will remain in place + through 3.x, it may be unstable, and will likely change in 4.x. + Parameters ---------- check_data: bool @@ -1600,6 +1613,7 @@ def set_all_data_external( binary: bool Whether file will be stored as binary """ + # copy any files whose paths have changed self.simulation_data.mfpath.copy_files() # set data external for all packages in all models @@ -1636,6 +1650,7 @@ def set_all_data_external( def set_all_data_internal(self, check_data=True): # set data external for all packages in all models + for model in self._models.values(): model.set_all_data_internal(check_data) # set data external for solution packages diff --git a/flopy/utils/check.py b/flopy/utils/check.py index 432dc52214..0552baeded 100644 --- a/flopy/utils/check.py +++ b/flopy/utils/check.py @@ -1,6 +1,6 @@ import os -from pathlib import Path from typing import Optional, Union +from warnings import warn import numpy as np from numpy.lib import recfunctions @@ -799,6 +799,15 @@ def fields_view(arr, fields): class mf6check(check): + """ + Check an mf6 package for common errors. + + .. deprecated:: 3.9 + The MF6 check mechanism is deprecated pending reimplementation + in a future release. While the checks API will remain in place + through 3.x, it may be unstable, and will likely change in 4.x. + """ + def __init__( self, package, @@ -807,6 +816,12 @@ def __init__( level=1, property_threshold_values={}, ): + warn( + "The MF6 check mechanism is deprecated pending reimplementation " + "in a future release. While the checks API will remain in place " + "through 3.x, it may be unstable, and will likely change in 4.x.", + category=DeprecationWarning, + ) super().__init__(package, f, verbose, level, property_threshold_values) if hasattr(package, "model_or_sim"): self.model = package.model_or_sim