Merge pull request #1372 from radarhere/pathlib

Added support for pathlib Path objects to open and save
This commit is contained in:
Hugo van Kemenade 2015-08-05 16:41:40 +03:00
commit 60cb3f7550
2 changed files with 29 additions and 14 deletions

View File

@ -1640,7 +1640,7 @@ class Image(object):
implement the ``seek``, ``tell``, and ``write`` implement the ``seek``, ``tell``, and ``write``
methods, and be opened in binary mode. methods, and be opened in binary mode.
:param fp: File name or file object. :param fp: A filename (string), pathlib.Path object or file object.
:param format: Optional format override. If omitted, the :param format: Optional format override. If omitted, the
format to use is determined from the filename extension. format to use is determined from the filename extension.
If a file object was used instead of a filename, this If a file object was used instead of a filename, this
@ -1653,13 +1653,15 @@ class Image(object):
may have been created, and may contain partial data. may have been created, and may contain partial data.
""" """
filename = ""
if isPath(fp): if isPath(fp):
filename = fp filename = fp
else: elif sys.version_info >= (3, 4):
if hasattr(fp, "name") and isPath(fp.name): from pathlib import Path
filename = fp.name if isinstance(fp, Path):
else: filename = str(fp.resolve())
filename = "" elif hasattr(fp, "name") and isPath(fp.name):
filename = fp.name
# may mutate self! # may mutate self!
self.load() self.load()
@ -1687,8 +1689,8 @@ class Image(object):
else: else:
save_handler = SAVE[format.upper()] save_handler = SAVE[format.upper()]
if isPath(fp): if filename:
fp = builtins.open(fp, "wb") fp = builtins.open(filename, "wb")
close = 1 close = 1
else: else:
close = 0 close = 0
@ -2265,9 +2267,9 @@ def open(fp, mode="r"):
:py:meth:`~PIL.Image.Image.load` method). See :py:meth:`~PIL.Image.Image.load` method). See
:py:func:`~PIL.Image.new`. :py:func:`~PIL.Image.new`.
:param fp: A filename (string) or a file object. The file object :param fp: A filename (string), pathlib.Path object or a file object.
must implement :py:meth:`~file.read`, :py:meth:`~file.seek`, and The file object must implement :py:meth:`~file.read`, :py:meth:`~file.seek`,
:py:meth:`~file.tell` methods, and be opened in binary mode. and :py:meth:`~file.tell` methods, and be opened in binary mode.
:param mode: The mode. If given, this argument must be "r". :param mode: The mode. If given, this argument must be "r".
:returns: An :py:class:`~PIL.Image.Image` object. :returns: An :py:class:`~PIL.Image.Image` object.
:exception IOError: If the file cannot be found, or the image cannot be :exception IOError: If the file cannot be found, or the image cannot be
@ -2277,11 +2279,15 @@ def open(fp, mode="r"):
if mode != "r": if mode != "r":
raise ValueError("bad mode %r" % mode) raise ValueError("bad mode %r" % mode)
filename = ""
if isPath(fp): if isPath(fp):
filename = fp filename = fp
fp = builtins.open(fp, "rb") elif sys.version_info >= (3, 4):
else: from pathlib import Path
filename = "" if isinstance(fp, Path):
filename = str(fp.resolve())
if filename:
fp = builtins.open(filename, "rb")
try: try:
fp.seek(0) fp.seek(0)

View File

@ -1,6 +1,7 @@
from helper import unittest, PillowTestCase, hopper from helper import unittest, PillowTestCase, hopper
from PIL import Image from PIL import Image
import sys
class TestImage(PillowTestCase): class TestImage(PillowTestCase):
@ -48,6 +49,14 @@ class TestImage(PillowTestCase):
im = io.BytesIO(b'') im = io.BytesIO(b'')
self.assertRaises(IOError, lambda: Image.open(im)) self.assertRaises(IOError, lambda: Image.open(im))
@unittest.skipIf(sys.version_info < (3, 4),
"pathlib only available in Python 3.4 or later")
def test_pathlib(self):
from pathlib import Path
im = Image.open(Path("Tests/images/hopper.jpg"))
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
def test_internals(self): def test_internals(self):
im = Image.new("L", (100, 100)) im = Image.new("L", (100, 100))