-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Failed: [undefined]OSError: Could not find a backend to open <fsspec.implementations.local.LocalFileOpener object at * > with iomode 'r' since version 2022.8.0 #1057
Comments
I haven't yet found the problem root, but it is certainly on the write call not the read - the BMP extension is not making it to pillow, and so whatever is default is getting written, so then BMP fails to read it. A file does get created, but nothing can read it as a BMP. Yet, you can pass the fsspec file-like to pillow for writing or reading just fine. Perhaps we can ping someone at imagio to ask why the extension information isn't reaching the required place? |
@martindurant: I agree that the problem is in the write and not in the read. I nailed down the problem to #1010. Due to the new method fileno, imageio will directly use the integer file descriptor rather than the file object to write to. This happens in https://github.com/python-pillow/Pillow/blob/main/src/PIL/ImageFile.py:520 try:
fh = fp.fileno()
fp.flush()
_encode_tile(im, fp, tile, bufsize, fh)
except (AttributeError, io.UnsupportedOperation) as exc:
_encode_tile(im, fp, tile, bufsize, None, exc)
if hasattr(fp, "flush"):
fp.flush() Before #1010 (without fileno) the AttributeError was raised and the _encode_tile happened without using fileno. After #1010 the version = "head"
dir = pathlib.Path().resolve()
# just an arbitrary bitmap with constant value 23, to easily analyze the binaries
img = (23 * np.ones((3, 3, 3))).astype("uint8")
# via native python file open, works just fine
filename = f"{dir}/via-native-{version}.bmp"
with open(filename, mode="wb") as file:
iio.imwrite(file, img, extension=pathlib.Path(filename).suffix)
with open(filename, mode="rb") as file:
img_ = iio.imread(file, extension=pathlib.Path(filename).suffix)
np.testing.assert_array_equal(img, img_)
# via fsspec open, writes the bitmap header AFTER the content of the file
# hence throws could not find a backend to open
filename = f"{dir}/via-fsspec-{version}.bmp"
fs = fsspec.filesystem("file", auto_mkdir=True)
with fs.open(filename, mode="wb") as file:
iio.imwrite(file, img, extension=pathlib.Path(filename).suffix)
with open(filename, mode="rb") as file:
img_ = iio.imread(file, extension=pathlib.Path(filename).suffix)
np.testing.assert_array_equal(img, img_) The output of the files in int8 decoding is:
It turns out, that the bmp header is located at the tail (!) instead of the start (starting with 66 77 90 ...) of the file. I conclude, that the LocalFileOpener does not work properly when used with 'integer file descriptors'. If LocalFileOpener is supposed to support fileno (such as suggested in #1010) then this issue should be further investigated. Next, I would drill into the encode_to_file of imageio to fix this issue. Before doing this, I would like to ask fsspec experts to have a look at the |
Found the issue. The I cannot make this more transparent, the actual call chain is hidden in cpython. One explanation would be, that the exception raised by In any case, making the It is probably a good idea to completely remove the |
I see the point of having the |
Solution merged in #1070. |
Description
Starting with version 2022.8.0 the 'file' protocol does not interoperate with imageio.v3. Reading a file from
fs.open(filename,mode='rb')
leads to the exeptionDespite the fact that it occurs in the imageio read call, I guess this is an fsspec issue since the issue does not occur on fsspec==2022.7.1. Also, other fsspec protocols, such as abfs work just fine.
Releated issue may be #579 .
Minimal reproducible sample
The text was updated successfully, but these errors were encountered: