Skip to content

Commit 84ca88c

Browse files
authored
Merge pull request #2 from phobson/ruff-gha
ruff config
2 parents e9e3fc4 + 4c0731a commit 84ca88c

23 files changed

+162
-121
lines changed

.github/workflows/python-ruff.yml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: ruff 'n' stuff
2+
on: [pull_request]
3+
4+
jobs:
5+
build:
6+
runs-on: ubuntu-latest
7+
steps:
8+
- uses: actions/checkout@v3
9+
- name: Install Python
10+
uses: actions/setup-python@v4
11+
with:
12+
python-version: "3.12"
13+
- name: Install dependencies
14+
run: |
15+
python -m pip install --upgrade pip
16+
pip install ruff
17+
# Update output format to enable automatic inline annotations.
18+
- name: Run Ruff
19+
run: ruff check --output-format=github .

.github/workflows/python-run-tests.yml

+11-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ name: Run basic unit tests
55

66
on:
77
push:
8-
branches: [ main ]
8+
branches: [ master ]
99
pull_request:
10-
branches: [ main ]
10+
branches: [ master ]
1111

1212
jobs:
1313
build:
@@ -26,14 +26,21 @@ jobs:
2626
create-args: >-
2727
python=${{ matrix.python-version }}
2828
gridgen
29-
numpy
29+
shapely
30+
fiona
31+
geopandas
32+
scipy
3033
matplotlib
31-
pyproj
34+
ipywidgets
3235
pytest
36+
pytest-mpl
37+
pytest-cov
38+
pytest-pep8
3339
coverage
3440
docopt
3541
requests
3642
pyyaml
43+
pygridgen
3744
init-shell: bash
3845
cache-environment: true
3946
post-cleanup: 'all'

check_pygridtools.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
matplotlib.use('agg')
66
style.use('classic')
77

8-
import pygridtools
8+
import pygridtools # noqa: E402
99

1010

1111
if '--strict' in sys.argv:

pygridtools/__init__.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from .misc import *
2-
from .core import *
3-
from . import iotools
4-
from . import viz
5-
from . import validate
1+
from .misc import * # noqa: F403
2+
from .core import * # noqa: F403
3+
from . import iotools # noqa: F401
4+
from . import viz # noqa: F401
5+
from . import validate # noqa: F401
66

7-
from .tests import test, teststrict
7+
from .tests import test, teststrict # noqa: F401

pygridtools/core.py

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from __future__ import division
21

32
import warnings
43
from copy import deepcopy
@@ -198,7 +197,7 @@ def extract(nodes, jstart=None, istart=None, jend=None, iend=None):
198197
return deepcopy(nodes[jstart:jend, istart:iend])
199198

200199

