Skip to content

Commit

Permalink
refactor: apply Ruff-specific rule checks (#2377)
Browse files Browse the repository at this point in the history
Apply Ruff-specific rule (RUF) checks 

* RUF002, RUFF003: ambiguous Unicode character
* RUF013: implicit optional
* RUF100: unused noqa
* RUF015: unnecessary iterable allocation for first element, i.e. use next()
  • Loading branch information
mwtoews authored Nov 22, 2024
1 parent 1993af1 commit 4c1bf6c
Show file tree
Hide file tree
Showing 23 changed files with 46 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .docs/Notebooks/groundwater_paper_example_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# ## Basic Flopy example
#
# From:
# Bakker, Mark, Post, Vincent, Langevin, C. D., Hughes, J. D., White, J. T., Starn, J. J. and Fienen, M. N., 2016, Scripting MODFLOW Model Development Using Python and FloPy: Groundwater, v. 54, p. 733739, https://doi.org/10.1111/gwat.12413.
# Bakker, Mark, Post, Vincent, Langevin, C. D., Hughes, J. D., White, J. T., Starn, J. J. and Fienen, M. N., 2016, Scripting MODFLOW Model Development Using Python and FloPy: Groundwater, v. 54, p. 733-739, https://doi.org/10.1111/gwat.12413.

# Import the `modflow` and `utils` subpackages of FloPy and give them the aliases `fpm` and `fpu`, respectively

Expand Down
2 changes: 1 addition & 1 deletion .docs/Notebooks/groundwater_paper_uspb_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# # Capture fraction example
#
# From:
# Bakker, Mark, Post, Vincent, Langevin, C. D., Hughes, J. D., White, J. T., Starn, J. J. and Fienen, M. N., 2016, Scripting MODFLOW Model Development Using Python and FloPy: Groundwater, v. 54, p. 733739, https://doi.org/10.1111/gwat.12413.
# Bakker, Mark, Post, Vincent, Langevin, C. D., Hughes, J. D., White, J. T., Starn, J. J. and Fienen, M. N., 2016, Scripting MODFLOW Model Development Using Python and FloPy: Groundwater, v. 54, p. 733-739, https://doi.org/10.1111/gwat.12413.

# +
import os
Expand Down
2 changes: 1 addition & 1 deletion .docs/Notebooks/mfusg_zaidel_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#
# One of the most challenging numerical cases for MODFLOW arises from drying-rewetting problems often associated with abrupt changes in the elevations of impervious base of a thin unconfined aquifer. This problem simulates a discontinuous water table configuration over a stairway impervious base and flow between constant-head boundaries in column 1 and 200. This problem is based on
#
# [Zaidel, J. (2013), Discontinuous Steady-State Analytical Solutions of the Boussinesq Equation and Their Numerical Representation by Modflow. Groundwater, 51: 952959. doi: 10.1111/gwat.12019](https://doi.org/10.1111/gwat.12019)
# [Zaidel, J. (2013), Discontinuous Steady-State Analytical Solutions of the Boussinesq Equation and Their Numerical Representation by Modflow. Groundwater, 51: 952-959. doi: 10.1111/gwat.12019](https://doi.org/10.1111/gwat.12019)
#
# The model consistes of a grid of 200 columns, 1 row, and 1 layer; a bottom altitude of ranging from 20 to 0 m; constant heads of 23 and 5 m in column 1 and 200, respectively; and a horizontal hydraulic conductivity of $1x10^{-4}$ m/d. The discretization is 5 m in the row direction for all cells.
#
Expand Down
2 changes: 1 addition & 1 deletion .docs/Notebooks/mt3dms_sft_lkt_uzt_tutorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@
nlakes = int(np.max(LakArr))
ipakcb = ipakcb # From above
theta = -1.0 # Implicit
nssitr = 10 # Maximum number of iterations for Newtons method
nssitr = 10 # Maximum number of iterations for Newton's method
sscncr = 1.000e-03 # Convergence criterion for equilibrium lake stage solution
surfdep = 2.000e00 # Height of small topological variations in lake-bottom
stages = 268.00 # Initial stage of each lake at the beginning of the run
Expand Down
2 changes: 1 addition & 1 deletion .docs/Notebooks/uzf_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

# # Unsaturated Zone Flow (UZF) Package demo
# Demonstrates functionality of the flopy UZF module using the example from [Niswonger and others (2006)](https://pubs.usgs.gov/tm/2006/tm6a19/). This is the same as the SFR example problem from Prudic and others (2004;
# p. 1319), except the UZF package replaces the ET and RCH packages.
# p. 13-19), except the UZF package replaces the ET and RCH packages.
#
# #### Problem description:
#
Expand Down
2 changes: 1 addition & 1 deletion .docs/create_rstfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def create_examples_rst():
"mt3d": {"title": "MT3D and SEAWAT examples", "files": []},
"2016gw-paper": {
"title": "Examples from Bakker and others (2016)",
"description": "Bakker, Mark, Post, Vincent, Langevin, C. D., Hughes, J. D., White, J. T., Starn, J. J. and Fienen, M. N., 2016, Scripting MODFLOW Model Development Using Python and FloPy: Groundwater, v. 54, p. 733–739, https://doi.org/10.1111/gwat.12413.",
"description": "Bakker, Mark, Post, Vincent, Langevin, C. D., Hughes, J. D., White, J. T., Starn, J. J. and Fienen, M. N., 2016, Scripting MODFLOW Model Development Using Python and FloPy: Groundwater, v. 54, p. 733–739, https://doi.org/10.1111/gwat.12413.", # noqa: RUF001
"files": [],
},
"2023gw-paper": {
Expand Down
2 changes: 1 addition & 1 deletion autotest/test_cbc_full3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def test_cbc_full3D_mf6(function_tmpdir, path):
sim.run_simulation()

# get the groundwater model and determine the size of the model grid
gwf_name = list(sim.model_names)[0]
gwf_name = next(iter(sim.model_names))
gwf = sim.get_model(gwf_name)
nnodes, shape3d = gwf.modelgrid.nnodes, gwf.modelgrid.shape

Expand Down
2 changes: 1 addition & 1 deletion autotest/test_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ def test_structured_xyz_intersect(example_data_path):

def test_vertex_xyz_intersect(example_data_path):
sim = MFSimulation.load(sim_ws=example_data_path / "mf6" / "test003_gwfs_disv")
ml = sim.get_model(list(sim.model_names)[0])
ml = sim.get_model(next(iter(sim.model_names)))
mg = ml.modelgrid

assert mg.size == np.prod((mg.nlay, mg.ncpl))
Expand Down
2 changes: 1 addition & 1 deletion autotest/test_zonbud_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ def test_zonebudget_6(function_tmpdir, example_data_path):

df = zb.get_dataframes()

assert list(df)[0] == "test_alias", "Alias testing failed"
assert next(iter(df)) == "test_alias", "Alias testing failed"


@pytest.mark.mf6
Expand Down
12 changes: 6 additions & 6 deletions flopy/export/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ def __init__(self, sciencebase_id, model):
self.creator_institution
) # also in CF convention for global attributes
self.project = self.sb["title"]
self.publisher_name = [
self.publisher_name = next(
d.get("name")
for d in self.sb["contacts"]
if "publisher" in d.get("type").lower()
][0]
)
self.publisher_email = self.sb["provenance"]["linkProcess"].get("processedBy")
# TODO: should publisher_url be obtained from linkReference?
# publisher_url = self.sb['provenance']['linkProcess'].get('linkReference')
Expand All @@ -106,7 +106,7 @@ def __init__(self, sciencebase_id, model):

def _get_xml_attribute(self, attr):
try:
return list(self.xmlroot.iter(attr))[0].text
return next(iter(self.xmlroot.iter(attr))).text
except:
return None

Expand All @@ -116,9 +116,9 @@ def bounds(self):

@property
def creator(self):
return [
return next(
d for d in self.sb["contacts"] if "point of contact" in d["type"].lower()
][0]
)

@property
def creator_url(self):
Expand Down Expand Up @@ -181,7 +181,7 @@ def time_coverage(self):
l = self.sb["dates"]
tc = {}
for t in ["start", "end"]:
tc[t] = [d.get("dateString") for d in l if t in d["type"].lower()][0]
tc[t] = next(d.get("dateString") for d in l if t in d["type"].lower())
if not np.all(self.model_time.steady_state) and pd is not None:
# replace with times from model reference
tc["start"] = self.model_time.start_datetime
Expand Down
4 changes: 2 additions & 2 deletions flopy/export/vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ def add_transient_array(self, d, name=None, masked_values=None):
if not self._vtk_geometry_set:
self._set_vtk_grid_geometry()

k = list(d.keys())[0]
k = next(iter(d.keys()))
transient = {}
if isinstance(d[k], DataInterface):
if d[k].data_type in (DataType.array2d, DataType.array3d):
Expand Down Expand Up @@ -937,7 +937,7 @@ def add_transient_vector(self, d, name, masked_values=None):
self._set_vtk_grid_geometry()

if self.__transient_data:
k = list(self.__transient_data.keys())[0]
k = next(iter(self.__transient_data.keys()))
if len(d) != len(self.__transient_data[k]):
print(
"Transient vector not same size as transient arrays time "
Expand Down
4 changes: 2 additions & 2 deletions flopy/mbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -1554,9 +1554,9 @@ def check(
if p.unit_number[i] != 0:
if p.unit_number[i] in package_units.values():
duplicate_units[p.name[i]] = p.unit_number[i]
otherpackage = [
otherpackage = next(
k for k, v in package_units.items() if v == p.unit_number[i]
][0]
)
duplicate_units[otherpackage] = p.unit_number[i]
if len(duplicate_units) > 0:
for k, v in duplicate_units.items():
Expand Down
2 changes: 1 addition & 1 deletion flopy/mfusg/mfusgcln.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
Process for MODFLOW-USG, GSI Environmental, March, 2021
Panday, Sorab, Langevin, C.D., Niswonger, R.G., Ibaraki, Motomu, and Hughes,
J.D., 2013, MODFLOWUSG version 1: An unstructured grid version of MODFLOW
J.D., 2013, MODFLOW-USG version 1: An unstructured grid version of MODFLOW
for simulating groundwater flow and tightly coupled processes using a control
volume finite-difference formulation: U.S. Geological Survey Techniques and
Methods, book 6, chap. A45, 66 p.
Expand Down
4 changes: 2 additions & 2 deletions flopy/modflow/mfmnw1.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,11 +447,11 @@ def _parse_5(f, itmp, qfrcmn_default=None, qfrcmx_default=None, qcut_default="")
qfrcmn = 0.0
qfrcmx = 0.0
if "qcut" in linetxt:
txt = [t for t in line if "qcut" in t][0]
txt = next(t for t in line if "qcut" in t)
qcut = txt
line.remove(txt)
elif "%cut" in linetxt:
txt = [t for t in line if "%cut" in t][0]
txt = next(t for t in line if "%cut" in t)
qcut = txt
line.remove(txt)
if "qcut" in linetxt or "%cut" in linetxt:
Expand Down
2 changes: 1 addition & 1 deletion flopy/modflow/mfmnw2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,7 @@ def __init__(
if (
"k"
not in stress_period_data[
list(stress_period_data.keys())[0]
next(iter(stress_period_data.keys()))
].dtype.names
):
self._add_kij_to_stress_period_data()
Expand Down
2 changes: 1 addition & 1 deletion flopy/modflow/mfrch.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def check(
# check for unusually high or low values of mean R/T
hk_package = {"UPW", "LPF"}.intersection(set(self.parent.get_package_list()))
if len(hk_package) > 0 and self.parent.structured:
pkg = list(hk_package)[0]
pkg = next(iter(hk_package))

# handle quasi-3D layers
# (ugly, would be nice to put this else where in a general function)
Expand Down
2 changes: 1 addition & 1 deletion flopy/modflow/mfuzf1.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ def __init__(
# Dataset 9, 11, 13 and 15 will be written automatically in the
# write_file function
# Data Set 10
# [FINF (NCOL, NROW)] U2DREL
# [FINF (NCOL, NROW)] - U2DREL

self.finf = Transient2d(model, (nrow, ncol), np.float32, finf, name="finf")
if ietflg > 0:
Expand Down
4 changes: 2 additions & 2 deletions flopy/plot/crosssection.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def __init__(
else:
self.ax = ax

onkey = list(line.keys())[0]
onkey = next(iter(line.keys()))
self.__geographic_xpts = None

# un-translate model grid into model coordinates
Expand Down Expand Up @@ -199,7 +199,7 @@ def __init__(
self.xypts[node] = points

if len(self.xypts) < 2:
if len(list(self.xypts.values())[0]) < 2:
if len(next(iter(self.xypts.values()))) < 2:
s = (
"cross-section cannot be created\n."
" less than 2 points intersect the model grid\n"
Expand Down
8 changes: 4 additions & 4 deletions flopy/utils/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -1083,8 +1083,8 @@ def compare_concentrations(


def compare_stages(
namefile1: Union[str, os.PathLike] = None,
namefile2: Union[str, os.PathLike] = None,
namefile1: Optional[Union[str, os.PathLike]] = None,
namefile2: Optional[Union[str, os.PathLike]] = None,
files1: Optional[Union[str, os.PathLike, list[Union[str, os.PathLike]]]] = None,
files2: Optional[Union[str, os.PathLike, list[Union[str, os.PathLike]]]] = None,
htol=0.001,
Expand Down Expand Up @@ -1295,8 +1295,8 @@ def compare_stages(


def compare(
namefile1: Union[str, os.PathLike] = None,
namefile2: Union[str, os.PathLike] = None,
namefile1: Optional[Union[str, os.PathLike]] = None,
namefile2: Optional[Union[str, os.PathLike]] = None,
precision="auto",
max_cumpd=0.01,
max_incpd=0.01,
Expand Down
5 changes: 3 additions & 2 deletions flopy/utils/gridintersect.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,9 +459,10 @@ def _intersect_point_shapely(
for ishp, cid in zip(ixresult, qcellids):
points = []
for pnt in shapely.get_parts(ishp):
if tuple(pnt.coords)[0] not in parsed:
next_pnt = next(iter(pnt.coords))
if next_pnt not in parsed:
points.append(pnt)
parsed.append(tuple(pnt.coords)[0])
parsed.append(next_pnt)

if len(points) > 1:
keep_pts.append(shapely.MultiPoint(points))
Expand Down
10 changes: 5 additions & 5 deletions flopy/utils/mfreadnam.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import os
from os import PathLike
from pathlib import Path, PurePosixPath, PureWindowsPath
from typing import Union
from typing import Optional, Union


class NamData:
Expand Down Expand Up @@ -295,9 +295,9 @@ def attribs_from_namfile_header(namefile):

def get_entries_from_namefile(
path: Union[str, PathLike],
ftype: str = None,
unit: int = None,
extension: str = None,
ftype: Optional[str] = None,
unit: Optional[int] = None,
extension: Optional[str] = None,
) -> list[tuple]:
"""Get entries from an MF6 namefile. Can select using FTYPE, UNIT, or file
extension.
Expand Down Expand Up @@ -481,7 +481,7 @@ def get_mf6_nper(tdisfile):
"""
with open(tdisfile) as f:
lines = f.readlines()
line = [line for line in lines if "NPER" in line.upper()][0]
line = next(line for line in lines if "NPER" in line.upper())
nper = line.strip().split()[1]
return nper

Expand Down
4 changes: 2 additions & 2 deletions flopy/utils/utils_def.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ def get_pak_vals_shape(model, vals):
if nrow is None: # unstructured
if isinstance(vals, dict):
try: # check for iterable
_ = (v for v in list(vals.values())[0])
_ = (v for v in next(iter(vals.values())))
except:
return (1, ncol[0]) # default to layer 1 node count
return np.array(list(vals.values())[0], ndmin=2).shape
return np.array(next(iter(vals.values())), ndmin=2).shape
else:
# check for single iterable
try:
Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ select = [
"F", # Pyflakes
"I001", # isort - unsorted-imports
# "ISC001", # implicitly concatenated string literals
"RUF", # Ruff-specific rules
]
ignore = [
"E402", # module level import not at top of file
Expand All @@ -151,11 +152,14 @@ ignore = [
"F524", # `.format` missing argument(s) for placeholder(s)
"F811", # Redefinition of unused variable
"F841", # local variable assigned but never used
"RUF005", # collection literal concatenation
"RUF012", # mutable class default
"RUF017", # quadratic-list-summation
]

[tool.ruff.lint.per-file-ignores]
".docs/**/*.py" = ["E501"]
"flopy/mf6/**/*.py" = ["C4", "E501", "F821", "ISC001"]
"flopy/mf6/**/*.py" = ["C4", "E", "F", "ISC", "RUF"]

[tool.codespell]
skip = "cliff.toml,./examples/data/*"
Expand Down

0 comments on commit 4c1bf6c

Please sign in to comment.