diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aca255d..e16ac08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,12 +24,12 @@ jobs: fail-fast: false matrix: os: [ "ubuntu-latest", "macos-latest", "macos-14" ] - python-version: [ "3.9", "3.10", "3.11", "3.12" ] + python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ] steps: - name: checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: environment setup - uses: conda-incubator/setup-miniconda@505e6394dae86d6a5c7fbb6e3fb8938e3e863830 # v3.1.1 + uses: conda-incubator/setup-miniconda@835234971496cad1653abb28a638a281cf32541f # v3.2.0 with: python-version: ${{ matrix.python-version }} channels: conda-forge diff --git a/.github/workflows/pypi.yaml b/.github/workflows/pypi.yaml index b79509f..cc57f0b 100644 --- a/.github/workflows/pypi.yaml +++ b/.github/workflows/pypi.yaml @@ -8,9 +8,9 @@ jobs: if: github.repository == 'NCAR/wrf-python' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.10' - name: Install dependencies @@ -28,9 +28,9 @@ jobs: if: startsWith(github.ref, 'refs/tags') runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.10' - name: Install dependencies @@ -44,7 +44,7 @@ jobs: run: | python -m twine check dist/* - name: Publish package to PyPI - uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4 + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 with: user: __token__ password: ${{ secrets.PYPI_WRF_PYTHON }} diff --git a/build_envs/environment.yml b/build_envs/environment.yml index 4c646a3..e889284 100644 --- a/build_envs/environment.yml +++ b/build_envs/environment.yml @@ -3,7 +3,7 @@ name: wrf_python_build channels: - conda-forge dependencies: - - python>=3.9, <3.13 + - python>=3.9, <3.14 - compilers - basemap - cartopy @@ -12,7 +12,6 @@ dependencies: - netcdf4 - numpy - pycodestyle - - setuptools - sphinx - sphinx_rtd_theme - sphinxcontrib-googleanalytics diff --git a/build_envs/platform-specific/macos_arm64.yml b/build_envs/platform-specific/macos_arm64.yml index 2e475f0..d6483dd 100644 --- a/build_envs/platform-specific/macos_arm64.yml +++ b/build_envs/platform-specific/macos_arm64.yml @@ -3,7 +3,7 @@ name: wrf_python_build channels: - conda-forge dependencies: - - python<3.12 + - python - basemap - cartopy - clang_osx-arm64 diff --git a/build_envs/platform-specific/macos_x64.yml b/build_envs/platform-specific/macos_x64.yml index 2415ebe..ba798c2 100644 --- a/build_envs/platform-specific/macos_x64.yml +++ b/build_envs/platform-specific/macos_x64.yml @@ -3,7 +3,7 @@ name: wrf_python_build channels: - conda-forge dependencies: - - python<3.12 + - python - basemap - cartopy - clang_osx-64 diff --git a/build_envs/platform-specific/windows.yml b/build_envs/platform-specific/windows.yml index 1053db0..46d53b2 100644 --- a/build_envs/platform-specific/windows.yml +++ b/build_envs/platform-specific/windows.yml @@ -4,7 +4,7 @@ channels: - conda-forge - msys2 dependencies: - - python<3.12 + - python - basemap - cartopy - jupyter diff --git a/doc/source/_templates/subproducts.txt b/doc/source/_templates/subproducts.txt index a13b2db..8a66605 100644 --- a/doc/source/_templates/subproducts.txt +++ b/doc/source/_templates/subproducts.txt @@ -5,9 +5,9 @@ +--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ | mcin | cape_2d | 2D Max CIN | J kg-1 | **missing** (float): Fill value for output only | +--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -| lcl | cape_2d | 2D Lifted Condensation Level | J kg-1 | **missing** (float): Fill value for output only | +| lcl | cape_2d | 2D Lifted Condensation Level | m | **missing** (float): Fill value for output only | +--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -| lfc | cape_2d | 2D Level of Free Convection | J kg-1 | **missing** (float): Fill value for output only | +| lfc | cape_2d | 2D Level of Free Convection | m | **missing** (float): Fill value for output only | +--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ | cape3d_only | cape_3d | 3D CAPE | J kg-1 | **missing** (float): Fill value for output only | +--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -116,4 +116,4 @@ | | | | kt | | | | | | | | | | | | ft s-1 | | -+--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ \ No newline at end of file ++--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/doc/source/new.rst b/doc/source/new.rst index 364af0b..1035cae 100644 --- a/doc/source/new.rst +++ b/doc/source/new.rst @@ -4,6 +4,15 @@ What's New Releases ------------- +v1.4.1 (November 2025) +^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Release 1.4.1 +- Support for Python 3.13 +- Fix to accommodate recent netCDF4 changes +- Remove pkg_resources +- Correct units for LCL and LFC in the subproduct diagnostics documentation + v1.4.0 (May 2025) ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/source/plot.rst b/doc/source/plot.rst index fb69a7f..19b7392 100644 --- a/doc/source/plot.rst +++ b/doc/source/plot.rst @@ -23,9 +23,6 @@ should be aware of a few shortcomings when working with WRF data. - The rotated pole projection requires the x and y limits to be set manually using set_xlim and set_ylim. -- You can't place latitude and longitude labels on the axes when using - any projection other than Mercator or LatLon. - Plotting a Two-dimensional Field ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +86,10 @@ Plotting a Two-dimensional Field ax.set_ylim(cartopy_ylim(smooth_slp)) # Add the gridlines - ax.gridlines(color="black", linestyle="dotted") + gl = ax.gridlines(draw_labels=True, color="black", linestyle="dotted") + gl.right_labels = False + gl.x_inline = False + gl.top_labels = False plt.title("Sea Level Pressure (hPa)") diff --git a/pyproject.toml b/pyproject.toml index 5047e19..0f00bb5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ maintainers = [ ] description = "Diagnostic and interpolation routines for WRF-ARW data." readme = "README.md" -requires-python = ">=3.9, <3.13" +requires-python = ">=3.9, <3.14" keywords = [ "python", "wrf-python", "wrf", "forecast", "model", "weather research and forecasting", "interpolation", @@ -30,6 +30,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering :: Atmospheric Science", "Topic :: Software Development", "Operating System :: POSIX", diff --git a/src/wrf/__init__.py b/src/wrf/__init__.py index 39cd608..99334d9 100644 --- a/src/wrf/__init__.py +++ b/src/wrf/__init__.py @@ -1,25 +1,8 @@ from __future__ import (absolute_import, division, print_function) import os -import pkg_resources - -try: - from . import api - from .api import * -except ImportError: - # For gfortran+msvc combination, extra shared libraries may exist - # (stored by numpy.distutils) - if os.name == "nt": - req = pkg_resources.Requirement.parse("wrf-python") - extra_dll_dir = pkg_resources.resource_filename(req, - "wrf-python/.libs") - if os.path.isdir(extra_dll_dir): - os.environ["PATH"] += os.pathsep + extra_dll_dir - - from . import api - from .api import * - else: - raise +from . import api +from .api import * __all__ = [] __all__.extend(api.__all__) diff --git a/src/wrf/constants.py b/src/wrf/constants.py index d660c62..827fed3 100644 --- a/src/wrf/constants.py +++ b/src/wrf/constants.py @@ -59,11 +59,15 @@ class ProjectionTypes(object): np.dtype(np.uint32): 4294967295, np.dtype(np.int64): Constants.DEFAULT_FILL_INT64, np.dtype(np.uint64): 18446744073709551614, - np.dtype(np.float_): Constants.DEFAULT_FILL_DOUBLE, np.dtype(np.float32): Constants.DEFAULT_FILL_FLOAT, np.dtype(np.float64): Constants.DEFAULT_FILL_DOUBLE } +try: + _DEFAULT_FILL_MAP[np.dtype(np.float_)] = Constants.DEFAULT_FILL_DOUBLE +except AttributeError: + pass + if version_info >= (3, ): _DEFAULT_FILL_MAP[np.int_] = Constants.DEFAULT_FILL_INT64 else: diff --git a/src/wrf/util.py b/src/wrf/util.py index 40229c7..99ef9ae 100644 --- a/src/wrf/util.py +++ b/src/wrf/util.py @@ -9,6 +9,7 @@ from types import GeneratorType import datetime as dt from inspect import getmodule +from netCDF4 import Dataset try: from inspect import signature @@ -134,7 +135,14 @@ def is_multi_file(wrfin): is a single NetCDF file object. """ - return (isinstance(wrfin, Iterable) and not isstr(wrfin)) + if isinstance(wrfin, Dataset): + is_iterable = False + elif isinstance(wrfin, Iterable): + is_iterable = True + else: + is_iterable = False + + return (is_iterable and not isstr(wrfin)) def has_time_coord(wrfnc): diff --git a/src/wrf/version.py b/src/wrf/version.py index 3e8d9f9..bf25615 100644 --- a/src/wrf/version.py +++ b/src/wrf/version.py @@ -1 +1 @@ -__version__ = "1.4.0" +__version__ = "1.4.1" diff --git a/test/ci_tests/utests.py b/test/ci_tests/utests.py index 5ae40e1..133afb0 100644 --- a/test/ci_tests/utests.py +++ b/test/ci_tests/utests.py @@ -107,7 +107,7 @@ def test(self): # print (hts_850) hts_850 = interplevel(hts, p, 850) - nt.assert_allclose(to_np(hts_850), ref_ht_850) + nt.assert_allclose(to_np(hts_850), ref_ht_850, rtol=1e-06) elif (varname == "vertcross"): ref_ht_cross = _get_refvals(referent, "vertcross", repeat, multi)