diff --git a/.docs/groundwater_paper/scripts/uspb_capture.py b/.docs/groundwater_paper/scripts/uspb_capture.py index 591ce5277e..c1b76602fc 100644 --- a/.docs/groundwater_paper/scripts/uspb_capture.py +++ b/.docs/groundwater_paper/scripts/uspb_capture.py @@ -104,15 +104,9 @@ def cf_model(model, k, i, j, base, Q=-100): # write some summary information fs.write(f"Problem size: {nrow} rows and {ncol} columns.\n") fs.write( - "Capture fraction analysis performed every {} rows and columns.\n".format( - nstep - ) -) -fs.write( - "Maximum number of analyses: {} rows and {} columns.\n".format( - nrow2, ncol2 - ) + f"Capture fraction analysis performed every {nstep} rows and columns.\n" ) +fs.write(f"Maximum number of analyses: {nrow2} rows and {ncol2} columns.\n") # create array to store capture fraction data (subset of model) cf_array = np.empty((10, nrow2, ncol2), dtype=float) @@ -131,9 +125,7 @@ def cf_model(model, k, i, j, base, Q=-100): if ibound[i, j] < 1: sys.stdout.write(".") else: - line = "\nrow {} of {} - col {} of {}\n".format( - icnt + 1, nrow2, jcnt + 1, ncol2 - ) + line = f"\nrow {icnt + 1} of {nrow2} - col {jcnt + 1} of {ncol2}\n" fs.write(line) sys.stdout.write(line) s0 = time.time() diff --git a/.docs/groundwater_paper/scripts/uspb_capture_par.py b/.docs/groundwater_paper/scripts/uspb_capture_par.py index 1803ba5fe2..41f666a19e 100644 --- a/.docs/groundwater_paper/scripts/uspb_capture_par.py +++ b/.docs/groundwater_paper/scripts/uspb_capture_par.py @@ -106,9 +106,7 @@ def copy_files(ml, nproc): os.makedirs(cf_pths[idx]) filelist = [f for f in os.listdir(cf_pths[0])] sys.stdout.write( - "copying files from {} to {}\n".format( - cf_pths[0], cf_pths[idx] - ) + f"copying files from {cf_pths[0]} to {cf_pths[idx]}\n" ) for f in filelist: if os.path.splitext(f)[1].lower() in exclude: @@ -179,9 +177,7 @@ def cf_model(imod, ion, nmax, k, i, j, Qt, base, hdry): sys.stdout.write(f" model number {imod} working directory: {pth}\n") make_well(pth, k, i, j, Qt) success, elt = run_model(pth) - line = "\nModel run: {} of {} (model number {})\n".format( - ion + 1, nmax, imod - ) + line = f"\nModel run: {ion + 1} of {nmax} (model number {imod})\n" line += f" row {i + 1} - col {j + 1}\n" line += f" {elt}\n" # get the results @@ -211,14 +207,12 @@ def cf_model(imod, ion, nmax, k, i, j, Qt, base, hdry): ] v[idx] = ((v1.sum() + v2.sum() + v3.sum()) - base) / (-Qt) except: - line += " Error: Model run: {} of {} (model number {}) - ".format( - ion + 1, nmax, imod - ) + line += f" Error: Model run: {ion + 1} of {nmax} (model number {imod}) - " line += "could not process model results.\n" v[:] = np.nan else: - line += " Error: Model run: {} of {} (model number {}) ".format( - ion + 1, nmax, imod + line += ( + f" Error: Model run: {ion + 1} of {nmax} (model number {imod}) " ) line += "did not execute successfully\n" v[:] = np.nan @@ -232,15 +226,11 @@ def doit(): ncores = mp.cpu_count() if nproc > ncores: sys.stdout.write( - "Requested {} cores but only {} cores are available.\n\n\n".format( - nproc, ncores - ) + f"Requested {nproc} cores but only {ncores} cores are available.\n\n\n" ) else: sys.stdout.write( - "Requested {} cores and {} cores are available.\n\n\n".format( - nproc, ncores - ) + f"Requested {nproc} cores and {ncores} cores are available.\n\n\n" ) # paths @@ -275,14 +265,10 @@ def doit(): # write some summary information fs.write(f"Problem size: {nrow} rows and {ncol} columns.\n") fs.write( - "Capture fraction analysis performed every {} rows and columns.\n".format( - nstep - ) + f"Capture fraction analysis performed every {nstep} rows and columns.\n" ) fs.write( - "Maximum number of analyses: {} rows and {} columns.\n".format( - nrow2, ncol2 - ) + f"Maximum number of analyses: {nrow2} rows and {ncol2} columns.\n" ) # create array to store capture fraction data (subset of model) @@ -359,9 +345,7 @@ def doit(): f"USPB_capture_fraction_{nstep:02d}_{idx + 1:02d}.dat", ) sys.stdout.write( - "saving capture fraction data to...{}\n".format( - os.path.basename(fn) - ) + f"saving capture fraction data to...{os.path.basename(fn)}\n" ) np.savetxt(fn, cf_array[idx, :, :], delimiter=" ") diff --git a/autotest/conftest.py b/autotest/conftest.py index 13e25a530a..b0d0f54bb3 100644 --- a/autotest/conftest.py +++ b/autotest/conftest.py @@ -2,7 +2,6 @@ from importlib import metadata from pathlib import Path from platform import system -from typing import List import matplotlib.pyplot as plt import pytest @@ -52,7 +51,7 @@ def flopy_data_path() -> Path: @pytest.fixture(scope="session") -def example_shapefiles(example_data_path) -> List[Path]: +def example_shapefiles(example_data_path) -> list[Path]: return [f.resolve() for f in (example_data_path / "prj_test").glob("*")] diff --git a/autotest/test_export.py b/autotest/test_export.py index ce423a214e..4c56f0e091 100644 --- a/autotest/test_export.py +++ b/autotest/test_export.py @@ -2,7 +2,6 @@ import os import shutil from pathlib import Path -from typing import List import matplotlib.pyplot as plt import numpy as np @@ -56,7 +55,7 @@ import pyproj -def namfiles() -> List[Path]: +def namfiles() -> list[Path]: mf2005_path = get_example_data_path() / "mf2005_test" return list(mf2005_path.rglob("*.nam")) @@ -998,9 +997,10 @@ def test_export_mf6_shp(function_tmpdir): # Compare exported riv shapefiles riv.export(function_tmpdir / "riv.shp") riv6.export(function_tmpdir / "riv6.shp") - with Reader(function_tmpdir / "riv.shp") as riv_shp, Reader( - function_tmpdir / "riv6.shp" - ) as riv6_shp: + with ( + Reader(function_tmpdir / "riv.shp") as riv_shp, + Reader(function_tmpdir / "riv6.shp") as riv6_shp, + ): assert list(riv_shp.shapeRecord(-1).record) == list( riv6_shp.shapeRecord(-1).record ) diff --git a/autotest/test_generate_classes.py b/autotest/test_generate_classes.py index 8e5962f412..bd6acde135 100644 --- a/autotest/test_generate_classes.py +++ b/autotest/test_generate_classes.py @@ -1,9 +1,9 @@ import sys +from collections.abc import Iterable from os import environ from pathlib import Path from platform import system from pprint import pprint -from typing import Iterable from warnings import warn import pytest diff --git a/autotest/test_lake_connections.py b/autotest/test_lake_connections.py index 71bab3d002..1632627117 100644 --- a/autotest/test_lake_connections.py +++ b/autotest/test_lake_connections.py @@ -503,8 +503,8 @@ def test_embedded_lak_prudic(example_data_path): nlay = 8 # Number of layers nrow = 36 # Number of rows ncol = 23 # Number of columns - delr = float(405.665) # Column width ($ft$) - delc = float(403.717) # Row width ($ft$) + delr = 405.665 # Column width ($ft$) + delc = 403.717 # Row width ($ft$) delv = 15.0 # Layer thickness ($ft$) top = 100.0 # Top of the model ($ft$) @@ -606,8 +606,8 @@ def test_embedded_lak_prudic_mixed(example_data_path): nlay = 8 # Number of layers nrow = 36 # Number of rows ncol = 23 # Number of columns - delr = float(405.665) # Column width ($ft$) - delc = float(403.717) # Row width ($ft$) + delr = 405.665 # Column width ($ft$) + delc = 403.717 # Row width ($ft$) delv = 15.0 # Layer thickness ($ft$) top = 100.0 # Top of the model ($ft$) diff --git a/autotest/test_mbase.py b/autotest/test_mbase.py index 732b188776..2e8688cb3a 100644 --- a/autotest/test_mbase.py +++ b/autotest/test_mbase.py @@ -66,8 +66,10 @@ def test_resolve_exe_by_rel_path(function_tmpdir, use_ext, forgive): assert which(actual) # check behavior if exe DNE - with pytest.warns(UserWarning) if forgive else pytest.raises( - FileNotFoundError + with ( + pytest.warns(UserWarning) + if forgive + else pytest.raises(FileNotFoundError) ): assert not resolve_exe("../bin/mf2005", forgive) diff --git a/autotest/test_modflow.py b/autotest/test_modflow.py index 5239ce4c66..5cb7b161df 100644 --- a/autotest/test_modflow.py +++ b/autotest/test_modflow.py @@ -3,7 +3,6 @@ import os import shutil from pathlib import Path -from typing import Dict import numpy as np import pandas as pd diff --git a/autotest/test_mp7.py b/autotest/test_mp7.py index edb82c48d6..d3d1b324f1 100644 --- a/autotest/test_mp7.py +++ b/autotest/test_mp7.py @@ -877,7 +877,7 @@ def test_mp7bas_porosity(ex01_mf6_model, porosity_type): # Initialize porosity array based on dim of dis.botm # lay_1=0.35, lay_2=0.30, lay_3=0.25 porosity = np.array([[[0.35]], [[0.30]], [[0.25]]]) * np.ones( - (gwf.dis.botm.array.shape) + gwf.dis.botm.array.shape ) # Diversify porosity values, adjust both halves of the model porosity[:, :, : porosity.shape[2] // 2] -= 0.05 diff --git a/flopy/export/netcdf.py b/flopy/export/netcdf.py index eda44e1172..f93469f4e2 100644 --- a/flopy/export/netcdf.py +++ b/flopy/export/netcdf.py @@ -219,8 +219,8 @@ def __init__( self.log("initializing attributes") self.nc_crs_str = "epsg:4326" self.nc_crs_longname = "https://www.opengis.net/def/crs/EPSG/0/4326" - self.nc_semi_major = float(6378137.0) - self.nc_inverse_flat = float(298.257223563) + self.nc_semi_major = 6378137.0 + self.nc_inverse_flat = 298.257223563 self.global_attributes = {} self.global_attributes["namefile"] = self.model.namefile diff --git a/flopy/export/shapefile_utils.py b/flopy/export/shapefile_utils.py index fef0fd13de..cf976871a3 100644 --- a/flopy/export/shapefile_utils.py +++ b/flopy/export/shapefile_utils.py @@ -10,7 +10,7 @@ import sys import warnings from pathlib import Path -from typing import List, Optional, Union +from typing import Optional, Union from warnings import warn import numpy as np @@ -489,7 +489,7 @@ def shape_attr_name(name, length=6, keep_layer=False): return n -def enforce_10ch_limit(names: List[str], warnings: bool = True) -> List[str]: +def enforce_10ch_limit(names: list[str], warnings: bool = True) -> list[str]: """Enforce 10 character limit for fieldnames. Add suffix for duplicate names starting at 0. diff --git a/flopy/mbase.py b/flopy/mbase.py index 0cf0f727e2..dbd65f5f33 100644 --- a/flopy/mbase.py +++ b/flopy/mbase.py @@ -17,7 +17,7 @@ from pathlib import Path from shutil import which from subprocess import PIPE, STDOUT, Popen -from typing import List, Optional, Tuple, Union +from typing import Optional, Union from warnings import warn import numpy as np @@ -1395,7 +1395,7 @@ def run_model( pause=False, report=False, normal_msg="normal termination", - ) -> Tuple[bool, List[str]]: + ) -> tuple[bool, list[str]]: """ This method will run the model using subprocess.Popen. @@ -1667,7 +1667,7 @@ def run_model( use_async=False, cargs=None, custom_print=None, -) -> Tuple[bool, List[str]]: +) -> tuple[bool, list[str]]: """ Run the model using subprocess.Popen, optionally collecting stdout and printing timestamped progress. Model workspace, namefile, executable to use, and several diff --git a/flopy/mf6/mfpackage.py b/flopy/mf6/mfpackage.py index 5bb69ec179..c9eb52a881 100644 --- a/flopy/mf6/mfpackage.py +++ b/flopy/mf6/mfpackage.py @@ -259,7 +259,7 @@ def write_header(self, fd): if len(self.data_items) > 1: for data_item in self.data_items[1:]: entry = data_item.get_file_entry(values_only=True) - fd.write("%s" % (entry.rstrip())) + fd.write(str(entry).rstrip()) if self.get_comment().text: fd.write(" ") self.get_comment().write(fd) diff --git a/flopy/mf6/mfsimbase.py b/flopy/mf6/mfsimbase.py index 6e1a960f8e..74dc8d036a 100644 --- a/flopy/mf6/mfsimbase.py +++ b/flopy/mf6/mfsimbase.py @@ -4,7 +4,7 @@ import sys import warnings from pathlib import Path -from typing import List, Optional, Union, cast +from typing import Optional, Union, cast import numpy as np @@ -1255,12 +1255,12 @@ def load_package( return package def register_ims_package( - self, solution_file: MFPackage, model_list: Union[str, List[str]] + self, solution_file: MFPackage, model_list: Union[str, list[str]] ): self.register_solution_package(solution_file, model_list) def register_solution_package( - self, solution_file: MFPackage, model_list: Union[str, List[str]] + self, solution_file: MFPackage, model_list: Union[str, list[str]] ): """ Register a solution package with the simulation. @@ -2642,7 +2642,7 @@ def _is_in_solution_group(self, item, index, any_idx_after=False): def plot( self, - model_list: Optional[Union[str, List[str]]] = None, + model_list: Optional[Union[str, list[str]]] = None, SelPackList=None, **kwargs, ): diff --git a/flopy/mf6/utils/model_splitter.py b/flopy/mf6/utils/model_splitter.py index e73a5cede0..a4db88e75f 100644 --- a/flopy/mf6/utils/model_splitter.py +++ b/flopy/mf6/utils/model_splitter.py @@ -117,7 +117,7 @@ } -class Mf6Splitter(object): +class Mf6Splitter: """ A class for splitting a single model into a multi-model simulation @@ -2493,7 +2493,7 @@ def _remap_obs(self, package, mapped_data, remapper, pkg_type=None): for mkey, model in self._model_dict.items(): idx = np.asarray(new_model2 == mkey).nonzero() tmp_node = new_node2[idx] - cidx = np.asarray((tmp_node != None)).nonzero() # noqa: E711 + cidx = np.asarray(tmp_node != None).nonzero() # noqa: E711 tmp_cellid = model.modelgrid.get_lrc( tmp_node[cidx].to_list() ) diff --git a/flopy/mfusg/mfusgdisu.py b/flopy/mfusg/mfusgdisu.py index 4f6459ce1b..2d3a4fb979 100644 --- a/flopy/mfusg/mfusgdisu.py +++ b/flopy/mfusg/mfusgdisu.py @@ -546,8 +546,8 @@ def load(cls, f, model, ext_unit_dict=None, check=True): if model.version != "mfusg": print( - "Warning: model version was reset from '{}' to 'mfusg' " - "in order to load a DISU file".format(model.version) + f"Warning: model version was reset from '{model.version}' " + "to 'mfusg' in order to load a DISU file" ) model.version = "mfusg" diff --git a/flopy/mfusg/mfusgsms.py b/flopy/mfusg/mfusgsms.py index 865e9d5f4c..f356292205 100644 --- a/flopy/mfusg/mfusgsms.py +++ b/flopy/mfusg/mfusgsms.py @@ -434,8 +434,8 @@ def load(cls, f, model, ext_unit_dict=None): if model.version != "mfusg": print( - "Warning: model version was reset from '{}' to 'mfusg' " - "in order to load a SMS file".format(model.version) + f"Warning: model version was reset from '{model.version}' " + "to 'mfusg' in order to load a SMS file" ) model.version = "mfusg" diff --git a/flopy/modflow/mfmnw1.py b/flopy/modflow/mfmnw1.py index d18c883b85..2f3fa75d52 100644 --- a/flopy/modflow/mfmnw1.py +++ b/flopy/modflow/mfmnw1.py @@ -139,10 +139,9 @@ def __init__( # -input format checks: lossTypes = ["skin", "linear", "nonlinear"] - assert self.losstype.lower() in lossTypes, ( - "LOSSTYPE (%s) must be one of the following: skin, linear, nonlinear" - % (self.losstype) - ) + assert ( + self.losstype.lower() in lossTypes + ), f"LOSSTYPE ({self.losstype}) must be one of the following: {lossTypes}" self.parent.add_package(self) @staticmethod @@ -272,7 +271,7 @@ def write_file(self): f = open(self.fn_path, "w") # -write header - f.write("%s\n" % self.heading) + f.write(f"{self.heading}\n") # -Section 1 - MXMNW ipakcb IWELPT NOMOITER REF:kspref f.write( @@ -287,7 +286,7 @@ def write_file(self): ) # -Section 2 - LOSSTYPE {PLossMNW} - f.write("%s\n" % (self.losstype)) + f.write(f"{self.losstype}\n") if self.wel1_bynode_qsum is not None: # -Section 3a - {FILE:filename WEL1:iunw1} @@ -327,7 +326,7 @@ def write_file(self): # -Un-numbered section PREFIX:MNWNAME if self.mnwname: - f.write("PREFIX:%s\n" % (self.mnwname)) + f.write(f"PREFIX:{self.mnwname}\n") f.close() diff --git a/flopy/modflow/mfpbc.py b/flopy/modflow/mfpbc.py index 9239d13858..9853c55ff6 100644 --- a/flopy/modflow/mfpbc.py +++ b/flopy/modflow/mfpbc.py @@ -75,7 +75,7 @@ def write_file(self): """ f_pbc = open(self.fn_path, "w") - f_pbc.write("%s\n" % self.heading) + f_pbc.write(f"{self.heading}\n") f_pbc.write("%10i%10i\n" % (self.mxactp, self.mxcos)) for n in range(self.parent.get_package("DIS").nper): if n < len(self.layer_row_column_data): diff --git a/flopy/modflow/mfrch.py b/flopy/modflow/mfrch.py index a9a22e394f..915619965c 100644 --- a/flopy/modflow/mfrch.py +++ b/flopy/modflow/mfrch.py @@ -241,7 +241,7 @@ def check( if len(lessthan) > 0: txt = ( "\r Mean R/T ratio < checker warning threshold of " - "{} for {} stress periods".format(RTmin, len(lessthan)) + f"{RTmin} for {len(lessthan)} stress periods" ) chk._add_to_summary( type="Warning", value=R_T.min(), desc=txt @@ -253,8 +253,8 @@ def check( if len(greaterthan) > 0: txt = ( "\r Mean R/T ratio > checker warning " - "threshold of {} for " - "{} stress periods".format(RTmax, len(greaterthan)) + f"threshold of {RTmax} for " + f"{len(greaterthan)} stress periods" ) chk._add_to_summary( type="Warning", value=R_T.max(), desc=txt diff --git a/flopy/modflow/mfsfr2.py b/flopy/modflow/mfsfr2.py index 62112fb51a..9d5336e816 100644 --- a/flopy/modflow/mfsfr2.py +++ b/flopy/modflow/mfsfr2.py @@ -3168,9 +3168,9 @@ def _fmt_string_list(array, float_format="{!s}"): float_format = "{!s}" elif vtype == "s": raise ValueError( - "'str' type found in dtype for {!r}. " + f"'str' type found in dtype for {name!r}. " "This gives unpredictable results when " - "recarray to file - change to 'object' type".format(name) + "recarray to file - change to 'object' type" ) else: raise ValueError(f"unknown dtype for {name!r}: {vtype!r}") diff --git a/flopy/modflow/mfstr.py b/flopy/modflow/mfstr.py index 572efa7e11..00c9ad1c3f 100644 --- a/flopy/modflow/mfstr.py +++ b/flopy/modflow/mfstr.py @@ -283,7 +283,7 @@ def __init__( if ntrib > 10: raise Exception( "ModflowStr error: ntrib must be less that 10: " - "specified value = {}".format(ntrib) + f"specified value = {ntrib}" ) if options is None: @@ -366,8 +366,8 @@ def __init__( d = d.to_records(index=False) if isinstance(d, np.recarray): e = ( - "ModflowStr error: recarray dtype: {} does not match " - "self dtype: {}".format(d.dtype, self.dtype) + f"ModflowStr error: recarray dtype: {d.dtype} " + f"does not match self dtype: {self.dtype}" ) assert d.dtype == self.dtype, e elif isinstance(d, np.ndarray): @@ -384,7 +384,7 @@ def __init__( else: raise Exception( "ModflowStr error: unsupported data type: " - "{} at kper {}".format(type(d), key) + f"{type(d)} at kper {key}" ) # add stress_period_data to package @@ -397,8 +397,8 @@ def __init__( d = np.array(d) if isinstance(d, np.recarray): e = ( - "ModflowStr error: recarray dtype: {} does not match " - "self dtype: {}".format(d.dtype, self.dtype2) + f"ModflowStr error: recarray dtype: {d.dtype} " + f"does not match self dtype: {self.dtype2}" ) assert d.dtype == self.dtype2, e elif isinstance(d, np.ndarray): @@ -417,7 +417,7 @@ def __init__( else: raise Exception( "ModflowStr error: unsupported data type: " - "{} at kper {}".format(type(d), key) + f"{type(d)} at kper {key}" ) # add segment_data to package diff --git a/flopy/modflow/mfswi2.py b/flopy/modflow/mfswi2.py index bc783208da..c5e6fb9b02 100644 --- a/flopy/modflow/mfswi2.py +++ b/flopy/modflow/mfswi2.py @@ -271,7 +271,7 @@ def __init__( if len(obsnam) != nobs: raise Exception( "ModflowSwi2: obsnam must be a list with a " - "length of {} not {}.".format(nobs, len(obsnam)) + f"length of {nobs} not {len(obsnam)}." ) if nobs > 0: diff --git a/flopy/modflow/mfupw.py b/flopy/modflow/mfupw.py index 35da223f3b..3d6b311709 100644 --- a/flopy/modflow/mfupw.py +++ b/flopy/modflow/mfupw.py @@ -363,8 +363,8 @@ def load(cls, f, model, ext_unit_dict=None, check=True): if model.version != "mfnwt": print( - "Warning: model version was reset from '{}' to 'mfnwt' " - "in order to load a UPW file".format(model.version) + f"Warning: model version was reset from '{model.version}' " + "to 'mfnwt' in order to load a UPW file" ) model.version = "mfnwt" diff --git a/flopy/modpath/mp7.py b/flopy/modpath/mp7.py index 6eea1cf99f..d2ad195940 100644 --- a/flopy/modpath/mp7.py +++ b/flopy/modpath/mp7.py @@ -110,7 +110,7 @@ def __init__( raise TypeError( "Modpath7: flow model is not an instance of " "flopy.modflow.Modflow or flopy.mf6.MFModel. " - "Passed object of type {}".format(type(flowmodel)) + f"Passed object of type {type(flowmodel)}" ) # if a MFModel instance ensure flowmodel is a MODFLOW 6 GWF model @@ -121,7 +121,7 @@ def __init__( ): raise TypeError( "Modpath7: flow model type must be gwf. " - "Passed model_type is {}.".format(flowmodel.model_type) + f"Passed model_type is {flowmodel.model_type}." ) # set flowmodel and flow_version attributes diff --git a/flopy/modpath/mp7bas.py b/flopy/modpath/mp7bas.py index 8126499d36..155bb977c8 100644 --- a/flopy/modpath/mp7bas.py +++ b/flopy/modpath/mp7bas.py @@ -96,8 +96,8 @@ def __init__( # check iface value if value < 0 or value > 6: raise ValueError( - "defaultiface for package {} must be between 0 and 1 " - "({} specified)".format(key, value) + f"defaultiface for package {key} must be between 0 and 1 " + f"({value} specified)" ) self.defaultifacecount = defaultifacecount diff --git a/flopy/modpath/mp7particledata.py b/flopy/modpath/mp7particledata.py index 472ff19151..26fad032d1 100644 --- a/flopy/modpath/mp7particledata.py +++ b/flopy/modpath/mp7particledata.py @@ -6,8 +6,8 @@ """ from collections import namedtuple +from collections.abc import Iterator from itertools import product -from typing import Iterator, Tuple import numpy as np import pandas as pd @@ -410,7 +410,7 @@ def cvt_z(p, k, i, j): span = mx - mn return mn + span * p - def convert(row) -> Tuple[float, float, float]: + def convert(row) -> tuple[float, float, float]: verts = grid.get_cell_vertices(row.i, row.j) xs, ys = list(zip(*verts)) return [ @@ -436,7 +436,7 @@ def cvt_z(p, nn): span = mx - mn return mn + span * p - def convert(row) -> Tuple[float, float, float]: + def convert(row) -> tuple[float, float, float]: verts = grid.get_cell_vertices(row.node) xs, ys = list(zip(*verts)) return [ diff --git a/flopy/mt3d/mtdsp.py b/flopy/mt3d/mtdsp.py index c7811c0133..84442e0b94 100644 --- a/flopy/mt3d/mtdsp.py +++ b/flopy/mt3d/mtdsp.py @@ -209,8 +209,8 @@ def __init__( val = kwargs.pop(name) else: print( - "DSP: setting dmcoef for component {} " - "to zero, kwarg name {}".format(icomp, name) + f"DSP: setting dmcoef for component {icomp} " + f"to zero, kwarg name {name}" ) u2or3 = utype( model, diff --git a/flopy/mt3d/mtrct.py b/flopy/mt3d/mtrct.py index 5ae9b35763..93cbf317c9 100644 --- a/flopy/mt3d/mtrct.py +++ b/flopy/mt3d/mtrct.py @@ -284,8 +284,8 @@ def __init__( val = kwargs.pop(name) else: print( - "RCT: setting sp1 for component {} to zero, " - "kwarg name {}".format(icomp, name) + f"RCT: setting sp1 for component {icomp} to zero, " + f"kwarg name {name}" ) u3d = Util3d( model, @@ -320,8 +320,8 @@ def __init__( val = kwargs.pop(name) else: print( - "RCT: setting sp2 for component {} to zero, " - "kwarg name {}".format(icomp, name) + f"RCT: setting sp2 for component {icomp} to zero, " + f"kwarg name {name}" ) u3d = Util3d( model, @@ -356,8 +356,8 @@ def __init__( val = kwargs.pop(name) else: print( - "RCT: setting rc1 for component {} to zero, " - "kwarg name {}".format(icomp, name) + f"RCT: setting rc1 for component {icomp} to zero, " + f"kwarg name {name}" ) u3d = Util3d( model, @@ -392,8 +392,8 @@ def __init__( val = kwargs.pop(name) else: print( - "RCT: setting rc2 for component {} to zero, " - "kwarg name {}".format(icomp, name) + f"RCT: setting rc2 for component {icomp} to zero, " + f"kwarg name {name}" ) u3d = Util3d( model, diff --git a/flopy/pest/templatewriter.py b/flopy/pest/templatewriter.py index ad0eb12534..a0a6fcf20b 100644 --- a/flopy/pest/templatewriter.py +++ b/flopy/pest/templatewriter.py @@ -46,8 +46,8 @@ def write_template(self): # Check to make sure pak has p.type as an attribute if not hasattr(pak, p.type.lower()): msg = ( - "Parameter named {} of type {} not found in " - "package {}".format(p.name, p.type.lower(), ftype) + f"Parameter named {p.name} of type {p.type.lower()} " + f"not found in package {ftype}" ) raise Exception(msg) diff --git a/flopy/utils/binaryfile.py b/flopy/utils/binaryfile.py index ce95d500f8..a729308ea1 100644 --- a/flopy/utils/binaryfile.py +++ b/flopy/utils/binaryfile.py @@ -14,7 +14,7 @@ import warnings from pathlib import Path from shutil import move -from typing import List, Optional, Union +from typing import Optional, Union import numpy as np import pandas as pd @@ -1675,7 +1675,7 @@ def get_data( paknam=None, paknam2=None, full3D=False, - ) -> Union[List, np.ndarray]: + ) -> Union[list, np.ndarray]: """ Get data from the binary budget file. diff --git a/flopy/utils/compare.py b/flopy/utils/compare.py index 2e5f3fd6b9..a69538a430 100644 --- a/flopy/utils/compare.py +++ b/flopy/utils/compare.py @@ -1,6 +1,6 @@ import os import textwrap -from typing import List, Optional, Union +from typing import Optional, Union import numpy as np @@ -85,10 +85,10 @@ def compare_budget( max_incpd=0.01, outfile: Optional[Union[str, os.PathLike]] = None, files1: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, files2: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, ): """Compare the budget results from two simulations. @@ -292,10 +292,10 @@ def compare_swrbudget( max_incpd=0.01, outfile: Optional[Union[str, os.PathLike]] = None, files1: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, files2: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, ): """Compare the SWR budget results from two simulations. @@ -493,10 +493,10 @@ def compare_heads( htol=0.001, outfile: Optional[Union[str, os.PathLike]] = None, files1: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, files2: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, difftol=False, verbose=False, @@ -884,10 +884,10 @@ def compare_concentrations( ctol=0.001, outfile: Optional[Union[str, os.PathLike]] = None, files1: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, files2: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, difftol=False, verbose=False, @@ -1115,10 +1115,10 @@ def compare_stages( namefile1: Union[str, os.PathLike] = None, namefile2: Union[str, os.PathLike] = None, files1: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, files2: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, htol=0.001, outfile: Optional[Union[str, os.PathLike]] = None, @@ -1337,10 +1337,10 @@ def compare( outfile1: Optional[Union[str, os.PathLike]] = None, outfile2: Optional[Union[str, os.PathLike]] = None, files1: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, files2: Optional[ - Union[str, os.PathLike, List[Union[str, os.PathLike]]] + Union[str, os.PathLike, list[Union[str, os.PathLike]]] ] = None, ): """Compare the budget and head results for two MODFLOW-based model diff --git a/flopy/utils/geometry.py b/flopy/utils/geometry.py index 5a103760c4..f99d8de9ad 100644 --- a/flopy/utils/geometry.py +++ b/flopy/utils/geometry.py @@ -57,7 +57,7 @@ def __init__( else: err = ( "Supported shape types are Polygon, LineString, " - "and Point: Supplied shape type {}".format(shapetype) + f"and Point: Supplied shape type {shapetype}" ) raise TypeError(err) diff --git a/flopy/utils/gridgen.py b/flopy/utils/gridgen.py index 437f3a0be5..4b7b15a913 100644 --- a/flopy/utils/gridgen.py +++ b/flopy/utils/gridgen.py @@ -2,7 +2,7 @@ import subprocess import warnings from pathlib import Path -from typing import List, Union +from typing import Union import numpy as np @@ -1979,7 +1979,7 @@ def read_qtg_nodesperlay_dat(model_ws: Union[str, os.PathLike], nlay: int): @staticmethod def read_quadtreegrid_top_dat( - model_ws: Union[str, os.PathLike], nodelay: List[int], lay: int + model_ws: Union[str, os.PathLike], nodelay: list[int], lay: int ): """Read quadtreegrid.top_.dat file @@ -2002,7 +2002,7 @@ def read_quadtreegrid_top_dat( @staticmethod def read_quadtreegrid_bot_dat( - model_ws: Union[str, os.PathLike], nodelay: List[int], lay: int + model_ws: Union[str, os.PathLike], nodelay: list[int], lay: int ): """Read quadtreegrid.bot_.dat file diff --git a/flopy/utils/gridutil.py b/flopy/utils/gridutil.py index 4c1366aa4d..f3387c72da 100644 --- a/flopy/utils/gridutil.py +++ b/flopy/utils/gridutil.py @@ -2,15 +2,15 @@ Grid utilities """ +from collections.abc import Collection, Iterable, Sequence from math import floor -from typing import Collection, Iterable, List, Sequence, Tuple, Union import numpy as np from .cvfdutil import centroid_of_polygon, get_disv_gridprops -def get_lni(ncpl, nodes) -> List[Tuple[int, int]]: +def get_lni(ncpl, nodes) -> list[tuple[int, int]]: """ Get layer index and within-layer node index (both 0-based). @@ -292,7 +292,7 @@ def get_disv_kwargs( # botm check if np.isscalar(botm): botm = botm * np.ones((nlay, nrow, ncol), dtype=float) - elif isinstance(botm, List): + elif isinstance(botm, list): assert ( len(botm) == nlay ), "if botm provided as a list it must have length nlay" diff --git a/flopy/utils/mflistfile.py b/flopy/utils/mflistfile.py index 33f13b77f4..ced237728a 100644 --- a/flopy/utils/mflistfile.py +++ b/flopy/utils/mflistfile.py @@ -773,7 +773,7 @@ def _get_sp(self, ts, sp, seekpoint): if line == "": print( "end of file found while seeking budget " - "information for ts,sp: {} {}".format(ts, sp) + f"information for ts,sp: {ts} {sp}" ) return self.null_entries @@ -789,7 +789,7 @@ def _get_sp(self, ts, sp, seekpoint): if line == "": print( "end of file found while seeking budget " - "information for ts,sp: {} {}".format(ts, sp) + f"information for ts,sp: {ts} {sp}" ) return self.null_entries if len(re.findall("=", line)) == 2: @@ -880,7 +880,7 @@ def _get_totim(self, ts, sp, seekpoint): if line == "": print( "end of file found while seeking budget " - "information for ts,sp: {} {}".format(ts, sp) + f"information for ts,sp: {ts} {sp}" ) return np.nan, np.nan, np.nan elif ( diff --git a/flopy/utils/mfreadnam.py b/flopy/utils/mfreadnam.py index ba833b842d..07625936cd 100644 --- a/flopy/utils/mfreadnam.py +++ b/flopy/utils/mfreadnam.py @@ -11,7 +11,7 @@ import os from os import PathLike from pathlib import Path, PurePosixPath, PureWindowsPath -from typing import List, Tuple, Union +from typing import Union class NamData: @@ -298,7 +298,7 @@ def get_entries_from_namefile( ftype: str = None, unit: int = None, extension: str = None, -) -> List[Tuple]: +) -> list[tuple]: """Get entries from an MF6 namefile. Can select using FTYPE, UNIT, or file extension. This function only supports MF6 namefiles. diff --git a/flopy/utils/modpathfile.py b/flopy/utils/modpathfile.py index 5bc3e20609..695b9b83c4 100644 --- a/flopy/utils/modpathfile.py +++ b/flopy/utils/modpathfile.py @@ -4,7 +4,7 @@ import itertools import os -from typing import List, Optional, Tuple, Union +from typing import Optional, Union import numpy as np from numpy.lib.recfunctions import append_fields, repack_fields @@ -33,7 +33,7 @@ def __init__( @staticmethod def parse( file_path: Union[str, os.PathLike], file_type: str - ) -> Tuple[bool, int, int, Optional[int]]: + ) -> tuple[bool, int, int, Optional[int]]: """ Extract preliminary information from a MODPATH output file: - whether in compact format @@ -97,7 +97,7 @@ def parse( def intersect( self, cells, to_recarray - ) -> Union[List[np.recarray], np.recarray]: + ) -> Union[list[np.recarray], np.recarray]: if self.version < 7: try: raslice = self._data[["k", "i", "j"]] @@ -239,7 +239,7 @@ def __init__( self.dtype, self._data = self._load() self.nid = np.unique(self._data["particleid"]) - def _load(self) -> Tuple[np.dtype, np.ndarray]: + def _load(self) -> tuple[np.dtype, np.ndarray]: dtype = self.dtypes[self.version] if self.version == 7: dtyper = np.dtype( @@ -563,7 +563,7 @@ def __init__( self.dtype, self._data = self._load() self.nid = np.unique(self._data["particleid"]) - def _load(self) -> Tuple[np.dtype, np.ndarray]: + def _load(self) -> tuple[np.dtype, np.ndarray]: dtype = self.dtypes[self.version] data = loadtxt(self.fname, dtype=dtype, skiprows=self.skiprows) @@ -873,7 +873,7 @@ def __init__(self, filename, verbose=False): self.dtype, self._data = self._load() self.nid = np.unique(self._data["particleid"]) - def _load(self) -> Tuple[np.dtype, np.ndarray]: + def _load(self) -> tuple[np.dtype, np.ndarray]: dtype = self.dtypes[self.version] if self.version in [3, 5] and not self.compact: dtype = np.dtype( diff --git a/flopy/utils/parse_version.py b/flopy/utils/parse_version.py index cd07d4a3ec..8b4cdae897 100644 --- a/flopy/utils/parse_version.py +++ b/flopy/utils/parse_version.py @@ -12,7 +12,8 @@ import itertools import re import warnings -from typing import Callable, Iterator, SupportsInt, Tuple, Union +from collections.abc import Iterator +from typing import Callable, SupportsInt, Union __all__ = [ "parse", @@ -88,28 +89,28 @@ def __neg__(self: object) -> InfinityType: InfiniteTypes = Union[InfinityType, NegativeInfinityType] -PrePostDevType = Union[InfiniteTypes, Tuple[str, int]] +PrePostDevType = Union[InfiniteTypes, tuple[str, int]] SubLocalType = Union[InfiniteTypes, int, str] LocalType = Union[ NegativeInfinityType, - Tuple[ + tuple[ Union[ SubLocalType, - Tuple[SubLocalType, str], - Tuple[NegativeInfinityType, SubLocalType], + tuple[SubLocalType, str], + tuple[NegativeInfinityType, SubLocalType], ], ..., ], ] -CmpKey = Tuple[ +CmpKey = tuple[ int, - Tuple[int, ...], + tuple[int, ...], PrePostDevType, PrePostDevType, PrePostDevType, LocalType, ] -LegacyCmpKey = Tuple[int, Tuple[str, ...]] +LegacyCmpKey = tuple[int, tuple[str, ...]] VersionComparisonMethod = Callable[ [Union[CmpKey, LegacyCmpKey], Union[CmpKey, LegacyCmpKey]], bool ] diff --git a/flopy/utils/voronoi.py b/flopy/utils/voronoi.py index d3f52566ae..db3d5fd26e 100644 --- a/flopy/utils/voronoi.py +++ b/flopy/utils/voronoi.py @@ -1,5 +1,5 @@ +from collections.abc import Iterator from math import sqrt -from typing import Iterator, Tuple import numpy as np @@ -10,7 +10,7 @@ def get_sorted_vertices( icell_vertices, vertices, verbose=False -) -> Iterator[Tuple[float, int]]: +) -> Iterator[tuple[float, int]]: centroid = vertices[icell_vertices].mean(axis=0) tlist = [] for i, iv in enumerate(icell_vertices): diff --git a/pyproject.toml b/pyproject.toml index 76dab29998..a128be2ab4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -117,7 +117,6 @@ include = ["flopy", "flopy.*"] [tool.ruff] line-length = 79 -target-version = "py38" include = [ "pyproject.toml", "flopy/**/*.py", @@ -150,4 +149,4 @@ ignore = [ "F811", # Redefinition of unused variable "F821", # undefined name TODO FIXME "F841", # local variable assigned but never used -] \ No newline at end of file +]