diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index b1c9f731f..d571692b1 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -875,6 +875,14 @@ def test_identical_frames_to_single_frame(duration, tmp_path): assert reread.info["duration"] == 8500 +def test_loop_none(tmp_path): + out = str(tmp_path / "temp.gif") + im = Image.new("L", (100, 100), "#000") + im.save(out, loop=None) + with Image.open(out) as reread: + assert "loop" not in reread.info + + def test_number_of_loops(tmp_path): number_of_loops = 2 diff --git a/docs/handbook/image-file-formats.rst b/docs/handbook/image-file-formats.rst index 0d8d9bc10..2a42bdacb 100644 --- a/docs/handbook/image-file-formats.rst +++ b/docs/handbook/image-file-formats.rst @@ -253,7 +253,7 @@ their :py:attr:`~PIL.Image.Image.info` values. **loop** Integer number of times the GIF should loop. 0 means that it will loop - forever. By default, the image will not loop. + forever. If omitted or ``None``, the image will not loop. **comment** A comment about the image. diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index 943842f77..92074b0d4 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -912,7 +912,7 @@ def _get_global_header(im, info): info and ( "transparency" in info - or "loop" in info + or info.get("loop") is not None or info.get("duration") or info.get("comment") ) @@ -937,7 +937,7 @@ def _get_global_header(im, info): # Global Color Table _get_header_palette(palette_bytes), ] - if "loop" in info: + if info.get("loop") is not None: header.append( b"!" + o8(255) # extension intro