internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: python-pillow/Pillow

Issue:
_imagingtiff is gone?
I'm building Pillow on Windows, and old tests check for import of _imagingtiff.  I found that this particular bit isn't being built, and ultimately traced it back to _imagingtiff.c no longer existing.  When was this change made?  Is tiff no longer supported?  Can the stuff aobut _imagingtiff.c be removed from setup.py?



Discussion:
Tiff is still there, but support has changed quite a bit from the PIL days.  I'm not aware of the _imagingtiff.c file, I don't really remember it from the old package, and I don't see it in the initial import here.

If you can use the prebuilt packages, I'd highly recommend going with them, as building on windows is kind of a pain, especially getting all the dependencies working.


Resolving patch:
diff --git a/PIL/ImageGrab.py b/PIL/ImageGrab.py
--- a/PIL/ImageGrab.py
+++ b/PIL/ImageGrab.py
@@ -22,13 +22,7 @@
     raise ImportError("ImageGrab is OS X and Windows only")
 
 if sys.platform == "win32":
-    try:
-        # built-in driver (1.1.3 and later)
-        grabber = Image.core.grabscreen
-    except AttributeError:
-        # stand-alone driver (pil plus)
-        import _grabscreen
-        grabber = _grabscreen.grab
+    grabber = Image.core.grabscreen
 elif sys.platform == "darwin":
     import os
     import tempfile
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -554,10 +554,6 @@ def build_extensions(self):
             exts.append(Extension(
                 "PIL._imagingft", ["_imagingft.c"], libraries=["freetype"]))
 
-        if os.path.isfile("_imagingtiff.c") and feature.tiff:
-            exts.append(Extension(
-                "PIL._imagingtiff", ["_imagingtiff.c"], libraries=["tiff"]))
-
         if os.path.isfile("_imagingcms.c") and feature.lcms:
             extra = []
             if sys.platform == "win32":


Test patch:
Repository: python-pillow/Pillow

Issue:
createfontdatachunk.py is marked as executable but does not start with shebang
Pillow/Scripts/createfontdatachunk.py is marked as executable but does not start with shebang.  See https://lintian.debian.org/tags/executable-not-elf-or-script.html



Discussion:

Resolving patch:
diff --git a/Scripts/createfontdatachunk.py b/Scripts/createfontdatachunk.py
--- a/Scripts/createfontdatachunk.py
+++ b/Scripts/createfontdatachunk.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 from __future__ import print_function
 import base64
 import os


Test patch:
Repository: python-pillow/Pillow

Issue:
pilprint.py allows Shell Command Injection 
With the the "-P" option, any shell command can get into the printer variable %a and will be executed.
In this screenshot you can see that i could inject the command ';xeyes;' wich starts the program xeyes.

