1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
# -*- coding: utf-8 -*-
from pathlib import Path
from sys import version_info
from warnings import filterwarnings
import pytest
from puremagic.main import what
filterwarnings("ignore", message="'imghdr' is deprecated")
try: # imghdr was removed from the standard library in Python 3.13
from imghdr import what as imghdr_what
except ModuleNotFoundError:
imghdr_what = None # type: ignore[assignment]
file_tests = ["bmp", "gif", "jpg", "png", "tif", "webp"]
here = Path(__file__).resolve().parent
@pytest.mark.skipif(imghdr_what is None, reason="imghdr was removed from the standard library in Python 3.13")
@pytest.mark.parametrize("file", file_tests)
def test_what_from_file(file, h=None):
"""Run each test with a path string and a pathlib.Path."""
file = str(here / f"resources/images/test.{file}")
assert what(file, h) == imghdr_what(file, h)
file = Path(file).resolve()
assert what(file, h) == imghdr_what(file, h)
@pytest.mark.skipif(imghdr_what is None, reason="imghdr was removed from the standard library in Python 3.13")
def test_what_from_file_none():
file = str(here / "resources/fake_file")
assert what(file) == imghdr_what(file) is None
file = Path(file).resolve()
assert what(file, None) == imghdr_what(file, None) is None
@pytest.mark.skipif(imghdr_what is None, reason="imghdr was removed from the standard library in Python 3.13")
def test_what_from_string_no_str(h="string"):
"""what() should raise a TypeError if h is a string."""
with pytest.raises(TypeError):
imghdr_what(None, h)
with pytest.raises(TypeError) as excinfo:
what(None, h)
assert str(excinfo.value) == "h must be bytes, not str. Consider using bytes.fromhex(h)"
string_tests = [
("bmp", "424d"),
("bmp", "424d787878785c3030305c303030"),
("bmp", b"BM"),
("exr", "762f3101"),
("exr", b"\x76\x2f\x31\x01"),
("exr", b"v/1\x01"),
("gif", "474946383761"),
("gif", "474946383961"),
("gif", b"GIF87a"),
("gif", b"GIF89a"),
("pbm", b"P1 "),
("pbm", b"P1\n"),
("pbm", b"P1\r"),
("pbm", b"P1\t"),
("pbm", b"P4 "),
("pbm", b"P4\n"),
("pbm", b"P4\r"),
("pbm", b"P4\t"),
("pgm", b"P2 "),
("pgm", b"P2\n"),
("pgm", b"P2\r"),
("pgm", b"P2\t"),
("pgm", b"P5 "),
("pgm", b"P5\n"),
("pgm", b"P5\r"),
("pgm", b"P5\t"),
("png", "89504e470d0a1a0a"),
("png", b"\211PNG\r\n\032\n"),
("png", b"\x89PNG\r\n\x1a\n"),
("ppm", b"P3 "),
("ppm", b"P3\n"),
("ppm", b"P3\r"),
("ppm", b"P3\t"),
("ppm", b"P6 "),
("ppm", b"P6\n"),
("ppm", b"P6\r"),
("ppm", b"P6\t"),
("rast", "59A66A95"),
("rast", b"\x59\xa6\x6a\x95"),
("rgb", "01da"),
("rgb", b"\x01\xda"),
("tiff", "49492a00"),
("tiff", "4d4d002a"),
("tiff", "4d4d002b"),
("tiff", b"II*\x00"), # bytes.fromhex('49492a00')
("tiff", b"MM\x00*"), # bytes.fromhex('4d4d002a')
("tiff", b"MM\x00+"), # bytes.fromhex('4d4d002b')
("webp", b"RIFF____WEBP"),
("xbm", b"#define "),
(None, "decafbad"),
(None, b"decafbad"),
]
@pytest.mark.skipif(imghdr_what is None, reason="imghdr was removed from the standard library in Python 3.13")
@pytest.mark.parametrize("expected, h", string_tests)
def test_what_from_string(expected, h):
if isinstance(h, str): # In imgdir.what() h must be bytes, not str.
h = bytes.fromhex(h) # ex. "474946383761" --> b"GIF87a"
assert imghdr_what(None, h) == what(None, h) == expected
@pytest.mark.skipif(imghdr_what is None, reason="imghdr was removed from the standard library in Python 3.13")
@pytest.mark.parametrize(
"expected, h",
[
("jpeg", "ffd8ffdb"),
("jpeg", b"\xff\xd8\xff\xdb"),
],
)
def test_what_from_string_py311(expected, h):
"""
These tests fail with imghdr on Python < 3.11.
"""
if isinstance(h, str): # In imgdir.what() h must be bytes, not str.
h = bytes.fromhex(h)
assert what(None, h) == expected
if version_info < (3, 11): # TODO: Document these imghdr fails
expected = None
assert imghdr_what(None, h) == expected
@pytest.mark.skipif(imghdr_what is None, reason="imghdr was removed from the standard library in Python 3.13")
@pytest.mark.parametrize(
"expected, h",
[
("jpeg", b"______Exif"),
("jpeg", b"______Exif"),
("jpeg", b"______JFIF"),
("jpeg", b"______JFIF"),
("tiff", "4949"),
("tiff", "49495c7832615c783030"),
("tiff", "4d4d"),
("tiff", "4d4d5c7830305c783261"),
("tiff", b"II"), # bytes.fromhex('4949')
("tiff", b"II\\x2a\\x00"), # bytes.fromhex('49495c7832615c783030')
("tiff", b"MM"), # bytes.fromhex('4d4d')
("tiff", b"MM\\x00\\x2a"), # bytes.fromhex('4d4d5c7830305c783261')
],
)
@pytest.mark.parametrize("imghdr_strict", [True, False])
def test_what_from_string_imghdr_strict(expected, h, imghdr_strict):
"""
These tests pass with imghdr but fail with puremagic.
"""
if isinstance(h, str): # In imgdir.what() h must be bytes, not str.
h = bytes.fromhex(h)
assert imghdr_what(None, h) == expected
assert what(None, h, imghdr_strict) == (expected if imghdr_strict else None)
|