Skip to content

Commit

Permalink
Make xESMF optional - remove dep for pip installs - pypi testing uses…
Browse files Browse the repository at this point in the history
… pypi
  • Loading branch information
aulemahal committed Feb 6, 2024
1 parent 8cab40a commit 1196b40
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 36 deletions.
22 changes: 5 additions & 17 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,23 @@ jobs:
python -m tox -e lint
test-pypi:
name: Test with Python${{ matrix.python-version }} (PyPI/tox)
name: Test with Python${{ matrix.python-version }} (PyPI/tox, no ESMF)
needs: lint
runs-on: ubuntu-latest
env:
COVERALLS_PARALLEL: true
COVERALLS_SERVICE_NAME: github
esmf-version: 8.4.2
strategy:
matrix:
include:
- python-version: "3.9"
tox-build: "py39-esmpy-coveralls"
tox-build: "py39-coveralls"
- python-version: "3.10"
tox-build: "py310-esmpy-coveralls"
tox-build: "py310-coveralls"
- python-version: "3.11"
tox-build: "py311-esmpy-coveralls"
tox-build: "py311-coveralls"
# - python-version: "3.12"
# tox-build: "py312-esmpy-coveralls"
# tox-build: "py312-coveralls"
defaults:
run:
shell: bash -l {0}
Expand All @@ -79,21 +78,10 @@ jobs:
with:
egress-policy: audit
- uses: actions/[email protected]
- name: Setup Conda (Micromamba) with Python ${{ matrix.python-version }}
uses: mamba-org/[email protected]
with:
cache-downloads: true
environment-name: xscen-pypi
create-args: >-
esmf=${{ env.esmf-version }}
mamba
python=${{ matrix.python-version }}
tox
- name: Test with tox
run: |
python -m tox -e ${{ matrix.tox-build }}
env:
ESMF_VERSION: ${{ env.esmf-version }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_FLAG_NAME: run-Python${{ matrix.python-version }}

Expand Down
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ dependencies = [
"toolz",
"xarray<2023.11.0", # FIXME: Remove when pandas 2.2 is released and xclim is fixed.
"xclim>=0.46.0",
"xesmf>=0.7",
"zarr"
]

Expand Down Expand Up @@ -104,6 +103,9 @@ docs = [
"sphinx-rtd-theme>=1.0",
"sphinxcontrib-napoleon"
]
extra = [
"xesmf>=0.7"
]

[project.urls]
"About Ouranos" = "https://www.ouranos.ca/en/"
Expand Down
7 changes: 7 additions & 0 deletions tests/test_aggregate.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
import xscen as xs
from xscen.testing import datablock_3d

try:
import xesmf as xe
except ImportError:
xe = None


class TestClimatologicalMean:
def test_future_warning(self):
Expand Down Expand Up @@ -414,6 +419,8 @@ class TestSpatialMean:
)
@pytest.mark.parametrize("lonstart", [-70, -30, 0])
def test_global(self, lonstart, method, exp):
if method == "xesmf" and xe is None:
pytest.skip("xesmf needed for testing averaging with method xesmf")
ds = datablock_3d(
np.array([[[0, 1, 2], [1, 2, 3], [2, 3, 4]]] * 3, "float"),
"tas",
Expand Down
9 changes: 7 additions & 2 deletions tests/test_ensembles.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
import pytest
import xarray as xr
import xclim as xc
import xesmf

try:
import xesmf as xe
except ImportError:
xe = None
from xclim.testing.helpers import test_timeseries as timeseries

import xscen as xs
Expand Down Expand Up @@ -1064,6 +1068,7 @@ def test_attribute_weight_error(self):


class TestEnsemblePartition:
@pytest.mark.skipif(xe is None, reason="xesmf needed for testing regrdding")
def test_build_partition_data(self, samplecat, tmp_path):
# test subset
datasets = samplecat.search(variable="tas").to_dataset_dict(
Expand All @@ -1083,7 +1088,7 @@ def test_build_partition_data(self, samplecat, tmp_path):
assert [i for i in ds.data_vars] == ["tg_mean"]

# test regrid
ds_grid = xesmf.util.cf_grid_2d(-75, -74, 0.25, 45, 48, 0.55)
ds_grid = xe.util.cf_grid_2d(-75, -74, 0.25, 45, 48, 0.55)
datasets = samplecat.search(variable="tas", member="r1i1p1f1").to_dataset_dict(
xarray_open_kwargs={"engine": "h5netcdf"}
)
Expand Down
6 changes: 6 additions & 0 deletions tests/test_regrid.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import numpy as np
import pytest

try:
import xesmf as xe
except ImportError:
xe = None
from xscen.regrid import create_bounds_rotated_pole, regrid_dataset
from xscen.testing import datablock_3d

Expand All @@ -22,6 +27,7 @@ def test_create_bounds_rotated_pole():
np.testing.assert_allclose(bnds.lat_bounds[-1, -1, 1], 42.5)


@pytest.mark.skipif(xe is None, reason="xesmf needed for testing regrdding")
class TestRegridDataset:
def test_simple(self, tmp_path):
dsout = datablock_3d(
Expand Down
15 changes: 2 additions & 13 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
min_version = 4.0
envlist =
lint
py{39,310,311,312}-esmpy
py{39,310,311,312}
docs-esmpy
requires =
babel
Expand Down Expand Up @@ -55,30 +55,19 @@ commands =
pytest --xdoctest xscen --durations=10 {posargs}

[testenv]
description = Run tests with pytest under {basepython} (Anaconda distribution)
description = Run tests with pytest under {basepython} (PyPI only)
setenv =
COV_CORE_SOURCE =
PYTEST_ADDOPTS = --color=yes --cov=xscen --strict-markers --verbose
PYTHONPATH = {toxinidir}
passenv =
COVERALLS_*
ESMFMKFILE
ESMF_VERSION
GITHUB_*
download = true
deps =
coveralls: coveralls
esmpy: git+https://github.com/esmf-org/esmf.git@v{env:ESMF_VERSION}\#subdirectory=src/addon/esmpy
extras =
dev
conda_channels =
conda-forge
defaults
conda_deps =
pytest
pytest-cov
xdoctest
conda_env = environment.yml
install_command = python -m pip install --no-user {opts} {packages}
commands_pre =
pip list
Expand Down
11 changes: 10 additions & 1 deletion xscen/aggregate.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
import xarray as xr
import xclim as xc
import xclim.core.calendar
import xesmf as xe

try:
import xesmf as xe
except ImportError:
xe = None
from xclim.core.indicator import Indicator

from .config import parse_config
Expand Down Expand Up @@ -930,6 +934,11 @@ def spatial_mean( # noqa: C901

# Uses xesmf.SpatialAverager
elif method == "xesmf":
if xe is None:
raise ImportError(
"Method xesmf requires xESMF to work, please install that package."
)

# If the region is a bounding box, call shapely and geopandas to transform it into an input compatible with xesmf
if region["method"] == "bbox":
polygon_geom = shapely.box(
Expand Down
15 changes: 13 additions & 2 deletions xscen/regrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
import cf_xarray as cfxr
import numpy as np
import xarray as xr
import xesmf as xe

try:
import xesmf as xe
from xesmf.frontend import Regridder
except ImportError:
xe = None
Regridder = "xesmf.Regridder"

from .config import parse_config

Expand Down Expand Up @@ -75,6 +81,11 @@ def regrid_dataset( # noqa: C901
--------
xesmf.regridder, xesmf.util.cf_grid_2d
"""
if xe is None:
raise ImportError(
"xscen's regridding functionality requires xESMF to work, please install that package."
)

regridder_kwargs = regridder_kwargs or {}

ds_grids = [] # list of target grids
Expand Down Expand Up @@ -293,7 +304,7 @@ def _regridder(
method: str = "bilinear",
unmapped_to_nan: Optional[bool] = True,
**kwargs,
) -> xe.frontend.Regridder:
) -> Regridder:
"""Call to xesmf Regridder with a few default arguments.
Parameters
Expand Down

0 comments on commit 1196b40

Please sign in to comment.