Skip to content
This repository has been archived by the owner on Oct 27, 2021. It is now read-only.

Commit

Permalink
Drop support for Python 2.6
Browse files Browse the repository at this point in the history
* Drop unittest2 requirement
* Use set literals
* Use dict/set comprehension
* Use str.format() automatic numbering
  • Loading branch information
jdufresne authored and wiredfool committed Nov 22, 2016
1 parent 70c2df2 commit dbe9f85
Show file tree
Hide file tree
Showing 23 changed files with 41 additions and 73 deletions.
7 changes: 2 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ python:
- "pypy3"
- 3.5
- 2.7
- 2.6
- "2.7_with_system_site_packages" # For PyQt4
- 3.2
- 3.3
Expand All @@ -24,10 +23,8 @@ install:
- "travis_retry pip install cffi"
- "travis_retry pip install nose"
- "travis_retry pip install check-manifest"
# Pyroma tests sometimes hang on PyPy and Python 2.6; skip for those
- if [ $TRAVIS_PYTHON_VERSION != "pypy" && $TRAVIS_PYTHON_VERSION != "2.6" ]; then travis_retry pip install pyroma; fi

- if [ "$TRAVIS_PYTHON_VERSION" == "2.6" ]; then travis_retry pip install unittest2; fi
# Pyroma tests sometimes hang on PyPy; skip
- if [ $TRAVIS_PYTHON_VERSION != "pypy" ]; then travis_retry pip install pyroma; fi

# Coverage 4.0 doesn't support Python 3.2
- if [ "$TRAVIS_PYTHON_VERSION" == "3.2" ]; then travis_retry pip install coverage==3.7.1; fi
Expand Down
2 changes: 1 addition & 1 deletion PIL/BmpImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def _bitmap(self, header=0, offset=0):
read, seek = self.fp.read, self.fp.seek
if header:
seek(header)
file_info = dict()
file_info = {}
file_info['header_size'] = i32(read(4)) # read bmp header size @offset 14 (this is part of the header size)
file_info['direction'] = -1
# --------------------- If requested, read header at a specific position
Expand Down
2 changes: 1 addition & 1 deletion PIL/IcoImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def sizes(self):
"""
Get a list of all available icon sizes and color depths.
"""
return set((h['width'], h['height']) for h in self.entry)
return {(h['width'], h['height']) for h in self.entry}

