1 Commits
f43 ... f42

Author SHA1 Message Date
Elliott Sales de Andrade
66c2059622 Update to 2025.1.2 2025-06-10 17:05:51 -04:00
7 changed files with 64 additions and 183 deletions

4
.gitignore vendored
View File

@@ -29,7 +29,3 @@
/xarray-2024.7.0.tar.gz
/xarray-2024.10.0.tar.gz
/xarray-2025.1.1.tar.gz
/xarray-2025.4.0.tar.gz
/xarray-2025.9.0.tar.gz
/xarray-2025.11.0.tar.gz
/xarray-2025.12.0.tar.gz

View File

@@ -0,0 +1,53 @@
From 33ab61521498550eda98d7aebc141635f9f218d7 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Sun, 19 Jan 2025 04:47:23 -0500
Subject: [PATCH] Avoid unsafe casts from float to unsigned int
Fixes #9815
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
xarray/coding/variables.py | 5 ++++-
xarray/core/duck_array_ops.py | 10 ++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/xarray/coding/variables.py b/xarray/coding/variables.py
index 83112628..b036fd5d 100644
--- a/xarray/coding/variables.py
+++ b/xarray/coding/variables.py
@@ -426,7 +426,10 @@ class CFMaskCoder(VariableCoder):
if fill_value is not None and has_unsigned:
pop_to(encoding, attrs, "_Unsigned")
# XXX: Is this actually needed? Doesn't the backend handle this?
- data = duck_array_ops.astype(duck_array_ops.around(data), dtype)
+ signed_dtype = np.dtype(f"i{dtype.itemsize}")
+ data = duck_array_ops.view(
+ duck_array_ops.astype(duck_array_ops.around(data), signed_dtype), dtype
+ )
attrs["_FillValue"] = fill_value
return Variable(dims, data, attrs, encoding, fastpath=True)
diff --git a/xarray/core/duck_array_ops.py b/xarray/core/duck_array_ops.py
index c3f15980..1cec78cb 100644
--- a/xarray/core/duck_array_ops.py
+++ b/xarray/core/duck_array_ops.py
@@ -236,6 +236,16 @@ def astype(data, dtype, **kwargs):
return data.astype(dtype, **kwargs)
+def view(data, *args, **kwargs):
+ if hasattr(data, "__array_namespace__"):
+ xp = get_array_namespace(data)
+ if xp == np:
+ # numpy currently doesn't have a view:
+ return data.view(*args, **kwargs)
+ return xp.view(data, *args, **kwargs)
+ return data.view(*args, **kwargs)
+
+
def asarray(data, xp=np, dtype=None):
converted = data if is_duck_array(data) else xp.asarray(data)
--
2.49.0

View File

