Skip to content

Commit ea9b3a5

Browse files
authored
Reset file pointer to 0 when reading file stream (#7304)
* Reset file pointer to 0 when reading file stream Instead of raising a ValueError about the file pointer not being at the start of the file, reset the file pointer automatically to zero, and warn that the pointer has been reset. * Expect warning rather than ValueError for test_open_twice Fixes the `Failed: DID NOT RAISE <class 'ValueError'>` * Remove checks for errors raised in test_open_fileobj The ValueError and RuntimeWarning isn't raised anymore. * Fix typo form -> from * Add changelog entry for bugfix * Remove warning about resetting file pointer to zero File pointer is reset to zero after reading the magic byte number anyway, so should be ok not to warn about this.
1 parent 0e5e3fe commit ea9b3a5

File tree

3 files changed

+10
-21
lines changed

3 files changed

+10
-21
lines changed

doc/whats-new.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ Bug fixes
6363
By `Michael Niklas <https://github.com/headtr1ck>`_.
6464
- Fix static typing of :py:meth:`xr.polyval` (:issue:`7312`, :pull:`7315`).
6565
By `Michael Niklas <https://github.com/headtr1ck>`_.
66+
- Fix multiple reads on fsspec S3 files by resetting file pointer to 0 when reading file streams (:issue:`6813`, :pull:`7304`).
67+
By `David Hoese <https://github.com/djhoese>`_ and `Wei Ji Leong <https://github.com/weiji14>`_.
6668

6769
Documentation
6870
~~~~~~~~~~~~~

xarray/core/utils.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -656,15 +656,11 @@ def read_magic_number_from_file(filename_or_obj, count=8) -> bytes:
656656
magic_number = filename_or_obj[:count]
657657
elif isinstance(filename_or_obj, io.IOBase):
658658
if filename_or_obj.tell() != 0:
659-
raise ValueError(
660-
"cannot guess the engine, "
661-
"file-like object read/write pointer not at the start of the file, "
662-
"please close and reopen, or use a context manager"
663-
)
659+
filename_or_obj.seek(0)
664660
magic_number = filename_or_obj.read(count)
665661
filename_or_obj.seek(0)
666662
else:
667-
raise TypeError(f"cannot read the magic number form {type(filename_or_obj)}")
663+
raise TypeError(f"cannot read the magic number from {type(filename_or_obj)}")
668664
return magic_number
669665

670666

xarray/tests/test_backends.py

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3159,13 +3159,12 @@ def test_open_badbytes(self) -> None:
31593159
def test_open_twice(self) -> None:
31603160
expected = create_test_data()
31613161
expected.attrs["foo"] = "bar"
3162-
with pytest.raises(ValueError, match=r"read/write pointer not at the start"):
3163-
with create_tmp_file() as tmp_file:
3164-
expected.to_netcdf(tmp_file, engine="h5netcdf")
3165-
with open(tmp_file, "rb") as f:
3162+
with create_tmp_file() as tmp_file:
3163+
expected.to_netcdf(tmp_file, engine="h5netcdf")
3164+
with open(tmp_file, "rb") as f:
3165+
with open_dataset(f, engine="h5netcdf"):
31663166
with open_dataset(f, engine="h5netcdf"):
3167-
with open_dataset(f, engine="h5netcdf"):
3168-
pass
3167+
pass
31693168

31703169
@requires_scipy
31713170
def test_open_fileobj(self) -> None:
@@ -3197,15 +3196,7 @@ def test_open_fileobj(self) -> None:
31973196
# `raises_regex`?). Ref https://github.com/pydata/xarray/pull/5191
31983197
with open(tmp_file, "rb") as f:
31993198
f.seek(8)
3200-
with pytest.raises(
3201-
ValueError,
3202-
match="match in any of xarray's currently installed IO",
3203-
):
3204-
with pytest.warns(
3205-
RuntimeWarning,
3206-
match=re.escape("'h5netcdf' fails while guessing"),
3207-
):
3208-
open_dataset(f)
3199+
open_dataset(f)
32093200

32103201

32113202
@requires_h5netcdf

0 commit comments

Comments
 (0)