diff --git a/.github/workflows/ci-additional.yaml b/.github/workflows/ci-additional.yaml index 93fbd10b845..e5beae04e69 100644 --- a/.github/workflows/ci-additional.yaml +++ b/.github/workflows/ci-additional.yaml @@ -32,6 +32,7 @@ jobs: with: fetch-depth: 2 persist-credentials: false + - uses: xarray-contrib/ci-trigger@10cd2bfec3484946a4058a421ddf9cfad101e715 # v1.2.1 id: detect-trigger with: @@ -50,8 +51,10 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false + - uses: xarray-contrib/pixi-lock/create-and-cache@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 id: pixi-lock + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: pixi-lock @@ -81,6 +84,7 @@ jobs: uses: xarray-contrib/pixi-lock/restore@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} + - uses: prefix-dev/setup-pixi@d3f436a425481402e6a95a1d1fc10331c708cd9e # v0.10.2 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} @@ -91,6 +95,7 @@ jobs: - name: Version info run: | pixi run -e ${{env.PIXI_ENV}} -- python xarray/util/print_versions.py + - name: Run doctests run: | # Raise an error if there are warnings in the doctests, with `-Werror`. @@ -116,27 +121,31 @@ jobs: with: fetch-depth: 0 # Fetch all history for all branches and tags. persist-credentials: false + - name: Restore cached pixi lockfile uses: xarray-contrib/pixi-lock/restore@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} + - uses: prefix-dev/setup-pixi@d3f436a425481402e6a95a1d1fc10331c708cd9e # v0.10.2 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true environments: ${{ env.PIXI_ENV }} cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + - name: set environment variables run: | echo "TODAY=$(date +'%Y-%m-%d')" >> $GITHUB_ENV echo "PYTHON_VERSION=$(pixi run -e ${{env.PIXI_ENV}} -- python --version | cut -d' ' -f2 | cut -d. -f1,2)" >> $GITHUB_ENV + - name: Version info run: | pixi run -e ${{env.PIXI_ENV}} -- python xarray/util/print_versions.py - name: Run mypy run: | - pixi run -e ${{env.PIXI_ENV}} -- python -m mypy --install-types --non-interactive --cobertura-xml-report mypy_report + pixi run -e ${{env.PIXI_ENV}} -- python -m mypy --cobertura-xml-report mypy_report - name: Upload mypy coverage to Codecov uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 @@ -162,27 +171,31 @@ jobs: with: fetch-depth: 0 # Fetch all history for all branches and tags. persist-credentials: false + - name: Restore cached pixi lockfile uses: xarray-contrib/pixi-lock/restore@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} + - uses: prefix-dev/setup-pixi@d3f436a425481402e6a95a1d1fc10331c708cd9e # v0.10.2 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true environments: ${{ env.PIXI_ENV }} cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + - name: set environment variables run: | echo "TODAY=$(date +'%Y-%m-%d')" >> $GITHUB_ENV echo "PYTHON_VERSION=$(pixi run -e ${{env.PIXI_ENV}} -- python --version | cut -d' ' -f2 | cut -d. -f1,2)" >> $GITHUB_ENV + - name: Version info run: | pixi run -e ${{env.PIXI_ENV}} -- python xarray/util/print_versions.py - name: Run mypy run: | - pixi run -e ${{env.PIXI_ENV}} -- python -m mypy --install-types --non-interactive --cobertura-xml-report mypy_report + pixi run -e ${{env.PIXI_ENV}} -- python -m mypy --cobertura-xml-report mypy_report - name: Upload mypy coverage to Codecov uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 @@ -216,6 +229,7 @@ jobs: uses: xarray-contrib/pixi-lock/restore@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} + - uses: prefix-dev/setup-pixi@d3f436a425481402e6a95a1d1fc10331c708cd9e # v0.10.2 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} @@ -227,10 +241,6 @@ jobs: run: | pixi run -e ${{env.PIXI_ENV}} -- python xarray/util/print_versions.py - - name: Install type stubs - run: | - pixi run -e ${{env.PIXI_ENV}} -- python -m mypy --install-types --non-interactive xarray/ || true - - name: Run stubtest (core modules) run: | pixi run -e ${{env.PIXI_ENV}} -- python -m mypy.stubtest \ @@ -267,16 +277,19 @@ jobs: uses: xarray-contrib/pixi-lock/restore@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} + - uses: prefix-dev/setup-pixi@d3f436a425481402e6a95a1d1fc10331c708cd9e # v0.10.2 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true environments: ${{ matrix.pixi-env }} cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + - name: set environment variables run: | echo "TODAY=$(date +'%Y-%m-%d')" >> $GITHUB_ENV echo "PYTHON_VERSION=$(pixi run -e ${{ matrix.pixi-env }} -- python --version | cut -d' ' -f2 | cut -d. -f1,2)" >> $GITHUB_ENV + - name: Version info run: | pixi run -e ${{ matrix.pixi-env }} -- python xarray/util/print_versions.py diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ccbf7a10dfc..a48e8485352 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -51,8 +51,10 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false + - uses: xarray-contrib/pixi-lock/create-and-cache@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 id: pixi-lock + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: pixi-lock @@ -107,10 +109,12 @@ jobs: with: fetch-depth: 0 # Fetch all history for all branches and tags. persist-credentials: false + - name: Restore cached pixi lockfile uses: xarray-contrib/pixi-lock/restore@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} + - uses: prefix-dev/setup-pixi@d3f436a425481402e6a95a1d1fc10331c708cd9e # v0.10.2 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} diff --git a/.github/workflows/hypothesis.yaml b/.github/workflows/hypothesis.yaml index 48f180fa9de..6216d9ebc98 100644 --- a/.github/workflows/hypothesis.yaml +++ b/.github/workflows/hypothesis.yaml @@ -31,6 +31,7 @@ jobs: with: fetch-depth: 2 persist-credentials: false + - uses: xarray-contrib/ci-trigger@10cd2bfec3484946a4058a421ddf9cfad101e715 # v1.2.1 id: detect-trigger with: @@ -57,8 +58,10 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false + - uses: xarray-contrib/pixi-lock/create-and-cache@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 id: pixi-lock + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: pixi-lock @@ -89,6 +92,7 @@ jobs: uses: xarray-contrib/pixi-lock/restore@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} + - uses: prefix-dev/setup-pixi@d3f436a425481402e6a95a1d1fc10331c708cd9e # v0.10.2 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} diff --git a/.github/workflows/nightly-wheels.yml b/.github/workflows/nightly-wheels.yml index f7dd1dee4e4..fb7dc01e26b 100644 --- a/.github/workflows/nightly-wheels.yml +++ b/.github/workflows/nightly-wheels.yml @@ -16,6 +16,7 @@ jobs: with: fetch-depth: 0 persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.12" diff --git a/.github/workflows/pypi-release.yaml b/.github/workflows/pypi-release.yaml index 66a177c0eb7..817504c48eb 100644 --- a/.github/workflows/pypi-release.yaml +++ b/.github/workflows/pypi-release.yaml @@ -26,6 +26,7 @@ jobs: with: fetch-depth: 0 persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 name: Install Python with: @@ -52,6 +53,7 @@ jobs: else echo "✅ Looks good" fi + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: releases @@ -65,10 +67,12 @@ jobs: name: Install Python with: python-version: "3.12" + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: releases path: dist + - name: List contents of built dist run: | ls -ltrh @@ -96,6 +100,7 @@ jobs: with: name: releases path: dist + - name: Publish package to TestPyPI if: github.event_name == 'push' uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 @@ -119,6 +124,7 @@ jobs: with: name: releases path: dist + - name: Publish package to PyPI uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 with: diff --git a/.github/workflows/upstream-dev-ci.yaml b/.github/workflows/upstream-dev-ci.yaml index d1fa4a93d61..d754aa36ba5 100644 --- a/.github/workflows/upstream-dev-ci.yaml +++ b/.github/workflows/upstream-dev-ci.yaml @@ -35,6 +35,7 @@ jobs: with: fetch-depth: 2 persist-credentials: false + - uses: xarray-contrib/ci-trigger@10cd2bfec3484946a4058a421ddf9cfad101e715 # v1.2.1 id: detect-trigger with: @@ -69,6 +70,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false + - uses: xarray-contrib/pixi-lock/create-and-cache@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 id: pixi-lock with: @@ -76,6 +78,7 @@ jobs: hash-files: | ${{ env.MANIFEST_PATH }} pyproject.toml + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: pixi-lock @@ -108,15 +111,18 @@ jobs: with: fetch-depth: 0 # Fetch all history for all branches and tags. persist-credentials: false + - name: Determine log path id: determine-log-path run: | echo "log-file=output-${ENV}-log.jsonl" >> $GITHUB_OUTPUT; + - name: Restore cached pixi lockfile uses: xarray-contrib/pixi-lock/restore@1fab4c17af8243f6ca1321bc941cf2325f46c05d # v0.1.1 with: manifest-path: ${{ env.MANIFEST_PATH }} cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} + - uses: prefix-dev/setup-pixi@d3f436a425481402e6a95a1d1fc10331c708cd9e # v0.10.2 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} @@ -124,12 +130,15 @@ jobs: environments: ${{ matrix.pixi-env }} manifest-path: ${{ env.MANIFEST_PATH }} cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + - name: Version info run: | pixi run --manifest-path "$MANIFEST_PATH" -e $ENV -- python xarray/util/print_versions.py + - name: Import xarray run: | pixi run --manifest-path "$MANIFEST_PATH" -e $ENV -- python -c 'import xarray' + - name: Run Tests if: success() id: status @@ -141,6 +150,7 @@ jobs: -e $ENV \ -- \ python -m pytest --timeout=60 -rf -nauto --report-log "$LOG_PATH" + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: failure() with: @@ -165,6 +175,7 @@ jobs: with: name: log file path: logs/ + - name: Generate and publish the report uses: scientific-python/issue-from-pytest-log-action@35b4e0a9e06f8e7e261778289cf4b968b722662d # v1.6.2 with: @@ -201,6 +212,7 @@ jobs: with: manifest-path: ${{ env.MANIFEST_PATH }} cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} + - uses: prefix-dev/setup-pixi@d3f436a425481402e6a95a1d1fc10331c708cd9e # v0.10.2 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} @@ -213,12 +225,15 @@ jobs: run: | echo "TODAY=$(date +'%Y-%m-%d')" >> $GITHUB_ENV echo "PYTHON_VERSION=$(pixi run --manifest-path "$MANIFEST_PATH" -e $ENV -- python --version | cut -d' ' -f2 | cut -d. -f1,2)" >> $GITHUB_ENV + - name: Version info run: | pixi run --manifest-path "$MANIFEST_PATH" -e $ENV -- python xarray/util/print_versions.py + - name: Run mypy run: | pixi run --manifest-path "$MANIFEST_PATH" -e $ENV -- python -m mypy --install-types --non-interactive --cobertura-xml-report mypy_report + - name: Upload mypy coverage to Codecov uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 with: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d5584fc81d8..c2f30c76367 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -59,12 +59,13 @@ repos: typing-extensions>=4.1.0, numpy, ] - # keep the mypy version used in CI (pixi.toml) in sync with the hook above, so that the - # pre-commit.ci autoupdate also updates mypy in CI + # keep the mypy version used in CI (pixi.toml) and the dev dependency group + # (pyproject.toml) in sync with the hook above, so that the pre-commit.ci autoupdate + # also updates mypy in CI and for uv users - repo: local hooks: - id: sync-mypy-version - name: sync the mypy version in pixi.toml + name: sync mypy version language: python files: ^\.pre-commit-config\.yaml$ pass_filenames: false @@ -73,7 +74,9 @@ repos: config = pathlib.Path('.pre-commit-config.yaml').read_text(); version = re.search(r'mirrors-mypy\s+rev: v?([0-9.]+)', config).group(1); pixi = pathlib.Path('pixi.toml'); - pixi.write_text(re.sub(r'(?m)^mypy = \"==[0-9.]+\"', f'mypy = \"=={version}\"', pixi.read_text()))" + pixi.write_text(re.sub(r'(?m)^mypy = \"==[0-9.]+\"', f'mypy = \"=={version}\"', pixi.read_text())); + pyproject = pathlib.Path('pyproject.toml'); + pyproject.write_text(re.sub(r'\"mypy==[0-9.]+\"', f'\"mypy=={version}\"', pyproject.read_text()))" - repo: https://github.com/citation-file-format/cff-converter-python rev: 5295f87c0e261da61a7b919fc754e3a77edd98a7 hooks: diff --git a/doc/user-guide/ecosystem.rst b/doc/user-guide/ecosystem.rst index 99ffa45adf4..7c5f9b0869d 100644 --- a/doc/user-guide/ecosystem.rst +++ b/doc/user-guide/ecosystem.rst @@ -17,6 +17,7 @@ Geosciences - `cf_xarray `_: Provides an accessor (DataArray.cf or Dataset.cf) that allows you to interpret Climate and Forecast metadata convention attributes present on xarray objects. - `climpred `_: Analysis of ensemble forecast models for climate prediction. - `geocube `_: Tool to convert geopandas vector data into rasterized xarray data. +- `GeoUtils `_: Raster and vector operations for geospatial analysis, built on rasterio and geopandas. - `GeoWombat `_: Utilities for analysis of remotely sensed and gridded raster data at scale (easily tame Landsat, Sentinel, Quickbird, and PlanetScope). - `grib2io `_: Utility to work with GRIB2 files including an xarray backend, DASK support for parallel reading in open_mfdataset, lazy loading of data, editing of GRIB2 attributes and GRIB2IO DataArray attrs, and spatial interpolation and reprojection of GRIB2 messages and GRIB2IO Datasets/DataArrays for both grid to grid and grid to stations. - `gsw-xarray `_: a wrapper around `gsw `_ that adds CF compliant attributes when possible, units, name. diff --git a/pixi.toml b/pixi.toml index ff9fb05e01d..8768fa44978 100644 --- a/pixi.toml +++ b/pixi.toml @@ -231,6 +231,7 @@ types-decorator = "*" types-networkx = "*" types-openpyxl = "*" types-psutil = "*" +types-pycurl = "*" types-Pygments = "*" types-python-dateutil = "*" types-pytz = "*" @@ -242,7 +243,10 @@ pip = "*" [feature.typing.pypi-dependencies] types-defusedxml = "*" +types-gevent = "*" types-pexpect = "*" +types-pysocks = "*" +types-xlrd = "*" # pandas-stubs / scipy-stubs live in their own feature, rather than in `typing`, # so that `test-nightly` can source them from PyPI (see the `nightly` feature) @@ -255,7 +259,7 @@ pandas-stubs = "<=2.3.3.251219" scipy-stubs = ">=1.17.1.2" [feature.typing.tasks] -mypy = { cmd = "mypy --install-types --non-interactive --cobertura-xml-report mypy_report", description = "Run mypy type checking and generate a Cobertura XML report." } +mypy = { cmd = "mypy --cobertura-xml-report mypy_report", description = "Run mypy type checking and generate a Cobertura XML report." } [feature.pre-commit.dependencies] pre-commit = "*" diff --git a/pyproject.toml b/pyproject.toml index 600d2c7a8bb..8ce4391adae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,12 +58,14 @@ types = [ "types-decorator", "types-defusedxml", "types-docutils", + "types-gevent", "types-networkx", "types-openpyxl", "types-pexpect", "types-psutil", "types-pycurl", "types-Pygments", + "types-pysocks", "types-python-dateutil", "types-pytz", "types-PyYAML", @@ -76,7 +78,7 @@ types = [ dev = [ "hypothesis", "jinja2", - "mypy==1.19.1", + "mypy==2.3.1", "pre-commit", "pytest", "pytest-cov",