def getimage(self, size, bpp=False):
"""
Expand Down
4 changes: 2 additions & 2 deletions PIL/JpegImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ def _fixup(value):
except: pass
return value

return dict((k, _fixup(v)) for k, v in src_dict.items())
return {k: _fixup(v) for k, v in src_dict.items()}


def _getexif(self):
Expand Down Expand Up @@ -488,7 +488,7 @@ def _getmp(self):
rawmpentries = mp[0xB002]
for entrynum in range(0, quant):
unpackedentry = unpack_from(
'{0}LLLHH'.format(endianness), rawmpentries, entrynum * 16)
'{}LLLHH'.format(endianness), rawmpentries, entrynum * 16)
labels = ('Attribute', 'Size', 'DataOffset', 'EntryNo1',
'EntryNo2')
mpentry = dict(zip(labels, unpackedentry))
Expand Down
16 changes: 6 additions & 10 deletions PIL/TiffImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
34677: "tiff_sgilog24",
}

COMPRESSION_INFO_REV = dict((v, k) for (k, v) in COMPRESSION_INFO.items())
COMPRESSION_INFO_REV = {v: k for k, v in COMPRESSION_INFO.items()}

OPEN_INFO = {
# (ByteOrder, PhotoInterpretation, SampleFormat, FillOrder, BitsPerSample,
Expand Down Expand Up @@ -294,11 +294,7 @@ def __init__(self, value, denominator=1):
return

elif denominator == 1:
if sys.hexversion < 0x2070000 and isinstance(value, float):
# python 2.6 is different.
self._val = Fraction.from_float(value)
else:
self._val = Fraction(value)
self._val = Fraction(value)
else:
self._val = Fraction(value, denominator)

Expand Down Expand Up @@ -592,7 +588,7 @@ def _register_basic(idx_fmt_name):
TYPES[idx] = name
size = struct.calcsize("=" + fmt)
_load_dispatch[idx] = size, lambda self, data, legacy_api=True: (
self._unpack("{0}{1}".format(len(data) // size, fmt), data))
self._unpack("{}{}".format(len(data) // size, fmt), data))
_write_dispatch[idx] = lambda self, *values: (
b"".join(self._pack(fmt, value) for value in values))

Expand Down Expand Up @@ -624,7 +620,7 @@ def write_string(self, value):

@_register_loader(5, 8)
def load_rational(self, data, legacy_api=True):
vals = self._unpack("{0}L".format(len(data) // 4), data)
vals = self._unpack("{}L".format(len(data) // 4), data)
combine = lambda a, b: (a, b) if legacy_api else IFDRational(a, b)
return tuple(combine(num, denom)
for num, denom in zip(vals[::2], vals[1::2]))
Expand All @@ -644,7 +640,7 @@ def write_undefined(self, value):

@_register_loader(10, 8)
def load_signed_rational(self, data, legacy_api=True):
vals = self._unpack("{0}l".format(len(data) // 4), data)
vals = self._unpack("{}l".format(len(data) // 4), data)
combine = lambda a, b: (a, b) if legacy_api else IFDRational(a, b)
return tuple(combine(num, denom)
for num, denom in zip(vals[::2], vals[1::2]))
Expand Down Expand Up @@ -1518,7 +1514,7 @@ class AppendingTiffWriter:
# JPEGQTables = 519
# JPEGDCTables = 520
# JPEGACTables = 521
Tags = set((273, 288, 324, 519, 520, 521))
Tags = {273, 288, 324, 519, 520, 521}

def __init__(self, fn, new=False):
if hasattr(fn, 'read'):
Expand Down
14 changes: 7 additions & 7 deletions PIL/TiffTags.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,13 +418,13 @@ def _populate():

# some of these are not in our TAGS_V2 dict and were included from tiff.h

LIBTIFF_CORE = set([255, 256, 257, 258, 259, 262, 263, 266, 274, 277,
278, 280, 281, 340, 341, 282, 283, 284, 286, 287,
296, 297, 321, 320, 338, 32995, 322, 323, 32998,
32996, 339, 32997, 330, 531, 530, 301, 532, 333,
# as above
269 # this has been in our tests forever, and works
])
LIBTIFF_CORE = {255, 256, 257, 258, 259, 262, 263, 266, 274, 277,
278, 280, 281, 340, 341, 282, 283, 284, 286, 287,
296, 297, 321, 320, 338, 32995, 322, 323, 32998,
32996, 339, 32997, 330, 531, 530, 301, 532, 333,
# as above
269 # this has been in our tests forever, and works
}

LIBTIFF_CORE.remove(320) # Array of short, crashes
LIBTIFF_CORE.remove(301) # Array of short, crashes
Expand Down
4 changes: 0 additions & 4 deletions Tests/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ Install::

pip install coverage nose

If you're using Python 2.6, there's one additional dependency::

pip install unittest2

Execution
---------

Expand Down
6 changes: 1 addition & 5 deletions Tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@
import sys
import tempfile
import os

if sys.version_info[:2] <= (2, 6):
import unittest2 as unittest
else:
import unittest
import unittest


class PillowTestCase(unittest.TestCase):
Expand Down
6 changes: 3 additions & 3 deletions Tests/test_file_libtiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,9 @@ def test_additional_metadata(self):

# Get the list of the ones that we should be able to write

core_items = dict((tag, info) for tag, info in [(s, TiffTags.lookup(s)) for s
in TiffTags.LIBTIFF_CORE]
if info.type is not None)
core_items = {tag: info for tag, info in ((s, TiffTags.lookup(s)) for s
in TiffTags.LIBTIFF_CORE)
if info.type is not None}

# Exclude ones that have special meaning
# that we're already testing them
Expand Down
2 changes: 1 addition & 1 deletion Tests/test_file_tiff_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from PIL import Image, TiffImagePlugin, TiffTags
from PIL.TiffImagePlugin import _limit_rational, IFDRational

tag_ids = dict((info.name, info.value) for info in TiffTags.TAGS_V2.values())
tag_ids = {info.name: info.value for info in TiffTags.TAGS_V2.values()}


class TestFileTiffMetadata(PillowTestCase):
Expand Down
9 changes: 1 addition & 8 deletions Tests/test_image_getim.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from helper import unittest, PillowTestCase, hopper, py3
import sys


class TestImageGetIm(PillowTestCase):
Expand All @@ -11,13 +10,7 @@ def test_sanity(self):
if py3:
self.assertIn("PyCapsule", type_repr)

if sys.hexversion < 0x2070000:
# py2.6 x64, windows
target_types = (int, long)
else:
target_types = (int)

self.assertIsInstance(im.im.id, target_types)
self.assertIsInstance(im.im.id, int)


if __name__ == '__main__':
Expand Down
6 changes: 3 additions & 3 deletions Tests/test_image_resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,10 @@ def make_levels_case(self, mode):
def run_levels_case(self, i):
px = i.load()
for y in range(i.size[1]):
used_colors = set(px[x, y][0] for x in range(i.size[0]))
used_colors = {px[x, y][0] for x in range(i.size[0])}
self.assertEqual(256, len(used_colors),
'All colors should present in resized image. '
'Only {0} on {1} line.'.format(len(used_colors), y))
'Only {} on {} line.'.format(len(used_colors), y))

@unittest.skip("current implementation isn't precise enough")
def test_levels_rgba(self):
Expand Down Expand Up @@ -270,7 +270,7 @@ def run_dity_case(self, i, clean_pixel):
for y in range(i.size[1]):
for x in range(i.size[0]):
if px[x, y][-1] != 0 and px[x, y][:-1] != clean_pixel:
message = 'pixel at ({0}, {1}) is differ:\n{2}\n{3}'\
message = 'pixel at ({}, {}) is differ:\n{}\n{}'\
.format(x, y, px[x, y], clean_pixel)
self.assertEqual(px[x, y][:3], clean_pixel, message)

Expand Down
6 changes: 3 additions & 3 deletions Tests/test_image_resize.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ def test_endianness(self):
for f in [Image.LINEAR, Image.BOX, Image.BILINEAR, Image.HAMMING,
Image.BICUBIC, Image.LANCZOS]:
# samples resized with current filter
references = dict(
(name, self.resize(ch, (4, 4), f))
references = {
name: self.resize(ch, (4, 4), f)
for name, ch in samples.items()
)
}

for mode, channels_set in [
('RGB', ('blank', 'filled', 'dirty')),
Expand Down
2 changes: 1 addition & 1 deletion Tests/test_image_toqimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_sanity(self):
self.assertFalse(data.isNull())

# Test saving the file
tempfile = self.tempfile('temp_{0}.png'.format(mode))
tempfile = self.tempfile('temp_{}.png'.format(mode))
data.save(tempfile)


Expand Down
2 changes: 1 addition & 1 deletion Tests/test_image_toqpixmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_sanity(self):
self.assertFalse(data.isNull())

# Test saving the file
tempfile = self.tempfile('temp_{0}.png'.format(mode))
tempfile = self.tempfile('temp_{}.png'.format(mode))
data.save(tempfile)


Expand Down
6 changes: 1 addition & 5 deletions Tests/test_imagewin_pointers.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,7 @@ def serialize_dib(bi, pixels):
memcpy(bp, ctypes.byref(bf), ctypes.sizeof(bf))
memcpy(bp + ctypes.sizeof(bf), ctypes.byref(bi), bi.biSize)
memcpy(bp + bf.bfOffBits, pixels, bi.biSizeImage)
try:
return bytearray(buf)
except ValueError:
# py2.6
return buffer(buf)[:]
return bytearray(buf)

class TestImageWinPointers(PillowTestCase):
def test_pointer(self):
Expand Down
4 changes: 0 additions & 4 deletions _imaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -3073,11 +3073,7 @@ _getattr_id(ImagingObject* self, void* closure)
static PyObject*
_getattr_ptr(ImagingObject* self, void* closure)
{
#if PY_VERSION_HEX >= 0x02070000
return PyCapsule_New(self->image, IMAGING_MAGIC, NULL);
#else
return PyCObject_FromVoidPtrAndDesc(self->image, IMAGING_MAGIC, NULL);
#endif
}

static PyObject*
Expand Down
4 changes: 3 additions & 1 deletion docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ Notes

.. note:: Pillow < 2.0.0 supports Python versions 2.4, 2.5, 2.6, 2.7.

.. note:: Pillow >= 2.0.0 supports Python versions 2.6, 2.7, 3.2, 3.3, 3.4, 3.5
.. note:: Pillow >= 2.0.0 < 3.5.0 supports Python versions 2.6, 2.7, 3.2, 3.3, 3.4, 3.5

.. note:: Pillow >= 3.5.0 supports Python versions 2.7, 3.2, 3.3, 3.4, 3.5

Basic Installation
------------------
Expand Down
2 changes: 1 addition & 1 deletion py3.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Python3 definition file to consistently map the code to Python 2.6 or
Python3 definition file to consistently map the code to Python 2 or
Python 3.
PyInt and PyLong were merged into PyLong in Python 3, so all PyInt functions
Expand Down
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class feature:
features = ['zlib', 'jpeg', 'tiff', 'freetype', 'lcms', 'webp',
'webpmux', 'jpeg2000', 'imagequant']

required = set(['jpeg', 'zlib'])
required = {'jpeg', 'zlib'}

def __init__(self):
for f in self.features:
Expand Down Expand Up @@ -770,7 +770,6 @@ def debug_build():
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
"Topic :: Multimedia :: Graphics :: Viewers",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.2",
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# and then run "tox" from this directory.

[tox]
envlist = py26, py27, py32, py33, py34, py35
envlist = py27, py32, py33, py34, py35

[testenv]
commands =
Expand Down
3 changes: 0 additions & 3 deletions winbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ def setup_vms():
% (py, arch, VIRT_BASE, py, arch))
ret.append("%s%s%s\Scripts\pip.exe install nose" %
(VIRT_BASE, py, arch))
if py == '26':
ret.append("%s%s%s\Scripts\pip.exe install unittest2" %
(VIRT_BASE, py, arch))
return "\n".join(ret)


Expand Down
2 changes: 1 addition & 1 deletion winbuild/get_pythons.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os

if __name__ == '__main__':
for version in ['2.6.6', '2.7.10', '3.2.5', '3.3.5', '3.4.3']:
for version in ['2.7.10', '3.2.5', '3.3.5', '3.4.3']:
for platform in ['', '.amd64']:
for extension in ['', '.asc']:
fetch('https://www.python.org/ftp/python/%s/python-%s%s.msi%s'
Expand Down

0 comments on commit dbe9f85

Please sign in to comment.