![screenshot](https://cloud.githubusercontent.com/assets/13422603/10921195/6727d7de-8274-11e5-911b-ec04f1c1777e.png)

So please remove "os.popen" and use "subprocess" instead.



Discussion:

Resolving patch:
diff --git a/Scripts/pilprint.py b/Scripts/pilprint.py
old mode 100644
new mode 100755
--- a/Scripts/pilprint.py
+++ b/Scripts/pilprint.py
@@ -15,6 +15,7 @@
 import getopt
 import os
 import sys
+import subprocess
 
 VERSION = "pilprint 0.3/2003-05-05"
 
@@ -46,8 +47,8 @@ def description(filepath, image):
     print(v)
     sys.exit(1)
 
-printer = None  # print to stdout
-monochrome = 1  # reduce file size for most common case
+printerArgs = []  # print to stdout
+monochrome = 1    # reduce file size for most common case
 
 for o, a in opt:
     if o == "-d":
@@ -60,10 +61,10 @@ def description(filepath, image):
         monochrome = 0
     elif o == "-p":
         # default printer channel
-        printer = "lpr"
+        printerArgs = ["lpr"]
     elif o == "-P":
         # printer channel
-        printer = "lpr -P%s" % a
+        printerArgs = ["lpr","-P%s" % a]
 
 for filepath in argv:
     try:
@@ -76,8 +77,9 @@ def description(filepath, image):
             im.draft("L", im.size)
             im = im.convert("L")
 
-        if printer:
-            fp = os.popen(printer, "w")
+        if printerArgs:
+            p = subprocess.Popen(printerArgs, stdin=subprocess.PIPE)
+            fp = p.stdin
         else:
             fp = sys.stdout
 
@@ -91,6 +93,9 @@ def description(filepath, image):
         ps.image(letter, im)
         ps.end_document()
 
+        if printerArgs:
+            fp.close()
+
     except:
         print("cannot print image", end=' ')
         print("(%s:%s)" % (sys.exc_info()[0], sys.exc_info()[1]))


Test patch:
Repository: python-pillow/Pillow

Issue:
Not able to open tiff-file with Pillow (regression)
We encountered a tiff-file that Pillow failed to open in version 3.0.0, in version 2.9.0 it works just fine.

https://drive.google.com/a/greyrook.com/file/d/0Bypf_GpBFGxZU3A1QmsxQlRXVXc/view

on `Image.open(path)`: `IOError: cannot identify image file`



Discussion:
I've encountered the same problem on OS X and Ubuntu 14.04 LTS.

It looks like the wheels distributed on PyPI were compiled on a machine without libtiff – if I install from source (`pip install --no-binary=all --no-use-wheel Pillow==3`) it works as expected.

@acdha Which platform is missing tiff in the distributed files?

@wiredfool OS X and Linux 64-bit

We don't distribute binaries for Linux, so I'm not sure where that comes from.  The OS X wheels are built on Travis, and they pass the libtiff tests: https://travis-ci.org/python-pillow/pillow-wheels/jobs/88293220.

Hmmm, that's really quite odd – on both platforms, 2.9.0 installs without a
hitch with no special handling but 3.0.0 only works from source, not the
wheel. I'll look into it more on Monday.

Chris
On Fri, Nov 13, 2015 at 2:00 PM wiredfool notifications@github.com wrote:

> We don't distribute binaries for Linux, so I'm not sure where that comes
> from. The OS X wheels are built on Travis, and they pass the libtiff tests:
> https://travis-ci.org/python-pillow/pillow-wheels/jobs/88293220.
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/python-pillow/Pillow/issues/1526#issuecomment-156525316
> .


Resolving patch:
diff --git a/PIL/TiffTags.py b/PIL/TiffTags.py
--- a/PIL/TiffTags.py
+++ b/PIL/TiffTags.py
@@ -133,7 +133,7 @@ def cvt_enum(self, value):
 
     # FIXME add more tags here
     34665: ("ExifIFD", 3, 1),
-    34675: ('ICCProfile', 7, 1),
+    34675: ('ICCProfile', 7, 0),
 
     # MPInfo
     45056: ("MPFVersion", 7, 1),


Test patch:
diff --git a/Tests/images/hopper.iccprofile_binary.tif b/Tests/images/hopper.iccprofile_binary.tif
new file mode 100644
Binary files /dev/null and b/Tests/images/hopper.iccprofile_binary.tif differ
diff --git a/Tests/test_file_tiff_metadata.py b/Tests/test_file_tiff_metadata.py
--- a/Tests/test_file_tiff_metadata.py
+++ b/Tests/test_file_tiff_metadata.py
@@ -158,6 +158,14 @@ def test_iccprofile(self):
         self.assert_(type(im.info['icc_profile']) is not type(tuple))
         self.assertEqual(im.info['icc_profile'], reloaded.info['icc_profile'])
 
+    def test_iccprofile_binary(self):
+        # https://github.com/python-pillow/Pillow/issues/1526
+        # We should be able to load this, but probably won't be able to save it.
+
+        im = Image.open('Tests/images/hopper.iccprofile_binary.tif')
+        self.assertEqual(im.tag_v2.tagtype[34675], 1)
+        self.assert_(im.info['icc_profile'])
+
 
 
 if __name__ == '__main__':
Repository: python-pillow/Pillow

Issue:
Malformed spider file makes open() raise OverflowError
While fuzzing imagesfiles I found a file that causes `Image.open(infile).load()` to give the following stack trace:

```
Traceback (most recent call last):
  File "./test2.py", line 6, in <module>
    Image.open(infile).load()
  File "/install/local/lib/python2.7/site-packages/PIL/Image.py", line 2280, in open
    im = _open_core(fp, filename, prefix)
  File "/install/local/lib/python2.7/site-packages/PIL/Image.py", line 2266, in _open_core
    im = factory(fp, filename)
  File "/install/local/lib/python2.7/site-packages/PIL/ImageFile.py", line 100, in __init__
    self._open()
  File "/install/lib/python2.7/site-packages/PIL/SpiderImagePlugin.py", line 108, in _open
    hdrlen = isSpiderHeader(t)
  File "/install/lib/python2.7/site-packages/PIL/SpiderImagePlugin.py", line 66, in isSpiderHeader
    if not isInt(h[i]):
  File "/install/lib/python2.7/site-packages/PIL/SpiderImagePlugin.py", line 46, in isInt
    i = int(f)
OverflowError: cannot convert float infinity to integer
```

The image file is uploaded here: [spider_img.txt](https://github.com/python-pillow/Pillow/files/36721/spider_img.txt)

The following patch fixes the problem and changes it into an IOError

``` patch
--- a/PIL/SpiderImagePlugin.py
+++ b/PIL/SpiderImagePlugin.py
@@ -50,6 +50,8 @@ def isInt(f):
             return 0
     except ValueError:
         return 0
+    except OverflowError:
+        return 0

 iforms = [1, 3, -11, -12, -21, -22]
```



Discussion:
Thanks for finding this. I've created a PR with your change.

I presume that since the image file is one you've generated randomly, it is able to be distributed as a test image under Pillow's license, and that you're happy for this to be done?


Resolving patch:
diff --git a/PIL/SpiderImagePlugin.py b/PIL/SpiderImagePlugin.py
--- a/PIL/SpiderImagePlugin.py
+++ b/PIL/SpiderImagePlugin.py
@@ -50,6 +50,8 @@ def isInt(f):
             return 0
     except ValueError:
         return 0
+    except OverflowError:
+        return 0
 
 iforms = [1, 3, -11, -12, -21, -22]
 


Test patch:
diff --git a/Tests/images/invalid.spider b/Tests/images/invalid.spider
new file mode 100644
Binary files /dev/null and b/Tests/images/invalid.spider differ
diff --git a/Tests/test_file_spider.py b/Tests/test_file_spider.py
--- a/Tests/test_file_spider.py
+++ b/Tests/test_file_spider.py
@@ -80,6 +80,11 @@ def test_isInt_not_a_number(self):
         # Assert
         self.assertEqual(ret, 0)
 
+    def test_invalid_file(self):
+        invalid_file = "Tests/images/invalid.spider"
+        
+        self.assertRaises(IOError, lambda: Image.open(invalid_file))
+
 
 if __name__ == '__main__':
     unittest.main()
Repository: python-pillow/Pillow

Issue:
Inconsistent behavior when converting  RGB and HSV images to a numpy array 
The behavior of RGB and HSV Images is different when converting into a numpy array.

``` python
>>> from PIL import Image
>>> from numpy import array
>>> img = Image.open("\usr\bin\pic.jpg")
>>> arr = array(img)
>>> arr.shape
(800, 715, 3)
>>> img_hsv = img.convert("HSV")
>>> arr_hsv = array(img_hsv)
>>> arr.shape
()
```

In fact with the HSV Image what I get is not even a proper array but apparently just some container. I can't iterate on it, for instance. I assume this is something for you and not the numpy guys, please correct me if that's wrong!

Python is 2.7, Pillow is 2.9.0.



Discussion:
From my inspection, the problem is that HSV is not part of this list - https://github.com/python-pillow/Pillow/blob/master/PIL/Image.py#L240

Yep, it needs an entry there. Should be a one line fix + a test. 


Resolving patch:
diff --git a/PIL/Image.py b/PIL/Image.py
--- a/PIL/Image.py
+++ b/PIL/Image.py
@@ -250,6 +250,7 @@ def isImageType(t):
     "CMYK": ('|u1', 4),
     "YCbCr": ('|u1', 3),
     "LAB": ('|u1', 3),  # UNDONE - unsigned |u1i1i1
+    "HSV": ('|u1', 3),
     # I;16 == I;16L, and I;32 == I;32L
     "I;16": ('<u2', None),
     "I;16B": ('>u2', None),


Test patch:
diff --git a/Tests/test_numpy.py b/Tests/test_numpy.py
--- a/Tests/test_numpy.py
+++ b/Tests/test_numpy.py
@@ -113,6 +113,7 @@ def _to_array(mode, dtype):
                  ("I;16", '<u2'),
                  ("I;16B", '>u2'),
                  ("I;16L", '<u2'),
+                 ("HSV", 'uint8'),
                  ]
 
         for mode in modes:
Repository: python-pillow/Pillow

Issue:
TIFF tags removed when using libtiff
My specific utilization of Pillow requires that I generate a TIFF image with  G4 compression and provide at least the following tags; 256, 257, 259, 262, 273, 274, 278, 279, 282, and 283.

The following line in TiffImagePlugin.py specifies a list of tags to exclude from the file when using libtiff:
https://github.com/python-pillow/Pillow/blob/master/PIL/TiffImagePlugin.py#L1281

I cannot find any justification for this other than the comment on line 1280, "ICC Profile crashes."
Is it impossible to create a TIFF file using G4 compression with Pillow that contains the ROWSPERSTRIP (278) TIFF tag?



Discussion:
I took the liberty of removing "ROWSPERSTRIP" from the blocklist collection on my local environment and it appears to behave as expected, error free. Any additional information would be greatly appreciated.

IIRC, libtiff was supposed to be adding those tags based on how the library was doing the encoding. 

ICCprofile was crashing, probably due to some questionable handling of the attributes.


Resolving patch:
diff --git a/PIL/TiffImagePlugin.py b/PIL/TiffImagePlugin.py
--- a/PIL/TiffImagePlugin.py
+++ b/PIL/TiffImagePlugin.py
@@ -1277,8 +1277,10 @@ def _save(im, fp, filename):
             except io.UnsupportedOperation:
                 pass
 
-        # ICC Profile crashes.
-        blocklist = [STRIPOFFSETS, STRIPBYTECOUNTS, ROWSPERSTRIP, ICCPROFILE]
+        # STRIPOFFSETS and STRIPBYTECOUNTS are added by the library
+        # based on the data in the strip.
+        # ICCPROFILE crashes.
+        blocklist = [STRIPOFFSETS, STRIPBYTECOUNTS, ICCPROFILE]
         atts = {}
         # bits per sample is a single short in the tiff directory, not a list.
         atts[BITSPERSAMPLE] = bits[0]


Test patch:
diff --git a/Tests/test_file_libtiff.py b/Tests/test_file_libtiff.py
--- a/Tests/test_file_libtiff.py
+++ b/Tests/test_file_libtiff.py
@@ -165,6 +165,13 @@ def test_write_metadata(self):
                         self.assertEqual(
                             val, value, msg="%s didn't roundtrip" % tag)
 
+            # https://github.com/python-pillow/Pillow/issues/1561
+            requested_fields = ['StripByteCounts',
+                                'RowsPerStrip',
+                                'StripOffsets']
+            for field in requested_fields:
+                self.assertTrue(field in reloaded, "%s not in metadata" %field)
+
     def test_g3_compression(self):
         i = Image.open('Tests/images/hopper_g4_500.tif')
         out = self.tempfile("temp.tif")
Repository: python-pillow/Pillow

Issue:
ImageSequence.Iterator name is misleading
Hi Pillow developers,

I found this error message to be rather hilarious:

```
TypeError: 'Iterator' object is not an iterator
```

which was produced by this code:

``` python
from PIL import Image, ImageSequence

with Image.open('multipage.tiff', mode='r') as tif:
    i = ImageSequence.Iterator(tif)
    next(i)
```

It seems that `ImageSequence.Iterator` does not define an `__iter__()` method, which means that it is a sequence type but not an iterator type. In my opinion, this is misleading and I suggest that a proper `__iter__()` method should be added to the class definition.

Thanks.



Discussion:
Fair enough. I've created a PR.


Resolving patch:
diff --git a/PIL/ImageSequence.py b/PIL/ImageSequence.py
--- a/PIL/ImageSequence.py
+++ b/PIL/ImageSequence.py
@@ -32,6 +32,7 @@ def __init__(self, im):
         if not hasattr(im, "seek"):
             raise AttributeError("im must have seek method")
         self.im = im
+        self.position = 0
 
     def __getitem__(self, ix):
         try:
@@ -40,3 +41,17 @@ def __getitem__(self, ix):
             return self.im
         except EOFError:
             raise IndexError  # end of sequence
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        try:
+            self.im.seek(self.position)
+            self.position += 1
+            return self.im
+        except EOFError:
+            raise StopIteration
+
+    def next(self):
+        return self.__next__()


Test patch:
diff --git a/Tests/test_imagesequence.py b/Tests/test_imagesequence.py
--- a/Tests/test_imagesequence.py
+++ b/Tests/test_imagesequence.py
@@ -24,6 +24,14 @@ def test_sanity(self):
 
         self.assertRaises(AttributeError, lambda: ImageSequence.Iterator(0))
 
+    def test_iterator(self):
+        im = Image.open('Tests/images/multipage.tiff')
+        i = ImageSequence.Iterator(im)
+        for index in range(0, im.n_frames):
+            self.assertEqual(i[index], next(i))
+        self.assertRaises(IndexError, lambda: i[index+1])
+        self.assertRaises(StopIteration, lambda: next(i))
+
     def _test_multipage_tiff(self):
         im = Image.open('Tests/images/multipage.tiff')
         for index, frame in enumerate(ImageSequence.Iterator(im)):
Repository: python-pillow/Pillow

Issue:
Repeated looping over image stack shows last frame in place of first frame
When looping through the frames in an animation or TIFF stack with `ImageSequence.Iterator`, the frame pointer is not reset for the first frame. Consequently, if the loop is run through a second time the final frame is shown again instead of the first frame.
### Demo

Code

``` python
from PIL import Image, ImageSequence
import os
# Make a test image
os.system((
    "convert -depth 8 -size 1x1 xc:'rgb(100,100,100)' xc:'rgb(121,121,121)'"
    " xc:'rgb(142,142,142)' xc:'rgb(163,163,163)' image.tif"
))
# Open the image
im = Image.open('image.tif')
# Run through the image
print('First run')
for frame in ImageSequence.Iterator(im):
    print(list(frame.getdata()))
# Run through the image again
print('Second run')
for frame in ImageSequence.Iterator(im):
    print(list(frame.getdata()))
```

Output

```
First run
[100]
[121]
[142]
[163]
Second run
[163]
[121]
[142]
[163]
```



Discussion:
Sounds fair enough to me. I've created a PR for review.


Resolving patch:
diff --git a/PIL/ImageSequence.py b/PIL/ImageSequence.py
--- a/PIL/ImageSequence.py
+++ b/PIL/ImageSequence.py
@@ -35,8 +35,7 @@ def __init__(self, im):
 
     def __getitem__(self, ix):
         try:
-            if ix:
-                self.im.seek(ix)
+            self.im.seek(ix)
             return self.im
         except EOFError:
             raise IndexError  # end of sequence


Test patch:
diff --git a/Tests/test_imagesequence.py b/Tests/test_imagesequence.py
--- a/Tests/test_imagesequence.py
+++ b/Tests/test_imagesequence.py
@@ -44,6 +44,17 @@ def test_libtiff(self):
         self._test_multipage_tiff()
         TiffImagePlugin.READ_LIBTIFF = False
 
+    def test_consecutive(self):
+        im = Image.open('Tests/images/multipage.tiff')
+        firstFrame = None
+        for frame in ImageSequence.Iterator(im):
+            if firstFrame == None:
+                firstFrame = frame.copy()
+            pass
+        for frame in ImageSequence.Iterator(im):
+            self.assert_image_equal(frame, firstFrame)
+            break
+
 if __name__ == '__main__':
     unittest.main()
Repository: python-pillow/Pillow

Issue:
Pasting image with a 2-tuple doesn't behave as expected/documented in docstring.
The docstring on `Image.paste` indicates that if a 2-tuple value is provided for `box` then it will interpret that value as the upper-left corner (https://github.com/python-pillow/Pillow/blob/master/PIL/Image.py#L1278), however the code following the docstring treats it as a lower-left corner and is commented describing such behavior (https://github.com/python-pillow/Pillow/blob/master/PIL/Image.py#L1298, https://github.com/python-pillow/Pillow/blob/master/PIL/Image.py#L1308).



Discussion:
The way that I read it, `box = box + (box[0]+size[0], box[1]+size[1])` treats the 2-tuple value as a upper-left corner, adding `size` values to generate lower-right third and fourth values for the tuple. So it's the comment at 1298 that is wrong.

Feel free to correct my understanding.

Edit: I was mistakenly operating on the assumption that 0,0 was lower left rather than upper left. It does appear that the comment is wrong.


Resolving patch:
diff --git a/PIL/Image.py b/PIL/Image.py
--- a/PIL/Image.py
+++ b/PIL/Image.py
@@ -1295,7 +1295,7 @@ def paste(self, im, box=None, mask=None):
             box = (0, 0) + self.size
 
         if len(box) == 2:
-            # lower left corner given; get size from image or mask
+            # upper left corner given; get size from image or mask
             if isImageType(im):
                 size = im.size
             elif isImageType(mask):


Test patch:
Repository: python-pillow/Pillow

Issue:
crop does not sanity check for integers
Hi,
with Pillow 3.1.1:

```
>>> Image.new("RGB", (10, 10)).crop((0.3, 0.3, 4.6, 4.6)).size
(4.3, 4.3)
```

This then throws "integer argument expected, got float" when one tries to call convert() on the image or use the size in new().  Either crop should round/truncate or throw the error immediately.



Discussion:

Resolving patch:
diff --git a/PIL/Image.py b/PIL/Image.py
--- a/PIL/Image.py
+++ b/PIL/Image.py
@@ -1941,7 +1941,9 @@ def __init__(self, im, box):
 
         Image.__init__(self)
 
-        x0, y0, x1, y1 = box
+        # Round to nearest integer, runs int(round(x)) when unpacking
+        x0, y0, x1, y1 = map(int, map(round, box))
+
         if x1 < x0:
             x1 = x0
         if y1 < y0:


Test patch:
diff --git a/Tests/test_image_crop.py b/Tests/test_image_crop.py
--- a/Tests/test_image_crop.py
+++ b/Tests/test_image_crop.py
@@ -52,6 +52,20 @@ def test_negative_crop(self):
         self.assertEqual(len(im.getdata()), 0)
         self.assertRaises(IndexError, lambda: im.getdata()[0])
 
+    def test_crop_float(self):
+        # Check cropping floats are rounded to nearest integer
+        # https://github.com/python-pillow/Pillow/issues/1744
+
+        # Arrange
+        im = Image.new("RGB", (10, 10))
+        self.assertEqual(im.size, (10, 10))
+
+        # Act
+        cropped = im.crop((0.9, 1.1, 4.2, 5.8))
+
+        # Assert
+        self.assertEqual(cropped.size, (3, 5))
+
 
 if __name__ == '__main__':
     unittest.main()
Repository: python-pillow/Pillow

Issue:
Image.save does not work with pathlib.Path objects that represent non-existant files
Using Pillow 3.1.1, I'm running into an issue while trying to use pathlib.Path objects with Image.save. Image.save does not work with pathlib.Path objects that represent non-existant files.

```
>>> from pathlib import Path
>>> from PIL import Image
>>> path_exists = Path('existing_file.jpg')
>>> path_not_exists = Path('non-existant_file.jpg')
>>> test_img = Image.new('RGBA', (100,100))
>>> # no issues with this one
>>> test_img.save(path_exists)
>>> # FileNotFoundError: [Errno 2] No such file or directory: 'non-existant_file.jpg'
>>> test_img.save(path_not_exists)
```



Discussion:
Thanks for reporting this bug. The problem is because the pathlib.Path `resolve` method throws this error if the file does not exist. So rather than performing `str(fp.resolve)`, I think the solution is to use `str(fp)`.

You possibly have more experience in using pathlib than I do. Does this sound like a reasonable plan?


Resolving patch:
diff --git a/PIL/Image.py b/PIL/Image.py
--- a/PIL/Image.py
+++ b/PIL/Image.py
@@ -1636,7 +1636,7 @@ def save(self, fp, format=None, **params):
         elif sys.version_info >= (3, 4):
             from pathlib import Path
             if isinstance(fp, Path):
-                filename = str(fp.resolve())
+                filename = str(fp)
                 open_fp = True
         elif hasattr(fp, "name") and isPath(fp.name):
             # only set the name for metadata purposes


Test patch:
diff --git a/Tests/test_image.py b/Tests/test_image.py
--- a/Tests/test_image.py
+++ b/Tests/test_image.py
@@ -1,6 +1,7 @@
 from helper import unittest, PillowTestCase, hopper
 
 from PIL import Image
+import os
 import sys
 
 
@@ -57,6 +58,11 @@ def test_pathlib(self):
         self.assertEqual(im.mode, "RGB")
         self.assertEqual(im.size, (128, 128))
 
+        temp_file = self.tempfile("temp.jpg")
+        if os.path.exists(temp_file):
+            os.remove(temp_file)
+        im.save(Path(temp_file))
+
     def test_tempfile(self):
         # see #1460, pathlib support breaks tempfile.TemporaryFile on py27
         # Will error out on save on 3.0.0