diff --git a/.circleci/config.yml b/.circleci/config.yml index 5fc6d40897..887bee554a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,6 +17,20 @@ jobs: - run: name: Check dependencies are compatible command: pixi run --as-is pip check + - run: + name: Generate pre-commit cache key + command: date '+%Y-%W' | tee pre_commit_cache_key.txt + - restore_cache: + key: pre-commit-{{ .Branch }}-{{ checksum "pre_commit_cache_key.txt" }} + - run: + name: Check code quality + command: pixi run --as-is pre-commit run -a + - save_cache: + key: pre-commit-{{ .Branch }}-{{ checksum "pre_commit_cache_key.txt" }} + paths: + - ~/.cache/pre-commit + - ./.mypy_cache + - ./.ruff_cache - run: name: Run tests command: | diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b8a7c258bc..446682c200 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -14,6 +14,24 @@ updates: interval: "weekly" cooldown: default-days: 7 + groups: + gha: + patterns: + - "*" + labels: + - dependencies + - github_actions + - automatedPR + - package-ecosystem: "pre-commit" + directory: "/" + schedule: + interval: "weekly" + cooldown: + default-days: 7 + groups: + pre-commit: + patterns: + - "*" labels: - dependencies - github_actions diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000000..021560f489 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,23 @@ +name: GitHub Actions Security Analysis with zizmor 🌈 + +on: + push: + branches: ["main"] + pull_request: + branches: ["**"] + +permissions: {} + +jobs: + zizmor: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Run zizmor 🌈 + uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7 + with: + advanced-security: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 39f1308947..02dfd4946d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,20 +25,35 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace args: [--markdown-linebreak-ext=md] - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.15.22" + - repo: local hooks: - id: ruff-check - args: [--fix] + name: ruff check + entry: "pixi run --locked ruff check --force-exclude --fix" + additional_dependencies: ['pixi'] + language: python # system + require_serial: true + types_or: + - python + - jupyter - id: ruff-format - - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v2.3.0" - hooks: + name: ruff format + entry: "pixi run --locked ruff format --force-exclude" + additional_dependencies: ['pixi'] + language: python # system + require_serial: true + types_or: + - python + - jupyter - id: mypy - additional_dependencies: - - "types-PyYAML" - - "types-requests" - - "numpy" + name: mypy + entry: "pixi run --locked mypy" + additional_dependencies: ['pixi'] + language: python # system + types: + - python + pass_filenames: false + require_serial: true - repo: https://github.com/adrienverge/yamllint rev: "v1.38.0" hooks: @@ -53,8 +68,3 @@ repos: - id: check-citation-file-format - id: check-github-workflows - id: check-circle-ci - - repo: https://github.com/zizmorcore/zizmor-pre-commit - rev: v1.27.0 - hooks: - - id: zizmor - args: [--fix=safe] diff --git a/doc/contributing.rst b/doc/contributing.rst index a6b1701fa6..8cba49cd2c 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -39,8 +39,8 @@ whenever you read it. It is recommended that you open a `draft pull request `__ -early, as this will cause :ref:`CircleCI to run the unit tests `, -:ref:`pre-commit.ci to analyse your code `, and +early, as this will cause CircleCI to :ref:`run the tests ` and +:ref:`analyse the code `, and :ref:`readthedocs to build the documentation `. It's also easier to get help from other developers if your code is visible in a pull request. @@ -249,7 +249,7 @@ should be correct. Both `ruff`_ and `mypy`_ are automatically run by pre-commit. When you make a pull request, adherence to the Python development best practices -is checked by `pre-commit.ci `_. +is checked by running the pre-commit hooks on CircleCI. YAML ~~~~ diff --git a/esmvalcore/_task.py b/esmvalcore/_task.py index 5e50ae847f..432e05c425 100644 --- a/esmvalcore/_task.py +++ b/esmvalcore/_task.py @@ -1006,7 +1006,7 @@ def _run_task( ) -> tuple[list[str], set[TrackedFile]]: """Run task and return the result.""" if scheduler_address is None: - client = contextlib.nullcontext() + client: contextlib.AbstractContextManager = contextlib.nullcontext() else: client = Client(scheduler_address) diff --git a/esmvalcore/cmor/_fixes/cordex/cordex_fixes.py b/esmvalcore/cmor/_fixes/cordex/cordex_fixes.py index 9cc483ba11..18ded9688a 100644 --- a/esmvalcore/cmor/_fixes/cordex/cordex_fixes.py +++ b/esmvalcore/cmor/_fixes/cordex/cordex_fixes.py @@ -327,7 +327,7 @@ def _use_standard_lambert_conformal_grid( lon_coord.units = "degrees_east" lat_coord.units = "degrees_north" lon_coord.points, lat_coord.points = transformer.transform( - *np.meshgrid(x_coord.points, y_coord.points), + *np.meshgrid(x_coord.points, y_coord.points), # type: ignore[call-overload] errcheck=True, ) diff --git a/esmvalcore/io/intake_esgf.py b/esmvalcore/io/intake_esgf.py index eb1bffc4bc..6cf8f0eba9 100644 --- a/esmvalcore/io/intake_esgf.py +++ b/esmvalcore/io/intake_esgf.py @@ -186,7 +186,7 @@ def find_data(self, **facets: FacetValue) -> list[IntakeESGFDataset]: if not any(_isglob(v) for v in values) } # Translate "our" facets to ESGF facets and "our" values to ESGF values. - query = { + query: dict[str, Any] = { their_facet: [ self.values.get(our_facet, {}).get(v, v) for v in non_glob_facets[our_facet] diff --git a/esmvalcore/preprocessor/_area.py b/esmvalcore/preprocessor/_area.py index 34ceacad0c..801de835b7 100644 --- a/esmvalcore/preprocessor/_area.py +++ b/esmvalcore/preprocessor/_area.py @@ -16,6 +16,7 @@ import numpy as np import shapely import shapely.ops +import shapely.vectorized from dask import array as da from iris.coords import AuxCoord from iris.cube import CubeList @@ -47,6 +48,8 @@ logger = logging.getLogger(__name__) +type ExtractShapeMethod = Literal["contains", "representative"] + SHAPE_ID_KEYS: tuple[str, ...] = ("name", "NAME", "Name", "id", "ID") @@ -597,7 +600,7 @@ def _get_masks_from_geometries( geometries: dict[str, dict], lon: np.ndarray, lat: np.ndarray, - method: str = "contains", + method: ExtractShapeMethod = "contains", decomposed: bool = False, ) -> dict[str, np.ndarray]: """Get cube masks from requested regions.""" @@ -643,7 +646,7 @@ def _get_bounds( def _get_single_mask( lon: np.ndarray, lat: np.ndarray, - method: str, + method: ExtractShapeMethod, geometry: dict, ) -> np.ndarray: """Get single mask from one region.""" @@ -750,7 +753,7 @@ def _update_shapefile_path( def extract_shape( cube: Cube, shapefile: str | Path, - method: str = "contains", + method: ExtractShapeMethod = "contains", crop: bool = True, decomposed: bool = False, ids: list | dict | None = None, diff --git a/esmvalcore/preprocessor/_compare_with_refs.py b/esmvalcore/preprocessor/_compare_with_refs.py index 4e6fc6c180..a77c3b9ce5 100644 --- a/esmvalcore/preprocessor/_compare_with_refs.py +++ b/esmvalcore/preprocessor/_compare_with_refs.py @@ -592,7 +592,7 @@ def _get_emd( arr: np.ndarray, ref_arr: np.ndarray, bin_centers: np.ndarray, -) -> np.ndarray: +) -> float | np.ma.core.MaskedConstant: """Calculate Earth mover's distance (non-lazy).""" if np.ma.is_masked(arr) or np.ma.is_masked(ref_arr): return np.ma.masked # this is safe because PMFs will be masked arrays diff --git a/esmvalcore/preprocessor/_io.py b/esmvalcore/preprocessor/_io.py index 34b3838120..2b78838f79 100644 --- a/esmvalcore/preprocessor/_io.py +++ b/esmvalcore/preprocessor/_io.py @@ -25,7 +25,7 @@ from esmvalcore.iris_helpers import dataset_to_iris if TYPE_CHECKING: - from collections.abc import Sequence + from collections.abc import Mapping, MutableMapping, Sequence from dask.delayed import Delayed @@ -163,7 +163,7 @@ def load( def _load_zarr( file: str | Path, ignore_warnings: list[dict[str, Any]] | None = None, - backend_kwargs: dict[str, Any] | None = None, + backend_kwargs: Mapping[str, Any] | None = None, ) -> CubeList: # note on ``chunks`` kwarg to ``xr.open_dataset()`` # docs.xarray.dev/en/stable/generated/xarray.open_dataset.html @@ -177,7 +177,7 @@ def _load_zarr( # https://github.com/pp-mo/ncdata/issues/139 time_coder = xr.coders.CFDatetimeCoder(use_cftime=True) - open_kwargs = { + open_kwargs: MutableMapping[str, Any] = { "consolidated": False, "decode_times": time_coder, "engine": "zarr", diff --git a/pixi.lock b/pixi.lock index a8abbb0eca..947a15538f 100644 --- a/pixi.lock +++ b/pixi.lock @@ -22,6 +22,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/apsw-3.53.2.0-py314h5bd0f2a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py314h5bd0f2a_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ast-serialize-0.6.0-py310hd8a072f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/at-spi2-atk-2.38.0-h0630a04_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/at-spi2-core-2.40.3-h0630a04_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-h04ea711_2.conda @@ -196,6 +197,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/mmh3-5.2.1-py314ha160325_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.2.1-py314h97ea11e_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/muparser-2.3.5-h5888daf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-2.3.0-py314h518bba1_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/netcdf-fortran-4.6.3-nompi_h4a60669_100.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.7.4-nompi_py311h498b1eb_108.conda @@ -223,6 +225,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/pyproj-3.7.2-py314h7ce3bca_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.6-habeac84_100_cp314.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-eccodes-2.47.0-np2py314h56abb78_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-librt-0.13.0-py314h0f05182_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-stratify-0.4.0-py314h5bd0f2a_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-xxhash-3.7.0-py314he82b845_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda @@ -231,6 +234,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-2026.6.3-py314h1bee95f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.21-h462bb3b_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.4-h92489ea_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.18.0-py314hf07bd8e_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/shapely-2.1.2-py314hbe3edd8_2.conda @@ -407,6 +411,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/multidict-6.7.1-pyh62beb40_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myproxyclient-2.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myst-nb-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myst-parser-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.22.1-pyhcf101f3_0.conda @@ -420,12 +425,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/numpy-typing-compat-20260602.2.5-pyhb860519_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/optype-0.18.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/optype-numpy-0.18.0-pyh5504437_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandas-stubs-3.0.3.260530-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.1.2-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.10.0-pyhcf101f3_0.conda @@ -481,6 +491,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/scipy-stubs-1.18.0.1-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -506,6 +517,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-1.1.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/types-psutil-7.2.2.20260518-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/types-pytz-2026.2.0.20260518-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/types-pyyaml-6.0.12.20260518-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/types-shapely-2.1.0.20260402-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda @@ -668,6 +683,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/multidict-6.7.1-pyh62beb40_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myproxyclient-2.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myst-nb-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myst-parser-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.22.1-pyhcf101f3_0.conda @@ -681,12 +697,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/numpy-typing-compat-20260602.2.5-pyhb860519_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/optype-0.18.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/optype-numpy-0.18.0-pyh5504437_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandas-stubs-3.0.3.260530-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.1.2-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.10.0-pyhcf101f3_0.conda @@ -742,6 +763,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/scipy-stubs-1.18.0.1-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -767,6 +789,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-1.1.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/types-psutil-7.2.2.20260518-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/types-pytz-2026.2.0.20260518-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/types-pyyaml-6.0.12.20260518-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/types-shapely-2.1.0.20260402-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda @@ -793,6 +819,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/apsw-3.53.2.0-py314h6c2aa35_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py314h0612a62_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ast-serialize-0.6.0-py310h3b8a9b8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hd03087b_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-auth-0.10.3-hc11c9a1_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-cal-0.9.14-h81c6212_2.conda @@ -944,6 +971,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mmh3-5.2.1-py314h4ed92d5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.2.1-py314hf8a3a22_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/muparser-2.3.5-h11e0b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-2.3.0-py314h2fbedac_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf-fortran-4.6.3-nompi_h7d4a3b5_100.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf4-1.7.4-nompi_py311hfd37af6_108.conda @@ -973,6 +1001,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyproj-3.7.2-py314h986c384_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.6-h156bc91_100_cp314.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-eccodes-2.47.0-np2py314h4e57505_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-librt-0.13.0-py314ha14b1ff_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-stratify-0.4.0-py314h0612a62_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-xxhash-3.7.0-py314hd7fbd5c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py314h6e9b3f0_1.conda @@ -981,6 +1010,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/re2-2025.11.05-ha480c28_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-2026.6.3-py314he1d1ac0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.21-h828de30_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.18.0-py314h18e1515_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/shapely-2.1.2-py314h277790e_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/snappy-1.2.2-hada39a4_1.conda @@ -4980,6 +5010,25 @@ packages: run_exports: {} size: 35598 timestamp: 1762509505285 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ast-serialize-0.6.0-py310hd8a072f_0.conda + noarch: python + sha256: 98eef90c96e2185254d12e667337077b989e9892167ff2c969e19b9296f42743 + md5: 530aaeffb462b062bf8e3abb66879cf0 + depends: + - python >=3.10 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - _python_abi3_support 1.* + - cpython >=3.10 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ast-serialize?source=hash-mapping + run_exports: {} + size: 1120486 + timestamp: 1782863830347 - conda: https://conda.anaconda.org/conda-forge/linux-64/at-spi2-atk-2.38.0-h0630a04_3.tar.bz2 sha256: 26ab9386e80bf196e51ebe005da77d57decf6d989b4f34d96130560bc133479c md5: 6b889f174df1e0f816276ae69281af4d @@ -9087,6 +9136,26 @@ packages: - muparser >=2.3.5,<2.4.0a0 size: 203174 timestamp: 1747116762269 +- conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-2.3.0-py314h518bba1_0.conda + sha256: 77158133fc8c3fc95acc74742efab4ac40ccd070298c4a946ac8f99b5b7017a9 + md5: 862cee264de9cdba7dda3ccf6312f74e + depends: + - ast-serialize >=0.6.0,<1.0.0 + - mypy_extensions >=1.0.0 + - pathspec >=1.0.0 + - python + - python-librt >=0.13.0 + - typing_extensions >=4.6.0 + - psutil >=4.0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.14.* *_cp314 + license: MIT + purls: + - pkg:pypi/mypy?source=compressed-mapping + run_exports: {} + size: 23233304 + timestamp: 1783986175097 - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda sha256: fc89f74bbe362fb29fa3c037697a89bec140b346a2469a90f7936d1d7ea4d8a3 md5: fc21868a1a5aacc937e7a18747acb8a5 @@ -9143,7 +9212,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/netcdf4?source=compressed-mapping + - pkg:pypi/netcdf4?source=hash-mapping run_exports: {} size: 1094073 timestamp: 1782151628345 @@ -10218,6 +10287,21 @@ packages: run_exports: {} size: 241426 timestamp: 1777545172589 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-librt-0.13.0-py314h0f05182_0.conda + sha256: 80d77ec218796cfa55d51c228532ec7b22da40fae2cae0ee96cf2b8ce6645115 + md5: a9a1c6031fb3a464862d63835dff423b + depends: + - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.14.* *_cp314 + license: MIT + license_family: MIT + purls: + - pkg:pypi/librt?source=hash-mapping + run_exports: {} + size: 162454 + timestamp: 1783529456936 - conda: https://conda.anaconda.org/conda-forge/linux-64/python-stratify-0.4.0-py312h4c3975b_3.conda sha256: 89ad22ddc2be4a0faacfc1209c8053fbff94fb1ac6ecf5b9d53767c46bf9b4f4 md5: b0610b4174af97290f5f466a72583071 @@ -10518,6 +10602,22 @@ packages: run_exports: {} size: 300129 timestamp: 1782831350283 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.21-h462bb3b_1.conda + noarch: python + sha256: e1c9458765584c20a11b400957b0d91889ead735a99f425323fbbf2fe26e7bb8 + md5: cd350880cf64a121362ed2e14ce7341f + depends: + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + constrains: + - __glibc >=2.17 + license: MIT + purls: + - pkg:pypi/ruff?source=compressed-mapping + run_exports: {} + size: 9347142 + timestamp: 1784124753497 - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.4-h92489ea_1.conda sha256: de0bb8c7526684c9927cc687d4d07abe09d023a3ec950cfcd61089b495e2e616 md5: a20feedf58ce5441b115cebf284a9a75 @@ -11746,7 +11846,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/beautifulsoup4?source=hash-mapping + - pkg:pypi/beautifulsoup4?source=compressed-mapping run_exports: {} size: 92704 timestamp: 1780853175566 @@ -11761,7 +11861,7 @@ packages: - tinycss2 >=1.1.0,<1.5 license: Apache-2.0 AND MIT purls: - - pkg:pypi/bleach?source=compressed-mapping + - pkg:pypi/bleach?source=hash-mapping run_exports: {} size: 142246 timestamp: 1780675823953 @@ -11807,7 +11907,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/bokeh?source=compressed-mapping + - pkg:pypi/bokeh?source=hash-mapping run_exports: {} size: 4526315 timestamp: 1781002115296 @@ -12100,7 +12200,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/dask?source=compressed-mapping + - pkg:pypi/dask?source=hash-mapping run_exports: {} size: 1069053 timestamp: 1781221472758 @@ -12195,7 +12295,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/distributed?source=compressed-mapping + - pkg:pypi/distributed?source=hash-mapping run_exports: {} size: 838296 timestamp: 1781563082788 @@ -12327,7 +12427,7 @@ packages: license: Apache-2.0 license_family: APACHE purls: - - pkg:pypi/fastcore?source=compressed-mapping + - pkg:pypi/fastcore?source=hash-mapping run_exports: {} size: 104111 timestamp: 1782729278094 @@ -12510,7 +12610,7 @@ packages: license: Apache-2.0 license_family: APACHE purls: - - pkg:pypi/frozenlist?source=compressed-mapping + - pkg:pypi/frozenlist?source=hash-mapping run_exports: {} size: 19878 timestamp: 1779999782801 @@ -13215,7 +13315,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyter-client?source=compressed-mapping + - pkg:pypi/jupyter-client?source=hash-mapping run_exports: {} size: 117954 timestamp: 1781019994076 @@ -13286,7 +13386,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyter-server?source=compressed-mapping + - pkg:pypi/jupyter-server?source=hash-mapping run_exports: {} size: 363068 timestamp: 1781713810089 @@ -13540,7 +13640,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/mdit-py-plugins?source=compressed-mapping + - pkg:pypi/mdit-py-plugins?source=hash-mapping run_exports: {} size: 50460 timestamp: 1778692223625 @@ -13626,6 +13726,18 @@ packages: run_exports: {} size: 45567 timestamp: 1759838155628 +- conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda + sha256: 6ed158e4e5dd8f6a10ad9e525631e35cee8557718f83de7a4e3966b1f772c4b1 + md5: e9c622e0d00fa24a6292279af3ab6d06 + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/mypy-extensions?source=hash-mapping + run_exports: {} + size: 11766 + timestamp: 1745776666688 - conda: https://conda.anaconda.org/conda-forge/noarch/myst-nb-1.4.0-pyhcf101f3_0.conda sha256: c81d0c8c74c3da66808f8da09d8e48f2af2d173d357d45239defaf466838edba md5: da07c7b1588ad0a44118d28aeb31b6a6 @@ -13676,7 +13788,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/narwhals?source=compressed-mapping + - pkg:pypi/narwhals?source=hash-mapping run_exports: {} size: 285532 timestamp: 1780672242196 @@ -13843,6 +13955,20 @@ packages: run_exports: {} size: 16817 timestamp: 1733408419340 +- conda: https://conda.anaconda.org/conda-forge/noarch/numpy-typing-compat-20260602.2.5-pyhb860519_1.conda + sha256: 510cf01dd2b3934078f8fda5360a645649e0652a4edd94fcaace58e0d53bde56 + md5: f337e1f9bbae5c509a95f77dc3a47a14 + depends: + - python >=3.12 + - numpy <2.6,>=2.5 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy-typing-compat?source=hash-mapping + run_exports: {} + size: 13203 + timestamp: 1782221065995 - conda: https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.3.1-pyhd8ed1ab_0.conda sha256: dfa8222df90736fa13f8896f5a573a50273af8347542d412c3bd1230058e56a5 md5: d4f3f31ee39db3efecb96c0728d4bdbf @@ -13858,6 +13984,35 @@ packages: run_exports: {} size: 102059 timestamp: 1750415349440 +- conda: https://conda.anaconda.org/conda-forge/noarch/optype-0.18.0-pyhc364b38_0.conda + sha256: d88ea70bdbe44ea7e06d5305c363b4624609ed2712f2742e6fb25f05c536fdc0 + md5: c3b24fd5393b5c674dd9607424201e18 + depends: + - python >=3.12 + - typing-extensions >=4.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/optype?source=hash-mapping + run_exports: {} + size: 64931 + timestamp: 1780922251176 +- conda: https://conda.anaconda.org/conda-forge/noarch/optype-numpy-0.18.0-pyh5504437_0.conda + sha256: aa5238f44c1563606f0a448b480e67793422a125321f2039bd519915c21d547d + md5: 1871ee7210705711aec48e32842b3ca8 + depends: + - python >=3.12 + - numpy >=2.0,<2.8 + - numpy-typing-compat >=20260602.2.0,<20260603.2.0 + - optype ==0.18.0 pyhc364b38_0 + - python + license: BSD-3-Clause + license_family: BSD + purls: [] + run_exports: {} + size: 10913 + timestamp: 1780922251176 - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda sha256: 1840bd90d25d4930d60f57b4f38d4e0ae3f5b8db2819638709c36098c6ba770c md5: e51f1e4089cad105b6cac64bd8166587 @@ -13884,6 +14039,20 @@ packages: run_exports: {} size: 91574 timestamp: 1777103621679 +- conda: https://conda.anaconda.org/conda-forge/noarch/pandas-stubs-3.0.3.260530-pyhd8ed1ab_0.conda + sha256: e411d70a35f09f4439d3e8c60ec1a9263b1ee8e7746b610f79087244e1c06a3a + md5: 86cc2a42dc6d7ae2236cfc3a81d4ecc0 + depends: + - numpy >=1.26.0 + - python >=3.11 + - types-pytz >=2022.1.1 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pandas-stubs?source=hash-mapping + run_exports: {} + size: 110817 + timestamp: 1780233848320 - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 sha256: 2bb9ba9857f4774b85900c2562f7e711d08dd48e2add9bee4e1612fbee27e16f md5: 457c2c8c08e54905d6954e79cb5b5db9 @@ -13923,6 +14092,18 @@ packages: run_exports: {} size: 20884 timestamp: 1715026639309 +- conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + sha256: 6eaee417d33f298db79bc7185ab1208604c0e6cf51dade34cd513c6f9db9c6f3 + md5: 11adc78451c998c0fd162584abfa3559 + depends: + - python >=3.10 + license: MPL-2.0 + license_family: MOZILLA + purls: + - pkg:pypi/pathspec?source=hash-mapping + run_exports: {} + size: 56559 + timestamp: 1777271601895 - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda sha256: 202af1de83b585d36445dc1fda94266697341994d1a3328fabde4989e1b3d07a md5: d0d408b1f18883a944376da5cf8101ea @@ -14484,7 +14665,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/python-discovery?source=compressed-mapping + - pkg:pypi/python-discovery?source=hash-mapping run_exports: {} size: 35514 timestamp: 1781257630962 @@ -14792,6 +14973,22 @@ packages: run_exports: {} size: 11074 timestamp: 1766025162370 +- conda: https://conda.anaconda.org/conda-forge/noarch/scipy-stubs-1.18.0.1-pyhc364b38_0.conda + sha256: 5fcdd4d08f120fa991dd0057b16cc8e33eedb29e19f7c29752feb33d76567c8a + md5: 762dcb2958a9b7cda6e38d0c04378715 + depends: + - python >=3.12 + - optype-numpy >=0.15.0,<0.20.0 + - python + constrains: + - scipy >=1.18.0,<1.19.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/scipy-stubs?source=hash-mapping + run_exports: {} + size: 381529 + timestamp: 1783898380185 - conda: https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_7.conda sha256: fabfe031ede99898cb2b0b805f6c0d64fcc24ecdb444de3a83002d8135bf4804 md5: 5f0ebbfea12d8e5bddff157e271fdb2f @@ -15005,7 +15202,7 @@ packages: license: BSD-2-Clause license_family: BSD purls: - - pkg:pypi/sphinxcontrib-serializinghtml?source=compressed-mapping + - pkg:pypi/sphinxcontrib-serializinghtml?source=hash-mapping run_exports: {} size: 30640 timestamp: 1781260357443 @@ -15035,7 +15232,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/starlette?source=compressed-mapping + - pkg:pypi/starlette?source=hash-mapping run_exports: {} size: 64264 timestamp: 1781447071524 @@ -15172,6 +15369,55 @@ packages: run_exports: {} size: 24279 timestamp: 1766494826559 +- conda: https://conda.anaconda.org/conda-forge/noarch/types-psutil-7.2.2.20260518-pyhd8ed1ab_0.conda + sha256: 4a42fa75861f41e8f1a694fc6e673c0877cbe02aa54ccbaec13cd33bead83713 + md5: 63874239ef27c5b5a8e3409a07382292 + depends: + - python >=3.10 + license: Apache-2.0 AND MIT + purls: + - pkg:pypi/types-psutil?source=hash-mapping + run_exports: {} + size: 32892 + timestamp: 1779102286490 +- conda: https://conda.anaconda.org/conda-forge/noarch/types-pytz-2026.2.0.20260518-pyhcf101f3_0.conda + sha256: b96a77604fbe7cf4df9d48a1679247c5877aad00d00e663ce2e06f13b3e72dcb + md5: ee605d821d094cfb7d0eecdecaccdeee + depends: + - python >=3.10 + - python + license: Apache-2.0 AND MIT + purls: + - pkg:pypi/types-pytz?source=hash-mapping + run_exports: {} + size: 20398 + timestamp: 1779096753335 +- conda: https://conda.anaconda.org/conda-forge/noarch/types-pyyaml-6.0.12.20260518-pyhcf101f3_0.conda + sha256: 58eb35e905356d7105db51e1cd7eb5a9f2029e0d0bb345215c0eb525babaffb4 + md5: 8c9d908beae2f052bf188c41c85f0b80 + depends: + - python >=3.10 + - python + license: Apache-2.0 AND MIT + purls: + - pkg:pypi/types-pyyaml?source=hash-mapping + run_exports: {} + size: 26875 + timestamp: 1779101988372 +- conda: https://conda.anaconda.org/conda-forge/noarch/types-shapely-2.1.0.20260402-pyhcf101f3_0.conda + sha256: 77814d0eb90f9686de6929ab1301adb721afdf221dd12bca2f3a28054d50b87a + md5: 881262e1e2db2323071c4964c5028c7f + depends: + - python >=3.10 + - numpy >=1.20 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/types-shapely?source=hash-mapping + run_exports: {} + size: 37614 + timestamp: 1775123303475 - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c md5: edd329d7d3a4ab45dcf905899a7a6115 @@ -15285,7 +15531,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/uvicorn?source=hash-mapping + - pkg:pypi/uvicorn?source=compressed-mapping run_exports: {} size: 56228 timestamp: 1780574319325 @@ -15316,7 +15562,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/virtualenv?source=compressed-mapping + - pkg:pypi/virtualenv?source=hash-mapping run_exports: {} size: 3111990 timestamp: 1781651033074 @@ -15630,6 +15876,24 @@ packages: run_exports: {} size: 34218 timestamp: 1762509977830 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ast-serialize-0.6.0-py310h3b8a9b8_0.conda + noarch: python + sha256: 0efbe4158ee4d5ff4108ad1b8c677e85eb1a8f3bb48fe2277579860d38e48315 + md5: 9bc9209a773faadbdca5fe45d9aa9cdc + depends: + - python >=3.10 + - __osx >=11.0 + - _python_abi3_support 1.* + - cpython >=3.10 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ast-serialize?source=hash-mapping + run_exports: {} + size: 1077921 + timestamp: 1782863843092 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hd03087b_2.conda sha256: b0747f9b1bc03d1932b4d8c586f39a35ac97e7e72fe6e63f2b2a2472d466f3c1 md5: 57301986d02d30d6805fdce6c99074ee @@ -19517,6 +19781,25 @@ packages: - muparser >=2.3.5,<2.4.0a0 size: 154087 timestamp: 1747117056226 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-2.3.0-py314h2fbedac_0.conda + sha256: 614b2b3941810a3747c521f496bd22dcd36f27749e065982e02d02f1f9aaa170 + md5: 416fa3630816cb0deb540caef775461a + depends: + - ast-serialize >=0.6.0,<1.0.0 + - mypy_extensions >=1.0.0 + - pathspec >=1.0.0 + - python + - python-librt >=0.13.0 + - typing_extensions >=4.6.0 + - psutil >=4.0 + - __osx >=11.0 + - python_abi 3.14.* *_cp314 + license: MIT + purls: + - pkg:pypi/mypy?source=compressed-mapping + run_exports: {} + size: 13696727 + timestamp: 1783986170854 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda sha256: 4ea6c620b87bd1d42bb2ccc2c87cd2483fa2d7f9e905b14c223f11ff3f4c455d md5: 343d10ed5b44030a2f67193905aea159 @@ -19708,7 +19991,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/numpy?source=compressed-mapping + - pkg:pypi/numpy?source=hash-mapping run_exports: weak: - numpy >=1.25,<3 @@ -20648,6 +20931,21 @@ packages: run_exports: {} size: 250582 timestamp: 1777545231051 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-librt-0.13.0-py314ha14b1ff_0.conda + sha256: 0d5b3b303a091063a42ac72ddf39a9c31216217773cc15b2fc54f349cbc96f91 + md5: e5d073b8e272361036e77d0a00145965 + depends: + - python + - __osx >=11.0 + - python 3.14.* *_cp314 + - python_abi 3.14.* *_cp314 + license: MIT + license_family: MIT + purls: + - pkg:pypi/librt?source=hash-mapping + run_exports: {} + size: 135028 + timestamp: 1783529652113 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-stratify-0.4.0-py312h4409184_3.conda sha256: 1ff8e204e8ba4c965da0a3d95ca177149f338d50a258a3f5cfdcacc95698dab6 md5: 6bca21dd95ce7b36d983fa6a3b831b4a @@ -20937,10 +21235,25 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/rpds-py?source=compressed-mapping + - pkg:pypi/rpds-py?source=hash-mapping run_exports: {} size: 285627 timestamp: 1782831308617 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.21-h828de30_1.conda + noarch: python + sha256: 2ebfbffb6b31462a75880772ad96021d4fbb35bd00e93d656d8a36d11c4c08aa + md5: 1020f02c620bee30481275fa159b78be + depends: + - python + - __osx >=11.0 + constrains: + - __osx >=11.0 + license: MIT + purls: + - pkg:pypi/ruff?source=compressed-mapping + run_exports: {} + size: 8639697 + timestamp: 1784124877114 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.18.0-py312h4519d97_0.conda sha256: 708f27ae8ccf62cf714dc5c6f728ae733dc14315c842e935ed7f491d214df2b0 md5: 5a352ca7e4f49ca6585dd30a4812bd20 @@ -21217,7 +21530,7 @@ packages: license: Apache-2.0 license_family: Apache purls: - - pkg:pypi/tornado?source=compressed-mapping + - pkg:pypi/tornado?source=hash-mapping run_exports: {} size: 915857 timestamp: 1781007345425 diff --git a/pyproject.toml b/pyproject.toml index e77eb18e9d..bdd047dd41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -137,10 +137,15 @@ exclude_lines = [ [tool.mypy] # See https://mypy.readthedocs.io/en/stable/config_file.html +packages = "esmvalcore" ignore_missing_imports = true enable_error_code = [ "truthy-bool", ] +exclude = [ + "^doc/conf.py$", + "esmvalcore/cmor/tables/", +] # Configure linters @@ -296,8 +301,16 @@ test-r = { features = ["test-r"], solve-group = "test-r" } # Other development tools. [tool.pixi.feature.dev.dependencies] "jupyterlab" = "*" +"mypy" = "*" "pre-commit" = "*" "py-spy" = "*" +"ruff" = "*" +# Mypy type stubs +"pandas-stubs" = "*" +"scipy-stubs" = "*" +"types-PyYAML" = "*" +"types-psutil" = "*" +"types-shapely" = "*" # Feature for running tests with Python 3.12. [tool.pixi.feature.py312.dependencies]