Skip to content

Commit

Permalink
Merge pull request #3612 from dopplershift/drop-py39
Browse files Browse the repository at this point in the history
Drop Python 3.9
  • Loading branch information
dopplershift authored Aug 28, 2024
2 parents ddc198c + eb36c3d commit 178a1f3
Show file tree
Hide file tree
Showing 36 changed files with 96 additions and 98 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/docs-conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ jobs:
fail-fast: false
matrix:
include:
- python-version: 3.9
os: Windows
- python-version: '3.10'
os: Windows
- python-version: 3.11
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.9, '3.10', 3.11]
python-version: ['3.10', 3.11]
check-links: [false]
include:
- python-version: 3.12
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/tests-conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.9, 3.12]
python-version: ['3.10', 3.12]
os: [macOS, Windows]
include:
- python-version: '3.10'
os: macOS
- python-version: 3.11
os: Windows

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/tests-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.9, '3.10', 3.11, 3.12]
python-version: ['3.10', 3.11, 3.12]
dep-versions: [Latest]
no-extras: ['']
include:
- python-version: 3.9
- python-version: '3.10'
dep-versions: Minimum
- python-version: 3.9
- python-version: '3.10'
dep-versions: Minimum
no-extras: 'No Extras'
- python-version: 3.12
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ on a future ``1.x`` version.
For additional MetPy examples not included in this repository, please see the [Unidata Python
Gallery](https://unidata.github.io/python-gallery/).

We support Python >= 3.9.
We support Python >= 3.10.

Need Help?
----------
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MetPy
=====

MetPy is a collection of tools in Python for reading, visualizing, and performing calculations
with weather data. MetPy supports Python >= 3.9 and is freely available under a permissive
with weather data. MetPy supports Python >= 3.10 and is freely available under a permissive
`open source license <https://github.com/Unidata/MetPy/blob/main/LICENSE>`_.

If you're new to MetPy, check out our :doc:`Getting Started <userguide/startingguide>` guide.
Expand Down
2 changes: 1 addition & 1 deletion docs/userguide/installguide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Requirements
------------
In general, MetPy tries to support minor versions of dependencies released within the last two
years. For Python itself, that generally means supporting the last two minor releases; MetPy
currently supports Python >= 3.9.
currently supports Python >= 3.10.

.. literalinclude:: ../../pyproject.toml
:start-at: matplotlib
Expand Down
3 changes: 2 additions & 1 deletion examples/formats/NEXRAD_Level_2_File.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
fig = plt.figure(figsize=(15, 8))
add_metpy_logo(fig, 190, 85, size='large')

for var_data, var_range, ax_rect in zip((ref, rho), (ref_range, rho_range), spec):
for var_data, var_range, ax_rect in zip((ref, rho), (ref_range, rho_range), spec,
strict=False):
# Turn into an array, then mask
data = np.ma.array(var_data)
data[np.isnan(data)] = np.ma.masked
Expand Down
2 changes: 1 addition & 1 deletion examples/formats/NEXRAD_Level_3_File.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
ctables = (('NWSStormClearReflectivity', -20, 0.5), # dBZ
('NWS8bitVel', -100, 1.0)) # m/s

for v, ctable, ax_rect in zip(('N0Q', 'N0U'), ctables, spec):
for v, ctable, ax_rect in zip(('N0Q', 'N0U'), ctables, spec, strict=False):
# Open the file
name = get_test_data(f'nids/KOUN_SDUS54_{v}TLX_201305202016', as_file_obj=False)
f = Level3File(name)
Expand Down
10 changes: 5 additions & 5 deletions examples/gridding/Inverse_Distance_Verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ def draw_circle(ax, x, y, r, m, label):
#
# The variable ``indices`` represents the index of each matched coordinate within the
# cKDTree's ``data`` list.
grid_points = np.array(list(zip(sim_gridx, sim_gridy)))
grid_points = np.array(list(zip(sim_gridx, sim_gridy, strict=False)))

radius = 40
obs_tree = cKDTree(list(zip(xp, yp)))
obs_tree = cKDTree(list(zip(xp, yp, strict=False)))
indices = obs_tree.query_ball_point(grid_points, r=radius)

###########################################
Expand All @@ -83,7 +83,7 @@ def draw_circle(ax, x, y, r, m, label):
barnes_dist = dist_2(sim_gridx[1], sim_gridy[1], x2, y2)
barnes_obs = zp[indices[1]]

kappa = calc_kappa(average_spacing(list(zip(xp, yp))))
kappa = calc_kappa(average_spacing(list(zip(xp, yp, strict=False))))

barnes_val = barnes_point(barnes_dist, barnes_obs, kappa)

Expand Down Expand Up @@ -121,7 +121,7 @@ def draw_circle(ax, x, y, r, m, label):
mx, my = obs_tree.data[indices[0]].T
mz = zp[indices[0]]

for x, y, z in zip(mx, my, mz):
for x, y, z in zip(mx, my, mz, strict=False):
d = np.sqrt((sim_gridx[0] - x)**2 + (y - sim_gridy[0])**2)
ax.plot([sim_gridx[0], x], [sim_gridy[0], y], '--')

Expand Down Expand Up @@ -160,7 +160,7 @@ def draw_circle(ax, x, y, r, m, label):
mx, my = obs_tree.data[indices[1]].T
mz = zp[indices[1]]

for x, y, z in zip(mx, my, mz):
for x, y, z in zip(mx, my, mz, strict=False):
d = np.sqrt((sim_gridx[1] - x)**2 + (y - sim_gridy[1])**2)
ax.plot([sim_gridx[1], x], [sim_gridy[1], y], '--')

Expand Down
7 changes: 4 additions & 3 deletions examples/gridding/Natural_Neighbor_Verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@
ax.set_title('Triangulation of observations and test grid cell '
'natural neighbor interpolation values')

members, circumcenters = geometry.find_natural_neighbors(tri, list(zip(sim_gridx, sim_gridy)))
members, circumcenters = geometry.find_natural_neighbors(tri, list(zip(sim_gridx, sim_gridy,
strict=False)))

val = natural_neighbor_point(xp, yp, zp, (sim_gridx[0], sim_gridy[0]), tri, members[0],
circumcenters)
Expand Down Expand Up @@ -164,7 +165,7 @@ def draw_circle(ax, x, y, r, m, label):
# spatial data structure that we use here simply to show areal ratios.
# Notice that the two natural neighbor triangle circumcenters are also vertices
# in the Voronoi plot (green dots), and the observations are in the polygons (blue dots).
vort = Voronoi(list(zip(xp, yp)))
vort = Voronoi(list(zip(xp, yp, strict=False)))

fig, ax = plt.subplots(1, 1, figsize=(15, 10))
ax.ishold = lambda: True # Work-around for Matplotlib 3.0.0 incompatibility
Expand All @@ -175,7 +176,7 @@ def draw_circle(ax, x, y, r, m, label):
x_0 = xp[nn_ind]
y_0 = yp[nn_ind]

for x, y, z in zip(x_0, y_0, z_0):
for x, y, z in zip(x_0, y_0, z_0, strict=False):
ax.annotate(f'{x}, {y}: {z:.3f} F', xy=(x, y))

ax.plot(sim_gridx[0], sim_gridy[0], 'k+', markersize=10)
Expand Down
2 changes: 1 addition & 1 deletion examples/plots/Plotting_Surface_Analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def plot_bulletin(ax, data):
# Handle H/L points using MetPy's StationPlot class
for field in ('HIGH', 'LOW'):
rows = data[data.feature == field]
x, y = zip(*((pt.x, pt.y) for pt in rows.geometry))
x, y = zip(*((pt.x, pt.y) for pt in rows.geometry), strict=False)
sp = StationPlot(ax, x, y, transform=ccrs.PlateCarree(), clip_on=True)
sp.plot_text('C', [field[0]] * len(x), **complete_style[field])
sp.plot_parameter('S', rows.strength, **complete_style[field])
Expand Down
2 changes: 1 addition & 1 deletion examples/plots/US_Counties.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
ax2 = fig.add_subplot(1, 3, 2, projection=proj)
ax3 = fig.add_subplot(1, 3, 3, projection=proj)

for scale, axis in zip(['20m', '5m', '500k'], [ax1, ax2, ax3]):
for scale, axis in zip(['20m', '5m', '500k'], [ax1, ax2, ax3], strict=False):
axis.set_extent([270.25, 270.9, 38.15, 38.75], ccrs.Geodetic())
axis.add_feature(USCOUNTIES.with_scale(scale))
13 changes: 6 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ classifiers = [
"Development Status :: 5 - Production/Stable",
"Framework :: Matplotlib",
"Programming Language :: Python",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand All @@ -24,17 +23,17 @@ classifiers = [
"Operating System :: OS Independent",
"License :: OSI Approved :: BSD License"
]
requires-python = ">=3.9"
requires-python = ">=3.10"
dependencies = [
"matplotlib>=3.5.0",
"numpy>=1.20.0",
"numpy>=1.22.0",
"pandas>=1.4.0",
"pint>=0.17",
"pooch>=1.2.0",
"pyproj>=3.0.0",
"pyproj>=3.3.0",
"scipy>=1.8.0",
"traitlets>=5.0.5",
"xarray>=0.21.0"
"traitlets>=5.1.0",
"xarray>=2022.6.0"
]

[project.entry-points."xarray.backends"]
Expand All @@ -57,7 +56,7 @@ examples = [
test = [
"netCDF4",
"packaging>=21.0",
"pytest>=6.2",
"pytest>=7.0",
"pytest-mpl"
]
extras = [
Expand Down
2 changes: 1 addition & 1 deletion src/metpy/calc/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,7 @@ def zoom_xarray(input_field, zoom, output=None, order=3, mode='constant', cval=0
if not np.iterable(zoom):
zoom = tuple(zoom for _ in input_field.dims)
zoomed_dim_coords = {}
for dim_name, dim_zoom in zip(input_field.dims, zoom):
for dim_name, dim_zoom in zip(input_field.dims, zoom, strict=False):
if dim_name in input_field.coords:
zoomed_dim_coords[dim_name] = scipy_zoom(
input_field[dim_name].data, dim_zoom, order=order, mode=mode, cval=cval,
Expand Down
2 changes: 1 addition & 1 deletion src/metpy/calc/kinematics.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ def advection(

return -sum(
wind * gradient
for wind, gradient in zip(wind_vector.values(), gradient_vector)
for wind, gradient in zip(wind_vector.values(), gradient_vector, strict=False)
)


Expand Down
2 changes: 1 addition & 1 deletion src/metpy/calc/thermo.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ def _wide_option(intersect_type, p_list, t_list, pressure, parcel_temperature_pr
lfc_p_list, _ = find_intersections(pressure, parcel_temperature_profile,
temperature, direction='increasing',
log_x=True)
diff = [lfc_p.m - el_p.m for lfc_p, el_p in zip(lfc_p_list, el_p_list)]
diff = [lfc_p.m - el_p.m for lfc_p, el_p in zip(lfc_p_list, el_p_list, strict=False)]
return (p_list[np.where(diff == np.max(diff))][0],
t_list[np.where(diff == np.max(diff))][0])

Expand Down
6 changes: 3 additions & 3 deletions src/metpy/interpolate/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def natural_neighbor_to_grid(xp, yp, variable, grid_x, grid_y):
"""
# Handle grid-to-points conversion, and use function from `interpolation`
points_obs = list(zip(xp, yp))
points_obs = list(zip(xp, yp, strict=False))
points_grid = generate_grid_coords(grid_x, grid_y)
img = natural_neighbor_to_points(points_obs, variable, points_grid)
return img.reshape(grid_x.shape)
Expand Down Expand Up @@ -214,7 +214,7 @@ def inverse_distance_to_grid(xp, yp, variable, grid_x, grid_y, r, gamma=None, ka
"""
# Handle grid-to-points conversion, and use function from `interpolation`
points_obs = list(zip(xp, yp))
points_obs = list(zip(xp, yp, strict=False))
points_grid = generate_grid_coords(grid_x, grid_y)
img = inverse_distance_to_points(points_obs, variable, points_grid, r, gamma=gamma,
kappa=kappa, min_neighbors=min_neighbors, kind=kind)
Expand Down Expand Up @@ -296,7 +296,7 @@ def interpolate_to_grid(x, y, z, interp_type='linear', hres=50000,
grid_x, grid_y = generate_grid(hres, boundary_coords)

# Handle grid-to-points conversion, and use function from `interpolation`
points_obs = np.array(list(zip(x, y)))
points_obs = np.array(list(zip(x, y, strict=False)))
points_grid = generate_grid_coords(grid_x, grid_y)
img = interpolate_to_points(points_obs, z, points_grid, interp_type=interp_type,
minimum_neighbors=minimum_neighbors, gamma=gamma,
Expand Down
6 changes: 3 additions & 3 deletions src/metpy/interpolate/points.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def cressman_point(sq_dist, values, radius):
weights = tools.cressman_weights(sq_dist, radius)
total_weights = np.sum(weights)

return sum(v * (w / total_weights) for (w, v) in zip(weights, values))
return sum(v * (w / total_weights) for (w, v) in zip(weights, values, strict=False))


def barnes_point(sq_dist, values, kappa, gamma=None):
Expand Down Expand Up @@ -82,7 +82,7 @@ def barnes_point(sq_dist, values, kappa, gamma=None):
weights = tools.barnes_weights(sq_dist, kappa, gamma)
total_weights = np.sum(weights)

return sum(v * (w / total_weights) for (w, v) in zip(weights, values))
return sum(v * (w / total_weights) for (w, v) in zip(weights, values, strict=False))


def natural_neighbor_point(xp, yp, variable, grid_loc, tri, neighbors, circumcenters):
Expand Down Expand Up @@ -271,7 +271,7 @@ def inverse_distance_to_points(points, values, xi, r, gamma=None, kappa=None, mi

img = np.asarray([interp_func(geometry.dist_2(*grid, *obs_tree.data[matches].T),
values[matches]) if len(matches) >= min_neighbors else np.nan
for matches, grid in zip(indices, xi)])
for matches, grid in zip(indices, xi, strict=False)])

if org_units:
img = units.Quantity(img, org_units)
Expand Down
2 changes: 1 addition & 1 deletion src/metpy/interpolate/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def remove_repeat_coordinates(x, y, z):
coords = []
variable = []

for (x_, y_, t_) in zip(x, y, z):
for (x_, y_, t_) in zip(x, y, z, strict=False):
if (x_, y_) not in coords:
coords.append((x_, y_))
variable.append(t_)
Expand Down
8 changes: 4 additions & 4 deletions src/metpy/io/_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def __init__(self, info, prefmt='', tuple_name=None):
"""Initialize the NamedStruct."""
if tuple_name is None:
tuple_name = 'NamedStruct'
names, fmts = zip(*info)
names, fmts = zip(*info, strict=False)
self.converters = {}
conv_off = 0
for ind, i in enumerate(info):
Expand Down Expand Up @@ -118,7 +118,7 @@ class DictStruct:

def __init__(self, info, prefmt=''):
"""Initialize the DictStruct."""
names, formats = zip(*info)
names, formats = zip(*info, strict=False)

# Remove empty names
self._names = [n for n in names if n]
Expand All @@ -131,7 +131,7 @@ def size(self):
return self._struct.size

def _create(self, items):
return dict(zip(self._names, items))
return dict(zip(self._names, items, strict=False))

def unpack(self, s):
"""Parse bytes and return a dict."""
Expand All @@ -151,7 +151,7 @@ def __init__(self, *args, **kwargs):
self.val_map = dict(enumerate(args))

# Invert the kwargs dict so that we can map from value to name
self.val_map.update(zip(kwargs.values(), kwargs.keys()))
self.val_map.update(zip(kwargs.values(), kwargs.keys(), strict=False))

def __call__(self, val):
"""Map an integer to the string representation."""
Expand Down
9 changes: 5 additions & 4 deletions src/metpy/io/gempak.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,9 @@ def __init__(self, file):
fkey_prod = product(['header_name', 'header_length', 'header_type'],
range(1, self.prod_desc.file_headers + 1))
fkey_names = ['{}{}'.format(*x) for x in fkey_prod]
fkey_info = list(zip(fkey_names, np.repeat(('4s', 'i', 'i'),
self.prod_desc.file_headers)))
fkey_info = list(zip(fkey_names,
np.repeat(('4s', 'i', 'i'), self.prod_desc.file_headers),
strict=False))
self.file_keys_format = NamedStruct(fkey_info, self.prefmt, 'FileKeys')

self._buffer.jump_to(self._start, _word_to_position(self.prod_desc.file_keys_ptr))
Expand Down Expand Up @@ -790,7 +791,7 @@ def _convert_ftime(ftime):
@staticmethod
def _convert_level(level):
"""Convert levels."""
if isinstance(level, (int, float)) and level >= 0:
if isinstance(level, int | float) and level >= 0:
return level
else:
return None
Expand Down Expand Up @@ -1897,7 +1898,7 @@ def _merge_sounding(self, parts):
if num_man_levels >= 1:
for mp, mt, mz in zip(parts['TTAA']['PRES'],
parts['TTAA']['TEMP'],
parts['TTAA']['HGHT']):
parts['TTAA']['HGHT'], strict=False):
if self.prod_desc.missing_float not in [
mp,
mt,
Expand Down
2 changes: 1 addition & 1 deletion src/metpy/io/gini.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def _scaled_int(s):

def _name_lookup(names):
r"""Create an io helper to convert an integer to a named value."""
mapper = dict(zip(range(len(names)), names))
mapper = dict(zip(range(len(names)), names, strict=False))

def lookup(val):
return mapper.get(val, 'UnknownValue')
Expand Down
Loading

0 comments on commit 178a1f3

Please sign in to comment.