mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 01:16:16 +03:00
Merge remote-tracking branch 'upstream/master' into pytest.importorskip
This commit is contained in:
commit
2d5e479bcc
|
@ -3,22 +3,18 @@ from io import BytesIO
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from .helper import PillowTestCase, is_win32
|
from .helper import PillowTestCase, is_win32, skip_unless_feature
|
||||||
|
|
||||||
# Limits for testing the leak
|
# Limits for testing the leak
|
||||||
mem_limit = 1024 * 1048576
|
mem_limit = 1024 * 1048576
|
||||||
stack_size = 8 * 1048576
|
stack_size = 8 * 1048576
|
||||||
iterations = int((mem_limit / stack_size) * 2)
|
iterations = int((mem_limit / stack_size) * 2)
|
||||||
codecs = dir(Image.core)
|
|
||||||
test_file = "Tests/images/rgb_trns_ycbc.jp2"
|
test_file = "Tests/images/rgb_trns_ycbc.jp2"
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(is_win32(), "requires Unix or macOS")
|
@unittest.skipIf(is_win32(), "requires Unix or macOS")
|
||||||
|
@skip_unless_feature("jpg_2000")
|
||||||
class TestJpegLeaks(PillowTestCase):
|
class TestJpegLeaks(PillowTestCase):
|
||||||
def setUp(self):
|
|
||||||
if "jpeg2k_encoder" not in codecs or "jpeg2k_decoder" not in codecs:
|
|
||||||
self.skipTest("JPEG 2000 support not available")
|
|
||||||
|
|
||||||
def test_leak_load(self):
|
def test_leak_load(self):
|
||||||
from resource import setrlimit, RLIMIT_AS, RLIMIT_STACK
|
from resource import setrlimit, RLIMIT_AS, RLIMIT_STACK
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import unittest
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import Image, ImageMath
|
from PIL import Image, ImageMath, features
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -172,6 +172,11 @@ def skip_known_bad_test(msg=None):
|
||||||
pytest.skip(msg or "Known bad test")
|
pytest.skip(msg or "Known bad test")
|
||||||
|
|
||||||
|
|
||||||
|
def skip_unless_feature(feature):
|
||||||
|
reason = "%s not available" % feature
|
||||||
|
return pytest.mark.skipif(not features.check(feature), reason=reason)
|
||||||
|
|
||||||
|
|
||||||
class PillowTestCase(unittest.TestCase):
|
class PillowTestCase(unittest.TestCase):
|
||||||
def delete_tempfile(self, path):
|
def delete_tempfile(self, path):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -3,12 +3,12 @@ import io
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import features
|
from PIL import features
|
||||||
|
|
||||||
|
from .helper import skip_unless_feature
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from PIL import _webp
|
from PIL import _webp
|
||||||
|
|
||||||
HAVE_WEBP = True
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAVE_WEBP = False
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_check():
|
def test_check():
|
||||||
|
@ -21,18 +21,18 @@ def test_check():
|
||||||
assert features.check_feature(feature) == features.check(feature)
|
assert features.check_feature(feature) == features.check(feature)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAVE_WEBP, reason="WebP not available")
|
@skip_unless_feature("webp")
|
||||||
def test_webp_transparency():
|
def test_webp_transparency():
|
||||||
assert features.check("transp_webp") != _webp.WebPDecoderBuggyAlpha()
|
assert features.check("transp_webp") != _webp.WebPDecoderBuggyAlpha()
|
||||||
assert features.check("transp_webp") == _webp.HAVE_TRANSPARENCY
|
assert features.check("transp_webp") == _webp.HAVE_TRANSPARENCY
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAVE_WEBP, reason="WebP not available")
|
@skip_unless_feature("webp")
|
||||||
def test_webp_mux():
|
def test_webp_mux():
|
||||||
assert features.check("webp_mux") == _webp.HAVE_WEBPMUX
|
assert features.check("webp_mux") == _webp.HAVE_WEBPMUX
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAVE_WEBP, reason="WebP not available")
|
@skip_unless_feature("webp")
|
||||||
def test_webp_anim():
|
def test_webp_anim():
|
||||||
assert features.check("webp_anim") == _webp.HAVE_WEBPANIM
|
assert features.check("webp_anim") == _webp.HAVE_WEBPANIM
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import io
|
import io
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from PIL import EpsImagePlugin, Image
|
from PIL import EpsImagePlugin, Image, features
|
||||||
|
|
||||||
from .helper import PillowTestCase, assert_image_similar, hopper
|
from .helper import PillowTestCase, assert_image_similar, hopper, skip_unless_feature
|
||||||
|
|
||||||
HAS_GHOSTSCRIPT = EpsImagePlugin.has_ghostscript()
|
HAS_GHOSTSCRIPT = EpsImagePlugin.has_ghostscript()
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class TestFileEps(PillowTestCase):
|
||||||
cmyk_image.load()
|
cmyk_image.load()
|
||||||
self.assertEqual(cmyk_image.mode, "RGB")
|
self.assertEqual(cmyk_image.mode, "RGB")
|
||||||
|
|
||||||
if "jpeg_decoder" in dir(Image.core):
|
if features.check("jpg"):
|
||||||
with Image.open("Tests/images/pil_sample_rgb.jpg") as target:
|
with Image.open("Tests/images/pil_sample_rgb.jpg") as target:
|
||||||
assert_image_similar(cmyk_image, target, 10)
|
assert_image_similar(cmyk_image, target, 10)
|
||||||
|
|
||||||
|
@ -114,11 +114,9 @@ class TestFileEps(PillowTestCase):
|
||||||
self.assertRaises(ValueError, im.save, tmpfile)
|
self.assertRaises(ValueError, im.save, tmpfile)
|
||||||
|
|
||||||
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
|
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
|
||||||
|
@skip_unless_feature("zlib")
|
||||||
def test_render_scale1(self):
|
def test_render_scale1(self):
|
||||||
# We need png support for these render test
|
# We need png support for these render test
|
||||||
codecs = dir(Image.core)
|
|
||||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
|
||||||
self.skipTest("zip/deflate support not available")
|
|
||||||
|
|
||||||
# Zero bounding box
|
# Zero bounding box
|
||||||
with Image.open(file1) as image1_scale1:
|
with Image.open(file1) as image1_scale1:
|
||||||
|
@ -137,11 +135,9 @@ class TestFileEps(PillowTestCase):
|
||||||
assert_image_similar(image2_scale1, image2_scale1_compare, 10)
|
assert_image_similar(image2_scale1, image2_scale1_compare, 10)
|
||||||
|
|
||||||
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
|
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
|
||||||
|
@skip_unless_feature("zlib")
|
||||||
def test_render_scale2(self):
|
def test_render_scale2(self):
|
||||||
# We need png support for these render test
|
# We need png support for these render test
|
||||||
codecs = dir(Image.core)
|
|
||||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
|
||||||
self.skipTest("zip/deflate support not available")
|
|
||||||
|
|
||||||
# Zero bounding box
|
# Zero bounding box
|
||||||
with Image.open(file1) as image1_scale2:
|
with Image.open(file1) as image1_scale2:
|
||||||
|
|
|
@ -2,7 +2,7 @@ import unittest
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import GifImagePlugin, Image, ImageDraw, ImagePalette
|
from PIL import GifImagePlugin, Image, ImageDraw, ImagePalette, features
|
||||||
|
|
||||||
from .helper import (
|
from .helper import (
|
||||||
PillowTestCase,
|
PillowTestCase,
|
||||||
|
@ -13,15 +13,6 @@ from .helper import (
|
||||||
netpbm_available,
|
netpbm_available,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
|
||||||
from PIL import _webp
|
|
||||||
|
|
||||||
HAVE_WEBP = True
|
|
||||||
except ImportError:
|
|
||||||
HAVE_WEBP = False
|
|
||||||
|
|
||||||
codecs = dir(Image.core)
|
|
||||||
|
|
||||||
# sample gif stream
|
# sample gif stream
|
||||||
TEST_GIF = "Tests/images/hopper.gif"
|
TEST_GIF = "Tests/images/hopper.gif"
|
||||||
|
|
||||||
|
@ -30,10 +21,6 @@ with open(TEST_GIF, "rb") as f:
|
||||||
|
|
||||||
|
|
||||||
class TestFileGif(PillowTestCase):
|
class TestFileGif(PillowTestCase):
|
||||||
def setUp(self):
|
|
||||||
if "gif_encoder" not in codecs or "gif_decoder" not in codecs:
|
|
||||||
self.skipTest("gif support not available") # can this happen?
|
|
||||||
|
|
||||||
def test_sanity(self):
|
def test_sanity(self):
|
||||||
with Image.open(TEST_GIF) as im:
|
with Image.open(TEST_GIF) as im:
|
||||||
im.load()
|
im.load()
|
||||||
|
@ -562,7 +549,7 @@ class TestFileGif(PillowTestCase):
|
||||||
|
|
||||||
self.assertEqual(reread.info["background"], im.info["background"])
|
self.assertEqual(reread.info["background"], im.info["background"])
|
||||||
|
|
||||||
if HAVE_WEBP and _webp.HAVE_WEBPANIM:
|
if features.check("webp") and features.check("webp_anim"):
|
||||||
with Image.open("Tests/images/hopper.webp") as im:
|
with Image.open("Tests/images/hopper.webp") as im:
|
||||||
self.assertIsInstance(im.info["background"], tuple)
|
self.assertIsInstance(im.info["background"], tuple)
|
||||||
im.save(out)
|
im.save(out)
|
||||||
|
|
|
@ -13,19 +13,15 @@ from .helper import (
|
||||||
djpeg_available,
|
djpeg_available,
|
||||||
hopper,
|
hopper,
|
||||||
is_win32,
|
is_win32,
|
||||||
|
skip_unless_feature,
|
||||||
unittest,
|
unittest,
|
||||||
)
|
)
|
||||||
|
|
||||||
codecs = dir(Image.core)
|
|
||||||
|
|
||||||
TEST_FILE = "Tests/images/hopper.jpg"
|
TEST_FILE = "Tests/images/hopper.jpg"
|
||||||
|
|
||||||
|
|
||||||
|
@skip_unless_feature("jpg")
|
||||||
class TestFileJpeg(PillowTestCase):
|
class TestFileJpeg(PillowTestCase):
|
||||||
def setUp(self):
|
|
||||||
if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs:
|
|
||||||
self.skipTest("jpeg support not available")
|
|
||||||
|
|
||||||
def roundtrip(self, im, **options):
|
def roundtrip(self, im, **options):
|
||||||
out = BytesIO()
|
out = BytesIO()
|
||||||
im.save(out, "JPEG", **options)
|
im.save(out, "JPEG", **options)
|
||||||
|
@ -687,11 +683,8 @@ class TestFileJpeg(PillowTestCase):
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(is_win32(), "Windows only")
|
@unittest.skipUnless(is_win32(), "Windows only")
|
||||||
|
@skip_unless_feature("jpg")
|
||||||
class TestFileCloseW32(PillowTestCase):
|
class TestFileCloseW32(PillowTestCase):
|
||||||
def setUp(self):
|
|
||||||
if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs:
|
|
||||||
self.skipTest("jpeg support not available")
|
|
||||||
|
|
||||||
def test_fd_leak(self):
|
def test_fd_leak(self):
|
||||||
tmpfile = self.tempfile("temp.jpg")
|
tmpfile = self.tempfile("temp.jpg")
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,9 @@ from .helper import (
|
||||||
assert_image_similar,
|
assert_image_similar,
|
||||||
is_big_endian,
|
is_big_endian,
|
||||||
on_ci,
|
on_ci,
|
||||||
|
skip_unless_feature,
|
||||||
)
|
)
|
||||||
|
|
||||||
codecs = dir(Image.core)
|
|
||||||
|
|
||||||
test_card = Image.open("Tests/images/test-card.png")
|
test_card = Image.open("Tests/images/test-card.png")
|
||||||
test_card.load()
|
test_card.load()
|
||||||
|
|
||||||
|
@ -21,11 +20,8 @@ test_card.load()
|
||||||
# 'Not enough memory to handle tile data'
|
# 'Not enough memory to handle tile data'
|
||||||
|
|
||||||
|
|
||||||
|
@skip_unless_feature("jpg_2000")
|
||||||
class TestFileJpeg2k(PillowTestCase):
|
class TestFileJpeg2k(PillowTestCase):
|
||||||
def setUp(self):
|
|
||||||
if "jpeg2k_encoder" not in codecs or "jpeg2k_decoder" not in codecs:
|
|
||||||
self.skipTest("JPEG 2000 support not available")
|
|
||||||
|
|
||||||
def roundtrip(self, im, **options):
|
def roundtrip(self, im, **options):
|
||||||
out = BytesIO()
|
out = BytesIO()
|
||||||
im.save(out, "JPEG2000", **options)
|
im.save(out, "JPEG2000", **options)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import os
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from ctypes import c_float
|
from ctypes import c_float
|
||||||
|
|
||||||
from PIL import Image, ImageFilter, TiffImagePlugin, TiffTags, features
|
from PIL import Image, ImageFilter, TiffImagePlugin, TiffTags
|
||||||
|
|
||||||
from .helper import (
|
from .helper import (
|
||||||
PillowTestCase,
|
PillowTestCase,
|
||||||
|
@ -15,16 +15,14 @@ from .helper import (
|
||||||
assert_image_similar,
|
assert_image_similar,
|
||||||
assert_image_similar_tofile,
|
assert_image_similar_tofile,
|
||||||
hopper,
|
hopper,
|
||||||
|
skip_unless_feature,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@skip_unless_feature("libtiff")
|
||||||
class LibTiffTestCase(PillowTestCase):
|
class LibTiffTestCase(PillowTestCase):
|
||||||
def setUp(self):
|
|
||||||
if not features.check("libtiff"):
|
|
||||||
self.skipTest("tiff support not available")
|
|
||||||
|
|
||||||
def _assert_noerr(self, im):
|
def _assert_noerr(self, im):
|
||||||
"""Helper tests that assert basic sanity about the g4 tiff reading"""
|
"""Helper tests that assert basic sanity about the g4 tiff reading"""
|
||||||
# 1 bit
|
# 1 bit
|
||||||
|
@ -727,13 +725,9 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
|
|
||||||
assert_image_equal_tofile(im, "Tests/images/tiff_16bit_RGBa_target.png")
|
assert_image_equal_tofile(im, "Tests/images/tiff_16bit_RGBa_target.png")
|
||||||
|
|
||||||
|
@skip_unless_feature("jpg")
|
||||||
def test_gimp_tiff(self):
|
def test_gimp_tiff(self):
|
||||||
# Read TIFF JPEG images from GIMP [@PIL168]
|
# Read TIFF JPEG images from GIMP [@PIL168]
|
||||||
|
|
||||||
codecs = dir(Image.core)
|
|
||||||
if "jpeg_decoder" not in codecs:
|
|
||||||
self.skipTest("jpeg support not available")
|
|
||||||
|
|
||||||
filename = "Tests/images/pil168.tif"
|
filename = "Tests/images/pil168.tif"
|
||||||
with Image.open(filename) as im:
|
with Image.open(filename) as im:
|
||||||
self.assertEqual(im.mode, "RGB")
|
self.assertEqual(im.mode, "RGB")
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import Image, ImagePalette, features
|
from PIL import Image, ImagePalette
|
||||||
|
|
||||||
from .helper import assert_image_similar, hopper
|
from .helper import assert_image_similar, hopper, skip_unless_feature
|
||||||
|
|
||||||
MicImagePlugin = pytest.importorskip(
|
MicImagePlugin = pytest.importorskip(
|
||||||
"PIL.MicImagePlugin", reason="olefile not installed"
|
"PIL.MicImagePlugin", reason="olefile not installed"
|
||||||
)
|
)
|
||||||
|
pytestmark = skip_unless_feature("libtiff")
|
||||||
pytestmark = pytest.mark.skipif(
|
|
||||||
not features.check("libtiff"), reason="libtiff not installed"
|
|
||||||
)
|
|
||||||
|
|
||||||
TEST_FILE = "Tests/images/hopper.mic"
|
TEST_FILE = "Tests/images/hopper.mic"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,11 @@ from io import BytesIO
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from .helper import assert_image_similar, is_pypy
|
from .helper import assert_image_similar, is_pypy, skip_unless_feature
|
||||||
|
|
||||||
test_files = ["Tests/images/sugarshack.mpo", "Tests/images/frozenpond.mpo"]
|
test_files = ["Tests/images/sugarshack.mpo", "Tests/images/frozenpond.mpo"]
|
||||||
|
|
||||||
|
pytestmark = skip_unless_feature("jpg")
|
||||||
def setup_module():
|
|
||||||
codecs = dir(Image.core)
|
|
||||||
if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs:
|
|
||||||
pytest.skip("jpeg support not available")
|
|
||||||
|
|
||||||
|
|
||||||
def frame_roundtrip(im, **options):
|
def frame_roundtrip(im, **options):
|
||||||
|
|
|
@ -15,18 +15,9 @@ from .helper import (
|
||||||
is_big_endian,
|
is_big_endian,
|
||||||
is_win32,
|
is_win32,
|
||||||
on_ci,
|
on_ci,
|
||||||
|
skip_unless_feature,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
|
||||||
from PIL import _webp
|
|
||||||
|
|
||||||
HAVE_WEBP = True
|
|
||||||
except ImportError:
|
|
||||||
HAVE_WEBP = False
|
|
||||||
|
|
||||||
codecs = dir(Image.core)
|
|
||||||
|
|
||||||
|
|
||||||
# sample png stream
|
# sample png stream
|
||||||
|
|
||||||
TEST_PNG_FILE = "Tests/images/hopper.png"
|
TEST_PNG_FILE = "Tests/images/hopper.png"
|
||||||
|
@ -63,11 +54,8 @@ def roundtrip(im, **options):
|
||||||
return Image.open(out)
|
return Image.open(out)
|
||||||
|
|
||||||
|
|
||||||
|
@skip_unless_feature("zlib")
|
||||||
class TestFilePng(PillowTestCase):
|
class TestFilePng(PillowTestCase):
|
||||||
def setUp(self):
|
|
||||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
|
||||||
self.skipTest("zip/deflate support not available")
|
|
||||||
|
|
||||||
def get_chunks(self, filename):
|
def get_chunks(self, filename):
|
||||||
chunks = []
|
chunks = []
|
||||||
with open(filename, "rb") as fp:
|
with open(filename, "rb") as fp:
|
||||||
|
@ -632,9 +620,8 @@ class TestFilePng(PillowTestCase):
|
||||||
with Image.open(test_file) as reloaded:
|
with Image.open(test_file) as reloaded:
|
||||||
self.assertEqual(reloaded.info["exif"], b"Exif\x00\x00exifstring")
|
self.assertEqual(reloaded.info["exif"], b"Exif\x00\x00exifstring")
|
||||||
|
|
||||||
@unittest.skipUnless(
|
@skip_unless_feature("webp")
|
||||||
HAVE_WEBP and _webp.HAVE_WEBPANIM, "WebP support not installed with animation"
|
@skip_unless_feature("webp_anim")
|
||||||
)
|
|
||||||
def test_apng(self):
|
def test_apng(self):
|
||||||
with Image.open("Tests/images/iss634.apng") as im:
|
with Image.open("Tests/images/iss634.apng") as im:
|
||||||
self.assertEqual(im.get_format_mimetype(), "image/apng")
|
self.assertEqual(im.get_format_mimetype(), "image/apng")
|
||||||
|
@ -645,14 +632,11 @@ class TestFilePng(PillowTestCase):
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(is_win32(), "requires Unix or macOS")
|
@unittest.skipIf(is_win32(), "requires Unix or macOS")
|
||||||
|
@skip_unless_feature("zlib")
|
||||||
class TestTruncatedPngPLeaks(PillowLeakTestCase):
|
class TestTruncatedPngPLeaks(PillowLeakTestCase):
|
||||||
mem_limit = 2 * 1024 # max increase in K
|
mem_limit = 2 * 1024 # max increase in K
|
||||||
iterations = 100 # Leak is 56k/iteration, this will leak 5.6megs
|
iterations = 100 # Leak is 56k/iteration, this will leak 5.6megs
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
|
||||||
self.skipTest("zip/deflate support not available")
|
|
||||||
|
|
||||||
def test_leak_load(self):
|
def test_leak_load(self):
|
||||||
with open("Tests/images/hopper.png", "rb") as f:
|
with open("Tests/images/hopper.png", "rb") as f:
|
||||||
DATA = BytesIO(f.read(16 * 1024))
|
DATA = BytesIO(f.read(16 * 1024))
|
||||||
|
|
|
@ -1,25 +1,18 @@
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import Image, TarIO
|
from PIL import Image, TarIO, features
|
||||||
|
|
||||||
from .helper import is_pypy
|
from .helper import is_pypy
|
||||||
|
|
||||||
codecs = dir(Image.core)
|
|
||||||
|
|
||||||
# Sample tar archive
|
# Sample tar archive
|
||||||
TEST_TAR_FILE = "Tests/images/hopper.tar"
|
TEST_TAR_FILE = "Tests/images/hopper.tar"
|
||||||
|
|
||||||
|
|
||||||
def setup_module():
|
|
||||||
if "zip_decoder" not in codecs and "jpeg_decoder" not in codecs:
|
|
||||||
pytest.skip("neither jpeg nor zip support available")
|
|
||||||
|
|
||||||
|
|
||||||
def test_sanity():
|
def test_sanity():
|
||||||
for codec, test_path, format in [
|
for codec, test_path, format in [
|
||||||
["zip_decoder", "hopper.png", "PNG"],
|
["zlib", "hopper.png", "PNG"],
|
||||||
["jpeg_decoder", "hopper.jpg", "JPEG"],
|
["jpg", "hopper.jpg", "JPEG"],
|
||||||
]:
|
]:
|
||||||
if codec in codecs:
|
if features.check(codec):
|
||||||
with TarIO.TarIO(TEST_TAR_FILE, test_path) as tar:
|
with TarIO.TarIO(TEST_TAR_FILE, test_path) as tar:
|
||||||
with Image.open(tar) as im:
|
with Image.open(tar) as im:
|
||||||
im.load()
|
im.load()
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import unittest
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import Image, WebPImagePlugin
|
from PIL import Image, WebPImagePlugin
|
||||||
|
|
||||||
|
@ -8,6 +6,7 @@ from .helper import (
|
||||||
assert_image_similar,
|
assert_image_similar,
|
||||||
assert_image_similar_tofile,
|
assert_image_similar_tofile,
|
||||||
hopper,
|
hopper,
|
||||||
|
skip_unless_feature,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -32,7 +31,7 @@ class TestUnsupportedWebp(PillowTestCase):
|
||||||
WebPImagePlugin.SUPPORTED = True
|
WebPImagePlugin.SUPPORTED = True
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(HAVE_WEBP, "WebP support not installed")
|
@skip_unless_feature("webp")
|
||||||
class TestFileWebp(PillowTestCase):
|
class TestFileWebp(PillowTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.rgb_mode = "RGB"
|
self.rgb_mode = "RGB"
|
||||||
|
@ -155,9 +154,8 @@ class TestFileWebp(PillowTestCase):
|
||||||
Image.open(blob).load()
|
Image.open(blob).load()
|
||||||
Image.open(blob).load()
|
Image.open(blob).load()
|
||||||
|
|
||||||
@unittest.skipUnless(
|
@skip_unless_feature("webp")
|
||||||
HAVE_WEBP and _webp.HAVE_WEBPANIM, "WebP save all not available"
|
@skip_unless_feature("webp_anim")
|
||||||
)
|
|
||||||
def test_background_from_gif(self):
|
def test_background_from_gif(self):
|
||||||
with Image.open("Tests/images/chi.gif") as im:
|
with Image.open("Tests/images/chi.gif") as im:
|
||||||
original_value = im.convert("RGB").getpixel((1, 1))
|
original_value = im.convert("RGB").getpixel((1, 1))
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from .helper import assert_image_equal, assert_image_similar, is_big_endian, on_ci
|
from .helper import (
|
||||||
|
assert_image_equal,
|
||||||
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
|
assert_image_similar,
|
||||||
|
is_big_endian,
|
||||||
|
on_ci,
|
||||||
def setup_module():
|
skip_unless_feature,
|
||||||
if not _webp.HAVE_WEBPANIM:
|
|
||||||
pytest.skip(
|
|
||||||
"WebP library does not contain animation support, not testing animation"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
pytestmark = [
|
||||||
|
skip_unless_feature("webp"),
|
||||||
|
skip_unless_feature("webp_anim"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_n_frames():
|
def test_n_frames():
|
||||||
"""Ensure that WebP format sets n_frames and is_animated attributes correctly."""
|
"""Ensure that WebP format sets n_frames and is_animated attributes correctly."""
|
||||||
|
|
|
@ -4,7 +4,6 @@ from PIL import Image
|
||||||
from .helper import assert_image_equal, hopper
|
from .helper import assert_image_equal, hopper
|
||||||
|
|
||||||
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
|
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
|
||||||
|
|
||||||
RGB_MODE = "RGB"
|
RGB_MODE = "RGB"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,13 @@ from io import BytesIO
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
from .helper import skip_unless_feature
|
||||||
|
|
||||||
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
|
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
|
||||||
|
pytestmark = [
|
||||||
|
skip_unless_feature("webp"),
|
||||||
def setup_module():
|
skip_unless_feature("webp_mux"),
|
||||||
if not _webp.HAVE_WEBPMUX:
|
]
|
||||||
pytest.skip("WebPMux support not installed")
|
|
||||||
|
|
||||||
|
|
||||||
def test_read_exif_metadata():
|
def test_read_exif_metadata():
|
||||||
|
@ -93,10 +94,8 @@ def test_read_no_exif():
|
||||||
assert not webp_image._getexif()
|
assert not webp_image._getexif()
|
||||||
|
|
||||||
|
|
||||||
|
@skip_unless_feature("webp_anim")
|
||||||
def test_write_animated_metadata(tmp_path):
|
def test_write_animated_metadata(tmp_path):
|
||||||
if not _webp.HAVE_WEBPANIM:
|
|
||||||
pytest.skip("WebP animation support not available")
|
|
||||||
|
|
||||||
iccp_data = b"<iccp_data>"
|
iccp_data = b"<iccp_data>"
|
||||||
exif_data = b"<exif_data>"
|
exif_data = b"<exif_data>"
|
||||||
xmp_data = b"<xmp_data>"
|
xmp_data = b"<xmp_data>"
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import unittest
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
from PIL import Image, ImageDraw, ImageFont, features
|
from .helper import PillowLeakTestCase, skip_unless_feature
|
||||||
|
|
||||||
from .helper import PillowLeakTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class TestTTypeFontLeak(PillowLeakTestCase):
|
class TestTTypeFontLeak(PillowLeakTestCase):
|
||||||
|
@ -19,7 +17,7 @@ class TestTTypeFontLeak(PillowLeakTestCase):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@unittest.skipUnless(features.check("freetype2"), "Test requires freetype2")
|
@skip_unless_feature("freetype2")
|
||||||
def test_leak(self):
|
def test_leak(self):
|
||||||
ttype = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 20)
|
ttype = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 20)
|
||||||
self._test_font(ttype)
|
self._test_font(ttype)
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
from PIL import FontFile, Image, ImageDraw, ImageFont, PcfFontFile
|
from PIL import FontFile, Image, ImageDraw, ImageFont, PcfFontFile
|
||||||
|
|
||||||
from .helper import PillowTestCase, assert_image_equal, assert_image_similar
|
from .helper import (
|
||||||
|
PillowTestCase,
|
||||||
codecs = dir(Image.core)
|
assert_image_equal,
|
||||||
|
assert_image_similar,
|
||||||
|
skip_unless_feature,
|
||||||
|
)
|
||||||
|
|
||||||
fontname = "Tests/fonts/10x20-ISO8859-1.pcf"
|
fontname = "Tests/fonts/10x20-ISO8859-1.pcf"
|
||||||
|
|
||||||
message = "hello, world"
|
message = "hello, world"
|
||||||
|
|
||||||
|
|
||||||
|
@skip_unless_feature("zlib")
|
||||||
class TestFontPcf(PillowTestCase):
|
class TestFontPcf(PillowTestCase):
|
||||||
def setUp(self):
|
|
||||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
|
||||||
self.skipTest("zlib support not available")
|
|
||||||
|
|
||||||
def save_font(self):
|
def save_font(self):
|
||||||
with open(fontname, "rb") as test_file:
|
with open(fontname, "rb") as test_file:
|
||||||
font = PcfFontFile.PcfFontFile(test_file)
|
font = PcfFontFile.PcfFontFile(test_file)
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
import pytest
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from .helper import fromstring, tostring
|
from .helper import fromstring, skip_unless_feature, tostring
|
||||||
|
|
||||||
|
pytestmark = skip_unless_feature("jpg")
|
||||||
def setup_module():
|
|
||||||
codecs = dir(Image.core)
|
|
||||||
if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs:
|
|
||||||
pytest.skip("jpeg support not available")
|
|
||||||
|
|
||||||
|
|
||||||
def draft_roundtrip(in_mode, in_size, req_mode, req_size):
|
def draft_roundtrip(in_mode, in_size, req_mode, req_size):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from PIL import Image
|
from PIL import Image, features
|
||||||
|
|
||||||
from .helper import PillowTestCase, assert_image_equal, hopper
|
from .helper import PillowTestCase, assert_image_equal, hopper
|
||||||
|
|
||||||
|
@ -44,9 +44,7 @@ class TestImageSplit(PillowTestCase):
|
||||||
assert_image_equal(hopper("YCbCr"), split_merge("YCbCr"))
|
assert_image_equal(hopper("YCbCr"), split_merge("YCbCr"))
|
||||||
|
|
||||||
def test_split_open(self):
|
def test_split_open(self):
|
||||||
codecs = dir(Image.core)
|
if features.check("zlib"):
|
||||||
|
|
||||||
if "zip_encoder" in codecs:
|
|
||||||
test_file = self.tempfile("temp.png")
|
test_file = self.tempfile("temp.png")
|
||||||
else:
|
else:
|
||||||
test_file = self.tempfile("temp.pcx")
|
test_file = self.tempfile("temp.pcx")
|
||||||
|
@ -60,5 +58,5 @@ class TestImageSplit(PillowTestCase):
|
||||||
self.assertEqual(split_open("L"), 1)
|
self.assertEqual(split_open("L"), 1)
|
||||||
self.assertEqual(split_open("P"), 1)
|
self.assertEqual(split_open("P"), 1)
|
||||||
self.assertEqual(split_open("RGB"), 3)
|
self.assertEqual(split_open("RGB"), 3)
|
||||||
if "zip_encoder" in codecs:
|
if features.check("zlib"):
|
||||||
self.assertEqual(split_open("RGBA"), 4)
|
self.assertEqual(split_open("RGBA"), 4)
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import Image, ImageColor, ImageDraw, ImageFont, features
|
from PIL import Image, ImageColor, ImageDraw, ImageFont
|
||||||
|
|
||||||
from .helper import assert_image_equal, assert_image_similar, hopper
|
from .helper import (
|
||||||
|
assert_image_equal,
|
||||||
|
assert_image_similar,
|
||||||
|
hopper,
|
||||||
|
skip_unless_feature,
|
||||||
|
)
|
||||||
|
|
||||||
BLACK = (0, 0, 0)
|
BLACK = (0, 0, 0)
|
||||||
WHITE = (255, 255, 255)
|
WHITE = (255, 255, 255)
|
||||||
|
@ -30,8 +35,6 @@ POINTS2 = [10, 10, 20, 40, 30, 30]
|
||||||
|
|
||||||
KITE_POINTS = [(10, 50), (70, 10), (90, 50), (70, 90), (10, 50)]
|
KITE_POINTS = [(10, 50), (70, 10), (90, 50), (70, 90), (10, 50)]
|
||||||
|
|
||||||
HAS_FREETYPE = features.check("freetype2")
|
|
||||||
|
|
||||||
|
|
||||||
def test_sanity():
|
def test_sanity():
|
||||||
im = hopper("RGB").copy()
|
im = hopper("RGB").copy()
|
||||||
|
@ -912,7 +915,7 @@ def test_textsize_empty_string():
|
||||||
draw.textsize("test\n")
|
draw.textsize("test\n")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available")
|
@skip_unless_feature("freetype2")
|
||||||
def test_textsize_stroke():
|
def test_textsize_stroke():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
|
@ -924,7 +927,7 @@ def test_textsize_stroke():
|
||||||
assert draw.multiline_textsize("ABC\nAaaa", font, stroke_width=2) == (52, 44)
|
assert draw.multiline_textsize("ABC\nAaaa", font, stroke_width=2) == (52, 44)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available")
|
@skip_unless_feature("freetype2")
|
||||||
def test_stroke():
|
def test_stroke():
|
||||||
for suffix, stroke_fill in {"same": None, "different": "#0f0"}.items():
|
for suffix, stroke_fill in {"same": None, "different": "#0f0"}.items():
|
||||||
# Arrange
|
# Arrange
|
||||||
|
@ -941,7 +944,7 @@ def test_stroke():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available")
|
@skip_unless_feature("freetype2")
|
||||||
def test_stroke_multiline():
|
def test_stroke_multiline():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (100, 250))
|
im = Image.new("RGB", (100, 250))
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import pytest
|
from PIL import Image, ImageDraw, ImageDraw2
|
||||||
from PIL import Image, ImageDraw, ImageDraw2, features
|
|
||||||
|
|
||||||
from .helper import assert_image_equal, assert_image_similar, hopper
|
from .helper import (
|
||||||
|
assert_image_equal,
|
||||||
|
assert_image_similar,
|
||||||
|
hopper,
|
||||||
|
skip_unless_feature,
|
||||||
|
)
|
||||||
|
|
||||||
BLACK = (0, 0, 0)
|
BLACK = (0, 0, 0)
|
||||||
WHITE = (255, 255, 255)
|
WHITE = (255, 255, 255)
|
||||||
|
@ -30,7 +34,6 @@ POINTS2 = [10, 10, 20, 40, 30, 30]
|
||||||
|
|
||||||
KITE_POINTS = [(10, 50), (70, 10), (90, 50), (70, 90), (10, 50)]
|
KITE_POINTS = [(10, 50), (70, 10), (90, 50), (70, 90), (10, 50)]
|
||||||
|
|
||||||
HAS_FREETYPE = features.check("freetype2")
|
|
||||||
FONT_PATH = "Tests/fonts/FreeMono.ttf"
|
FONT_PATH = "Tests/fonts/FreeMono.ttf"
|
||||||
|
|
||||||
|
|
||||||
|
@ -178,7 +181,7 @@ def test_big_rectangle():
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar(im, Image.open(expected), 1)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available")
|
@skip_unless_feature("freetype2")
|
||||||
def test_text():
|
def test_text():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
|
@ -193,7 +196,7 @@ def test_text():
|
||||||
assert_image_similar(im, Image.open(expected), 13)
|
assert_image_similar(im, Image.open(expected), 13)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available")
|
@skip_unless_feature("freetype2")
|
||||||
def test_textsize():
|
def test_textsize():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
|
@ -207,7 +210,7 @@ def test_textsize():
|
||||||
assert size[1] == 12
|
assert size[1] == 12
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available")
|
@skip_unless_feature("freetype2")
|
||||||
def test_textsize_empty_string():
|
def test_textsize_empty_string():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
|
@ -222,7 +225,7 @@ def test_textsize_empty_string():
|
||||||
draw.textsize("test\n", font)
|
draw.textsize("test\n", font)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available")
|
@skip_unless_feature("freetype2")
|
||||||
def test_flush():
|
def test_flush():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import unittest
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from PIL import EpsImagePlugin, Image, ImageFile
|
from PIL import EpsImagePlugin, Image, ImageFile, features
|
||||||
|
|
||||||
from .helper import (
|
from .helper import (
|
||||||
PillowTestCase,
|
PillowTestCase,
|
||||||
|
@ -10,19 +9,10 @@ from .helper import (
|
||||||
assert_image_similar,
|
assert_image_similar,
|
||||||
fromstring,
|
fromstring,
|
||||||
hopper,
|
hopper,
|
||||||
|
skip_unless_feature,
|
||||||
tostring,
|
tostring,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
|
||||||
from PIL import _webp
|
|
||||||
|
|
||||||
HAVE_WEBP = True
|
|
||||||
except ImportError:
|
|
||||||
HAVE_WEBP = False
|
|
||||||
|
|
||||||
|
|
||||||
codecs = dir(Image.core)
|
|
||||||
|
|
||||||
# save original block sizes
|
# save original block sizes
|
||||||
MAXBLOCK = ImageFile.MAXBLOCK
|
MAXBLOCK = ImageFile.MAXBLOCK
|
||||||
SAFEBLOCK = ImageFile.SAFEBLOCK
|
SAFEBLOCK = ImageFile.SAFEBLOCK
|
||||||
|
@ -53,7 +43,7 @@ class TestImageFile(PillowTestCase):
|
||||||
assert_image_similar(im1.convert("P"), im2, 1)
|
assert_image_similar(im1.convert("P"), im2, 1)
|
||||||
assert_image_equal(*roundtrip("IM"))
|
assert_image_equal(*roundtrip("IM"))
|
||||||
assert_image_equal(*roundtrip("MSP"))
|
assert_image_equal(*roundtrip("MSP"))
|
||||||
if "zip_encoder" in codecs:
|
if features.check("zlib"):
|
||||||
try:
|
try:
|
||||||
# force multiple blocks in PNG driver
|
# force multiple blocks in PNG driver
|
||||||
ImageFile.MAXBLOCK = 8192
|
ImageFile.MAXBLOCK = 8192
|
||||||
|
@ -77,7 +67,7 @@ class TestImageFile(PillowTestCase):
|
||||||
# EPS comes back in RGB:
|
# EPS comes back in RGB:
|
||||||
assert_image_similar(im1, im2.convert("L"), 20)
|
assert_image_similar(im1, im2.convert("L"), 20)
|
||||||
|
|
||||||
if "jpeg_encoder" in codecs:
|
if features.check("jpg"):
|
||||||
im1, im2 = roundtrip("JPEG") # lossy compression
|
im1, im2 = roundtrip("JPEG") # lossy compression
|
||||||
assert_image(im1, im2.mode, im2.size)
|
assert_image(im1, im2.mode, im2.size)
|
||||||
|
|
||||||
|
@ -90,10 +80,8 @@ class TestImageFile(PillowTestCase):
|
||||||
p.feed(data)
|
p.feed(data)
|
||||||
self.assertEqual((48, 48), p.image.size)
|
self.assertEqual((48, 48), p.image.size)
|
||||||
|
|
||||||
|
@skip_unless_feature("zlib")
|
||||||
def test_safeblock(self):
|
def test_safeblock(self):
|
||||||
if "zip_encoder" not in codecs:
|
|
||||||
self.skipTest("PNG (zlib) encoder not available")
|
|
||||||
|
|
||||||
im1 = hopper()
|
im1 = hopper()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -120,10 +108,8 @@ class TestImageFile(PillowTestCase):
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
p.close()
|
p.close()
|
||||||
|
|
||||||
|
@skip_unless_feature("zlib")
|
||||||
def test_truncated_with_errors(self):
|
def test_truncated_with_errors(self):
|
||||||
if "zip_encoder" not in codecs:
|
|
||||||
self.skipTest("PNG (zlib) encoder not available")
|
|
||||||
|
|
||||||
with Image.open("Tests/images/truncated_image.png") as im:
|
with Image.open("Tests/images/truncated_image.png") as im:
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
im.load()
|
im.load()
|
||||||
|
@ -132,10 +118,8 @@ class TestImageFile(PillowTestCase):
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
|
@skip_unless_feature("zlib")
|
||||||
def test_truncated_without_errors(self):
|
def test_truncated_without_errors(self):
|
||||||
if "zip_encoder" not in codecs:
|
|
||||||
self.skipTest("PNG (zlib) encoder not available")
|
|
||||||
|
|
||||||
with Image.open("Tests/images/truncated_image.png") as im:
|
with Image.open("Tests/images/truncated_image.png") as im:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||||
try:
|
try:
|
||||||
|
@ -143,18 +127,14 @@ class TestImageFile(PillowTestCase):
|
||||||
finally:
|
finally:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||||
|
|
||||||
|
@skip_unless_feature("zlib")
|
||||||
def test_broken_datastream_with_errors(self):
|
def test_broken_datastream_with_errors(self):
|
||||||
if "zip_encoder" not in codecs:
|
|
||||||
self.skipTest("PNG (zlib) encoder not available")
|
|
||||||
|
|
||||||
with Image.open("Tests/images/broken_data_stream.png") as im:
|
with Image.open("Tests/images/broken_data_stream.png") as im:
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
|
@skip_unless_feature("zlib")
|
||||||
def test_broken_datastream_without_errors(self):
|
def test_broken_datastream_without_errors(self):
|
||||||
if "zip_encoder" not in codecs:
|
|
||||||
self.skipTest("PNG (zlib) encoder not available")
|
|
||||||
|
|
||||||
with Image.open("Tests/images/broken_data_stream.png") as im:
|
with Image.open("Tests/images/broken_data_stream.png") as im:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||||
try:
|
try:
|
||||||
|
@ -292,10 +272,8 @@ class TestPyDecoder(PillowTestCase):
|
||||||
self.assertEqual(reloaded_exif[40963], 455)
|
self.assertEqual(reloaded_exif[40963], 455)
|
||||||
self.assertEqual(exif[305], "Pillow test")
|
self.assertEqual(exif[305], "Pillow test")
|
||||||
|
|
||||||
@unittest.skipIf(
|
@skip_unless_feature("webp")
|
||||||
not HAVE_WEBP or not _webp.HAVE_WEBPANIM,
|
@skip_unless_feature("webp_anim")
|
||||||
"WebP support not installed with animation",
|
|
||||||
)
|
|
||||||
def test_exif_webp(self):
|
def test_exif_webp(self):
|
||||||
with Image.open("Tests/images/hopper.webp") as im:
|
with Image.open("Tests/images/hopper.webp") as im:
|
||||||
exif = im.getexif()
|
exif = im.getexif()
|
||||||
|
|
|
@ -3,11 +3,11 @@ import distutils.version
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
|
||||||
import unittest
|
import unittest
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
from PIL import Image, ImageDraw, ImageFont, features
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
from .helper import (
|
from .helper import (
|
||||||
PillowTestCase,
|
PillowTestCase,
|
||||||
|
@ -16,6 +16,7 @@ from .helper import (
|
||||||
assert_image_similar_tofile,
|
assert_image_similar_tofile,
|
||||||
is_pypy,
|
is_pypy,
|
||||||
is_win32,
|
is_win32,
|
||||||
|
skip_unless_feature,
|
||||||
)
|
)
|
||||||
|
|
||||||
FONT_PATH = "Tests/fonts/FreeMono.ttf"
|
FONT_PATH = "Tests/fonts/FreeMono.ttf"
|
||||||
|
@ -23,37 +24,8 @@ FONT_SIZE = 20
|
||||||
|
|
||||||
TEST_TEXT = "hey you\nyou are awesome\nthis looks awkward"
|
TEST_TEXT = "hey you\nyou are awesome\nthis looks awkward"
|
||||||
|
|
||||||
HAS_FREETYPE = features.check("freetype2")
|
|
||||||
HAS_RAQM = features.check("raqm")
|
|
||||||
|
|
||||||
|
@skip_unless_feature("freetype2")
|
||||||
class SimplePatcher:
|
|
||||||
def __init__(self, parent_obj, attr_name, value):
|
|
||||||
self._parent_obj = parent_obj
|
|
||||||
self._attr_name = attr_name
|
|
||||||
self._saved = None
|
|
||||||
self._is_saved = False
|
|
||||||
self._value = value
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
# Patch the attr on the object
|
|
||||||
if hasattr(self._parent_obj, self._attr_name):
|
|
||||||
self._saved = getattr(self._parent_obj, self._attr_name)
|
|
||||||
setattr(self._parent_obj, self._attr_name, self._value)
|
|
||||||
self._is_saved = True
|
|
||||||
else:
|
|
||||||
setattr(self._parent_obj, self._attr_name, self._value)
|
|
||||||
self._is_saved = False
|
|
||||||
|
|
||||||
def __exit__(self, type, value, traceback):
|
|
||||||
# Restore the original value
|
|
||||||
if self._is_saved:
|
|
||||||
setattr(self._parent_obj, self._attr_name, self._saved)
|
|
||||||
else:
|
|
||||||
delattr(self._parent_obj, self._attr_name)
|
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(HAS_FREETYPE, "ImageFont not available")
|
|
||||||
class TestImageFont(PillowTestCase):
|
class TestImageFont(PillowTestCase):
|
||||||
LAYOUT_ENGINE = ImageFont.LAYOUT_BASIC
|
LAYOUT_ENGINE = ImageFont.LAYOUT_BASIC
|
||||||
|
|
||||||
|
@ -491,7 +463,7 @@ class TestImageFont(PillowTestCase):
|
||||||
def _test_fake_loading_font(self, path_to_fake, fontname):
|
def _test_fake_loading_font(self, path_to_fake, fontname):
|
||||||
# Make a copy of FreeTypeFont so we can patch the original
|
# Make a copy of FreeTypeFont so we can patch the original
|
||||||
free_type_font = copy.deepcopy(ImageFont.FreeTypeFont)
|
free_type_font = copy.deepcopy(ImageFont.FreeTypeFont)
|
||||||
with SimplePatcher(ImageFont, "_FreeTypeFont", free_type_font):
|
with mock.patch.object(ImageFont, "_FreeTypeFont", free_type_font, create=True):
|
||||||
|
|
||||||
def loadable_font(filepath, size, index, encoding, *args, **kwargs):
|
def loadable_font(filepath, size, index, encoding, *args, **kwargs):
|
||||||
if filepath == path_to_fake:
|
if filepath == path_to_fake:
|
||||||
|
@ -502,7 +474,7 @@ class TestImageFont(PillowTestCase):
|
||||||
filepath, size, index, encoding, *args, **kwargs
|
filepath, size, index, encoding, *args, **kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
with SimplePatcher(ImageFont, "FreeTypeFont", loadable_font):
|
with mock.patch.object(ImageFont, "FreeTypeFont", loadable_font):
|
||||||
font = ImageFont.truetype(fontname)
|
font = ImageFont.truetype(fontname)
|
||||||
# Make sure it's loaded
|
# Make sure it's loaded
|
||||||
name = font.getname()
|
name = font.getname()
|
||||||
|
@ -513,10 +485,9 @@ class TestImageFont(PillowTestCase):
|
||||||
# A lot of mocking here - this is more for hitting code and
|
# A lot of mocking here - this is more for hitting code and
|
||||||
# catching syntax like errors
|
# catching syntax like errors
|
||||||
font_directory = "/usr/local/share/fonts"
|
font_directory = "/usr/local/share/fonts"
|
||||||
with SimplePatcher(sys, "platform", "linux"):
|
with mock.patch("sys.platform", "linux"):
|
||||||
patched_env = copy.deepcopy(os.environ)
|
patched_env = {"XDG_DATA_DIRS": "/usr/share/:/usr/local/share/"}
|
||||||
patched_env["XDG_DATA_DIRS"] = "/usr/share/:/usr/local/share/"
|
with mock.patch.dict(os.environ, patched_env):
|
||||||
with SimplePatcher(os, "environ", patched_env):
|
|
||||||
|
|
||||||
def fake_walker(path):
|
def fake_walker(path):
|
||||||
if path == font_directory:
|
if path == font_directory:
|
||||||
|
@ -534,7 +505,7 @@ class TestImageFont(PillowTestCase):
|
||||||
]
|
]
|
||||||
return [(path, [], ["some_random_font.ttf"])]
|
return [(path, [], ["some_random_font.ttf"])]
|
||||||
|
|
||||||
with SimplePatcher(os, "walk", fake_walker):
|
with mock.patch("os.walk", fake_walker):
|
||||||
# Test that the font loads both with and without the
|
# Test that the font loads both with and without the
|
||||||
# extension
|
# extension
|
||||||
self._test_fake_loading_font(
|
self._test_fake_loading_font(
|
||||||
|
@ -559,7 +530,7 @@ class TestImageFont(PillowTestCase):
|
||||||
# Like the linux test, more cover hitting code rather than testing
|
# Like the linux test, more cover hitting code rather than testing
|
||||||
# correctness.
|
# correctness.
|
||||||
font_directory = "/System/Library/Fonts"
|
font_directory = "/System/Library/Fonts"
|
||||||
with SimplePatcher(sys, "platform", "darwin"):
|
with mock.patch("sys.platform", "darwin"):
|
||||||
|
|
||||||
def fake_walker(path):
|
def fake_walker(path):
|
||||||
if path == font_directory:
|
if path == font_directory:
|
||||||
|
@ -577,7 +548,7 @@ class TestImageFont(PillowTestCase):
|
||||||
]
|
]
|
||||||
return [(path, [], ["some_random_font.ttf"])]
|
return [(path, [], ["some_random_font.ttf"])]
|
||||||
|
|
||||||
with SimplePatcher(os, "walk", fake_walker):
|
with mock.patch("os.walk", fake_walker):
|
||||||
self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial.ttf")
|
self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial.ttf")
|
||||||
self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial")
|
self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial")
|
||||||
self._test_fake_loading_font(font_directory + "/Single.otf", "Single")
|
self._test_fake_loading_font(font_directory + "/Single.otf", "Single")
|
||||||
|
@ -752,6 +723,6 @@ class TestImageFont(PillowTestCase):
|
||||||
_check_text(font, "Tests/images/variation_tiny_axes.png", 32.5)
|
_check_text(font, "Tests/images/variation_tiny_axes.png", 32.5)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(HAS_RAQM, "Raqm not Available")
|
@skip_unless_feature("raqm")
|
||||||
class TestImageFont_RaqmLayout(TestImageFont):
|
class TestImageFont_RaqmLayout(TestImageFont):
|
||||||
LAYOUT_ENGINE = ImageFont.LAYOUT_RAQM
|
LAYOUT_ENGINE = ImageFont.LAYOUT_RAQM
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
import unittest
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
from PIL import Image, ImageDraw, ImageFont, features
|
from .helper import PillowTestCase, assert_image_similar, skip_unless_feature
|
||||||
|
|
||||||
from .helper import PillowTestCase, assert_image_similar
|
|
||||||
|
|
||||||
FONT_SIZE = 20
|
FONT_SIZE = 20
|
||||||
FONT_PATH = "Tests/fonts/DejaVuSans.ttf"
|
FONT_PATH = "Tests/fonts/DejaVuSans.ttf"
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(features.check("raqm"), "Raqm Library is not installed.")
|
@skip_unless_feature("raqm")
|
||||||
class TestImagecomplextext(PillowTestCase):
|
class TestImagecomplextext(PillowTestCase):
|
||||||
def test_english(self):
|
def test_english(self):
|
||||||
# smoke test, this should not fail
|
# smoke test, this should not fail
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import Image, ImageOps
|
from PIL import Image, ImageOps, features
|
||||||
|
|
||||||
from .helper import (
|
from .helper import (
|
||||||
assert_image_equal,
|
assert_image_equal,
|
||||||
|
@ -8,13 +8,6 @@ from .helper import (
|
||||||
hopper,
|
hopper,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
|
||||||
from PIL import _webp
|
|
||||||
|
|
||||||
HAVE_WEBP = True
|
|
||||||
except ImportError:
|
|
||||||
HAVE_WEBP = False
|
|
||||||
|
|
||||||
|
|
||||||
class Deformer:
|
class Deformer:
|
||||||
def getmesh(self, im):
|
def getmesh(self, im):
|
||||||
|
@ -274,7 +267,7 @@ def test_colorize_3color_offset():
|
||||||
|
|
||||||
def test_exif_transpose():
|
def test_exif_transpose():
|
||||||
exts = [".jpg"]
|
exts = [".jpg"]
|
||||||
if HAVE_WEBP and _webp.HAVE_WEBPANIM:
|
if features.check("webp") and features.check("webp_anim"):
|
||||||
exts.append(".webp")
|
exts.append(".webp")
|
||||||
for ext in exts:
|
for ext in exts:
|
||||||
with Image.open("Tests/images/hopper" + ext) as base_im:
|
with Image.open("Tests/images/hopper" + ext) as base_im:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from PIL import Image, ImageSequence, TiffImagePlugin
|
from PIL import Image, ImageSequence, TiffImagePlugin
|
||||||
|
|
||||||
from .helper import PillowTestCase, assert_image_equal, hopper
|
from .helper import PillowTestCase, assert_image_equal, hopper, skip_unless_feature
|
||||||
|
|
||||||
|
|
||||||
class TestImageSequence(PillowTestCase):
|
class TestImageSequence(PillowTestCase):
|
||||||
|
@ -47,12 +47,8 @@ class TestImageSequence(PillowTestCase):
|
||||||
def test_tiff(self):
|
def test_tiff(self):
|
||||||
self._test_multipage_tiff()
|
self._test_multipage_tiff()
|
||||||
|
|
||||||
|
@skip_unless_feature("libtiff")
|
||||||
def test_libtiff(self):
|
def test_libtiff(self):
|
||||||
codecs = dir(Image.core)
|
|
||||||
|
|
||||||
if "libtiff_encoder" not in codecs or "libtiff_decoder" not in codecs:
|
|
||||||
self.skipTest("tiff support not available")
|
|
||||||
|
|
||||||
TiffImagePlugin.READ_LIBTIFF = True
|
TiffImagePlugin.READ_LIBTIFF = True
|
||||||
self._test_multipage_tiff()
|
self._test_multipage_tiff()
|
||||||
TiffImagePlugin.READ_LIBTIFF = False
|
TiffImagePlugin.READ_LIBTIFF = False
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from fractions import Fraction
|
from fractions import Fraction
|
||||||
|
|
||||||
from PIL import Image, TiffImagePlugin
|
from PIL import Image, TiffImagePlugin, features
|
||||||
from PIL.TiffImagePlugin import IFDRational
|
from PIL.TiffImagePlugin import IFDRational
|
||||||
|
|
||||||
from .helper import PillowTestCase, hopper
|
from .helper import PillowTestCase, hopper
|
||||||
|
@ -43,7 +43,7 @@ class Test_IFDRational(PillowTestCase):
|
||||||
|
|
||||||
def test_ifd_rational_save(self):
|
def test_ifd_rational_save(self):
|
||||||
methods = (True, False)
|
methods = (True, False)
|
||||||
if "libtiff_encoder" not in dir(Image.core):
|
if not features.check("libtiff"):
|
||||||
methods = (False,)
|
methods = (False,)
|
||||||
|
|
||||||
for libtiff in methods:
|
for libtiff in methods:
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import unittest
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from PIL import Image, features
|
from PIL import Image
|
||||||
|
|
||||||
from .helper import PillowLeakTestCase
|
from .helper import PillowLeakTestCase, skip_unless_feature
|
||||||
|
|
||||||
test_file = "Tests/images/hopper.webp"
|
test_file = "Tests/images/hopper.webp"
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(features.check("webp"), "WebP is not installed")
|
@skip_unless_feature("webp")
|
||||||
class TestWebPLeaks(PillowLeakTestCase):
|
class TestWebPLeaks(PillowLeakTestCase):
|
||||||
|
|
||||||
mem_limit = 3 * 1024 # kb
|
mem_limit = 3 * 1024 # kb
|
||||||
|
|
Loading…
Reference in New Issue
Block a user