from __future__ import annotations import math from fractions import Fraction from pathlib import Path import pytest from PIL import Image, TiffImagePlugin from PIL.TiffImagePlugin import IFDRational from .helper import hopper, skip_unless_feature def _test_equal( num: float | Fraction | IFDRational, denom: int, target: float | Fraction | IFDRational, ) -> None: t = IFDRational(num, denom) assert target == t assert t == target def test_sanity() -> None: _test_equal(1, 1, 1) _test_equal(1, 1, Fraction(1, 1)) _test_equal(2, 2, 1) _test_equal(1.0, 1, Fraction(1, 1)) _test_equal(Fraction(1, 1), 1, Fraction(1, 1)) _test_equal(IFDRational(1, 1), 1, 1) _test_equal(1, 2, Fraction(1, 2)) _test_equal(1, 2, IFDRational(1, 2)) _test_equal(7, 5, 1.4) def test_ranges() -> None: for num in range(1, 10): for denom in range(1, 10): assert IFDRational(num, denom) == IFDRational(num, denom) def test_nonetype() -> None: # Fails if the _delegate function doesn't return a valid function xres = IFDRational(72) yres = IFDRational(72) assert xres._val is not None assert xres.numerator is not None assert xres.denominator is not None assert yres._val is not None assert xres assert yres @pytest.mark.parametrize( "libtiff", (pytest.param(True, marks=skip_unless_feature("libtiff")), False) ) def test_ifd_rational_save( monkeypatch: pytest.MonkeyPatch, tmp_path: Path, libtiff: bool ) -> None: im = hopper() out = tmp_path / "temp.tiff" res = IFDRational(301, 1) monkeypatch.setattr(TiffImagePlugin, "WRITE_LIBTIFF", libtiff) im.save(out, dpi=(res, res), compression="raw") with Image.open(out) as reloaded: assert isinstance(reloaded, TiffImagePlugin.TiffImageFile) assert float(IFDRational(301, 1)) == float(reloaded.tag_v2[282]) @pytest.mark.parametrize( "numerator, denominator, expected_result", [ (1, 1, 1.0), (1, 0, float("nan")), ], ) def test_float_cast(numerator: int, denominator: int, expected_result: float) -> None: value = float(IFDRational(numerator, denominator)) if math.isnan(expected_result): assert value else: assert value == expected_result