diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 0c9ff5bd1f8..b6ed2fddde0 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -62,6 +62,8 @@ Bug fixes By `Michael Niklas `_. - Fix static typing of :py:meth:`xr.polyval` (:issue:`7312`, :pull:`7315`). By `Michael Niklas `_. +- Fix multiple reads on fsspec S3 files by resetting file pointer to 0 when reading file streams (:issue:`6813`, :pull:`7304`). + By `David Hoese `_ and `Wei Ji Leong `_. Documentation ~~~~~~~~~~~~~ diff --git a/xarray/core/utils.py b/xarray/core/utils.py index 979075efe5e..caa4be08290 100644 --- a/xarray/core/utils.py +++ b/xarray/core/utils.py @@ -654,15 +654,11 @@ def read_magic_number_from_file(filename_or_obj, count=8) -> bytes: magic_number = filename_or_obj[:count] elif isinstance(filename_or_obj, io.IOBase): if filename_or_obj.tell() != 0: - raise ValueError( - "cannot guess the engine, " - "file-like object read/write pointer not at the start of the file, " - "please close and reopen, or use a context manager" - ) + filename_or_obj.seek(0) magic_number = filename_or_obj.read(count) filename_or_obj.seek(0) else: - raise TypeError(f"cannot read the magic number form {type(filename_or_obj)}") + raise TypeError(f"cannot read the magic number from {type(filename_or_obj)}") return magic_number diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index 70987a3dd38..e3faeedbd13 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -3159,13 +3159,12 @@ def test_open_badbytes(self) -> None: def test_open_twice(self) -> None: expected = create_test_data() expected.attrs["foo"] = "bar" - with pytest.raises(ValueError, match=r"read/write pointer not at the start"): - with create_tmp_file() as tmp_file: - expected.to_netcdf(tmp_file, engine="h5netcdf") - with open(tmp_file, "rb") as f: + with create_tmp_file() as tmp_file: + expected.to_netcdf(tmp_file, engine="h5netcdf") + with open(tmp_file, "rb") as f: + with open_dataset(f, engine="h5netcdf"): with open_dataset(f, engine="h5netcdf"): - with open_dataset(f, engine="h5netcdf"): - pass + pass @requires_scipy def test_open_fileobj(self) -> None: @@ -3197,15 +3196,7 @@ def test_open_fileobj(self) -> None: # `raises_regex`?). Ref https://github.com/pydata/xarray/pull/5191 with open(tmp_file, "rb") as f: f.seek(8) - with pytest.raises( - ValueError, - match="match in any of xarray's currently installed IO", - ): - with pytest.warns( - RuntimeWarning, - match=re.escape("'h5netcdf' fails while guessing"), - ): - open_dataset(f) + open_dataset(f) @requires_h5netcdf