Skip to content

Commit ce68103

Browse files
committed
Merge branch 'main' into concat-multi-var-index
* main: Fix performance regression in interp from pydata#9881 (pydata#10370) html repr: improve style for dropdown sections (pydata#10354) Grouper tweaks. (pydata#10362) Docs: Add links to getting help mermaid diagram (pydata#10324) Enforce ruff/flynt rules (FLY) (pydata#10375) Add missing AbstractWritableDataStore base methods and arguments (pydata#10343) Improve html repr in dark mode (Jupyterlab + Xarray docs) (pydata#10353) Pin Mypy to 1.15 (pydata#10378) use numpy dtype exposed by zarr array instead of metadata.data_type (pydata#10348) Fix doc typo for caption "Interoperability" (pydata#10374) Implement cftime vectorization as discussed in PR pydata#8322 (pydata#8324) Enforce ruff/flake8-pyi rules (PYI) (pydata#10359) Apply assorted ruff/Pylint rules (PL) / Enforce PLE rules (pydata#10366) (fix): pandas extension array repr for int64[pyarrow] (pydata#10317) Enforce ruff/flake8-implicit-str-concat rules (ISC) (pydata#10368) Enforce ruff/refurb rules (FURB) (pydata#10367) Ignore ruff/Pyflakes rule F401 more precisely (pydata#10369) Apply assorted ruff/flake8-simplify rules (SIM) (pydata#10364) Apply assorted ruff/flake8-pytest-style rules (PT) (pydata#10363) Fix "a array" misspelling (pydata#10365)
2 parents 29319e8 + 34efef2 commit ce68103

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+808
-678
lines changed

ci/requirements/environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ dependencies:
2020
- iris
2121
- lxml # Optional dep of pydap
2222
- matplotlib-base
23+
- mypy==1.15 # mypy 1.16 breaks CI
2324
- nc-time-axis
2425
- netcdf4
2526
- numba

doc/_static/style.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,11 @@ html[data-theme="dark"] .sd-card img[src*=".svg"] {
4444
.bd-content .sd-card .sd-card-body {
4545
background-color: unset !important;
4646
}
47+
48+
/* workaround Pydata Sphinx theme using light colors for widget cell outputs in dark-mode */
49+
/* works for many widgets but not for Xarray html reprs */
50+
/* https://github.com/pydata/pydata-sphinx-theme/issues/2189 */
51+
html[data-theme="dark"] div.cell_output .text_html:has(div.xr-wrap) {
52+
background-color: var(--pst-color-on-background) !important;
53+
color: var(--pst-color-text-base) !important;
54+
}

doc/conf.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import sys
77
from contextlib import suppress
88
from textwrap import dedent, indent
9-
9+
import packaging.version
1010
import sphinx_autosummary_accessors
1111
import yaml
1212
from sphinx.application import Sphinx
@@ -185,7 +185,7 @@
185185
autodoc_type_aliases = napoleon_type_aliases # Keep both in sync
186186

187187
# mermaid config
188-
mermaid_version = "10.9.1"
188+
mermaid_version = "11.6.0"
189189

190190
# Add any paths that contain templates here, relative to this directory.
191191
templates_path = ["_templates", sphinx_autosummary_accessors.templates_path]
@@ -201,10 +201,9 @@
201201
project = "xarray"
202202
copyright = f"2014-{datetime.datetime.now().year}, xarray Developers"
203203

204-
# The short X.Y version.
205-
version = xarray.__version__.split("+")[0]
206-
# The full version, including alpha/beta/rc tags.
207-
release = xarray.__version__
204+
# The short Y.M.D version.
205+
v = packaging.version.parse(xarray.__version__)
206+
version = ".".join(str(p) for p in v.release)
208207

209208
# There are two options for replacing |today|: either, you set today to some
210209
# non-false value, then it is used:
@@ -314,6 +313,7 @@
314313
"installing.rst": "getting-started-guide/installing.rst",
315314
"quick-overview.rst": "getting-started-guide/quick-overview.rst",
316315
"contributing.rst": "contribute/contributing.rst",
316+
"developers-meeting.rst": "contribute/developers-meeting.rst",
317317
}
318318

319319
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,

doc/get-help/help-diagram.rst

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,72 @@ Getting Help
33

