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

Issue:
JPEG2000 files do not return pixel access object on calling the load() function
### What did you do?

I tried to load pixels of a j2k file but got None instead of the pixel access object.
Same for other jpeg 2000 file extensions like jpk. 
Since `j2k.show()` shows the image perfectly, the problem is only in the load function. 
### What did you expect to happen?

I expected it to return the pixel access object like it does for other file types.
### What actually happened?

the load() function returned None
### What versions of Pillow and Python are you using?

Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32
Pillow 3.3.0

```
j2k = Image.open('./MyImage.j2k')
pix = j2k.load()
assert pix is not None #Assertion fails
```



Discussion:

Resolving patch:
diff --git a/PIL/FpxImagePlugin.py b/PIL/FpxImagePlugin.py
--- a/PIL/FpxImagePlugin.py
+++ b/PIL/FpxImagePlugin.py
@@ -216,7 +216,7 @@ def load(self):
             self.fp = self.ole.openstream(self.stream[:2] +
                                           ["Subimage 0000 Data"])
 
-        ImageFile.ImageFile.load(self)
+        return ImageFile.ImageFile.load(self)
 
 #
 # --------------------------------------------------------------------
diff --git a/PIL/Jpeg2KImagePlugin.py b/PIL/Jpeg2KImagePlugin.py
--- a/PIL/Jpeg2KImagePlugin.py
+++ b/PIL/Jpeg2KImagePlugin.py
@@ -207,7 +207,7 @@ def load(self):
             t3 = (t[3][0], self.reduce, self.layers, t[3][3], t[3][4])
             self.tile = [(t[0], (0, 0) + self.size, t[2], t3)]
 
-        ImageFile.ImageFile.load(self)
+        return ImageFile.ImageFile.load(self)
 
 
 def _accept(prefix):


Test patch:
diff --git a/Tests/test_file_jpeg2k.py b/Tests/test_file_jpeg2k.py
--- a/Tests/test_file_jpeg2k.py
+++ b/Tests/test_file_jpeg2k.py
@@ -34,7 +34,8 @@ def test_sanity(self):
         self.assertRegexpMatches(Image.core.jp2klib_version, '\d+\.\d+\.\d+$')
 
         im = Image.open('Tests/images/test-card-lossless.jp2')
-        im.load()
+        px = im.load()
+        self.assertEqual(px[0,0], (0, 0, 0))
         self.assertEqual(im.mode, 'RGB')
         self.assertEqual(im.size, (640, 480))
         self.assertEqual(im.format, 'JPEG2000')
Repository: python-pillow/Pillow

Issue:
Error when saving TIFF as JPEG with original DPI
Recently upgraded from Pillow 2.9 to Pillow 3.3. After the upgrade, I can no longer save TIFF files as JPEG images with the original DPI. Now it will raise:

TypeError: an integer is required

Unit test that reproduces the problem:

``` python
    def test_save_tiff_with_dpi(self):

        outfile = self.tempfile("temp.tif")

        infile = "Tests/images/hopper.tif"
        im = Image.open(infile)

        im.save(outfile, 'JPEG', dpi=im.info['dpi'])

        reloaded = Image.open(outfile)
        reloaded.load()

        self.assertEqual(im.info['dpi'], reloaded.info['dpi'])
```

It seems the issue is that the TIFF DPI can be floating point, but JPEG can only be saved as integer. Would be nice if DPI was handled consistently. Short of that, it would be nice if the documentation was clear about the type expected for DPI.

This issue is basically the same as [1301](https://github.com/python-pillow/Pillow/issues/1301), except for TIFF instead of BMP.



Discussion:

Resolving patch:
diff --git a/PIL/JpegImagePlugin.py b/PIL/JpegImagePlugin.py
--- a/PIL/JpegImagePlugin.py
+++ b/PIL/JpegImagePlugin.py
@@ -593,7 +593,7 @@ def _save(im, fp, filename):
 
     info = im.encoderinfo
 
-    dpi = info.get("dpi", (0, 0))
+    dpi = [int(round(x)) for x in info.get("dpi", (0, 0))]
 
     quality = info.get("quality", 0)
     subsampling = info.get("subsampling", -1)


Test patch:
diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py
--- a/Tests/test_file_jpeg.py
+++ b/Tests/test_file_jpeg.py
@@ -469,6 +469,19 @@ def test_save_modes_with_warnings(self):
             img = Image.new(mode, (20, 20))
             self.assert_warning(DeprecationWarning, img.save, out, "JPEG")
 
+    def test_save_tiff_with_dpi(self):
+        # Arrange
+        outfile = self.tempfile("temp.tif")
+        im = Image.open("Tests/images/hopper.tif")
+
+        # Act
+        im.save(outfile, 'JPEG', dpi=im.info['dpi'])
+
+        # Assert
+        reloaded = Image.open(outfile)
+        reloaded.load()
+        self.assertEqual(im.info['dpi'], reloaded.info['dpi'])
+
 
 if __name__ == '__main__':
     unittest.main()
Repository: python-pillow/Pillow

Issue:
unintuitive save properties
> **progressive**
> If present, indicates that this image should be stored as a progressive JPEG file.

It is not completely obvious that `progressive = False` evaluates to it being set. I guess it's difficult to change this whilst keeping backwards compatibility. (I doubt someone passes `progressive = False` with the intention to enable it.)



Discussion:

Resolving patch:
diff --git a/PIL/JpegImagePlugin.py b/PIL/JpegImagePlugin.py
--- a/PIL/JpegImagePlugin.py
+++ b/PIL/JpegImagePlugin.py
@@ -682,13 +682,16 @@ def validate_qtables(qtables):
                       o8(len(markers)) + marker)
             i += 1
 
+    # "progressive" is the official name, but older documentation
+    # says "progression"
+    # FIXME: issue a warning if the wrong form is used (post-1.1.7)
+    progressive = info.get("progressive", False) or\
+                  info.get("progression", False)
+
     # get keyword arguments
     im.encoderconfig = (
         quality,
-        # "progressive" is the official name, but older documentation
-        # says "progression"
-        # FIXME: issue a warning if the wrong form is used (post-1.1.7)
-        "progressive" in info or "progression" in info,
+        progressive,
         info.get("smooth", 0),
         "optimize" in info,
         info.get("streamtype", 0),
@@ -704,7 +707,7 @@ def validate_qtables(qtables):
     # channels*size, this is a value that's been used in a django patch.
     # https://github.com/matthewwithanm/django-imagekit/issues/50
     bufsize = 0
-    if "optimize" in info or "progressive" in info or "progression" in info:
+    if "optimize" in info or progressive:
         # keep sets quality to 0, but the actual value may be high.
         if quality >= 95 or quality == 0:
             bufsize = 2 * im.size[0] * im.size[1]


Test patch:
diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py
--- a/Tests/test_file_jpeg.py
+++ b/Tests/test_file_jpeg.py
@@ -227,12 +227,20 @@ def test_exif_gps_typeerror(self):
 
     def test_progressive_compat(self):
         im1 = self.roundtrip(hopper())
+        self.assertFalse(im1.info.get("progressive"))
+        self.assertFalse(im1.info.get("progression"))
+
+        im2 = self.roundtrip(hopper(), progressive=0)
+        im3 = self.roundtrip(hopper(), progression=0)  # compatibility
+        self.assertFalse(im2.info.get("progressive"))
+        self.assertFalse(im2.info.get("progression"))
+        self.assertFalse(im3.info.get("progressive"))
+        self.assertFalse(im3.info.get("progression"))
+
         im2 = self.roundtrip(hopper(), progressive=1)
         im3 = self.roundtrip(hopper(), progression=1)  # compatibility
         self.assert_image_equal(im1, im2)
         self.assert_image_equal(im1, im3)
-        self.assertFalse(im1.info.get("progressive"))
-        self.assertFalse(im1.info.get("progression"))
         self.assertTrue(im2.info.get("progressive"))
         self.assertTrue(im2.info.get("progression"))
         self.assertTrue(im3.info.get("progressive"))
Repository: python-pillow/Pillow

Issue:
Image.paste box=None doesn't work as documented
The docs say that box having a value of `None` is "same as (0, 0)".  But [the code clearly shows](https://github.com/python-pillow/Pillow/blob/master/PIL/Image.py#L1311) that it's actually equal to (0, 0, self.size[0], self.size[1]).

The difference is an exception occurs if the image being pasted in (the one in the first argument) is not the same size as the destination image.  If instead you pass `box=(0, 0)`, you don't get an exception when the pasted image is a different size as it's just pasted at the top left regardless of it's size.

```
img = Image.new(
    mode='RGBA',
    size=(100, 100),
    color=(255,255,255,0)
)

small_img = Image.new(
    mode='RGBA',
    size=(50, 50),
    color=(255,255,255,0)
)

img.paste(small_img, box=(0,0))  #  this works fine
img.paste(small_img)  # this throws an exception
```

It looks like it's safe to just change:
```
    if box is None:
        # cover all of self
        box = (0, 0) + self.size
```
into:
```
    if box is None:
        box = (0, 0)
```



Discussion:

Resolving patch:
diff --git a/PIL/Image.py b/PIL/Image.py
--- a/PIL/Image.py
+++ b/PIL/Image.py
@@ -1307,8 +1307,7 @@ def paste(self, im, box=None, mask=None):
             box = None
 
         if box is None:
-            # cover all of self
-            box = (0, 0) + self.size
+            box = (0, 0)
 
         if len(box) == 2:
             # upper left corner given; get size from image or mask
@@ -1321,7 +1320,7 @@ def paste(self, im, box=None, mask=None):
                 raise ValueError(
                     "cannot determine region size; use 4-item box"
                     )
-            box = box + (box[0]+size[0], box[1]+size[1])
+            box += (box[0]+size[0], box[1]+size[1])
 
         if isStringType(im):
             from PIL import ImageColor


Test patch:
diff --git a/Tests/test_image_paste.py b/Tests/test_image_paste.py
--- a/Tests/test_image_paste.py
+++ b/Tests/test_image_paste.py
@@ -251,6 +251,13 @@ def test_color_mask_RGBa(self):
                 (126, 63, 255, 63)
             ])
 
+    def test_different_sizes(self):
+        im = Image.new('RGB', (100, 100))
+        im2 = Image.new('RGB', (50, 50))
+
+        im.copy().paste(im2)
+        im.copy().paste(im2, (0,0))
+
 
 if __name__ == '__main__':
     unittest.main()
Repository: python-pillow/Pillow

Issue:
Build: Python 3.6 is out
Python 3.6.0 was officially released today and is available on Travis CI. 

https://www.python.org/downloads/release/python-360/



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -763,6 +763,7 @@ def debug_build():
               "Programming Language :: Python :: 3.3",
               "Programming Language :: Python :: 3.4",
               "Programming Language :: Python :: 3.5",
+              "Programming Language :: Python :: 3.6",
               'Programming Language :: Python :: Implementation :: CPython',
               'Programming Language :: Python :: Implementation :: PyPy',
           ],


Test patch:
Repository: python-pillow/Pillow

Issue:
Invalid string escapes
There are a couple of invalid string/byte escapes left in the code (Python 3.6 warn about them)::

./PIL/GimpPaletteFile.py:44: bad string escape 'if re.match(b"\\w+:|#", s):'
./PIL/PngImagePlugin.py:51: bad string escape 'is_cid = re.compile(b"\\w\\w\\w\\w").match'
./PIL/XbmImagePlugin.py:29: bad string escape 'b"\\s*#define[ \\t]+.*_width[ \\t]+(?P<width>[0-9]+)[\\r\\n]+"'
./winbuild/build_dep.py:111: bad string escape '""" + "\\n".join(\'set %s=%%BUILD%%\\%s\' % (k.upper(), v[\'dir\'])'
./winbuild/build.py:19: bad string escape 'ret.append("%s%s%s\\Scripts\\pip.exe install nose" %'
./winbuild/build.py:22: bad string escape 'ret.append("%s%s%s\\Scripts\\pip.exe install unittest2" %'



Discussion:
@nascheme What do you run on Python 3.6 to get these warnings?
It is a little script I wrote:
http://python.ca/nas/python/find_bad_escapes.py
I think ideally we would have a 2to3 like tool that just fixed the source code in-place.
Looks like the PIL/ trio were fixed in PR https://github.com/python-pillow/Pillow/pull/2186, and the build.py:22 one was removed by PR https://github.com/python-pillow/Pillow/pull/2243, leaving:

./winbuild/build_dep.py:111: bad string escape '""" + "\n".join('set %s=%%BUILD%%\%s' % (k.upper(), v['dir'])'
./winbuild/build.py:19: bad string escape 'ret.append("%s%s%s\Scripts\pip.exe install nose" %'

Is this one fixed then?
Just the winbuild scripts are left to fix.  This patch (untested) should fix them.

[pillow-escape.txt](https://github.com/python-pillow/Pillow/files/702451/pillow-escape.txt)


Resolving patch:
diff --git a/winbuild/build.py b/winbuild/build.py
--- a/winbuild/build.py
+++ b/winbuild/build.py
@@ -16,7 +16,7 @@ def setup_vms():
         for arch in ('', X64_EXT):
             ret.append("virtualenv -p c:/Python%s%s/python.exe --clear %s%s%s"
                        % (py, arch, VIRT_BASE, py, arch))
-            ret.append("%s%s%s\Scripts\pip.exe install nose" %
+            ret.append(r"%s%s%s\Scripts\pip.exe install nose" %
                        (VIRT_BASE, py, arch))
     return "\n".join(ret)
 
diff --git a/winbuild/build_dep.py b/winbuild/build_dep.py
--- a/winbuild/build_dep.py
+++ b/winbuild/build_dep.py
@@ -13,6 +13,7 @@ def _relpath(*args):
 def _relbuild(*args):
     return _relpath('build', *args)
 
+
 build_dir = _relpath('build')
 inc_dir = _relpath('depends')
 
@@ -108,7 +109,7 @@ def header():
 set CMAKE="cmake.exe"
 set INCLIB=%~dp0\depends
 set BUILD=%~dp0\build
-""" + "\n".join('set %s=%%BUILD%%\%s' % (k.upper(), v['dir'])
+""" + "\n".join(r'set %s=%%BUILD%%\%s' % (k.upper(), v['dir'])
                 for (k, v) in libs.items() if v['dir'])
 
 


Test patch:
Repository: python-pillow/Pillow

Issue:
cryptic error message when saving to a file without a valid extension
### What did you do?
I tried to save a file with an invalid extension, e. g. ".5"

### What did you expect to happen?
I would expect getting an error message telling me that pillow doesn't know this extension.

### What actually happened?
I got a somewhat cryptic error message:

      File "/usr/local/lib/python3.5/dist-packages/PIL/Image.py", line 1683, in save
        format = EXTENSION[ext]
    KeyError: '.5'`

### What versions of Pillow and Python are you using?
Python 3.5.2 with pillow 3.4.2

```
from PIL import Image
im = Image.open('test.jpg')
im.save('2.5') # error
```

I think this could be easily fixed by adding a `try`/`except` block around line 1718 in Image.py (line number corresponds to the version on github) that re-raises the exception with a clear error message.




Discussion:

Resolving patch:
diff --git a/PIL/Image.py b/PIL/Image.py
--- a/PIL/Image.py
+++ b/PIL/Image.py
@@ -1715,7 +1715,10 @@ def save(self, fp, format=None, **params):
         if not format:
             if ext not in EXTENSION:
                 init()
-            format = EXTENSION[ext]
+            try:
+                format = EXTENSION[ext]
+            except KeyError:
+                raise ValueError('unknown file extension: {}'.format(ext))
 
         if format.upper() not in SAVE:
             init()


Test patch:
diff --git a/Tests/test_image.py b/Tests/test_image.py
--- a/Tests/test_image.py
+++ b/Tests/test_image.py
@@ -87,6 +87,11 @@ def test_tempfile(self):
             reloaded = Image.open(fp)
             self.assert_image_similar(im, reloaded, 20)
 
+    def test_unknown_extension(self):
+        im = hopper()
+        temp_file = self.tempfile("temp.unknown")
+        self.assertRaises(ValueError, lambda: im.save(temp_file))
+
     def test_internals(self):
 
         im = Image.new("L", (100, 100))
Repository: python-pillow/Pillow

Issue:
Image of size zero is not getting initialized
I want an image with zero size. I have a lot of use for it.

```py
>>> from PIL import Image as im
>>> import numpy as np
>>> im.fromarray(np.empty((0, 0), dtype=np.uint8))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/dist-packages/PIL/Image.py", line 2187, in fromarray
    return frombuffer(mode, size, obj, "raw", rawmode, 0, 1)
  File "/usr/local/lib/python3.4/dist-packages/PIL/Image.py", line 2114, in frombuffer
    _check_size(size)
  File "/usr/local/lib/python3.4/dist-packages/PIL/Image.py", line 2001, in _check_size
    raise ValueError("Width and Height must be > 0")
ValueError: Width and Height must be > 0
```

This was working previously. But after this [commit](https://github.com/python-pillow/Pillow/commit/445451c0b9347b50e0f603db33f196e207de470d), in the latest version (i.e. 3.4.2) it is throwing an error.

As @manthey points out in the commit, one can create a zero sized image by cropping an existing one. So this too should be allowed. 

Thanks.


Discussion:

Resolving patch:
diff --git a/PIL/Image.py b/PIL/Image.py
--- a/PIL/Image.py
+++ b/PIL/Image.py
@@ -2036,7 +2036,7 @@ def _check_size(size):
     if len(size) != 2:
         raise ValueError("Size must be a tuple of length 2")
     if size[0] < 0 or size[1] < 0:
-        raise ValueError("Width and Height must be => 0")
+        raise ValueError("Width and height must be >= 0")
 
     return True
 


Test patch:
diff --git a/Tests/test_numpy.py b/Tests/test_numpy.py
--- a/Tests/test_numpy.py
+++ b/Tests/test_numpy.py
@@ -204,6 +204,14 @@ def test_putdata(self):
 
         self.assertEqual(len(im.getdata()), len(arr))
 
+    def test_zero_size(self):
+        # Shouldn't cause floating point exception
+        # See https://github.com/python-pillow/Pillow/issues/2259
+
+        im = Image.fromarray(numpy.empty((0, 0), dtype=numpy.uint8))
+
+        self.assertEqual(im.size, (0, 0))
+
 
 if __name__ == '__main__':
     unittest.main()
Repository: python-pillow/Pillow

Issue:
later commits to PR 2509 broken the compress_level=1 setting
This is a follow-up to #2509 .

Using the same test file from #2508 with current head ( 1.7.6-5795-g82c51e4 / 82c51e4 is )
https://cloud.githubusercontent.com/assets/327203/25754502/be994452-31bf-11e7-85da-9cc7fb2811bd.png

```
from PIL import Image
Image.open("cloud.githubusercontent.com/assets/327203/25754502/be994452-31bf-11e7-85da-9cc7fb2811bd.png").show()
Image.open("cloud.githubusercontent.com/assets/327203/25754502/be994452-31bf-11e7-85da-9cc7fb2811bd.png").save("m.png", compress_level=1)
```

The file size are as follows:
```
-rw-------. 1 Hin-Tak Hin-Tak   28907 May 14 00:59 tmpEYXgFV.PNG
-rw-------. 1 Hin-Tak Hin-Tak   28907 May 14 00:42 tmpud2qIG.PNG
-rw-rw-r--. 1 Hin-Tak Hin-Tak   36127 May 14 00:44 m.png
-rw-rw-r--. 1 Hin-Tak Hin-Tak 36127 May 14 01:00 m.png
```

The original is 29069 bytes. I did test in #2509 that I got the 36127 larger file size for minimum compression, instead of what 1.7.6-5795-g82c51e4 / 82c51e4 is now giving, the 28907 smaller file size.
So some of @wiredfool 's "improvements" broke the minumum compression setting, which I last tested worked in my #2509 series.

Anyway, you should aim at

```
from PIL import Image
Image.open("cloud.githubusercontent.com/assets/327203/25754502/be994452-31bf-11e7-85da-9cc7fb2811bd.png").show()
```

giving a /tmp/tmpPWRSTU.PNG of around 36k, not 28k.

Considered my experience in #2509, I'd prefer to switch off notification for this.



Discussion:

Resolving patch:
diff --git a/PIL/ImageShow.py b/PIL/ImageShow.py
--- a/PIL/ImageShow.py
+++ b/PIL/ImageShow.py
@@ -117,7 +117,7 @@ def get_command(self, file, **options):
 
     class MacViewer(Viewer):
         format = "PNG"
-        options = {'compress-level': 1}
+        options = {'compress_level': 1}
 
         def get_command(self, file, **options):
             # on darwin open returns immediately resulting in the temp
@@ -145,7 +145,7 @@ def which(executable):
 
     class UnixViewer(Viewer):
         format = "PNG"
-        options = {'compress-level': 1}
+        options = {'compress_level': 1}
 
         def show_file(self, file, **options):
             command, executable = self.get_command_ex(file, **options)


Test patch:
Repository: python-pillow/Pillow

Issue:
missing -dBATCH in ghostscript invocation in PIL/EpsImagePlugin.py
Just noticed that you are missing a `-dBATCH` in ghostscript invocation in PIL/EpsImagePlugin.py , from looking at 
https://github.com/python-pillow/Pillow/issues/2545

Without it, ghostscript finishes processing the input arguments and ends in the interactive prompt, and expects more input. This is likely not what you want. It had not caused problems so far since ghostscript gets out of interactive mode anyway on encountering control-d.

BTW, https://github.com/python-pillow/Pillow/issues/2545 is _not_ a ghostscript bug. It is a FreeBSD mispackaging. Building ghostscript from git works correctly.


Discussion:
@HinTak So you'd like it added? Can you send a PR?

Resolving patch:
diff --git a/PIL/EpsImagePlugin.py b/PIL/EpsImagePlugin.py
--- a/PIL/EpsImagePlugin.py
+++ b/PIL/EpsImagePlugin.py
@@ -121,6 +121,7 @@ def Ghostscript(tile, size, fp, scale=1):
                "-q",                         # quiet mode
                "-g%dx%d" % size,             # set output geometry (pixels)
                "-r%fx%f" % res,              # set input DPI (dots per inch)
+               "-dBATCH",                    # exit after processing
                "-dNOPAUSE",                  # don't pause between pages,
                "-dSAFER",                    # safe mode
                "-sDEVICE=ppmraw",            # ppm driver


Test patch:
Repository: python-pillow/Pillow

Issue:
windows pypy/4.2.0
Hoisted from https://github.com/python-pillow/Pillow/issues/2567#issuecomment-312707616

@CTPaHHuK-HEbA commented:

Windows, pypy:
```
  File "C:\Python27\pypy\site-packages\PIL\Image.py", line 63, in <module>
    PILLOW_VERSION))