@@ -1,42 +0,0 @@
From 260fec7f2a203093cb6626d464e30fab3ec70de7 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Mon, 15 Sep 2025 05:49:16 -0400
Subject: [PATCH 1/2] Drop pydap from dependencies
We didn't have it since it wasn't available in Python 3.10+, and it's
not yet pcakaged.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
pyproject.toml | 1 -
xarray/tests/test_backends.py | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index 52897064..23d0b8ee 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -38,7 +38,6 @@ complete = ["xarray[accel,etc,io,parallel,viz]"]
io = [
"netCDF4>=1.6.0",
"h5netcdf",
- "pydap",
"scipy>=1.13",
"zarr>=2.18",
"fsspec",
diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py
index 5aab1531..89461b0a 100644
--- a/xarray/tests/test_backends.py
+++ b/xarray/tests/test_backends.py
@@ -7457,7 +7457,7 @@ def test_remote_url_backend_auto_detection() -> None:
"https://disc2.gesdisc.eosdis.nasa.gov/dods/TRMM_3B42", # GrADS /dods/
]
- for url in dap_urls:
+ for url in dap_urls[:0]:
engine = guess_engine(url)
assert engine == expected_dap_backend, (
f"URL {url!r} should select {expected_dap_backend!r} but got {engine!r}"
--
2.52.0

View File

@@ -1,117 +0,0 @@
From 5e5ef99ce6cae2179a2cc89b551b187fb97f35fe Mon Sep 17 00:00:00 2001
From: David Bold <davidsch@fedoraproject.org>
Date: Tue, 25 Nov 2025 19:58:05 -0500
Subject: [PATCH 2/2] Ensure netcdf4 is locked while closing
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
xarray/backends/file_manager.py | 20 +++++++++++++++-----
xarray/backends/locks.py | 3 +++
xarray/backends/netCDF4_.py | 8 +++-----
3 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/xarray/backends/file_manager.py b/xarray/backends/file_manager.py
index f7cd4675..cf85eaf3 100644
--- a/xarray/backends/file_manager.py
+++ b/xarray/backends/file_manager.py
@@ -8,7 +8,7 @@ from collections.abc import Callable, Hashable, Iterator, Mapping, MutableMappin
from contextlib import AbstractContextManager, contextmanager
from typing import Any, Generic, Literal, TypeVar, cast
-from xarray.backends.locks import acquire
+from xarray.backends.locks import NETCDF4_PYTHON_LOCK, acquire
from xarray.backends.lru_cache import LRUCache
from xarray.core import utils
from xarray.core.options import OPTIONS
@@ -89,7 +89,7 @@ class CachingFileManager(FileManager[T_File]):
*args: Any,
mode: Any = _OMIT_MODE,
kwargs: Mapping[str, Any] | None = None,
- lock: Lock | None | Literal[False] = None,
+ lock: Lock | Literal[False] | None = None,
cache: MutableMapping[Any, T_File] | None = None,
manager_id: Hashable | None = None,
ref_counts: dict[Any, int] | None = None,
@@ -448,9 +448,16 @@ def _remove_del_methods():
class DummyFileManager(FileManager[T_File]):
"""FileManager that simply wraps an open file in the FileManager interface."""
- def __init__(self, value: T_File, *, close: Callable[[], None] | None = None):
+ def __init__(
+ self,
+ value: T_File,
+ *,
+ close: Callable[[], None] | None = None,
+ lock: Lock | Literal[False] | None = None,
+ ):
if close is None:
close = value.close
+ self._lock = lock
self._value = value
self._close = close
@@ -464,5 +471,8 @@ class DummyFileManager(FileManager[T_File]):
yield self._value
def close(self, needs_lock: bool = True) -> None:
- del needs_lock # unused
- self._close()
+ if needs_lock and self._lock:
+ with self._lock:
+ self._close()
+ else:
+ self._close()
diff --git a/xarray/backends/locks.py b/xarray/backends/locks.py
index 78444354..e2db5e93 100644
--- a/xarray/backends/locks.py
+++ b/xarray/backends/locks.py
@@ -281,3 +281,6 @@ def ensure_lock(lock: Lock | None | Literal[False]) -> Lock:
if lock is None or lock is False:
return DummyLock()
return lock
+
+
+NETCDF4_PYTHON_LOCK = combine_locks([NETCDFC_LOCK, HDF5_LOCK])
diff --git a/xarray/backends/netCDF4_.py b/xarray/backends/netCDF4_.py
index bb511f9b..5d5d4e74 100644
--- a/xarray/backends/netCDF4_.py
+++ b/xarray/backends/netCDF4_.py
@@ -30,7 +30,7 @@ from xarray.backends.file_manager import (
PickleableFileManager,
)
from xarray.backends.locks import (
- HDF5_LOCK,
+ NETCDF4_PYTHON_LOCK,
NETCDFC_LOCK,
combine_locks,
ensure_lock,
@@ -67,8 +67,6 @@ if TYPE_CHECKING:
# string used by netCDF4.
_endian_lookup = {"=": "native", ">": "big", "<": "little", "|": "native"}
-NETCDF4_PYTHON_LOCK = combine_locks([NETCDFC_LOCK, HDF5_LOCK])
-
class BaseNetCDF4Array(BackendArray):
__slots__ = ("datastore", "dtype", "shape", "variable_name")
@@ -421,7 +419,7 @@ class NetCDF4DataStore(WritableCFDataStore):
"argument is provided"
)
root = manager
- manager = DummyFileManager(root)
+ manager = DummyFileManager(root, lock=NETCDF4_PYTHON_LOCK)
self._manager = manager
self._group = group
@@ -520,7 +518,7 @@ class NetCDF4DataStore(WritableCFDataStore):
)
else:
manager = CachingFileManager(
- netCDF4.Dataset, filename, mode=mode, kwargs=kwargs
+ netCDF4.Dataset, filename, lock=lock, mode=mode, kwargs=kwargs
)
return cls(manager, group=group, mode=mode, lock=lock, autoclose=autoclose)
--
2.52.0

View File

@@ -1,3 +0,0 @@
This repository is maintained by packit.
https://packit.dev/
The file was generated using packit 1.12.0.post1.dev20+g7d30dac21.

View File

@@ -1,32 +1,28 @@
%global srcname xarray
Name: python-%{srcname}
Version: 2025.12.0
Version: 2025.1.2
Release: %autorelease
Summary: N-D labeled arrays and datasets in Python
License: Apache-2.0
URL: https://github.com/pydata/xarray
Source: %pypi_source %{srcname}
# Fedora specific.
Patch: 0001-Drop-pydap-from-dependencies.patch
# RHBZ#2395128
# https://github.com/pydata/xarray/pull/10788
Patch: 0002-Ensure-netcdf4-is-locked-while-closing.patch
# https://github.com/pydata/xarray/pull/9964
Patch: 0001-Avoid-unsafe-casts-from-float-to-unsigned-int.patch
BuildArch: noarch
BuildRequires: python3-devel
BuildRequires: python3dist(bottleneck)
BuildRequires: python3dist(dask[array]) >= 2023.11
BuildRequires: python3dist(dask[dataframe]) >= 2023.11
BuildRequires: python3dist(pint) >= 0.22
BuildRequires: python3dist(dask[array]) >= 2023.9
BuildRequires: python3dist(dask[dataframe]) >= 2023.9
BuildRequires: python3dist(pint) >= 0.16
BuildRequires: python3dist(pytest) >= 2.7.1
BuildRequires: python3dist(pytest-asyncio)
BuildRequires: python3dist(pytest-xdist)
BuildRequires: python3dist(pytest-timeout)
BuildRequires: python3dist(rasterio) >= 1.3
BuildRequires: python3dist(seaborn) >= 0.13
BuildRequires: python3dist(rasterio) >= 1.1
BuildRequires: python3dist(seaborn) >= 0.11
%global _description %{expand: \
Xarray (formerly xray) is an open source project and Python package that
@@ -68,8 +64,6 @@ Summary: %{summary}
%check
rm -rf xarray
echo >> pytest.ini # Ignore any command-line arguments from upstream.
pytest_args=(
-n auto
-m "not network"
@@ -77,7 +71,7 @@ pytest_args=(
-k 'not test_save_mfdataset_compute_false_roundtrip'
)
%{pytest} -ra "${pytest_args[@]}" --pyargs xarray --timeout 300 --full-trace
%{pytest} -ra "${pytest_args[@]}" --pyargs xarray
%files -n python3-%{srcname} -f %{pyproject_files}
%license licenses/*

View File

@@ -1 +1 @@
SHA512 (xarray-2025.12.0.tar.gz) = 7bbdf756d24a91c4a11c5d38d10dfe520e2cb80ba2beecdbf534fae76c6c6148232f2f072d068daab60146d46c89e12800276ebc1bc4d5228b16dde8f80d9793
SHA512 (xarray-2025.1.1.tar.gz) = a0cde2c8e38887878bcde25fd3ea6ee436b522ca73f52359d2c8ac1993447472d7cd5e5d4b11016ec48d1b86dba08e9207caf00b2b43ab896c777395e51f7943