Convert from unittest to pytest

This commit is contained in:
Hugo van Kemenade 2020-03-31 22:43:31 +03:00 committed by GitHub
parent 8373c38840
commit 92c9961cea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,269 +1,271 @@
import pytest import pytest
from PIL import Image, ImageSequence, PngImagePlugin from PIL import Image, ImageSequence, PngImagePlugin
from .helper import PillowTestCase
class TestFilePng(PillowTestCase):
# APNG browser support tests and fixtures via: # APNG browser support tests and fixtures via:
# https://philip.html5.org/tests/apng/tests.html # https://philip.html5.org/tests/apng/tests.html
# (referenced from https://wiki.mozilla.org/APNG_Specification) # (referenced from https://wiki.mozilla.org/APNG_Specification)
def test_apng_basic(self): def test_apng_basic():
with Image.open("Tests/images/apng/single_frame.png") as im: with Image.open("Tests/images/apng/single_frame.png") as im:
self.assertFalse(im.is_animated) assert not im.is_animated
self.assertEqual(im.n_frames, 1) assert im.n_frames == 1
self.assertEqual(im.get_format_mimetype(), "image/apng") assert im.get_format_mimetype() == "image/apng"
self.assertIsNone(im.info.get("default_image")) assert im.info.get("default_image") is None
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open("Tests/images/apng/single_frame_default.png") as im: with Image.open("Tests/images/apng/single_frame_default.png") as im:
self.assertTrue(im.is_animated) assert im.is_animated
self.assertEqual(im.n_frames, 2) assert im.n_frames == 2
self.assertEqual(im.get_format_mimetype(), "image/apng") assert im.get_format_mimetype() == "image/apng"
self.assertTrue(im.info.get("default_image")) assert im.info.get("default_image")
self.assertEqual(im.getpixel((0, 0)), (255, 0, 0, 255)) assert im.getpixel((0, 0)) == (255, 0, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (255, 0, 0, 255)) assert im.getpixel((64, 32)) == (255, 0, 0, 255)
im.seek(1) im.seek(1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
# test out of bounds seek # test out of bounds seek
with self.assertRaises(EOFError): with pytest.raises(EOFError):
im.seek(2) im.seek(2)
# test rewind support # test rewind support
im.seek(0) im.seek(0)
self.assertEqual(im.getpixel((0, 0)), (255, 0, 0, 255)) assert im.getpixel((0, 0)) == (255, 0, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (255, 0, 0, 255)) assert im.getpixel((64, 32)) == (255, 0, 0, 255)
im.seek(1) im.seek(1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
def test_apng_fdat(self):
def test_apng_fdat():
with Image.open("Tests/images/apng/split_fdat.png") as im: with Image.open("Tests/images/apng/split_fdat.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open("Tests/images/apng/split_fdat_zero_chunk.png") as im: with Image.open("Tests/images/apng/split_fdat_zero_chunk.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
def test_apng_dispose(self):
def test_apng_dispose():
with Image.open("Tests/images/apng/dispose_op_none.png") as im: with Image.open("Tests/images/apng/dispose_op_none.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open("Tests/images/apng/dispose_op_background.png") as im: with Image.open("Tests/images/apng/dispose_op_background.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0)) assert im.getpixel((0, 0)) == (0, 0, 0, 0)
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) assert im.getpixel((64, 32)) == (0, 0, 0, 0)
with Image.open("Tests/images/apng/dispose_op_background_final.png") as im: with Image.open("Tests/images/apng/dispose_op_background_final.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open("Tests/images/apng/dispose_op_previous.png") as im: with Image.open("Tests/images/apng/dispose_op_previous.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open("Tests/images/apng/dispose_op_previous_final.png") as im: with Image.open("Tests/images/apng/dispose_op_previous_final.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open("Tests/images/apng/dispose_op_previous_first.png") as im: with Image.open("Tests/images/apng/dispose_op_previous_first.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0)) assert im.getpixel((0, 0)) == (0, 0, 0, 0)
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) assert im.getpixel((64, 32)) == (0, 0, 0, 0)
def test_apng_dispose_region(self):
def test_apng_dispose_region():
with Image.open("Tests/images/apng/dispose_op_none_region.png") as im: with Image.open("Tests/images/apng/dispose_op_none_region.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open( with Image.open("Tests/images/apng/dispose_op_background_before_region.png") as im:
"Tests/images/apng/dispose_op_background_before_region.png"
) as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0)) assert im.getpixel((0, 0)) == (0, 0, 0, 0)
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) assert im.getpixel((64, 32)) == (0, 0, 0, 0)
with Image.open("Tests/images/apng/dispose_op_background_region.png") as im: with Image.open("Tests/images/apng/dispose_op_background_region.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 255, 255)) assert im.getpixel((0, 0)) == (0, 0, 255, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) assert im.getpixel((64, 32)) == (0, 0, 0, 0)
with Image.open("Tests/images/apng/dispose_op_previous_region.png") as im: with Image.open("Tests/images/apng/dispose_op_previous_region.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
def test_apng_blend(self):
def test_apng_blend():
with Image.open("Tests/images/apng/blend_op_source_solid.png") as im: with Image.open("Tests/images/apng/blend_op_source_solid.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open("Tests/images/apng/blend_op_source_transparent.png") as im: with Image.open("Tests/images/apng/blend_op_source_transparent.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0)) assert im.getpixel((0, 0)) == (0, 0, 0, 0)
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) assert im.getpixel((64, 32)) == (0, 0, 0, 0)
with Image.open("Tests/images/apng/blend_op_source_near_transparent.png") as im: with Image.open("Tests/images/apng/blend_op_source_near_transparent.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 2)) assert im.getpixel((0, 0)) == (0, 255, 0, 2)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 2)) assert im.getpixel((64, 32)) == (0, 255, 0, 2)
with Image.open("Tests/images/apng/blend_op_over.png") as im: with Image.open("Tests/images/apng/blend_op_over.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open("Tests/images/apng/blend_op_over_near_transparent.png") as im: with Image.open("Tests/images/apng/blend_op_over_near_transparent.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 97)) assert im.getpixel((0, 0)) == (0, 255, 0, 97)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
def test_apng_chunk_order(self):
def test_apng_chunk_order():
with Image.open("Tests/images/apng/fctl_actl.png") as im: with Image.open("Tests/images/apng/fctl_actl.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
def test_apng_delay(self):
def test_apng_delay():
with Image.open("Tests/images/apng/delay.png") as im: with Image.open("Tests/images/apng/delay.png") as im:
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 500.0) assert im.info.get("duration") == 500.0
im.seek(2) im.seek(2)
self.assertEqual(im.info.get("duration"), 1000.0) assert im.info.get("duration") == 1000.0
im.seek(3) im.seek(3)
self.assertEqual(im.info.get("duration"), 500.0) assert im.info.get("duration") == 500.0
im.seek(4) im.seek(4)
self.assertEqual(im.info.get("duration"), 1000.0) assert im.info.get("duration") == 1000.0
with Image.open("Tests/images/apng/delay_round.png") as im: with Image.open("Tests/images/apng/delay_round.png") as im:
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 500.0) assert im.info.get("duration") == 500.0
im.seek(2) im.seek(2)
self.assertEqual(im.info.get("duration"), 1000.0) assert im.info.get("duration") == 1000.0
with Image.open("Tests/images/apng/delay_short_max.png") as im: with Image.open("Tests/images/apng/delay_short_max.png") as im:
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 500.0) assert im.info.get("duration") == 500.0
im.seek(2) im.seek(2)
self.assertEqual(im.info.get("duration"), 1000.0) assert im.info.get("duration") == 1000.0
with Image.open("Tests/images/apng/delay_zero_denom.png") as im: with Image.open("Tests/images/apng/delay_zero_denom.png") as im:
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 500.0) assert im.info.get("duration") == 500.0
im.seek(2) im.seek(2)
self.assertEqual(im.info.get("duration"), 1000.0) assert im.info.get("duration") == 1000.0
with Image.open("Tests/images/apng/delay_zero_numer.png") as im: with Image.open("Tests/images/apng/delay_zero_numer.png") as im:
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 0.0) assert im.info.get("duration") == 0.0
im.seek(2) im.seek(2)
self.assertEqual(im.info.get("duration"), 0.0) assert im.info.get("duration") == 0.0
im.seek(3) im.seek(3)
self.assertEqual(im.info.get("duration"), 500.0) assert im.info.get("duration") == 500.0
im.seek(4) im.seek(4)
self.assertEqual(im.info.get("duration"), 1000.0) assert im.info.get("duration") == 1000.0
def test_apng_num_plays(self):
def test_apng_num_plays():
with Image.open("Tests/images/apng/num_plays.png") as im: with Image.open("Tests/images/apng/num_plays.png") as im:
self.assertEqual(im.info.get("loop"), 0) assert im.info.get("loop") == 0
with Image.open("Tests/images/apng/num_plays_1.png") as im: with Image.open("Tests/images/apng/num_plays_1.png") as im:
self.assertEqual(im.info.get("loop"), 1) assert im.info.get("loop") == 1
def test_apng_mode(self):
def test_apng_mode():
with Image.open("Tests/images/apng/mode_16bit.png") as im: with Image.open("Tests/images/apng/mode_16bit.png") as im:
self.assertEqual(im.mode, "RGBA") assert im.mode == "RGBA"
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 128, 191)) assert im.getpixel((0, 0)) == (0, 0, 128, 191)
self.assertEqual(im.getpixel((64, 32)), (0, 0, 128, 191)) assert im.getpixel((64, 32)) == (0, 0, 128, 191)
with Image.open("Tests/images/apng/mode_greyscale.png") as im: with Image.open("Tests/images/apng/mode_greyscale.png") as im:
self.assertEqual(im.mode, "L") assert im.mode == "L"
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), 128) assert im.getpixel((0, 0)) == 128
self.assertEqual(im.getpixel((64, 32)), 255) assert im.getpixel((64, 32)) == 255
with Image.open("Tests/images/apng/mode_greyscale_alpha.png") as im: with Image.open("Tests/images/apng/mode_greyscale_alpha.png") as im:
self.assertEqual(im.mode, "LA") assert im.mode == "LA"
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (128, 191)) assert im.getpixel((0, 0)) == (128, 191)
self.assertEqual(im.getpixel((64, 32)), (128, 191)) assert im.getpixel((64, 32)) == (128, 191)
with Image.open("Tests/images/apng/mode_palette.png") as im: with Image.open("Tests/images/apng/mode_palette.png") as im:
self.assertEqual(im.mode, "P") assert im.mode == "P"
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im = im.convert("RGB") im = im.convert("RGB")
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0)) assert im.getpixel((0, 0)) == (0, 255, 0)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0)) assert im.getpixel((64, 32)) == (0, 255, 0)
with Image.open("Tests/images/apng/mode_palette_alpha.png") as im: with Image.open("Tests/images/apng/mode_palette_alpha.png") as im:
self.assertEqual(im.mode, "P") assert im.mode == "P"
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im = im.convert("RGBA") im = im.convert("RGBA")
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open("Tests/images/apng/mode_palette_1bit_alpha.png") as im: with Image.open("Tests/images/apng/mode_palette_1bit_alpha.png") as im:
self.assertEqual(im.mode, "P") assert im.mode == "P"
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im = im.convert("RGBA") im = im.convert("RGBA")
self.assertEqual(im.getpixel((0, 0)), (0, 0, 255, 128)) assert im.getpixel((0, 0)) == (0, 0, 255, 128)
self.assertEqual(im.getpixel((64, 32)), (0, 0, 255, 128)) assert im.getpixel((64, 32)) == (0, 0, 255, 128)
def test_apng_chunk_errors(self):
def test_apng_chunk_errors():
with Image.open("Tests/images/apng/chunk_no_actl.png") as im: with Image.open("Tests/images/apng/chunk_no_actl.png") as im:
self.assertFalse(im.is_animated) assert not im.is_animated
def open(): def open():
with Image.open("Tests/images/apng/chunk_multi_actl.png") as im: with Image.open("Tests/images/apng/chunk_multi_actl.png") as im:
im.load() im.load()
self.assertFalse(im.is_animated) assert not im.is_animated
pytest.warns(UserWarning, open) pytest.warns(UserWarning, open)
with Image.open("Tests/images/apng/chunk_actl_after_idat.png") as im: with Image.open("Tests/images/apng/chunk_actl_after_idat.png") as im:
self.assertFalse(im.is_animated) assert not im.is_animated
with Image.open("Tests/images/apng/chunk_no_fctl.png") as im: with Image.open("Tests/images/apng/chunk_no_fctl.png") as im:
with self.assertRaises(SyntaxError): with pytest.raises(SyntaxError):
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
with Image.open("Tests/images/apng/chunk_repeat_fctl.png") as im: with Image.open("Tests/images/apng/chunk_repeat_fctl.png") as im:
with self.assertRaises(SyntaxError): with pytest.raises(SyntaxError):
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
with Image.open("Tests/images/apng/chunk_no_fdat.png") as im: with Image.open("Tests/images/apng/chunk_no_fdat.png") as im:
with self.assertRaises(SyntaxError): with pytest.raises(SyntaxError):
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
def test_apng_syntax_errors(self):
def test_apng_syntax_errors():
def open_frames_zero(): def open_frames_zero():
with Image.open("Tests/images/apng/syntax_num_frames_zero.png") as im: with Image.open("Tests/images/apng/syntax_num_frames_zero.png") as im:
self.assertFalse(im.is_animated) assert not im.is_animated
with self.assertRaises(OSError): with pytest.raises(OSError):
im.load() im.load()
pytest.warns(UserWarning, open_frames_zero) pytest.warns(UserWarning, open_frames_zero)
def open_frames_zero_default(): def open_frames_zero_default():
with Image.open( with Image.open("Tests/images/apng/syntax_num_frames_zero_default.png") as im:
"Tests/images/apng/syntax_num_frames_zero_default.png" assert not im.is_animated
) as im:
self.assertFalse(im.is_animated)
im.load() im.load()
pytest.warns(UserWarning, open_frames_zero_default) pytest.warns(UserWarning, open_frames_zero_default)
@ -275,21 +277,22 @@ class TestFilePng(PillowTestCase):
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
except Exception as e: except Exception as e:
exception = e exception = e
self.assertIsNone(exception) assert exception is None
with self.assertRaises(SyntaxError): with pytest.raises(SyntaxError):
with Image.open("Tests/images/apng/syntax_num_frames_high.png") as im: with Image.open("Tests/images/apng/syntax_num_frames_high.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im.load() im.load()
def open(): def open():
with Image.open("Tests/images/apng/syntax_num_frames_invalid.png") as im: with Image.open("Tests/images/apng/syntax_num_frames_invalid.png") as im:
self.assertFalse(im.is_animated) assert not im.is_animated
im.load() im.load()
pytest.warns(UserWarning, open) pytest.warns(UserWarning, open)
def test_apng_sequence_errors(self):
def test_apng_sequence_errors():
test_files = [ test_files = [
"sequence_start.png", "sequence_start.png",
"sequence_gap.png", "sequence_gap.png",
@ -300,24 +303,25 @@ class TestFilePng(PillowTestCase):
"sequence_fdat_fctl.png", "sequence_fdat_fctl.png",
] ]
for f in test_files: for f in test_files:
with self.assertRaises(SyntaxError): with pytest.raises(SyntaxError):
with Image.open("Tests/images/apng/{0}".format(f)) as im: with Image.open("Tests/images/apng/{0}".format(f)) as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im.load() im.load()
def test_apng_save(self):
def test_apng_save(tmp_path):
with Image.open("Tests/images/apng/single_frame.png") as im: with Image.open("Tests/images/apng/single_frame.png") as im:
test_file = self.tempfile("temp.png") test_file = str(tmp_path / "temp.png")
im.save(test_file, save_all=True) im.save(test_file, save_all=True)
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.load() im.load()
self.assertFalse(im.is_animated) assert not im.is_animated
self.assertEqual(im.n_frames, 1) assert im.n_frames == 1
self.assertEqual(im.get_format_mimetype(), "image/apng") assert im.get_format_mimetype() == "image/apng"
self.assertIsNone(im.info.get("default_image")) assert im.info.get("default_image") is None
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
with Image.open("Tests/images/apng/single_frame_default.png") as im: with Image.open("Tests/images/apng/single_frame_default.png") as im:
frames = [] frames = []
@ -329,20 +333,21 @@ class TestFilePng(PillowTestCase):
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.load() im.load()
self.assertTrue(im.is_animated) assert im.is_animated
self.assertEqual(im.n_frames, 2) assert im.n_frames == 2
self.assertEqual(im.get_format_mimetype(), "image/apng") assert im.get_format_mimetype() == "image/apng"
self.assertTrue(im.info.get("default_image")) assert im.info.get("default_image")
im.seek(1) im.seek(1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
def test_apng_save_split_fdat(self):
def test_apng_save_split_fdat(tmp_path):
# test to make sure we do not generate sequence errors when writing # test to make sure we do not generate sequence errors when writing
# frames with image data spanning multiple fdAT chunks (in this case # frames with image data spanning multiple fdAT chunks (in this case
# both the default image and first animation frame will span multiple # both the default image and first animation frame will span multiple
# data chunks) # data chunks)
test_file = self.tempfile("temp.png") test_file = str(tmp_path / "temp.png")
with Image.open("Tests/images/old-style-jpeg-compression.png") as im: with Image.open("Tests/images/old-style-jpeg-compression.png") as im:
frames = [im.copy(), Image.new("RGBA", im.size, (255, 0, 0, 255))] frames = [im.copy(), Image.new("RGBA", im.size, (255, 0, 0, 255))]
im.save( im.save(
@ -355,10 +360,11 @@ class TestFilePng(PillowTestCase):
im.load() im.load()
except Exception as e: except Exception as e:
exception = e exception = e
self.assertIsNone(exception) assert exception is None
def test_apng_save_duration_loop(self):
test_file = self.tempfile("temp.png") def test_apng_save_duration_loop(tmp_path):
test_file = str(tmp_path / "temp.png")
with Image.open("Tests/images/apng/delay.png") as im: with Image.open("Tests/images/apng/delay.png") as im:
frames = [] frames = []
durations = [] durations = []
@ -379,26 +385,27 @@ class TestFilePng(PillowTestCase):
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.load() im.load()
self.assertEqual(im.info.get("loop"), loop) assert im.info.get("loop") == loop
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 500.0) assert im.info.get("duration") == 500.0
im.seek(2) im.seek(2)
self.assertEqual(im.info.get("duration"), 1000.0) assert im.info.get("duration") == 1000.0
im.seek(3) im.seek(3)
self.assertEqual(im.info.get("duration"), 500.0) assert im.info.get("duration") == 500.0
im.seek(4) im.seek(4)
self.assertEqual(im.info.get("duration"), 1000.0) assert im.info.get("duration") == 1000.0
# test removal of duplicated frames # test removal of duplicated frames
frame = Image.new("RGBA", (128, 64), (255, 0, 0, 255)) frame = Image.new("RGBA", (128, 64), (255, 0, 0, 255))
frame.save(test_file, save_all=True, append_images=[frame], duration=[500, 250]) frame.save(test_file, save_all=True, append_images=[frame], duration=[500, 250])
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.load() im.load()
self.assertEqual(im.n_frames, 1) assert im.n_frames == 1
self.assertEqual(im.info.get("duration"), 750) assert im.info.get("duration") == 750
def test_apng_save_disposal(self):
test_file = self.tempfile("temp.png") def test_apng_save_disposal(tmp_path):
test_file = str(tmp_path / "temp.png")
size = (128, 64) size = (128, 64)
red = Image.new("RGBA", size, (255, 0, 0, 255)) red = Image.new("RGBA", size, (255, 0, 0, 255))
green = Image.new("RGBA", size, (0, 255, 0, 255)) green = Image.new("RGBA", size, (0, 255, 0, 255))
@ -414,8 +421,8 @@ class TestFilePng(PillowTestCase):
) )
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.seek(2) im.seek(2)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
# test APNG_DISPOSE_OP_BACKGROUND # test APNG_DISPOSE_OP_BACKGROUND
disposal = [ disposal = [
@ -432,8 +439,8 @@ class TestFilePng(PillowTestCase):
) )
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.seek(2) im.seek(2)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0)) assert im.getpixel((0, 0)) == (0, 0, 0, 0)
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) assert im.getpixel((64, 32)) == (0, 0, 0, 0)
disposal = [ disposal = [
PngImagePlugin.APNG_DISPOSE_OP_NONE, PngImagePlugin.APNG_DISPOSE_OP_NONE,
@ -448,8 +455,8 @@ class TestFilePng(PillowTestCase):
) )
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.seek(1) im.seek(1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
# test APNG_DISPOSE_OP_PREVIOUS # test APNG_DISPOSE_OP_PREVIOUS
disposal = [ disposal = [
@ -467,8 +474,8 @@ class TestFilePng(PillowTestCase):
) )
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.seek(3) im.seek(3)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
disposal = [ disposal = [
PngImagePlugin.APNG_DISPOSE_OP_NONE, PngImagePlugin.APNG_DISPOSE_OP_NONE,
@ -483,11 +490,12 @@ class TestFilePng(PillowTestCase):
) )
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.seek(1) im.seek(1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
def test_apng_save_blend(self):
test_file = self.tempfile("temp.png") def test_apng_save_blend(tmp_path):
test_file = str(tmp_path / "temp.png")
size = (128, 64) size = (128, 64)
red = Image.new("RGBA", size, (255, 0, 0, 255)) red = Image.new("RGBA", size, (255, 0, 0, 255))
green = Image.new("RGBA", size, (0, 255, 0, 255)) green = Image.new("RGBA", size, (0, 255, 0, 255))
@ -508,8 +516,8 @@ class TestFilePng(PillowTestCase):
) )
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.seek(2) im.seek(2)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
# test APNG_BLEND_OP_SOURCE on transparent color # test APNG_BLEND_OP_SOURCE on transparent color
blend = [ blend = [
@ -526,8 +534,8 @@ class TestFilePng(PillowTestCase):
) )
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.seek(2) im.seek(2)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0)) assert im.getpixel((0, 0)) == (0, 0, 0, 0)
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) assert im.getpixel((64, 32)) == (0, 0, 0, 0)
# test APNG_BLEND_OP_OVER # test APNG_BLEND_OP_OVER
red.save( red.save(
@ -540,8 +548,8 @@ class TestFilePng(PillowTestCase):
) )
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.seek(1) im.seek(1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
im.seek(2) im.seek(2)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) assert im.getpixel((0, 0)) == (0, 255, 0, 255)
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) assert im.getpixel((64, 32)) == (0, 255, 0, 255)