ImportError: The _imaging extension was built for another version of Pillow or PIL: Core Version: "4.2.0"Pillow Version:  4.2.0
```
'"4.2.0"' != '4.2.0'

----

Apparently the distutils on pypy are different on windows, and we're not testing pypy on appveyor. 

@cgohlke mentioned that the pypy build was non-functional, perhaps this is the reason. 


Discussion:
> @cgohlke mentioned that the pypy build was non-functional, perhaps this is the reason.

Yes, this is the same error I got.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -599,7 +599,7 @@ def build_extensions(self):
         if struct.unpack("h", "\0\1".encode('ascii'))[0] == 1:
             defs.append(("WORDS_BIGENDIAN", None))
 
-        if sys.platform == "win32":
+        if sys.platform == "win32" and not hasattr(sys, 'pypy_version_info'):
             defs.append(("PILLOW_VERSION", '"\\"%s\\""'%PILLOW_VERSION))
         else:
             defs.append(("PILLOW_VERSION", '"%s"'%PILLOW_VERSION))
diff --git a/winbuild/build.py b/winbuild/build.py
--- a/winbuild/build.py
+++ b/winbuild/build.py
@@ -72,6 +72,11 @@ def build_one(py_ver, compiler):
         args['python_path'] = "%PYTHON%"
     else:
         args['python_path'] = "%s%s\\Scripts" % (VIRT_BASE, py_ver)
+
+    args['executable'] = "python.exe"
+    if 'EXECUTABLE' in os.environ:
+        args['executable'] = "%EXECUTABLE%"
+        
     args['py_ver'] = py_ver
     if '34' in py_ver:
         args['tcl_ver'] = '86'
@@ -87,7 +92,7 @@ def build_one(py_ver, compiler):
 
 setlocal
 set LIB=%%LIB%%;C:\Python%(py_ver)s\tcl
-call %(python_path)s\python.exe setup.py %%BLDOPT%%
+call %(python_path)s\%(executable)s setup.py %%BLDOPT%%
 endlocal
 
 endlocal
diff --git a/winbuild/config.py b/winbuild/config.py
--- a/winbuild/config.py
+++ b/winbuild/config.py
@@ -5,6 +5,7 @@
 
 pythons = {  # '26': 7,
            '27': 7,
+           'pypy2': 7,
            # '32': 7,
            '33': 7.1,
            '34': 7.1}


Test patch: