id,node_id,number,state,locked,title,user,body,created_at,updated_at,closed_at,merged_at,merge_commit_sha,assignee,milestone,draft,head,base,author_association,auto_merge,repo,url,merged_by 774872375,PR_kwDOAMm_X84uL503,5948,closed,0,"Fix plot.line crash for data of shape (1, N) in _title_for_slice on format_item",9513634," Affected `xarray` versions `0.20.0`+ When dependabot recently made a PR to update `xarray` to `0.20.0` our integration test CI failed with ``` .... File ""/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/xarray/plot/plot.py"", line 447, in line ax.set_title(darray._title_for_slice()) File ""/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/xarray/core/dataarray.py"", line 3140, in _title_for_slice v=format_item(coord.values), File ""/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/xarray/core/formatting.py"", line 146, in format_item return f""{x:.4}"" TypeError: unsupported format string passed to numpy.ndarray.__format__ ``` We use `xarray.Dataarray.plot.line(x="""")` to plot data of shape `(N, M)` where `N` and `M` are `>=1`. The crash is caused because the following line https://github.com/pydata/xarray/blob/402a9b398868bd9bd385210138d6f8ea610c8c40/xarray/core/dataarray.py#L3136 allows arrays of shape `()` and `(1,)` to be passed into `format_item`, where both pass this check https://github.com/pydata/xarray/blob/402a9b398868bd9bd385210138d6f8ea610c8c40/xarray/core/formatting.py#L145-L146 But `f""{x:.4}""` only works for arrays of shape `()` and crashes on arrays of shape `(1,)` Before the check was https://github.com/pydata/xarray/blob/a78c1e0115d38cb4461fd1aba93334d440cff49c/xarray/core/formatting.py#L145-L146 Which didn't allow any arrays and caused the float formatting issue.
Code showing the differences ```python In [1]: import numpy as np In [2]: x = np.array(0.1) In [3]: x.shape Out[3]: () In [4]: np.issubdtype(type(x), np.floating) Out[4]: False In [5]: hasattr(x, ""dtype"") and np.issubdtype(x.dtype, np.floating) Out[5]: True In [6]: f""{x:.4}"" Out[6]: '0.1' In [7]: f""{x.item():.4}"" Out[7]: '0.1' In [8]: x = np.array([0.1]) In [9]: x.shape Out[9]: (1,) In [10]: np.issubdtype(type(x), np.floating) Out[10]: False In [11]: hasattr(x, ""dtype"") and np.issubdtype(x.dtype, np.floating) Out[11]: True In [12]: f""{x:.4}"" --------------------------------------------------------------------------- TypeError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_32644/2490801713.py in ----> 1 f""{x:.4}"" TypeError: unsupported format string passed to numpy.ndarray.__format__ In [13]: f""{x.item():.4}"" Out[13]: '0.1' ```
I hope `TestPlot1D` was the correct place to put the test since the plot itself is 1D but the data which are plotted have a second dimension with size 1 (naming thing and where to put things... 😅). - [x] Tests added - [x] Passes `pre-commit run --all-files` - [x] User visible changes (including notable bug fixes) are documented in `whats-new.rst` PS: Thanks for the awesome package ❤️ ",2021-11-06T22:56:59Z,2021-11-08T18:40:08Z,2021-11-08T17:27:45Z,2021-11-08T17:27:44Z,eac78cc0cc2a205bfaa49aa9a46987116021b97a,,,0,51b6cd89157defb426cb33afa44124dfbf1fb7bb,402a9b398868bd9bd385210138d6f8ea610c8c40,CONTRIBUTOR,,13221727,https://github.com/pydata/xarray/pull/5948, 835041515,PR_kwDOAMm_X84xxbjr,6207,closed,0,Fix missing dependecy definition of 'packaging',9513634,"Hi there, we just wanted to upgrade `xarray` to version `0.21.0` and our [ASV workflow on the CI started failing](https://github.com/glotaran/pyglotaran/runs/4989968632?check_suite_focus=true). ```python File ""/home/runner/work/pyglotaran/pyglotaran/benchmark/.asv/env/76391772e92136ec87b9940d70226329/lib/python3.8/site-packages/xarray/core/dask_array_compat.py"", line 4, in from packaging.version import Version ModuleNotFoundError: No module named 'packaging' ``` The reason is that `packaging` isn't a direct dependency of `xarray`. ```console $ johnnydep xarray 2022-01-29 08:28:38 [info ] init johnnydist [johnnydep.lib] dist=xarray parent=None 2022-01-29 08:28:40 [info ] init johnnydist [johnnydep.lib] dist=numpy>=1.18 parent=xarray 2022-01-29 08:28:44 [info ] init johnnydist [johnnydep.lib] dist=pandas>=1.1 parent=xarray 2022-01-29 08:28:47 [info ] init johnnydist [johnnydep.lib] dist=numpy>=1.18.5 parent=pandas>=1.1 2022-01-29 08:28:51 [info ] init johnnydist [johnnydep.lib] dist=python-dateutil>=2.8.1 parent=pandas>=1.1 2022-01-29 08:28:53 [info ] init johnnydist [johnnydep.lib] dist=pytz>=2020.1 parent=pandas>=1.1 2022-01-29 08:28:56 [info ] init johnnydist [johnnydep.lib] dist=six>=1.5 parent=python-dateutil>=2.8.1 name summary ------------------------------ ----------------------------------------------------------------------- xarray N-D labeled arrays and datasets in Python ├── numpy>=1.18 NumPy is the fundamental package for array computing with Python. └── pandas>=1.1 Powerful data structures for data analysis, time series, and statistics ├── numpy>=1.18.5 NumPy is the fundamental package for array computing with Python. ├── python-dateutil>=2.8.1 Extensions to the standard Python datetime module │ └── six>=1.5 Python 2 and 3 compatibility utilities └── pytz>=2020.1 World timezone definitions, modern and historical ``` The problem why your tests didn't catch this is that `packaging` is a dependency of `pytest` itself. ```console $ johnnydep pytest 2022-01-29 08:25:03 [info ] init johnnydist [johnnydep.lib] dist=pytest parent=None 2022-01-29 08:25:07 [info ] init johnnydist [johnnydep.lib] dist=atomicwrites>=1.0 parent=pytest 2022-01-29 08:25:09 [info ] init johnnydist [johnnydep.lib] dist=attrs>=19.2.0 parent=pytest 2022-01-29 08:25:11 [info ] init johnnydist [johnnydep.lib] dist=colorama parent=pytest 2022-01-29 08:25:14 [info ] init johnnydist [johnnydep.lib] dist=iniconfig parent=pytest 2022-01-29 08:25:16 [info ] init johnnydist [johnnydep.lib] dist=packaging parent=pytest 2022-01-29 08:25:18 [info ] init johnnydist [johnnydep.lib] dist=pluggy<2.0,>=0.12 parent=pytest 2022-01-29 08:25:20 [info ] init johnnydist [johnnydep.lib] dist=py>=1.8.2 parent=pytest 2022-01-29 08:25:23 [info ] init johnnydist [johnnydep.lib] dist=toml parent=pytest 2022-01-29 08:25:25 [info ] init johnnydist [johnnydep.lib] dist=pyparsing!=3.0.5,>=2.0.2 parent=packaging name summary -------------------------------- --------------------------------------------------------------------- pytest pytest: simple powerful testing with Python ├── atomicwrites>=1.0 Atomic file writes. ├── attrs>=19.2.0 Classes Without Boilerplate ├── colorama Cross-platform colored terminal text. ├── iniconfig iniconfig: brain-dead simple config-ini parsing ├── packaging Core utilities for Python packages │ └── pyparsing!=3.0.5,>=2.0.2 Python parsing module ├── pluggy<2.0,>=0.12 plugin and hook calling mechanisms for python ├── py>=1.8.2 library with cross-python path, ini-parsing, io, code, log facilities └── toml Python Library for Tom's Obvious, Minimal Language ``` We also only saw our ASV workflow fail since ASV only installs the package and all direct runtime dependencies in the venv it runs the benchmark with. I prepared a [dummy PR](https://github.com/s-weigand/pyglotaran/pull/84) on my fork to demonstrate that this [fixes the issue](https://github.com/s-weigand/pyglotaran/runs/4990111708?check_suite_focus=true). Since the release is only 10h old maybe just do a quick [post-release](https://www.python.org/dev/peps/pep-0440/#post-releases) so most users won't even notice. - [ ] User visible changes (including notable bug fixes) are documented in `whats-new.rst` ",2022-01-29T08:19:09Z,2022-02-01T18:29:04Z,2022-01-31T23:51:59Z,2022-01-31T23:51:59Z,5973ef380d244931f0b5d2d6bbf762ea7b0a0d44,,,0,1c64bd8ef4e62d96ffc96889501d71b36d041fa5,e8d42394b0b4a887ca7246aaae55f9347076f430,CONTRIBUTOR,,13221727,https://github.com/pydata/xarray/pull/6207,