201-
class ModelGrid(object):
200+
class ModelGrid:
202201
"""
203202
Container for a curvilinear-orthogonal grid. Provides convenient
204203
access to masking, manipulation, and visualization methods.
@@ -745,12 +744,15 @@ def mask_centroids(self, inside=None, outside=None, use_existing=True):
745744
cell_mask = numpy.bitwise_or(inside_cell_mask, outside_cell_mask)
746745
return self.update_cell_mask(mask=cell_mask, merge_existing=use_existing)
747746

748-
@numpy.deprecate(message='use mask_nodes or mask_centroids')
749747
def mask_cells_with_polygon(self, polyverts, use_centroids=True, **kwargs):
750-
if use_centroids:
751-
return self.mask_centroids(polyverts, **kwargs)
752-
else:
753-
return self.mask_nodes(polyverts, **kwargs)
748+
with warnings.warn(
749+
".mask_cells_with_polygon is deprecated. Use .mask_nodes or .mask_centroids",
750+
DeprecationWarning
751+
):
752+
if use_centroids:
753+
return self.mask_centroids(polyverts, **kwargs)
754+
else:
755+
return self.mask_nodes(polyverts, **kwargs)
754756

755757
def plot_cells(self, engine='mpl', ax=None, usemask=True, showisland=True,
756758
cell_kws=None, domain_kws=None, extent_kws=None,
@@ -822,10 +824,7 @@ def to_point_geodataframe(self, which='nodes', usemask=True, elev=None):
822824

823825
def to_polygon_geodataframe(self, usemask=True, elev=None):
824826
x, y = self._get_x_y(which='nodes', usemask=False)
825-
if usemask:
826-
mask = self.cell_mask.copy()
827-
else:
828-
mask = None
827+
mask = self.cell_mask.copy() if usemask else None
829828

830829
return misc.gdf_of_cells(x, y, mask, crs=self.crs, elev=elev, triangles=False)
831830

pygridtools/gefdc.py

+10-15
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
from shapely.geometry import Point
88
import geopandas
99

10-
from pygridtools import iotools
11-
from pygridtools import misc
1210
from pygridtools import validate
1311

1412

@@ -93,7 +91,7 @@ def write_cellinp(cell_array, outputfile='cell.inp', mode='w',
9391
nrows, ncols = cell_array.shape
9492

9593
rowfmt = '{0:3d} {1:s}\n'
96-
colfmt = f'{{:0{_n_digits(ncols)}d}}'
94+
# colfmt = f'{{:0{_n_digits(ncols)}d}}'
9795

9896
if cell_array.shape[1] > maxcols:
9997
first_array = cell_array[:, :maxcols]
@@ -108,7 +106,7 @@ def write_cellinp(cell_array, outputfile='cell.inp', mode='w',
108106

109107
else:
110108
columns = numpy.arange(1, maxcols + 1, dtype=int)
111-
colstr = [list('{:04d}'.format(c)) for c in columns]
109+
colstr = [list(f'{c:04d}') for c in columns]
112110
hundreds = ''.join([c[1] for c in colstr])
113111
tens = ''.join([c[2] for c in colstr])
114112
ones = ''.join([c[3] for c in colstr])
@@ -117,19 +115,16 @@ def write_cellinp(cell_array, outputfile='cell.inp', mode='w',
117115
if writeheader:
118116
title = 'C -- cell.inp for EFDC model by pygridtools\n'
119117
outfile.write(title)
120-
outfile.write('C {}\n'.format(hundreds[:ncols]))
121-
outfile.write('C {}\n'.format(tens[:ncols]))
122-
outfile.write('C {}\n'.format(ones[:ncols]))
118+
outfile.write(f'C {hundreds[:ncols]}\n')
119+
outfile.write(f'C {tens[:ncols]}\n')
120+
outfile.write(f'C {ones[:ncols]}\n')
123121

124122
for n, row in enumerate(cell_array):
125123
row_number = nrows - n
126124
row_strings = row.astype(str)
127125
cell_text = ''.join(row_strings.tolist())
128-
if rowlabels:
129-
rowheader = ''
130-
row_text = rowfmt.format(int(row_number), cell_text)
131-
else:
132-
row_text = ' {0:s}\n'.format(cell_text)
126+
127+
row_text = rowfmt.format(int(row_number), cell_text) if rowlabels else f' {cell_text:s}\n'
133128

134129
outfile.write(row_text)
135130

@@ -153,7 +148,7 @@ def write_gridout_file(xcoords, ycoords, outfile):
153148
})
154149

155150
with Path(outfile).open('w') as f:
156-
f.write('## {:d} x {:d}\n'.format(nx, ny))
151+
f.write(f'## {nx:d} x {ny:d}\n')
157152

158153
# XXX: https://github.com/pandas-dev/pandas/issues/21882
159154
with Path(outfile).open('a') as f:
@@ -295,8 +290,8 @@ def make_gefdc_cells(node_mask, cell_mask=None, triangles=False):
295290
if total == bank_cell * shift**2:
296291
cells[cj, ci] = land_cell
297292

298-
nrows = cells.shape[0]
299-
ncols = cells.shape[1]
293+
# nrows = cells.shape[0]
294+
# ncols = cells.shape[1]
300295

301296
# nchunks = numpy.ceil(ncols / maxcols)
302297
# if ncols > maxcols:

pygridtools/iotools.py

+4-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
import os
2-
from collections import OrderedDict
3-
from textwrap import dedent
41
import warnings
52

63
import numpy
7-
import pandas
84
from matplotlib import pyplot
9-
from shapely.geometry import Point, Polygon
105
import geopandas
116

127
try:
@@ -17,8 +12,6 @@
1712
from pygridgen.tests import requires
1813
import pygridgen as pgg
1914

20-
from pygridtools import misc
21-
from pygridtools import validate
2215
from pygridtools import viz
2316

2417

@@ -218,7 +211,7 @@ def interactive_grid_shape(grid, max_n=200, plotfxn=None, **kwargs):
218211
... ( 0, 0, 1.00), ( 0, 15, 0.50), ( 8, 15, -0.25),
219212
... (11, 13, -0.25)])
220213
>>> g = grid.Gridgen(d[:, 0], d[:, 1], d[:, 2], (75, 75), ul_idx=1, focus=None)
221-
>>> new_grid, widget = iotools.interactive_grid_shape(g, plotfxn=plot_grid)
214+
>>> new_grid, widget = iotools.interactive_grid_shape(g, plotfxn=plot_grid) # doctest: +SKIP
222215
"""
223216

