Accepting request 1199626 from devel:languages:python:numeric

- Update to 2024.7.0
  * Add test for rechunking to a size string by @dcherian in #9117
  * Update docstring in api.py for open_mfdataset(), clarifying
    "chunks" argument by @arthur-e in #9121
  * Grouper refactor by @dcherian in #9122
  * adjust repr tests to account for different platforms (#9127) by
    @mgorny in #9128
  * Support duplicate dimensions in .chunk by @mraspaud in #9099
  * Update zendoo badge link by @max-sixty in #9133
  * Split out distributed writes in zarr docs by @max-sixty in
    #9132
  * Improve to_zarr docs by @max-sixty in #9139
  * groupby: remove some internal use of IndexVariable by @dcherian
    in #9123
  * Improve zarr chunks docs by @max-sixty in #9140
  * Include numbagg in type checks by @max-sixty in #9159
  * Remove mypy exclusions for a couple more libraries by
    @max-sixty in #9160
  * Add test for #9155 by @max-sixty in #9161
  * switch to datetime unit "D" by @keewis in #9170
  * Slightly improve DataTree repr by @shoyer in #9064
  * Fix example code formatting for CachingFileManager by @djhoese
    in #9178
  * Change np.core.defchararray to np.char (#9165) by @pont-us in
    #9166
  * temporarily remove pydap from CI by @keewis in #9183
  * also pin numpy in the all-but-dask CI by @keewis in #9184
  * promote floating-point numeric datetimes to 64-bit before
    decoding by @keewis in #9182
  * "source" encoding for datasets opened from fsspec objects by

OBS-URL: https://build.opensuse.org/request/show/1199626
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-xarray?expand=0&rev=50
This commit is contained in:
Ana Guerrero 2024-09-09 12:45:45 +00:00 committed by Git OBS Bridge
commit 852099ad70
9 changed files with 468 additions and 907 deletions

View File

@ -1,3 +1,147 @@
-------------------------------------------------------------------
Wed Sep 4 09:11:37 UTC 2024 - Ben Greiner <code@bnavigator.de>
- Update to 2024.7.0
* Add test for rechunking to a size string by @dcherian in #9117
* Update docstring in api.py for open_mfdataset(), clarifying
"chunks" argument by @arthur-e in #9121
* Grouper refactor by @dcherian in #9122
* adjust repr tests to account for different platforms (#9127) by
@mgorny in #9128
* Support duplicate dimensions in .chunk by @mraspaud in #9099
* Update zendoo badge link by @max-sixty in #9133
* Split out distributed writes in zarr docs by @max-sixty in
#9132
* Improve to_zarr docs by @max-sixty in #9139
* groupby: remove some internal use of IndexVariable by @dcherian
in #9123
* Improve zarr chunks docs by @max-sixty in #9140
* Include numbagg in type checks by @max-sixty in #9159
* Remove mypy exclusions for a couple more libraries by
@max-sixty in #9160
* Add test for #9155 by @max-sixty in #9161
* switch to datetime unit "D" by @keewis in #9170
* Slightly improve DataTree repr by @shoyer in #9064
* Fix example code formatting for CachingFileManager by @djhoese
in #9178
* Change np.core.defchararray to np.char (#9165) by @pont-us in
#9166
* temporarily remove pydap from CI by @keewis in #9183
* also pin numpy in the all-but-dask CI by @keewis in #9184
* promote floating-point numeric datetimes to 64-bit before
decoding by @keewis in #9182
* "source" encoding for datasets opened from fsspec objects by
@keewis in #8923
* properly diff objects with arrays as attributes on variables by
@keewis in #9169
* Allow str in static typing of reindex, ffill etc. by @headtr1ck
in #9194
* Fix dark-theme in html[data-theme=dark]-tags by @prisae in
#9200
* Add open_datatree benchmark by @aladinor in #9158
* use a composite strategy to generate the dataframe with a
tz-aware datetime column by @keewis in #9174
* Hierarchical coordinates in DataTree by @shoyer in #9063
* avoid converting custom indexes to pandas indexes when
formatting coordinate diffs by @keewis in #9157
* Fix reductions for np.complex_ dtypes with numbagg by
@max-sixty in #9210
* Consolidate some numbagg tests by @max-sixty in #9211
* Use numpy 2.0-compat np.complex64 dtype in test by @max-sixty
in #9217
* Fix two bugs in DataTree.update() by @shoyer in #9214
* Only use necessary dims when creating temporary dataarray by
@Illviljan in #9206
* Cleanup test_coding_times.py by @Illviljan in #9223
* Use reshape and ravel from duck_array_ops in coding/times.py by
@Illviljan in #9225
* Use duckarray assertions in test_coding_times by @Illviljan in
#9226
* Fix time indexing regression in convert_calendar by @hmaarrfk
in #9192
* numpy 2 compatibility in the netcdf4 and h5netcdf backends by
@keewis in #9136
* numpy 2 compatibility in the iris code paths by @keewis in
#9156
* switch the documentation to run with numpy>=2 by @keewis in
#9177
* exclude the bots from the release notes by @keewis in #9235
* Add a .drop_attrs method by @max-sixty in #8258
* Allow mypy to run in vscode by @max-sixty in #9239
* Fix typing for test_plot.py by @Illviljan in #9234
* Added a space to the documentation by @ChrisCleaner in #9247
* Per-variable specification of boolean parameters in
open_dataset by @Ostheer in #9218
* Enable pandas type checking by @headtr1ck in #9213
* fix typing of fallback isdtype method by @headtr1ck in #9250
* Grouper, Resampler as public api by @dcherian in #8840
* Update dropna docstring by @TomNicholas in #9257
* Delete base and loffset parameters to resample by @dcherian in
#9233
* groupby, resample: Deprecate some positional args by @dcherian
in #9236
* Add encode_cf_datetime benchmark by @spencerkclark in #9262
* Update signature for _arrayfunction.array by @Illviljan in
#9237
* Fix copybutton for multi line examples in double digit ipython
cells by @mosc9575 in #9264
* add backend intro and how-to diagram by @JessicaS11 in #9175
* Restore ability to specify _FillValue as Python native integers
by @djhoese in #9258
* Adding open_datatree backend-specific keyword arguments by
@aladinor in #9199
* Change .groupby fastpath to work for monotonic increasing and
decreasing by @JoelJaeschke in #7427
* Fully deprecate squeeze kwarg to groupby by @dcherian in #9280
* Support rechunking to a frequency. by @dcherian in #9109
* automate extracting the contributors by @keewis in #9288
* Allow importing from xarray.groupers by @dcherian in #9289
- Release 2024.06.0
* TEST: Fix numbagg or bottlekneck skip by @hmaarrfk in #9034
* Use ME in test_plot instead of M by @hmaarrfk in #9035
* (fix): equality check against singleton PandasExtensionArray by
@ilan-gold in #9032
* array api-related upstream-dev failures by @keewis in #8854
* User-guide - pandas : Add alternative to
xarray.Dataset.from_dataframe by @loco-philippe in #9020
* Clarify matmul does xarray.dot by @mthramann in #9060
* Run tests on changes to root dotfiles by @max-sixty in #9062
* Speed up netCDF4, h5netcdf backends by @dcherian in #9067
* citation / orcid by @keewis in #9082
* fixes for the pint tests by @keewis in #8983
* Address latest pandas-related upstream test failures by
@spencerkclark in #9081
* Add scottyhq to CITATION.cff by @scottyhq in #9089
* Fix Typo in Bfill benchmark by @Ockenfuss in #9087
* add link to CF conventions on packed data in
doc/user-guide/io.rst by @kmuehlbauer in #9045
* add order for polynomial interpolation, fixes #8762 by
@nkarasiak in #9079
* Fix upcasting with python builtin numbers and numpy 2 by
@djhoese in #8946
* Add Eni to CITATION.cff by @eni-awowale in #9095
* add Jessica to citation by @JessicaS11 in #9096
* (fix): don't handle time-dtypes as extension arrays in
from_dataframe by @ilan-gold in #9042
* Micro optimizations to improve indexing by @hmaarrfk in #9002
* DAS-2067 - Migrate datatree io.py and common.py by
@owenlittlejohns in #9011
* open_datatree performance improvement on NetCDF, H5, and Zarr
files by @aladinor in #9014
* Adds Matt Savoie to CITATION.cff by @flamingbear in #9103
* skip the pandas datetime roundtrip test with pandas=3.0 by
@keewis in #9104
* Add user survey announcement to docs by @jhamman in #9101
* add remaining core-dev citations by @keewis in #9110
* Undo custom padding-top. by @dcherian in #9107
- Drop xarray-pr8854-np2.patch
- Drop xarray-pr9305-cftime.patch
* was actually gh#pydata/xarray#9035
- Add xarray-pr9321-dasktests.patch gh#pydata/xarray#9321
- Add xarray-pr9356-dasktests.patch gh#pydata/xarray#9356
- Add xarray-pr9403-np2.1-scalar.patch gh#pydata/xarray#9403
- Remove obsolete versions from extra requirements
------------------------------------------------------------------- -------------------------------------------------------------------
Wed Jun 5 15:00:43 UTC 2024 - Ben Greiner <code@bnavigator.de> Wed Jun 5 15:00:43 UTC 2024 - Ben Greiner <code@bnavigator.de>
@ -2019,8 +2163,8 @@ Sun Dec 20 16:09:14 UTC 2020 - Sebastian Wagner <sebix+novell.com@sebix.at>
- Replace the internal use of ``pd.Index.__or__`` and ``pd.Index.__and__`` with ``pd.Index.union`` - Replace the internal use of ``pd.Index.__or__`` and ``pd.Index.__and__`` with ``pd.Index.union``
and ``pd.Index.intersection`` as they will stop working as set operations in the future and ``pd.Index.intersection`` as they will stop working as set operations in the future
(:issue:`4565`). By `Mathias Hauser <https://github.com/mathause>`_. (:issue:`4565`). By `Mathias Hauser <https://github.com/mathause>`_.
- Add GitHub action for running nightly tests against upstream dependencies (:pull:`4583`). - Add GitHub action for running nightly tests against upstream dependencies (:pull:`4583`).
By `Anderson Banihirwe <https://github.com/andersy005>`_. By `Anderson Banihirwe <https://github.com/andersy005>`_.
- Ensure all figures are closed properly in plot tests (:pull:`4600`). - Ensure all figures are closed properly in plot tests (:pull:`4600`).
By `Yash Saboo <https://github.com/yashsaboo>`_, `Nirupam K N By `Yash Saboo <https://github.com/yashsaboo>`_, `Nirupam K N
<https://github.com/Nirupamkn>`_ and `Mathias Hauser <https://github.com/Nirupamkn>`_ and `Mathias Hauser
@ -2101,7 +2245,7 @@ Wed Sep 23 06:23:20 UTC 2020 - Sebastian Wagner <sebix+novell.com@sebix.at>
By `Jens Svensmark <https://github.com/jenssss>`_ By `Jens Svensmark <https://github.com/jenssss>`_
- Fix incorrect legend labels for :py:meth:`Dataset.plot.scatter` (:issue:`4126`). - Fix incorrect legend labels for :py:meth:`Dataset.plot.scatter` (:issue:`4126`).
By `Peter Hausamann <https://github.com/phausamann>`_. By `Peter Hausamann <https://github.com/phausamann>`_.
- Fix ``dask.optimize`` on ``DataArray`` producing an invalid Dask task graph (:issue:`3698`) - Fix ``dask.optimize`` on ``DataArray`` producing an invalid Dask task graph (:issue:`3698`)
By `Tom Augspurger <https://github.com/TomAugspurger>`_ By `Tom Augspurger <https://github.com/TomAugspurger>`_
- Fix ``pip install .`` when no ``.git`` directory exists; namely when the xarray source - Fix ``pip install .`` when no ``.git`` directory exists; namely when the xarray source
directory has been rsync'ed by PyCharm Professional for a remote deployment over SSH. directory has been rsync'ed by PyCharm Professional for a remote deployment over SSH.
@ -3039,64 +3183,64 @@ Tue Nov 13 14:30:03 UTC 2018 - Marketa Calabkova <mcalabkova@suse.com>
- update to version 0.11.0 - update to version 0.11.0
* Enhancements * Enhancements
+ xarray.DataArray.plot.line() can now accept multidimensional + xarray.DataArray.plot.line() can now accept multidimensional
coordinate variables as input. hue must be a dimension name coordinate variables as input. hue must be a dimension name
in this case. (GH2407) By Deepak Cherian. in this case. (GH2407) By Deepak Cherian.
+ Added support for Python 3.7. (GH2271). By Joe Hamman. + Added support for Python 3.7. (GH2271). By Joe Hamman.
+ Added support for plotting data with pandas.Interval coordinates, + Added support for plotting data with pandas.Interval coordinates,
such as those created by groupby_bins() By Maximilian Maahn. such as those created by groupby_bins() By Maximilian Maahn.
+ Added shift() for shifting the values of a CFTimeIndex by a + Added shift() for shifting the values of a CFTimeIndex by a
specified frequency. (GH2244). By Spencer Clark. specified frequency. (GH2244). By Spencer Clark.
+ Added support for using cftime.datetime coordinates with + Added support for using cftime.datetime coordinates with
differentiate(), differentiate(), interp(), and interp(). differentiate(), differentiate(), interp(), and interp().
By Spencer Clark By Spencer Clark
+ There is now a global option to either always keep or always + There is now a global option to either always keep or always
discard dataset and dataarray attrs upon operations. The option discard dataset and dataarray attrs upon operations. The option
is set with xarray.set_options(keep_attrs=True), and the default is set with xarray.set_options(keep_attrs=True), and the default
is to use the old behaviour. By Tom Nicholas. is to use the old behaviour. By Tom Nicholas.
+ Added a new backend for the GRIB file format based on ECMWF + Added a new backend for the GRIB file format based on ECMWF
cfgrib python driver and ecCodes C-library. (GH2475) By cfgrib python driver and ecCodes C-library. (GH2475) By
Alessandro Amici, sponsored by ECMWF. Alessandro Amici, sponsored by ECMWF.
+ Resample now supports a dictionary mapping from dimension to + Resample now supports a dictionary mapping from dimension to
frequency as its first argument, e.g., frequency as its first argument, e.g.,
data.resample({'time': '1D'}).mean(). This is consistent with data.resample({'time': '1D'}).mean(). This is consistent with
other xarray functions that accept either dictionaries or other xarray functions that accept either dictionaries or
keyword arguments. By Stephan Hoyer. keyword arguments. By Stephan Hoyer.
+ The preferred way to access tutorial data is now to load it + The preferred way to access tutorial data is now to load it
lazily with xarray.tutorial.open_dataset(). lazily with xarray.tutorial.open_dataset().
xarray.tutorial.load_dataset() calls Dataset.load() prior to xarray.tutorial.load_dataset() calls Dataset.load() prior to
returning (and is now deprecated). This was changed in order returning (and is now deprecated). This was changed in order
to facilitate using tutorial datasets with dask. By Joe Hamman. to facilitate using tutorial datasets with dask. By Joe Hamman.
* Bugfixes * Bugfixes
+ FacetGrid now properly uses the cbar_kwargs keyword argument. + FacetGrid now properly uses the cbar_kwargs keyword argument.
(GH1504, GH1717) By Deepak Cherian. (GH1504, GH1717) By Deepak Cherian.
+ Addition and subtraction operators used with a CFTimeIndex now + Addition and subtraction operators used with a CFTimeIndex now
preserve the indexs type. (GH2244). By Spencer Clark. preserve the indexs type. (GH2244). By Spencer Clark.
+ We now properly handle arrays of datetime.datetime and + We now properly handle arrays of datetime.datetime and
datetime.timedelta provided as coordinates. (GH2512) By datetime.timedelta provided as coordinates. (GH2512) By
`Deepak Cherian <https://github.com/dcherian`_. `Deepak Cherian <https://github.com/dcherian`_.
+ xarray.DataArray.roll correctly handles multidimensional arrays. + xarray.DataArray.roll correctly handles multidimensional arrays.
(GH2445) By Keisuke Fujii. (GH2445) By Keisuke Fujii.
+ xarray.plot() now properly accepts a norm argument and does not + xarray.plot() now properly accepts a norm argument and does not
override the norms vmin and vmax. (GH2381) By Deepak Cherian. override the norms vmin and vmax. (GH2381) By Deepak Cherian.
+ xarray.DataArray.std() now correctly accepts ddof keyword argument. + xarray.DataArray.std() now correctly accepts ddof keyword argument.
(GH2240) By Keisuke Fujii. (GH2240) By Keisuke Fujii.
+ Restore matplotlibs default of plotting dashed negative contours + Restore matplotlibs default of plotting dashed negative contours
when a single color is passed to DataArray.contour() e.g. when a single color is passed to DataArray.contour() e.g.
colors='k'. By Deepak Cherian. colors='k'. By Deepak Cherian.
+ Fix a bug that caused some indexing operations on arrays opened + Fix a bug that caused some indexing operations on arrays opened
with open_rasterio to error (GH2454). By Stephan Hoyer. with open_rasterio to error (GH2454). By Stephan Hoyer.
+ Subtracting one CFTimeIndex from another now returns a + Subtracting one CFTimeIndex from another now returns a
pandas.TimedeltaIndex, analogous to the behavior for pandas.TimedeltaIndex, analogous to the behavior for
DatetimeIndexes (GH2484). By Spencer Clark. DatetimeIndexes (GH2484). By Spencer Clark.
+ Adding a TimedeltaIndex to, or subtracting a TimedeltaIndex from + Adding a TimedeltaIndex to, or subtracting a TimedeltaIndex from
a CFTimeIndex is now allowed (GH2484). By Spencer Clark. a CFTimeIndex is now allowed (GH2484). By Spencer Clark.
+ Avoid use of Dasks deprecated get= parameter in tests by Matthew Rocklin. + Avoid use of Dasks deprecated get= parameter in tests by Matthew Rocklin.
+ An OverflowError is now accurately raised and caught during the + An OverflowError is now accurately raised and caught during the
encoding process if a reference date is used that is so distant that encoding process if a reference date is used that is so distant that
the dates must be encoded using cftime rather than NumPy (GH2272). the dates must be encoded using cftime rather than NumPy (GH2272).
By Spencer Clark. By Spencer Clark.
+ Chunked datasets can now roundtrip to Zarr storage continually with + Chunked datasets can now roundtrip to Zarr storage continually with
to_zarr and open_zarr (GH2300). By Lily Wang. to_zarr and open_zarr (GH2300). By Lily Wang.
------------------------------------------------------------------- -------------------------------------------------------------------
@ -3454,11 +3598,11 @@ Thu Jan 28 13:02:36 UTC 2016 - toddrme2178@gmail.com
This avoids a namespace conflict with the entire field of x-ray science. Renaming This avoids a namespace conflict with the entire field of x-ray science. Renaming
our project seemed like the right thing to do, especially because some our project seemed like the right thing to do, especially because some
scientists who work with actual x-rays are interested in using this project in scientists who work with actual x-rays are interested in using this project in
their work. Thanks for your understanding and patience in this transition. their work. Thanks for your understanding and patience in this transition.
* Breaking changes * Breaking changes
- The internal data model used by :py:class:`~xray.DataArray` has been - The internal data model used by :py:class:`~xray.DataArray` has been
rewritten to fix several outstanding issues. Internally, ``DataArray`` rewritten to fix several outstanding issues. Internally, ``DataArray``
is now implemented in terms of ``._variable`` and ``._coords`` is now implemented in terms of ``._variable`` and ``._coords``
attributes instead of holding variables in a ``Dataset`` object. attributes instead of holding variables in a ``Dataset`` object.
- It is no longer possible to convert a DataArray to a Dataset with - It is no longer possible to convert a DataArray to a Dataset with
:py:meth:`xray.DataArray.to_dataset` if it is unnamed. This will now :py:meth:`xray.DataArray.to_dataset` if it is unnamed. This will now
@ -3481,7 +3625,7 @@ Thu Jan 28 13:02:36 UTC 2016 - toddrme2178@gmail.com
- Passing a :py:class:`pandas.DataFrame` or :py:class:`pandas.Panel` to a Dataset constructor - Passing a :py:class:`pandas.DataFrame` or :py:class:`pandas.Panel` to a Dataset constructor
is now permitted. is now permitted.
- New function :py:func:`~xray.broadcast` for explicitly broadcasting - New function :py:func:`~xray.broadcast` for explicitly broadcasting
``DataArray`` and ``Dataset`` objects against each other. ``DataArray`` and ``Dataset`` objects against each other.
* Bug fixes * Bug fixes
- Fixes for several issues found on ``DataArray`` objects with the same name - Fixes for several issues found on ``DataArray`` objects with the same name
as one of their coordinates (see :ref:`v0.7.0.breaking` for more details). as one of their coordinates (see :ref:`v0.7.0.breaking` for more details).

View File

@ -25,11 +25,11 @@
%define psuffix %{nil} %define psuffix %{nil}
%endif %endif
%define ghversion 2024.05.0 %define ghversion 2024.07.0
%{?sle15_python_module_pythons} %{?sle15_python_module_pythons}
Name: python-xarray%{psuffix} Name: python-xarray%{psuffix}
Version: 2024.5.0 Version: 2024.7.0
Release: 0 Release: 0
Summary: N-D labeled arrays and datasets in Python Summary: N-D labeled arrays and datasets in Python
License: Apache-2.0 License: Apache-2.0
@ -38,10 +38,12 @@ Source: https://github.com/pydata/xarray/archive/refs/tags/v%{ghversion}
# PATCH-FEATURE-UPSTREAM local_dataset.patch gh#pydata/xarray#5377 mcepl@suse.com # PATCH-FEATURE-UPSTREAM local_dataset.patch gh#pydata/xarray#5377 mcepl@suse.com
# fix xr.tutorial.open_dataset to work with the preloaded cache. # fix xr.tutorial.open_dataset to work with the preloaded cache.
Patch0: local_dataset.patch Patch0: local_dataset.patch
# PATCH-FIX-UPSTREAM xarray-pr8854-np2.patch gh#pydata/xarray#8854 # PATCH-FIX-UPSTREAM xarray-pr9321-dasktests.patch gh#pydata/xarray#9321
Patch1: xarray-pr8854-np2.patch Patch1: xarray-pr9321-dasktests.patch
# PATCH-FIX-UPSTREAM xarray-pr9305-cftime.patch gh#pydata/xarray#9305 # PATCH-FIX-UPSTREAM xarray-pr9356-dasktests.patch gh#pydata/xarray#9356
Patch2: xarray-pr9305-cftime.patch Patch2: xarray-pr9356-dasktests.patch
# PATCH-FIX-UPSTREAM xarray-pr9403-np2.1-scalar.patch gh#pydata/xarray#9403
Patch3: xarray-pr9403-np2.1-scalar.patch
BuildRequires: %{python_module base >= 3.9} BuildRequires: %{python_module base >= 3.9}
BuildRequires: %{python_module pip} BuildRequires: %{python_module pip}
BuildRequires: %{python_module setuptools_scm} BuildRequires: %{python_module setuptools_scm}
@ -72,12 +74,12 @@ The dataset is an in-memory representation of a netCDF file.
%package accel %package accel
# for minimum versions, check ci/requirements/min-all-deps.yml # for minimum versions, check ci/requirements/min-all-deps.yml
Summary: The python xarray[accel] extra Summary: The python xarray[accel] extra
Requires: python-Bottleneck >= 1.3 Requires: python-Bottleneck
Requires: python-opt-einsum Requires: python-opt-einsum
Requires: python-scipy Requires: python-scipy
Requires: python-xarray = %{version} Requires: python-xarray = %{version}
# not available yet # not available yet
Recommends: python-flox >= 0.7 Recommends: python-flox
Recommends: python-numbagg Recommends: python-numbagg
%description accel %description accel
@ -117,21 +119,21 @@ Except pre-commit, Use `pip-%{python_bin_suffix} --user install pre-commit` to i
%package io %package io
Summary: The python xarray[io] extra Summary: The python xarray[io] extra
Requires: python-cftime >= 1.6 Requires: python-cftime
Requires: python-fsspec Requires: python-fsspec
Requires: python-h5netcdf >= 1.1 Requires: python-h5netcdf
Requires: python-netCDF4 >= 1.6 Requires: python-netCDF4
Requires: python-pooch Requires: python-pooch
Requires: python-scipy >= 1.10 Requires: python-scipy
Requires: python-xarray = %{version} Requires: python-xarray = %{version}
Requires: python-zarr >= 2.13 Requires: python-zarr
%description io %description io
The [io] extra for xarray, N-D labeled arrays and datasets in Python The [io] extra for xarray, N-D labeled arrays and datasets in Python
%package parallel %package parallel
Summary: The python xarray[parallel] extra Summary: The python xarray[parallel] extra
Requires: python-dask-complete >= 2022.12 Requires: python-dask-complete
Requires: python-xarray = %{version} Requires: python-xarray = %{version}
%description parallel %description parallel
@ -139,8 +141,8 @@ The [parallel] extra for xarray, N-D labeled arrays and datasets in Python
%package viz %package viz
Summary: The python xarray[viz] extra Summary: The python xarray[viz] extra
Requires: python-matplotlib >= 3.6 Requires: python-matplotlib
Requires: python-seaborn >= 0.12 Requires: python-seaborn
Requires: python-xarray = %{version} Requires: python-xarray = %{version}
# Not available yet # Not available yet
Recommends: python-nc-time-axis Recommends: python-nc-time-axis

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:604a801c7bba96524b09b993b159ae998e0987627949b667c884f65895939f11
size 3739324

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3db5160a699a7731fba26b42aef3f175ca3a6adfe5593bebd0b7af90e55d747d
size 3756547

View File

@ -1,772 +0,0 @@
From e066a6c559e9d7f31c359ea95da42d0e45c585ce Mon Sep 17 00:00:00 2001
From: Justus Magin <keewis@posteo.de>
Date: Tue, 19 Mar 2024 11:32:32 +0100
Subject: [PATCH 01/65] replace the use of `numpy.array_api` with
`array_api_strict`
This would make it a dependency of `namedarray`, and not allow
behavior that is allowed but not required by the array API standard. Otherwise we can:
- use the main `numpy` namespace
- use `array_api_compat` (would also be a new dependency) to allow
optional behavior
---
xarray/namedarray/_array_api.py | 9 ---------
1 file changed, 9 deletions(-)
Index: xarray-2024.05.0/xarray/namedarray/_array_api.py
===================================================================
--- xarray-2024.05.0.orig/xarray/namedarray/_array_api.py
+++ xarray-2024.05.0/xarray/namedarray/_array_api.py
@@ -1,6 +1,5 @@
from __future__ import annotations
-import warnings
from types import ModuleType
from typing import Any
@@ -21,14 +20,6 @@ from xarray.namedarray._typing import (
)
from xarray.namedarray.core import NamedArray
-with warnings.catch_warnings():
- warnings.filterwarnings(
- "ignore",
- r"The numpy.array_api submodule is still experimental",
- category=UserWarning,
- )
- import numpy.array_api as nxp # noqa: F401
-
def _get_data_namespace(x: NamedArray[Any, Any]) -> ModuleType:
if isinstance(x._data, _arrayapi):
@@ -68,13 +59,13 @@ def astype(
Examples
--------
- >>> narr = NamedArray(("x",), nxp.asarray([1.5, 2.5]))
+ >>> narr = NamedArray(("x",), np.asarray([1.5, 2.5]))
>>> narr
<xarray.NamedArray (x: 2)> Size: 16B
- Array([1.5, 2.5], dtype=float64)
+ array([1.5, 2.5])
>>> astype(narr, np.dtype(np.int32))
<xarray.NamedArray (x: 2)> Size: 8B
- Array([1, 2], dtype=int32)
+ array([1, 2], dtype=int32)
"""
if isinstance(x._data, _arrayapi):
xp = x._data.__array_namespace__()
@@ -109,7 +100,7 @@ def imag(
Examples
--------
- >>> narr = NamedArray(("x",), np.asarray([1.0 + 2j, 2 + 4j])) # TODO: Use nxp
+ >>> narr = NamedArray(("x",), np.asarray([1.0 + 2j, 2 + 4j]))
>>> imag(narr)
<xarray.NamedArray (x: 2)> Size: 16B
array([2., 4.])
@@ -141,7 +132,7 @@ def real(
Examples
--------
- >>> narr = NamedArray(("x",), np.asarray([1.0 + 2j, 2 + 4j])) # TODO: Use nxp
+ >>> narr = NamedArray(("x",), np.asarray([1.0 + 2j, 2 + 4j]))
>>> real(narr)
<xarray.NamedArray (x: 2)> Size: 16B
array([1., 2.])
@@ -179,15 +170,15 @@ def expand_dims(
Examples
--------
- >>> x = NamedArray(("x", "y"), nxp.asarray([[1.0, 2.0], [3.0, 4.0]]))
+ >>> x = NamedArray(("x", "y"), np.asarray([[1.0, 2.0], [3.0, 4.0]]))
>>> expand_dims(x)
<xarray.NamedArray (dim_2: 1, x: 2, y: 2)> Size: 32B
- Array([[[1., 2.],
- [3., 4.]]], dtype=float64)
+ array([[[1., 2.],
+ [3., 4.]]])
>>> expand_dims(x, dim="z")
<xarray.NamedArray (z: 1, x: 2, y: 2)> Size: 32B
- Array([[[1., 2.],
- [3., 4.]]], dtype=float64)
+ array([[[1., 2.],
+ [3., 4.]]])
"""
xp = _get_data_namespace(x)
dims = x.dims
Index: xarray-2024.05.0/xarray/tests/__init__.py
===================================================================
--- xarray-2024.05.0.orig/xarray/tests/__init__.py
+++ xarray-2024.05.0/xarray/tests/__init__.py
@@ -147,9 +147,10 @@ has_numbagg_or_bottleneck = has_numbagg
requires_numbagg_or_bottleneck = pytest.mark.skipif(
not has_scipy_or_netCDF4, reason="requires scipy or netCDF4"
)
-has_numpy_array_api, requires_numpy_array_api = _importorskip("numpy", "1.26.0")
has_numpy_2, requires_numpy_2 = _importorskip("numpy", "2.0.0")
+has_array_api_strict, requires_array_api_strict = _importorskip("array_api_strict")
+
def _importorskip_h5netcdf_ros3():
try:
Index: xarray-2024.05.0/xarray/tests/test_array_api.py
===================================================================
--- xarray-2024.05.0.orig/xarray/tests/test_array_api.py
+++ xarray-2024.05.0/xarray/tests/test_array_api.py
@@ -6,20 +6,9 @@ import xarray as xr
from xarray.testing import assert_equal
np = pytest.importorskip("numpy", minversion="1.22")
+xp = pytest.importorskip("array_api_strict")
-try:
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
-
- import numpy.array_api as xp
- from numpy.array_api._array_object import Array
-except ImportError:
- # for `numpy>=2.0`
- xp = pytest.importorskip("array_api_strict")
-
- from array_api_strict._array_object import Array # type: ignore[no-redef]
+from array_api_strict._array_object import Array # isort:skip # type: ignore[no-redef]
@pytest.fixture
@@ -65,8 +54,8 @@ def test_aggregation_skipna(arrays) -> N
def test_astype(arrays) -> None:
np_arr, xp_arr = arrays
expected = np_arr.astype(np.int64)
- actual = xp_arr.astype(np.int64)
- assert actual.dtype == np.int64
+ actual = xp_arr.astype(xp.int64)
+ assert actual.dtype == xp.int64
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
@@ -118,8 +107,10 @@ def test_indexing(arrays: tuple[xr.DataA
def test_properties(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
np_arr, xp_arr = arrays
- assert np_arr.nbytes == np_arr.data.nbytes
- assert xp_arr.nbytes == np_arr.data.nbytes
+
+ expected = np_arr.data.nbytes
+ assert np_arr.nbytes == expected
+ assert xp_arr.nbytes == expected
def test_reorganizing_operation(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
Index: xarray-2024.05.0/xarray/tests/test_namedarray.py
===================================================================
--- xarray-2024.05.0.orig/xarray/tests/test_namedarray.py
+++ xarray-2024.05.0/xarray/tests/test_namedarray.py
@@ -1,7 +1,6 @@
from __future__ import annotations
import copy
-import warnings
from abc import abstractmethod
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, Generic, cast, overload
@@ -79,6 +78,17 @@ class CustomArrayIndexable(
return np
+def check_duck_array_typevar(a: duckarray[Any, _DType]) -> duckarray[Any, _DType]:
+ # Mypy checks a is valid:
+ b: duckarray[Any, _DType] = a
+
+ # Runtime check if valid:
+ if isinstance(b, _arrayfunction_or_api):
+ return b
+ else:
+ raise TypeError(f"a ({type(a)}) is not a valid _arrayfunction or _arrayapi")
+
+
class NamedArraySubclassobjects:
@pytest.fixture
def target(self, data: np.ndarray[Any, Any]) -> Any:
@@ -328,48 +338,27 @@ class TestNamedArray(NamedArraySubclasso
named_array.dims = new_dims
assert named_array.dims == tuple(new_dims)
- def test_duck_array_class(
- self,
- ) -> None:
- def test_duck_array_typevar(
- a: duckarray[Any, _DType],
- ) -> duckarray[Any, _DType]:
- # Mypy checks a is valid:
- b: duckarray[Any, _DType] = a
-
- # Runtime check if valid:
- if isinstance(b, _arrayfunction_or_api):
- return b
- else:
- raise TypeError(
- f"a ({type(a)}) is not a valid _arrayfunction or _arrayapi"
- )
-
+ def test_duck_array_class(self) -> None:
numpy_a: NDArray[np.int64]
numpy_a = np.array([2.1, 4], dtype=np.dtype(np.int64))
- test_duck_array_typevar(numpy_a)
+ check_duck_array_typevar(numpy_a)
masked_a: np.ma.MaskedArray[Any, np.dtype[np.int64]]
masked_a = np.ma.asarray([2.1, 4], dtype=np.dtype(np.int64)) # type: ignore[no-untyped-call]
- test_duck_array_typevar(masked_a)
+ check_duck_array_typevar(masked_a)
custom_a: CustomArrayIndexable[Any, np.dtype[np.int64]]
custom_a = CustomArrayIndexable(numpy_a)
- test_duck_array_typevar(custom_a)
+ check_duck_array_typevar(custom_a)
+ def test_duck_array_class_array_api(self) -> None:
# Test numpy's array api:
- with warnings.catch_warnings():
- warnings.filterwarnings(
- "ignore",
- r"The numpy.array_api submodule is still experimental",
- category=UserWarning,
- )
- import numpy.array_api as nxp
+ nxp = pytest.importorskip("array_api_strict", minversion="1.0")
# TODO: nxp doesn't use dtype typevars, so can only use Any for the moment:
arrayapi_a: duckarray[Any, Any] # duckarray[Any, np.dtype[np.int64]]
- arrayapi_a = nxp.asarray([2.1, 4], dtype=np.dtype(np.int64))
- test_duck_array_typevar(arrayapi_a)
+ arrayapi_a = nxp.asarray([2.1, 4], dtype=nxp.int64)
+ check_duck_array_typevar(arrayapi_a)
def test_new_namedarray(self) -> None:
dtype_float = np.dtype(np.float32)
Index: xarray-2024.05.0/xarray/tests/test_strategies.py
===================================================================
--- xarray-2024.05.0.orig/xarray/tests/test_strategies.py
+++ xarray-2024.05.0/xarray/tests/test_strategies.py
@@ -1,6 +1,9 @@
+import warnings
+
import numpy as np
import numpy.testing as npt
import pytest
+from packaging.version import Version
pytest.importorskip("hypothesis")
# isort: split
@@ -19,7 +22,6 @@ from xarray.testing.strategies import (
unique_subset_of,
variables,
)
-from xarray.tests import requires_numpy_array_api
ALLOWED_ATTRS_VALUES_TYPES = (int, bool, str, np.ndarray)
@@ -199,7 +201,6 @@ class TestVariablesStrategy:
)
)
- @requires_numpy_array_api
@given(st.data())
def test_make_strategies_namespace(self, data):
"""
@@ -208,16 +209,24 @@ class TestVariablesStrategy:
We still want to generate dtypes not in the array API by default, but this checks we don't accidentally override
the user's choice of dtypes with non-API-compliant ones.
"""
- from numpy import (
- array_api as np_array_api, # requires numpy>=1.26.0, and we expect a UserWarning to be raised
- )
+ if Version(np.__version__) >= Version("2.0.0.dev0"):
+ nxp = np
+ else:
+ # requires numpy>=1.26.0, and we expect a UserWarning to be raised
+ with warnings.catch_warnings():
+ warnings.filterwarnings(
+ "ignore", category=UserWarning, message=".+See NEP 47."
+ )
+ from numpy import ( # type: ignore[no-redef,unused-ignore]
+ array_api as nxp,
+ )
- np_array_api_st = make_strategies_namespace(np_array_api)
+ nxp_st = make_strategies_namespace(nxp)
data.draw(
variables(
- array_strategy_fn=np_array_api_st.arrays,
- dtype=np_array_api_st.scalar_dtypes(),
+ array_strategy_fn=nxp_st.arrays,
+ dtype=nxp_st.scalar_dtypes(),
)
)
Index: xarray-2024.05.0/xarray/core/duck_array_ops.py
===================================================================
--- xarray-2024.05.0.orig/xarray/core/duck_array_ops.py
+++ xarray-2024.05.0/xarray/core/duck_array_ops.py
@@ -142,17 +142,25 @@ around.__doc__ = str.replace(
def isnull(data):
data = asarray(data)
- scalar_type = data.dtype.type
- if issubclass(scalar_type, (np.datetime64, np.timedelta64)):
+
+ xp = get_array_namespace(data)
+ scalar_type = data.dtype
+ if dtypes.is_datetime_like(scalar_type):
# datetime types use NaT for null
# note: must check timedelta64 before integers, because currently
# timedelta64 inherits from np.integer
return isnat(data)
- elif issubclass(scalar_type, np.inexact):
+ elif dtypes.isdtype(scalar_type, ("real floating", "complex floating"), xp=xp):
# float types use NaN for null
xp = get_array_namespace(data)
return xp.isnan(data)
- elif issubclass(scalar_type, (np.bool_, np.integer, np.character, np.void)):
+ elif dtypes.isdtype(scalar_type, ("bool", "integral"), xp=xp) or (
+ isinstance(scalar_type, np.dtype)
+ and (
+ np.issubdtype(scalar_type, np.character)
+ or np.issubdtype(scalar_type, np.void)
+ )
+ ):
# these types cannot represent missing values
return full_like(data, dtype=bool, fill_value=False)
else:
@@ -406,13 +414,22 @@ def _create_nan_agg_method(name, coerce_
if invariant_0d and axis == ():
return values
- values = asarray(values)
+ xp = get_array_namespace(values)
+ values = asarray(values, xp=xp)
- if coerce_strings and values.dtype.kind in "SU":
+ if coerce_strings and dtypes.is_string(values.dtype):
values = astype(values, object)
func = None
- if skipna or (skipna is None and values.dtype.kind in "cfO"):
+ if skipna or (
+ skipna is None
+ and (
+ dtypes.isdtype(
+ values.dtype, ("complex floating", "real floating"), xp=xp
+ )
+ or dtypes.is_object(values.dtype)
+ )
+ ):
nanname = "nan" + name
func = getattr(nanops, nanname)
else:
@@ -477,8 +494,8 @@ def _datetime_nanmin(array):
- numpy nanmin() don't work on datetime64 (all versions at the moment of writing)
- dask min() does not work on datetime64 (all versions at the moment of writing)
"""
- assert array.dtype.kind in "mM"
dtype = array.dtype
+ assert dtypes.is_datetime_like(dtype)
# (NaT).astype(float) does not produce NaN...
array = where(pandas_isnull(array), np.nan, array.astype(float))
array = min(array, skipna=True)
@@ -515,7 +532,7 @@ def datetime_to_numeric(array, offset=No
"""
# Set offset to minimum if not given
if offset is None:
- if array.dtype.kind in "Mm":
+ if dtypes.is_datetime_like(array.dtype):
offset = _datetime_nanmin(array)
else:
offset = min(array)
@@ -527,7 +544,7 @@ def datetime_to_numeric(array, offset=No
# This map_blocks call is for backwards compatibility.
# dask == 2021.04.1 does not support subtracting object arrays
# which is required for cftime
- if is_duck_dask_array(array) and np.issubdtype(array.dtype, object):
+ if is_duck_dask_array(array) and dtypes.is_object(array.dtype):
array = array.map_blocks(lambda a, b: a - b, offset, meta=array._meta)
else:
array = array - offset
@@ -537,11 +554,11 @@ def datetime_to_numeric(array, offset=No
array = np.array(array)
# Convert timedelta objects to float by first converting to microseconds.
- if array.dtype.kind in "O":
+ if dtypes.is_object(array.dtype):
return py_timedelta_to_float(array, datetime_unit or "ns").astype(dtype)
# Convert np.NaT to np.nan
- elif array.dtype.kind in "mM":
+ elif dtypes.is_datetime_like(array.dtype):
# Convert to specified timedelta units.
if datetime_unit:
array = array / np.timedelta64(1, datetime_unit)
@@ -641,7 +658,7 @@ def mean(array, axis=None, skipna=None,
from xarray.core.common import _contains_cftime_datetimes
array = asarray(array)
- if array.dtype.kind in "Mm":
+ if dtypes.is_datetime_like(array.dtype):
offset = _datetime_nanmin(array)
# xarray always uses np.datetime64[ns] for np.datetime64 data
@@ -689,7 +706,9 @@ def cumsum(array, axis=None, **kwargs):
def first(values, axis, skipna=None):
"""Return the first non-NA elements in this array along the given axis"""
- if (skipna or skipna is None) and values.dtype.kind not in "iSU":
+ if (skipna or skipna is None) and not (
+ dtypes.isdtype(values.dtype, "signed integer") or dtypes.is_string(values.dtype)
+ ):
# only bother for dtypes that can hold NaN
if is_chunked_array(values):
return chunked_nanfirst(values, axis)
@@ -700,7 +719,9 @@ def first(values, axis, skipna=None):
def last(values, axis, skipna=None):
"""Return the last non-NA elements in this array along the given axis"""
- if (skipna or skipna is None) and values.dtype.kind not in "iSU":
+ if (skipna or skipna is None) and not (
+ dtypes.isdtype(values.dtype, "signed integer") or dtypes.is_string(values.dtype)
+ ):
# only bother for dtypes that can hold NaN
if is_chunked_array(values):
return chunked_nanlast(values, axis)
Index: xarray-2024.05.0/xarray/core/dtypes.py
===================================================================
--- xarray-2024.05.0.orig/xarray/core/dtypes.py
+++ xarray-2024.05.0/xarray/core/dtypes.py
@@ -4,8 +4,9 @@ import functools
from typing import Any
import numpy as np
+from pandas.api.types import is_extension_array_dtype
-from xarray.core import utils
+from xarray.core import npcompat, utils
# Use as a sentinel value to indicate a dtype appropriate NA value.
NA = utils.ReprObject("<NA>")
@@ -60,22 +61,22 @@ def maybe_promote(dtype: np.dtype) -> tu
# N.B. these casting rules should match pandas
dtype_: np.typing.DTypeLike
fill_value: Any
- if np.issubdtype(dtype, np.floating):
+ if isdtype(dtype, "real floating"):
dtype_ = dtype
fill_value = np.nan
- elif np.issubdtype(dtype, np.timedelta64):
+ elif isinstance(dtype, np.dtype) and np.issubdtype(dtype, np.timedelta64):
# See https://github.com/numpy/numpy/issues/10685
# np.timedelta64 is a subclass of np.integer
# Check np.timedelta64 before np.integer
fill_value = np.timedelta64("NaT")
dtype_ = dtype
- elif np.issubdtype(dtype, np.integer):
+ elif isdtype(dtype, "integral"):
dtype_ = np.float32 if dtype.itemsize <= 2 else np.float64
fill_value = np.nan
- elif np.issubdtype(dtype, np.complexfloating):
+ elif isdtype(dtype, "complex floating"):
dtype_ = dtype
fill_value = np.nan + np.nan * 1j
- elif np.issubdtype(dtype, np.datetime64):
+ elif isinstance(dtype, np.dtype) and np.issubdtype(dtype, np.datetime64):
dtype_ = dtype
fill_value = np.datetime64("NaT")
else:
@@ -118,16 +119,16 @@ def get_pos_infinity(dtype, max_for_int=
-------
fill_value : positive infinity value corresponding to this dtype.
"""
- if issubclass(dtype.type, np.floating):
+ if isdtype(dtype, "real floating"):
return np.inf
- if issubclass(dtype.type, np.integer):
+ if isdtype(dtype, "integral"):
if max_for_int:
return np.iinfo(dtype).max
else:
return np.inf
- if issubclass(dtype.type, np.complexfloating):
+ if isdtype(dtype, "complex floating"):
return np.inf + 1j * np.inf
return INF
@@ -146,24 +147,66 @@ def get_neg_infinity(dtype, min_for_int=
-------
fill_value : positive infinity value corresponding to this dtype.
"""
- if issubclass(dtype.type, np.floating):
+ if isdtype(dtype, "real floating"):
return -np.inf
- if issubclass(dtype.type, np.integer):
+ if isdtype(dtype, "integral"):
if min_for_int:
return np.iinfo(dtype).min
else:
return -np.inf
- if issubclass(dtype.type, np.complexfloating):
+ if isdtype(dtype, "complex floating"):
return -np.inf - 1j * np.inf
return NINF
-def is_datetime_like(dtype):
+def is_datetime_like(dtype) -> bool:
"""Check if a dtype is a subclass of the numpy datetime types"""
- return np.issubdtype(dtype, np.datetime64) or np.issubdtype(dtype, np.timedelta64)
+ return _is_numpy_subdtype(dtype, (np.datetime64, np.timedelta64))
+
+
+def is_object(dtype) -> bool:
+ """Check if a dtype is object"""
+ return _is_numpy_subdtype(dtype, object)
+
+
+def is_string(dtype) -> bool:
+ """Check if a dtype is a string dtype"""
+ return _is_numpy_subdtype(dtype, (np.str_, np.character))
+
+
+def _is_numpy_subdtype(dtype, kind) -> bool:
+ if not isinstance(dtype, np.dtype):
+ return False
+
+ kinds = kind if isinstance(kind, tuple) else (kind,)
+ return any(np.issubdtype(dtype, kind) for kind in kinds)
+
+
+def isdtype(dtype, kind: str | tuple[str, ...], xp=None) -> bool:
+ """Compatibility wrapper for isdtype() from the array API standard.
+
+ Unlike xp.isdtype(), kind must be a string.
+ """
+ # TODO(shoyer): remove this wrapper when Xarray requires
+ # numpy>=2 and pandas extensions arrays are implemented in
+ # Xarray via the array API
+ if not isinstance(kind, str) and not (
+ isinstance(kind, tuple) and all(isinstance(k, str) for k in kind)
+ ):
+ raise TypeError(f"kind must be a string or a tuple of strings: {repr(kind)}")
+
+ if isinstance(dtype, np.dtype):
+ return npcompat.isdtype(dtype, kind)
+ elif is_extension_array_dtype(dtype):
+ # we never want to match pandas extension array dtypes
+ return False
+ else:
+ if xp is None:
+ xp = np
+ return xp.isdtype(dtype, kind)
def result_type(
@@ -184,12 +227,26 @@ def result_type(
-------
numpy.dtype for the result.
"""
- types = {np.result_type(t).type for t in arrays_and_dtypes}
+ from xarray.core.duck_array_ops import get_array_namespace
+
+ # TODO(shoyer): consider moving this logic into get_array_namespace()
+ # or another helper function.
+ namespaces = {get_array_namespace(t) for t in arrays_and_dtypes}
+ non_numpy = namespaces - {np}
+ if non_numpy:
+ [xp] = non_numpy
+ else:
+ xp = np
+
+ types = {xp.result_type(t) for t in arrays_and_dtypes}
- for left, right in PROMOTE_TO_OBJECT:
- if any(issubclass(t, left) for t in types) and any(
- issubclass(t, right) for t in types
- ):
- return np.dtype(object)
+ if any(isinstance(t, np.dtype) for t in types):
+ # only check if there's numpy dtypes the array API does not
+ # define the types we're checking for
+ for left, right in PROMOTE_TO_OBJECT:
+ if any(np.issubdtype(t, left) for t in types) and any(
+ np.issubdtype(t, right) for t in types
+ ):
+ return xp.dtype(object)
- return np.result_type(*arrays_and_dtypes)
+ return xp.result_type(*arrays_and_dtypes)
Index: xarray-2024.05.0/xarray/namedarray/core.py
===================================================================
--- xarray-2024.05.0.orig/xarray/namedarray/core.py
+++ xarray-2024.05.0/xarray/namedarray/core.py
@@ -470,10 +470,28 @@ class NamedArray(NamedArrayAggregations,
If the underlying data array does not include ``nbytes``, estimates
the bytes consumed based on the ``size`` and ``dtype``.
"""
+ from xarray.namedarray._array_api import _get_data_namespace
+
if hasattr(self._data, "nbytes"):
return self._data.nbytes # type: ignore[no-any-return]
+
+ if hasattr(self.dtype, "itemsize"):
+ itemsize = self.dtype.itemsize
+ elif isinstance(self._data, _arrayapi):
+ xp = _get_data_namespace(self)
+
+ if xp.isdtype(self.dtype, "bool"):
+ itemsize = 1
+ elif xp.isdtype(self.dtype, "integral"):
+ itemsize = xp.iinfo(self.dtype).bits // 8
+ else:
+ itemsize = xp.finfo(self.dtype).bits // 8
else:
- return self.size * self.dtype.itemsize
+ raise TypeError(
+ "cannot compute the number of bytes (no array API nor nbytes / itemsize)"
+ )
+
+ return self.size * itemsize
@property
def dims(self) -> _Dims:
Index: xarray-2024.05.0/xarray/tests/test_dtypes.py
===================================================================
--- xarray-2024.05.0.orig/xarray/tests/test_dtypes.py
+++ xarray-2024.05.0/xarray/tests/test_dtypes.py
@@ -4,6 +4,18 @@ import numpy as np
import pytest
from xarray.core import dtypes
+from xarray.tests import requires_array_api_strict
+
+try:
+ import array_api_strict
+except ImportError:
+
+ class DummyArrayAPINamespace:
+ bool = None
+ int32 = None
+ float64 = None
+
+ array_api_strict = DummyArrayAPINamespace
@pytest.mark.parametrize(
@@ -58,7 +70,6 @@ def test_inf(obj) -> None:
@pytest.mark.parametrize(
"kind, expected",
[
- ("a", (np.dtype("O"), "nan")), # dtype('S')
("b", (np.float32, "nan")), # dtype('int8')
("B", (np.float32, "nan")), # dtype('uint8')
("c", (np.dtype("O"), "nan")), # dtype('S1')
@@ -98,3 +109,54 @@ def test_nat_types_membership() -> None:
assert np.datetime64("NaT").dtype in dtypes.NAT_TYPES
assert np.timedelta64("NaT").dtype in dtypes.NAT_TYPES
assert np.float64 not in dtypes.NAT_TYPES
+
+
+@pytest.mark.parametrize(
+ ["dtype", "kinds", "xp", "expected"],
+ (
+ (np.dtype("int32"), "integral", np, True),
+ (np.dtype("float16"), "real floating", np, True),
+ (np.dtype("complex128"), "complex floating", np, True),
+ (np.dtype("U"), "numeric", np, False),
+ pytest.param(
+ array_api_strict.int32,
+ "integral",
+ array_api_strict,
+ True,
+ marks=requires_array_api_strict,
+ id="array_api-int",
+ ),
+ pytest.param(
+ array_api_strict.float64,
+ "real floating",
+ array_api_strict,
+ True,
+ marks=requires_array_api_strict,
+ id="array_api-float",
+ ),
+ pytest.param(
+ array_api_strict.bool,
+ "numeric",
+ array_api_strict,
+ False,
+ marks=requires_array_api_strict,
+ id="array_api-bool",
+ ),
+ ),
+)
+def test_isdtype(dtype, kinds, xp, expected) -> None:
+ actual = dtypes.isdtype(dtype, kinds, xp=xp)
+ assert actual == expected
+
+
+@pytest.mark.parametrize(
+ ["dtype", "kinds", "xp", "error", "pattern"],
+ (
+ (np.dtype("int32"), "foo", np, (TypeError, ValueError), "kind"),
+ (np.dtype("int32"), np.signedinteger, np, TypeError, "kind"),
+ (np.dtype("float16"), 1, np, TypeError, "kind"),
+ ),
+)
+def test_isdtype_error(dtype, kinds, xp, error, pattern):
+ with pytest.raises(error, match=pattern):
+ dtypes.isdtype(dtype, kinds, xp=xp)
Index: xarray-2024.05.0/xarray/core/npcompat.py
===================================================================
--- xarray-2024.05.0.orig/xarray/core/npcompat.py
+++ xarray-2024.05.0/xarray/core/npcompat.py
@@ -28,3 +28,33 @@
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+try:
+ # requires numpy>=2.0
+ from numpy import isdtype # type: ignore[attr-defined,unused-ignore]
+except ImportError:
+ import numpy as np
+
+ dtype_kinds = {
+ "bool": np.bool_,
+ "signed integer": np.signedinteger,
+ "unsigned integer": np.unsignedinteger,
+ "integral": np.integer,
+ "real floating": np.floating,
+ "complex floating": np.complexfloating,
+ "numeric": np.number,
+ }
+
+ def isdtype(dtype, kind):
+ kinds = kind if isinstance(kind, tuple) else (kind,)
+
+ unknown_dtypes = [kind for kind in kinds if kind not in dtype_kinds]
+ if unknown_dtypes:
+ raise ValueError(f"unknown dtype kinds: {unknown_dtypes}")
+
+ # verified the dtypes already, no need to check again
+ translated_kinds = [dtype_kinds[kind] for kind in kinds]
+ if isinstance(dtype, np.generic):
+ return any(isinstance(dtype, kind) for kind in translated_kinds)
+ else:
+ return any(np.issubdtype(dtype, kind) for kind in translated_kinds)

View File

@ -1,73 +0,0 @@
From cc4daebf1a4a41483c6b60fc57d82d8bc30911e5 Mon Sep 17 00:00:00 2001
From: Mark Harfouche <mark.harfouche@gmail.com>
Date: Sat, 18 May 2024 12:54:03 -0400
Subject: [PATCH] Use ME in test_plot instead of M
```
pytest xarray/tests/test_plot.py::TestNcAxisNotInstalled::test_ncaxis_notinstalled_line_plot
```
would return the following error
```
xarray/tests/test_plot.py E [100%]
======================================= ERRORS =======================================
____ ERROR at setup of TestNcAxisNotInstalled.test_ncaxis_notinstalled_line_plot _____
self = <xarray.tests.test_plot.TestNcAxisNotInstalled object at 0x78ed1992aa10>
@pytest.fixture(autouse=True)
def setUp(self) -> None:
"""
Create a DataArray with a time-axis that contains cftime.datetime
objects.
"""
month = np.arange(1, 13, 1)
data = np.sin(2 * np.pi * month / 12.0)
darray = DataArray(data, dims=["time"])
> darray.coords["time"] = xr.cftime_range(
start="2017", periods=12, freq="1M", calendar="noleap"
)
/home/mark/git/xarray/xarray/tests/test_plot.py:3004:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/mark/git/xarray/xarray/coding/cftime_offsets.py:1129: in cftime_range
offset = to_offset(freq)
/home/mark/git/xarray/xarray/coding/cftime_offsets.py:767: in to_offset
_emit_freq_deprecation_warning(freq)
/home/mark/git/xarray/xarray/coding/cftime_offsets.py:751: in _emit_freq_deprecation_warning
emit_user_level_warning(message, FutureWarning)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
message = "'M' is deprecated and will be removed in a future version. Please use 'ME' instead of 'M'."
category = <class 'FutureWarning'>
def emit_user_level_warning(message, category=None) -> None:
"""Emit a warning at the user level by inspecting the stack trace."""
stacklevel = find_stack_level()
> return warnings.warn(message, category=category, stacklevel=stacklevel)
E FutureWarning: 'M' is deprecated and will be removed in a future version. Please use 'ME' instead of 'M'.
/home/mark/git/xarray/xarray/core/utils.py:1112: FutureWarning
============================== short test summary info ===============================
ERROR xarray/tests/test_plot.py::TestNcAxisNotInstalled::test_ncaxis_notinstalled_line_plot - FutureWarning: 'M' is deprecated and will be removed in a future version. Please ...
================================== 1 error in 0.64s ==================================
```
---
xarray/tests/test_plot.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xarray/tests/test_plot.py b/xarray/tests/test_plot.py
index e636be5589f..27f4ded5646 100644
--- a/xarray/tests/test_plot.py
+++ b/xarray/tests/test_plot.py
@@ -3002,7 +3002,7 @@ def setUp(self) -> None:
data = np.sin(2 * np.pi * month / 12.0)
darray = DataArray(data, dims=["time"])
darray.coords["time"] = xr.cftime_range(
- start="2017", periods=12, freq="1M", calendar="noleap"
+ start="2017", periods=12, freq="1ME", calendar="noleap"
)
self.darray = darray

View File

@ -0,0 +1,118 @@
From 9406c49fb281d9ffbf88bfd46133288bd23649a4 Mon Sep 17 00:00:00 2001
From: Deepak Cherian <deepak@cherian.net>
Date: Tue, 6 Aug 2024 22:21:29 -0600
Subject: [PATCH 1/2] Fix some dask tests
---
xarray/tests/test_dask.py | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/xarray/tests/test_dask.py b/xarray/tests/test_dask.py
index 20491eca91a..1ef759b3d6a 100644
--- a/xarray/tests/test_dask.py
+++ b/xarray/tests/test_dask.py
@@ -640,8 +640,10 @@ def counting_get(*args, **kwargs):
def test_duplicate_dims(self):
data = np.random.normal(size=(4, 4))
- arr = DataArray(data, dims=("x", "x"))
- chunked_array = arr.chunk({"x": 2})
+ with pytest.warns(UserWarning, match="Duplicate dimension"):
+ arr = DataArray(data, dims=("x", "x"))
+ with pytest.warns(UserWarning, match="Duplicate dimension"):
+ chunked_array = arr.chunk({"x": 2})
assert chunked_array.chunks == ((2, 2), (2, 2))
assert chunked_array.chunksizes == {"x": (2, 2)}
@@ -1364,7 +1366,8 @@ def test_map_blocks_ds_transformations(func, map_ds):
@pytest.mark.parametrize("obj", [make_da(), make_ds()])
def test_map_blocks_da_ds_with_template(obj):
func = lambda x: x.isel(x=[1])
- template = obj.isel(x=[1, 5, 9])
+ # a simple .isel(x=[1, 5, 9]) puts all those in a single chunk.
+ template = xr.concat([obj.isel(x=[i]) for i in [1, 5, 9]], dim="x")
with raise_if_dask_computes():
actual = xr.map_blocks(func, obj, template=template)
assert_identical(actual, template)
@@ -1395,15 +1398,16 @@ def test_map_blocks_roundtrip_string_index():
def test_map_blocks_template_convert_object():
da = make_da()
+ ds = da.to_dataset()
+
func = lambda x: x.to_dataset().isel(x=[1])
- template = da.to_dataset().isel(x=[1, 5, 9])
+ template = xr.concat([da.to_dataset().isel(x=[i]) for i in [1, 5, 9]], dim="x")
with raise_if_dask_computes():
actual = xr.map_blocks(func, da, template=template)
assert_identical(actual, template)
- ds = da.to_dataset()
func = lambda x: x.to_dataarray().isel(x=[1])
- template = ds.to_dataarray().isel(x=[1, 5, 9])
+ template = xr.concat([ds.to_dataarray().isel(x=[i]) for i in [1, 5, 9]], dim="x")
with raise_if_dask_computes():
actual = xr.map_blocks(func, ds, template=template)
assert_identical(actual, template)
@@ -1429,7 +1433,7 @@ def test_map_blocks_errors_bad_template(obj):
xr.map_blocks(
lambda a: a.isel(x=[1]).assign_coords(x=[120]), # assign bad index values
obj,
- template=obj.isel(x=[1, 5, 9]),
+ template=xr.concat([obj.isel(x=[i]) for i in [1, 5, 9]], dim="x"),
).compute()
From 6fa200e542fe18b99a86a53126c10639192ea5e1 Mon Sep 17 00:00:00 2001
From: Deepak Cherian <deepak@cherian.net>
Date: Tue, 6 Aug 2024 22:29:24 -0600
Subject: [PATCH 2/2] Cleanup
---
xarray/tests/test_variable.py | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/xarray/tests/test_variable.py b/xarray/tests/test_variable.py
index 3f3f1756e45..ff6522c00eb 100644
--- a/xarray/tests/test_variable.py
+++ b/xarray/tests/test_variable.py
@@ -318,12 +318,11 @@ def test_datetime64_valid_range(self):
with pytest.raises(pderror, match=r"Out of bounds nanosecond"):
self.cls(["t"], [data])
- @pytest.mark.xfail(reason="pandas issue 36615")
@pytest.mark.filterwarnings("ignore:Converting non-nanosecond")
def test_timedelta64_valid_range(self):
data = np.timedelta64("200000", "D")
pderror = pd.errors.OutOfBoundsTimedelta
- with pytest.raises(pderror, match=r"Out of bounds nanosecond"):
+ with pytest.raises(pderror, match=r"Cannot convert"):
self.cls(["t"], [data])
def test_pandas_data(self):
@@ -2301,20 +2300,20 @@ def test_chunk(self):
assert blocked.chunks == ((3,), (3, 1))
assert blocked.data.name != first_dask_name
- @pytest.mark.xfail
+ @pytest.mark.skip
def test_0d_object_array_with_list(self):
super().test_0d_object_array_with_list()
- @pytest.mark.xfail
+ @pytest.mark.skip
def test_array_interface(self):
# dask array does not have `argsort`
super().test_array_interface()
- @pytest.mark.xfail
+ @pytest.mark.skip
def test_copy_index(self):
super().test_copy_index()
- @pytest.mark.xfail
+ @pytest.mark.skip
@pytest.mark.filterwarnings("ignore:elementwise comparison failed.*:FutureWarning")
def test_eq_all_dtypes(self):
super().test_eq_all_dtypes()

View File

@ -0,0 +1,98 @@
From 70e3f30d5a636f6d847acb2dd0d12cffeb601d41 Mon Sep 17 00:00:00 2001
From: Deepak Cherian <deepak@cherian.net>
Date: Tue, 13 Aug 2024 19:47:10 -0600
Subject: [PATCH 1/2] xfail np.cross tests
xref #9327
---
xarray/core/computation.py | 6 +++---
xarray/tests/test_computation.py | 12 ++++++++----
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/xarray/core/computation.py b/xarray/core/computation.py
index 5d21d0836b9..bb7122e82de 100644
--- a/xarray/core/computation.py
+++ b/xarray/core/computation.py
@@ -23,7 +23,7 @@
from xarray.core.merge import merge_attrs, merge_coordinates_without_align
from xarray.core.options import OPTIONS, _get_keep_attrs
from xarray.core.types import Dims, T_DataArray
-from xarray.core.utils import is_dict_like, is_duck_dask_array, is_scalar, parse_dims
+from xarray.core.utils import is_dict_like, is_scalar, parse_dims
from xarray.core.variable import Variable
from xarray.namedarray.parallelcompat import get_chunked_array_type
from xarray.namedarray.pycompat import is_chunked_array
@@ -1693,11 +1693,11 @@ def cross(
if a.sizes[dim] < b.sizes[dim]:
a = a.pad({dim: (0, 1)}, constant_values=0)
# TODO: Should pad or apply_ufunc handle correct chunking?
- a = a.chunk({dim: -1}) if is_duck_dask_array(a.data) else a
+ a = a.chunk({dim: -1}) if is_chunked_array(a.data) else a
else:
b = b.pad({dim: (0, 1)}, constant_values=0)
# TODO: Should pad or apply_ufunc handle correct chunking?
- b = b.chunk({dim: -1}) if is_duck_dask_array(b.data) else b
+ b = b.chunk({dim: -1}) if is_chunked_array(b.data) else b
else:
raise ValueError(
f"{dim!r} on {'a' if a.sizes[dim] == 1 else 'b'} is incompatible:"
diff --git a/xarray/tests/test_computation.py b/xarray/tests/test_computation.py
index 8b480b02472..e974b8b1ac8 100644
--- a/xarray/tests/test_computation.py
+++ b/xarray/tests/test_computation.py
@@ -2547,7 +2547,8 @@ def test_polyfit_polyval_integration(
"cartesian",
1,
],
- [ # Test 1 sized arrays with coords:
+ # Test 1 sized arrays with coords:
+ pytest.param(
xr.DataArray(
np.array([1]),
dims=["cartesian"],
@@ -2562,8 +2563,10 @@ def test_polyfit_polyval_integration(
np.array([4, 5, 6]),
"cartesian",
-1,
- ],
- [ # Test filling in between with coords:
+ marks=(pytest.mark.xfail(),),
+ ),
+ # Test filling in between with coords:
+ pytest.param(
xr.DataArray(
[1, 2],
dims=["cartesian"],
@@ -2578,7 +2581,8 @@ def test_polyfit_polyval_integration(
np.array([4, 5, 6]),
"cartesian",
-1,
- ],
+ marks=(pytest.mark.xfail(),),
+ ),
],
)
def test_cross(a, b, ae, be, dim: str, axis: int, use_dask: bool) -> None:
From deb9e3266ca163575b200960c14c87fc999dcfc6 Mon Sep 17 00:00:00 2001
From: Deepak Cherian <deepak@cherian.net>
Date: Tue, 13 Aug 2024 19:49:56 -0600
Subject: [PATCH 2/2] Force numpy>=2
---
ci/requirements/environment.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ci/requirements/environment.yml b/ci/requirements/environment.yml
index ef02a3e7f23..40ef4a7fc74 100644
--- a/ci/requirements/environment.yml
+++ b/ci/requirements/environment.yml
@@ -26,7 +26,7 @@ dependencies:
- numba
- numbagg
- numexpr
- - numpy
+ - numpy>=2
- opt_einsum
- packaging
- pandas

View File

@ -0,0 +1,44 @@
From 17367f3545a48d8b8a18bf8f7054b19351c255dc Mon Sep 17 00:00:00 2001
From: Justus Magin <keewis@posteo.de>
Date: Tue, 27 Aug 2024 15:18:32 +0200
Subject: [PATCH 1/3] also call `np.asarray` on numpy scalars
---
xarray/core/variable.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: xarray-2024.07.0/xarray/core/variable.py
===================================================================
--- xarray-2024.07.0.orig/xarray/core/variable.py
+++ xarray-2024.07.0/xarray/core/variable.py
@@ -309,7 +309,7 @@ def as_compatible_data(
else:
data = np.asarray(data)
- if not isinstance(data, np.ndarray) and (
+ if not isinstance(data, np.ndarray | np.generic) and (
hasattr(data, "__array_function__") or hasattr(data, "__array_namespace__")
):
return cast("T_DuckArray", data)
Index: xarray-2024.07.0/xarray/tests/test_variable.py
===================================================================
--- xarray-2024.07.0.orig/xarray/tests/test_variable.py
+++ xarray-2024.07.0/xarray/tests/test_variable.py
@@ -2585,10 +2585,15 @@ class TestAsCompatibleData(Generic[T_Duc
assert source_ndarray(x) is source_ndarray(as_compatible_data(x))
def test_converted_types(self):
- for input_array in [[[0, 1, 2]], pd.DataFrame([[0, 1, 2]])]:
+ for input_array in [
+ [[0, 1, 2]],
+ pd.DataFrame([[0, 1, 2]]),
+ np.float64(1.4),
+ np.str_("abc"),
+ ]:
actual = as_compatible_data(input_array)
assert_array_equal(np.asarray(input_array), actual)
- assert np.ndarray == type(actual)
+ assert np.ndarray is type(actual)
assert np.asarray(input_array).dtype == actual.dtype
def test_masked_array(self):