from __future__ import annotations import pytest from PIL import Image from .helper import hopper @pytest.mark.parametrize( "mode, dest_modes", ( ("L", ["I", "F", "LA", "RGB", "RGBA", "RGBX", "CMYK", "YCbCr", "HSV"]), ("I", ["L", "F"]), # Technically I;32 can work for any 4x8bit storage. ("F", ["I", "L", "LA", "RGB", "RGBA", "RGBX", "CMYK", "YCbCr", "HSV"]), ("LA", ["L", "F"]), ("RGB", ["L", "F"]), ("RGBA", ["L", "F"]), ("RGBX", ["L", "F"]), ("CMYK", ["L", "F"]), ("YCbCr", ["L", "F"]), ("HSV", ["L", "F"]), ), ) def test_invalid_array_type(mode: str, dest_modes: list[str]) -> None: img = hopper(mode) for dest_mode in dest_modes: with pytest.raises(ValueError): Image.fromarrow(img, dest_mode, img.size) def test_invalid_array_size() -> None: img = hopper("RGB") assert img.size != (10, 10) with pytest.raises(ValueError): Image.fromarrow(img, "RGB", (10, 10)) def test_release_schema() -> None: # these should not error out, valgrind should be clean img = hopper("L") schema = img.__arrow_c_schema__() del schema def test_release_array() -> None: # these should not error out, valgrind should be clean img = hopper("L") array, schema = img.__arrow_c_array__() del array del schema def test_readonly() -> None: img = hopper("L") reloaded = Image.fromarrow(img, img.mode, img.size) assert reloaded.readonly == 1 reloaded._readonly = 0 assert reloaded.readonly == 1 def test_multiblock_l_image() -> None: block_size = Image.core.get_block_size() # check a 2 block image in single channel mode size = (4096, 2 * block_size // 4096) img = Image.new("L", size, 128) with pytest.raises(ValueError): (schema, arr) = img.__arrow_c_array__() def test_multiblock_rgba_image() -> None: block_size = Image.core.get_block_size() # check a 2 block image in 4 channel mode size = (4096, (block_size // 4096) // 2) img = Image.new("RGBA", size, (128, 127, 126, 125)) with pytest.raises(ValueError): (schema, arr) = img.__arrow_c_array__() def test_multiblock_l_schema() -> None: block_size = Image.core.get_block_size() # check a 2 block image in single channel mode size = (4096, 2 * block_size // 4096) img = Image.new("L", size, 128) with pytest.raises(ValueError): img.__arrow_c_schema__() def test_multiblock_rgba_schema() -> None: block_size = Image.core.get_block_size() # check a 2 block image in 4 channel mode size = (4096, (block_size // 4096) // 2) img = Image.new("RGBA", size, (128, 127, 126, 125)) with pytest.raises(ValueError): img.__arrow_c_schema__() def test_singleblock_l_image() -> None: Image.core.set_use_block_allocator(1) block_size = Image.core.get_block_size() # check a 2 block image in 4 channel mode size = (4096, 2 * (block_size // 4096)) img = Image.new("L", size, 128) assert img.im.isblock() (schema, arr) = img.__arrow_c_array__() assert schema assert arr Image.core.set_use_block_allocator(0) def test_singleblock_rgba_image() -> None: Image.core.set_use_block_allocator(1) block_size = Image.core.get_block_size() # check a 2 block image in 4 channel mode size = (4096, (block_size // 4096) // 2) img = Image.new("RGBA", size, (128, 127, 126, 125)) assert img.im.isblock() (schema, arr) = img.__arrow_c_array__() assert schema assert arr Image.core.set_use_block_allocator(0) def test_singleblock_l_schema() -> None: Image.core.set_use_block_allocator(1) block_size = Image.core.get_block_size() # check a 2 block image in single channel mode size = (4096, 2 * block_size // 4096) img = Image.new("L", size, 128) assert img.im.isblock() schema = img.__arrow_c_schema__() assert schema Image.core.set_use_block_allocator(0) def test_singleblock_rgba_schema() -> None: Image.core.set_use_block_allocator(1) block_size = Image.core.get_block_size() # check a 2 block image in 4 channel mode size = (4096, (block_size // 4096) // 2) img = Image.new("RGBA", size, (128, 127, 126, 125)) assert img.im.isblock() schema = img.__arrow_c_schema__() assert schema Image.core.set_use_block_allocator(0)