224217
if not plotfxn:
@@ -235,7 +228,7 @@ def interactive_grid_shape(grid, max_n=200, plotfxn=None, **kwargs):
235228
)
236229

237230

238-
class _FocusProperties():
231+
class _FocusProperties:
239232
"""A dummy class to hold the properties of the grid._FocusPoint() object.
240233
This class is required so that multiple ipywidgets.interactive widgets
241234
can interact on the same plot.
@@ -399,7 +392,7 @@ def interactive_grid_focus(g, n_points, plotfxn=None, **kwargs):
399392
... (11, 13, -0.25)])
400393
>>> g = grid.Gridgen(d[:, 0], d[:, 1], d[:, 2], (75, 75), ul_idx=1, focus=None)
401394
>>> n = 4 # number of focus objects
402-
>>> new_grid, widget = iotools.interactive_grid_focus(g, n)
395+
>>> new_grid, widget = iotools.interactive_grid_focus(g, n) # doctest: +SKIP
403396
"""
404397

405398
if not plotfxn:
@@ -437,6 +430,6 @@ def interactive_grid_focus(g, n_points, plotfxn=None, **kwargs):
437430
tab_nest = ipywidgets.Tab()
438431
tab_nest.children = widgets
439432
for n in range(len(widgets)):
440-
tab_nest.set_title(n, 'Focus {}'.format(n + 1))
433+
tab_nest.set_title(n, f'Focus {n + 1}')
441434

442435
return focus_points, tab_nest

pygridtools/misc.py

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from collections import OrderedDict
22
from shapely.geometry import Point, Polygon
3+
import importlib
34

45
import numpy
56
import matplotlib.path as mpath
67
import pandas
7-
from shapely import geometry
88
import geopandas
99
from pygridgen import csa
1010

@@ -81,7 +81,7 @@ def make_record(ID, coords, geomtype, props):
8181
"""
8282

8383
if geomtype not in ['Point', 'LineString', 'Polygon']:
84-
raise ValueError('Geometry {} not suppered'.format(geomtype))
84+
raise ValueError(f'Geometry {geomtype} not suppered')
8585

8686
if isinstance(coords, numpy.ma.MaskedArray):
8787
coords = coords.data
@@ -123,10 +123,9 @@ def interpolate_bathymetry(bathy, x_points, y_points, xcol='x', ycol='y', zcol='
123123
124124
"""
125125