44
Navigating the wealth of resources available for Xarray can be overwhelming.
55
We've created this flow chart to help guide you towards the best way to get help, depending on what you're working towards.
6-
The links to each resource are provided below the diagram.
76

8-
Also be sure to check out our "FAQ" and "How do I..." pages in this section for solutions to common questions.
7+
Also be sure to check out our :ref:`faq`. and :ref:`howdoi` pages for solutions to common questions.
98

10-
A major strength of Xarray is in the user community. Sometimes you might not have a concrete question by would simply like to connect with other Xarray users. We have a few
9+
A major strength of Xarray is in the user community. Sometimes you might not yet have a concrete question but would simply like to connect with other Xarray users. We have a few accounts on different social platforms for that! :ref:`socials`.
1110

1211
We look forward to hearing from you!
1312

13+
Help Flowchart
14+
--------------
15+
..
16+
_comment: mermaid Flowcharg "link" text gets secondary color background, SVG icon fill gets primary color
17+
18+
.. raw:: html
19+
20+
<style>
21+
/* Ensure PST link colors don't override mermaid text colors */
22+
.mermaid a {
23+
color: white;
24+
}
25+
.mermaid a:hover {
26+
color: magenta;
27+
text-decoration-color: magenta;
28+
}
29+
.mermaid a:visited {
30+
color: white;
31+
text-decoration-color: white;
32+
}
33+
</style>
34+
1435
.. mermaid::
36+
:config: {"theme":"base","themeVariables":{"fontSize":"20px","primaryColor":"#fff","primaryTextColor":"#fff","primaryBorderColor":"#59c7d6","lineColor":"#e28126","secondaryColor":"#767985"}}
1537
:alt: Flowchart illustrating the different ways to access help using or contributing to Xarray.
1638

1739
flowchart TD
1840
intro[Welcome to Xarray! How can we help?]:::quesNodefmt
19-
usage(["fa:fa-chalkboard-user Xarray Tutorials
20-
fab:fa-readme Xarray Docs
21-
fab:fa-google Google/fab:fa-stack-overflow Stack Exchange
22-
fa:fa-robot Ask AI/a Language Learning Model (LLM)"]):::ansNodefmt
23-
API([fab:fa-readme Xarray Docs
24-
fab:fa-readme extension's docs]):::ansNodefmt
25-
help([fab:fa-github Xarray Discussions
26-
fab:fa-discord Xarray Discord
27-
fa:fa-users Xarray Office Hours
28-
fa:fa-globe Pangeo Discourse]):::ansNodefmt
29-
bug([Report and Propose here:
30-
fab:fa-github Xarray Issues]):::ansNodefmt
31-
contrib([fa:fa-book-open Xarray Contributor's Guide]):::ansNodefmt
32-
pr(["fab:fa-github Pull Request (PR)"]):::ansNodefmt
33-
dev([fab:fa-github Comment on your PR
34-
fa:fa-users Developer's Meeting]):::ansNodefmt
41+
usage([fa:fa-chalkboard-user <a href="https://tutorial.xarray.dev">Xarray Tutorial</a>
42+
fab:fa-readme <a href="https://docs.xarray.dev">Xarray Docs</a>
43+
fab:fa-stack-overflow <a href="https://stackoverflow.com/questions/tagged/python-xarray">Stack Exchange</a>
44+
fab:fa-google <a href="https://www.google.com">Ask Google</a>
45+
fa:fa-robot Ask AI ChatBot]):::ansNodefmt
46+
extensions([Extension docs:
47+
fab:fa-readme <a href="https://docs.dask.org">Dask</a>
48+
fab:fa-readme <a href="https://corteva.github.io/rioxarray">Rioxarray</a>]):::ansNodefmt
49+
help([fab:fa-github <a href="https://github.com/pydata/xarray/discussions">Xarray Discussions</a>
50+
fab:fa-discord <a href="https://discord.com/invite/wEKPCt4PDu">Xarray Discord</a>
51+
fa:fa-globe <a href="https://discourse.pangeo.io">Pangeo Discourse</a>]):::ansNodefmt
52+
bug([Let us know:
53+
fab:fa-github <a href="https://github.com/pydata/xarray/issues">Xarray Issues</a>]):::ansNodefmt
54+
contrib([fa:fa-book-open <a href="https://docs.xarray.dev/en/latest/contribute">Xarray Contributor's Guide</a>]):::ansNodefmt
55+
pr([fab:fa-github <a href="https://github.com/pydata/xarray/pulls">Pull Request</a>]):::ansNodefmt
56+
dev([fab:fa-github Add PR Comment
57+
fa:fa-users <a href="https://docs.xarray.dev/en/stable/contribute/developers-meeting.html">Attend Developer's Meeting</a> ]):::ansNodefmt
3558
report[Thanks for letting us know!]:::quesNodefmt
36-
merged[fa:fa-hands-clapping Your PR was merged.
37-
Thanks for contributing to Xarray!]:::quesNodefmt
59+
merged[fa:fa-hands-clapping Thanks for contributing to Xarray!]:::quesNodefmt
3860

3961

4062
intro -->|How do I use Xarray?| usage
41-
usage -->|"with extensions (like Dask)"| API
63+
usage -->|"With extensions (like Dask, Rioxarray, etc.)"| extensions
4264

43-
usage -->|I'd like some more help| help
44-
intro -->|I found a bug| bug
45-
intro -->|I'd like to make a small change| contrib
46-
subgraph bugcontrib[Bugs and Contributions]
47-
bug
48-
contrib
49-
bug -->|I just wanted to tell you| report
50-
bug<-->|I'd like to fix the bug!| contrib
51-
pr -->|my PR was approved| merged
52-
end
65+
usage -->|I still have questions or could use some guidance | help
66+
intro -->|I think I found a bug| bug
67+
bug
68+
contrib
69+
bug -->|I just wanted to tell you| report
70+
bug<-->|I'd like to fix the bug!| contrib
71+
pr -->|my PR was approved| merged
5372

5473

5574
intro -->|I wish Xarray could...| bug
@@ -58,20 +77,16 @@ We look forward to hearing from you!
5877
pr <-->|my PR is quiet| dev
5978
contrib -->pr
6079

61-
classDef quesNodefmt fill:#9DEEF4,stroke:#206C89
62-
63-
classDef ansNodefmt fill:#FFAA05,stroke:#E37F17
80+
classDef quesNodefmt font-size:20pt,fill:#0e4666,stroke:#59c7d6,stroke-width:3
81+
classDef ansNodefmt font-size:18pt,fill:#4a4a4a,stroke:#17afb4,stroke-width:3
82+
linkStyle default font-size:16pt,stroke-width:4
6483

65-
classDef boxfmt fill:#FFF5ED,stroke:#E37F17
66-
class bugcontrib boxfmt
67-
68-
linkStyle default font-size:20pt,color:#206C89
6984

7085
Flowchart links
7186
---------------
7287
- `Xarray Tutorials <https://tutorial.xarray.dev/>`__
7388
- `Xarray Docs <https://docs.xarray.dev>`__
74-
- `Google/Stack Exchange <https://stackoverflow.com/questions/tagged/python-xarray>`__
89+
- `Stack Exchange <https://stackoverflow.com/questions/tagged/python-xarray>`__
7590
- `Xarray Discussions <https://github.com/pydata/xarray/discussions>`__
7691
- `Xarray Discord <https://discord.com/invite/wEKPCt4PDu>`__
7792
- `Xarray Office Hours <https://github.com/pydata/xarray/discussions/categories/office-hours>`__
@@ -80,7 +95,6 @@ Flowchart links
8095
- :ref:`contributing`
8196
- :ref:`developers-meeting`
8297

83-
8498
.. toctree::
8599
:maxdepth: 1
86100
:hidden:

doc/get-help/howdoi.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ How do I ...
6969
- ``obj.dt.month`` for example where ``obj`` is a :py:class:`~xarray.DataArray` containing ``datetime64`` or ``cftime`` values. See :ref:`dt_accessor` for more.
7070
* - round off time values to a specified frequency
7171
- ``obj.dt.ceil``, ``obj.dt.floor``, ``obj.dt.round``. See :ref:`dt_accessor` for more.
72-
* - make a mask that is ``True`` where an object contains any of the values in a array
72+
* - make a mask that is ``True`` where an object contains any of the values in an array
7373
- :py:meth:`Dataset.isin`, :py:meth:`DataArray.isin`
7474
* - Index using a boolean mask
7575
- :py:meth:`Dataset.query`, :py:meth:`DataArray.query`, :py:meth:`Dataset.where`, :py:meth:`DataArray.where`

doc/user-guide/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ examples that describe many common tasks that you can accomplish with Xarray.
4343

4444
.. toctree::
4545
:maxdepth: 2
46-
:caption: Interoperatbility
46+
:caption: Interoperability
4747

4848
pandas
4949
duckarrays

doc/whats-new.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ Bug fixes
5050
calculating mean in rolling for correct operations (preserve float dtypes,
5151
correct mean of bool arrays) (:issue:`10340`, :pull:`10341`).
5252
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
53+
- Improve the html ``repr`` of Xarray objects (dark mode, icons and variable attribute / data
54+
dropdown sections).
55+
(:pull:`10353`, :pull:`10354`)
56+
By `Benoit Bovy <https://github.com/benbovy>`_.
5357
- Raise an error when attempting to encode :py:class:`numpy.datetime64` values
5458
prior to the Gregorian calendar reform date of 1582-10-15 with a
5559
``"standard"`` or ``"gregorian"`` calendar. Previously we would warn and
@@ -65,7 +69,10 @@ Performance
6569
in :py:class:`~xarray.indexing.VectorizedIndexer` and :py:class:`~xarray.indexing.OuterIndexer`
6670
(:issue:`10316`).
6771
By `Jesse Rusak <https://github.com/jder>`_.
68-
72+
- Fix performance regression in interp where more data was loaded than was necessary. (:issue:`10287`).
73+
By `Deepak Cherian <https://github.com/dcherian>`_.
74+
- Speed up encoding of :py:class:`cftime.datetime` objects by roughly a factor
75+
of three (:pull:`8324`). By `Antoine Gibek <https://github.com/antscloud>`_.
6976

7077
Documentation
7178
~~~~~~~~~~~~~

pyproject.toml

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,27 +249,35 @@ extend-exclude = ["doc", "_typed_ops.pyi"]
249249

250250
[tool.ruff.lint]
251251
extend-select = [
252-
"W", # pycodestyle warnings
253-
"I", # isort
254-
"UP", # pyupgrade
255252
"B", # flake8-bugbear
256253
"C4", # flake8-comprehensions
254+
"ISC", # flake8-implicit-str-concat
257255
"PIE", # flake8-pie
258256
"TID", # flake8-tidy-imports (absolute imports)
259-
"PGH", # pygrep-hooks
257+
"PYI", # flake8-pyi
258+
"FLY", # flynt
259+
"I", # isort
260260
"PERF", # Perflint
261+
"W", # pycodestyle warnings
262+
"PGH", # pygrep-hooks
263+
"PLE", # Pylint Errors
264+
"UP", # pyupgrade
265+
"FURB", # refurb
261266
"RUF",
262267
]
263268
extend-safe-fixes = [
264269
"TID252", # absolute imports
265270
]
266271
ignore = [
267-
"E402", # module level import not at top of file
268-
"E731", # do not assign a lambda expression, use a def
269-
"UP007", # use X | Y for type annotations
270272
"C40", # unnecessary generator, comprehension, or literal
271273
"PIE790", # unnecessary pass statement
274+
"PYI019", # use `Self` instead of custom TypeVar
275+
"PYI041", # use `float` instead of `int | float`
272276
"PERF203", # try-except within a loop incurs performance overhead
277+
"E402", # module level import not at top of file
278+
"E731", # do not assign a lambda expression, use a def
279+
"UP007", # use X | Y for type annotations
280+
"FURB105", # unnecessary empty string passed to `print`
273281
"RUF001", # string contains ambiguous unicode character
274282
"RUF002", # docstring contains ambiguous acute accent unicode character
275283
"RUF003", # comment contains ambiguous no-break space unicode character
@@ -280,6 +288,9 @@ ignore = [
280288
[tool.ruff.lint.per-file-ignores]
281289
# don't enforce absolute imports
282290
"asv_bench/**" = ["TID252"]
291+
# looks like ruff bugs
292+
"xarray/core/_typed_ops.py" = ["PYI034"]
293+
"xarray/namedarray/_typing.py" = ["PYI018", "PYI046"]
283294

284295
[tool.ruff.lint.isort]
285296
known-first-party = ["xarray"]

xarray/backends/api.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
T_NetcdfEngine = Literal["netcdf4", "scipy", "h5netcdf"]
7272
T_Engine = Union[
7373
T_NetcdfEngine,
74-
Literal["pydap", "zarr"],
74+
Literal["pydap", "zarr"], # noqa: PYI051
7575
type[BackendEntrypoint],
7676
str, # no nice typing support for custom backends
7777
None,
@@ -710,8 +710,8 @@ def open_dataset(
710710
def open_dataarray(
711711
filename_or_obj: str | os.PathLike[Any] | ReadBuffer | AbstractDataStore,
712712
*,
713-
engine: T_Engine | None = None,
714-
chunks: T_Chunks | None = None,
713+
engine: T_Engine = None,
714+
chunks: T_Chunks = None,
715715
cache: bool | None = None,
716716
decode_cf: bool | None = None,
717717
mask_and_scale: bool | None = None,
@@ -1394,7 +1394,7 @@ def open_mfdataset(
13941394
| os.PathLike
13951395
| ReadBuffer
13961396
| NestedSequence[str | os.PathLike | ReadBuffer],
1397-
chunks: T_Chunks | None = None,
1397+
chunks: T_Chunks = None,
13981398
concat_dim: (
13991399
str
14001400
| DataArray
@@ -1406,7 +1406,7 @@ def open_mfdataset(
14061406
) = None,
14071407
compat: CompatOptions = "no_conflicts",
14081408
preprocess: Callable[[Dataset], Dataset] | None = None,
1409-
engine: T_Engine | None = None,
1409+
engine: T_Engine = None,
14101410
data_vars: Literal["all", "minimal", "different"] | list[str] = "all",
14111411
coords="different",
14121412
combine: Literal["by_coords", "nested"] = "by_coords",

xarray/backends/common.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,10 @@ def add(self, source, target, region=None):
338338
self.sources.append(source)
339339
self.targets.append(target)
340340
self.regions.append(region)
341+
elif region:
342+
target[region] = source
341343
else:
342-
if region:
343-
target[region] = source
344-
else:
345-
target[...] = source
344+
target[...] = source
346345

347346
def sync(self, compute=True, chunkmanager_store_kwargs=None):
348347
if self.sources:
@@ -402,7 +401,10 @@ def encode_attribute(self, a):
402401
"""encode one attribute"""
403402
return a
404403

405-
def set_dimension(self, dim, length): # pragma: no cover
404+
def prepare_variable(self, name, variable, check_encoding, unlimited_dims):
405+
raise NotImplementedError()
406+
407+
def set_dimension(self, dim, length, is_unlimited): # pragma: no cover
406408
raise NotImplementedError()
407409

408410
def set_attribute(self, k, v): # pragma: no cover

xarray/backends/h5netcdf_.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,16 @@ def _read_attributes(h5netcdf_var):
6868
# bytes attributes to strings
6969
attrs = {}
7070
for k, v in h5netcdf_var.attrs.items():
71-
if k not in ["_FillValue", "missing_value"]:
72-
if isinstance(v, bytes):
73-
try:
74-
v = v.decode("utf-8")
75-
except UnicodeDecodeError:
76-
emit_user_level_warning(
77-
f"'utf-8' codec can't decode bytes for attribute "
78-
f"{k!r} of h5netcdf object {h5netcdf_var.name!r}, "
79-
f"returning bytes undecoded.",
80-
UnicodeWarning,
81-
)
71+
if k not in ["_FillValue", "missing_value"] and isinstance(v, bytes):
72+
try:
73+
v = v.decode("utf-8")
74+
except UnicodeDecodeError:
75+
emit_user_level_warning(
76+
f"'utf-8' codec can't decode bytes for attribute "
77+
f"{k!r} of h5netcdf object {h5netcdf_var.name!r}, "
78+
f"returning bytes undecoded.",
79+
UnicodeWarning,
80+
)
8281
attrs[k] = v
8382
return attrs
8483

xarray/backends/locks.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,7 @@ def _get_lock_maker(scheduler=None):
118118
dask.utils.get_scheduler_lock
119119
"""
120120

121-
if scheduler is None:
122-
return _get_threaded_lock
123-
elif scheduler == "threaded":
121+
if scheduler is None or scheduler == "threaded":
124122
return _get_threaded_lock
125123
elif scheduler == "multiprocessing":
126124
return _get_multiprocessing_lock

0 commit comments

Comments
 (0)