126-
try:
127-
import pygridgen
128-
except ImportError: # pragma: no cover
129-
raise ImportError("`pygridgen` not installed. Cannot interpolate bathymetry.")
126+
HASPGG = bool(importlib.util.find_spec("pygridgen"))
127+
if not HASPGG:
128+
raise RuntimeError("`pygridgen` not installed. Cannot interpolate bathymetry.")
130129

131130
if bathy is None:
132131
elev = numpy.zeros(x_points.shape)
@@ -372,7 +371,7 @@ def gdf_of_cells(X, Y, mask, crs, elev=None, triangles=False):
372371
# build the attributes
373372
record = OrderedDict(
374373
id=row, ii=ii + 2, jj=jj + 2, elev=Z,
375-
ii_jj='{:02d}_{:02d}'.format(ii + 2, jj + 2),
374+
ii_jj=f'{ii + 2:02d}_{jj + 2:02d}',
376375
geometry=Polygon(shell=coords)
377376
)
378377

@@ -428,7 +427,7 @@ def gdf_of_points(X, Y, crs, elev=None):
428427
record = OrderedDict(
429428
id=int(row), ii=int(ii + 2), jj=int(jj + 2),
430429
elev=float(elev[jj, ii]),
431-
ii_jj='{:02d}_{:02d}'.format(ii + 2, jj + 2),
430+
ii_jj=f'{ii + 2:02d}_{jj + 2:02d}',
432431
geometry=Point(coords)
433432
)
434433

pygridtools/tests/__init__.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from importlib import resources
22

3-
import pygridtools
43
from pygridgen.tests import requires
54

65
try:
@@ -11,15 +10,15 @@
1110

1211
@requires(pytest, 'pytest')
1312
def test(*args):
14-
options = [resources('pygridtools', '')]
13+
options = [str(resources.files("pygridtools"))]
1514
options.extend(list(args))
1615
return pytest.main(options)
1716

1817

1918
@requires(pytest, 'pytest')
2019
def teststrict(*args):
2120
options = list(set([
22-
resources('pygridtools', ''),
21+
str(resources.files("pygridtools")),
2322
'--mpl',
2423
'--doctest-modules'
2524
] + list(args)))

pygridtools/tests/conftest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from pygridtools.iotools import _FocusProperties
1111

1212

13-
class FakeGrid(object):
13+
class FakeGrid:
1414
def __init__(self, boundary):
1515
self.x, self.y = simple_nodes()
1616
self.xn, self.yn = simple_nodes()

pygridtools/tests/test_core.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import os
2-
import warnings
31
from pkg_resources import resource_filename
4-
import tempfile
52

63
import numpy
74
from numpy import nan
@@ -282,7 +279,7 @@ def polyverts():
282279
def test_ModelGrid_bad_shapes(simple_cells):
283280
xc, yc = simple_cells
284281
with raises(ValueError):
285-
mg = core.ModelGrid(xc, yc[2:, 2:])
282+
core.ModelGrid(xc, yc[2:, 2:])
286283

287284

288285
def test_ModelGrid_nodes_and_cells(g1, simple_cells):
@@ -665,7 +662,10 @@ def test_masks_no_polys(mg):
665662

666663
def test_ModelGrid_to_point_geodataframe(g1):
667664
expectedfile = resource_filename('pygridtools.tests.baseline_files', 'mgshp_nomask_nodes_points.shp')
668-
expected = geopandas.read_file(expectedfile)
665+
expected = geopandas.read_file(expectedfile).assign(
666+
ii=lambda df: df["ii"].astype("int64"),
667+
jj=lambda df: df["jj"].astype("int64"),
668+
)
669669
result = g1.to_point_geodataframe(which='nodes', usemask=False)
670670
utils.assert_gdfs_equal(expected.drop(columns=['river', 'reach']), result)
671671

0 commit comments

Comments
 (0)