Merge branch 'master' into pr_2687

This commit is contained in:
Andrew Murray 2019-02-15 21:12:38 +11:00 committed by GitHub
commit 45752d2a28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
469 changed files with 11195 additions and 4751 deletions

View File

@ -18,9 +18,13 @@ environment:
PIP_DIR: bin PIP_DIR: bin
VENV: YES VENV: YES
- PYTHON: C:/Python27-x64 - PYTHON: C:/Python27-x64
- PYTHON: C:/Python34 - PYTHON: C:/Python37
- PYTHON: C:/Python27 - PYTHON: C:/Python27
- PYTHON: C:/Python34-x64 - PYTHON: C:/Python37-x64
- PYTHON: C:/Python36
- PYTHON: C:/Python36-x64
- PYTHON: C:/Python35
- PYTHON: C:/Python35-x64
- PYTHON: C:/msys64/mingw32 - PYTHON: C:/msys64/mingw32
EXECUTABLE: bin/python3 EXECUTABLE: bin/python3
PIP_DIR: bin PIP_DIR: bin
@ -82,6 +86,9 @@ after_test:
matrix: matrix:
fast_finish: true fast_finish: true
cache:
- '%LOCALAPPDATA%\pip\Cache'
artifacts: artifacts:
- path: pillow\dist\*.egg - path: pillow\dist\*.egg
name: egg name: egg
@ -106,6 +113,7 @@ deploy:
folder: win/$(APPVEYOR_BUILD_NUMBER)/ folder: win/$(APPVEYOR_BUILD_NUMBER)/
artifact: /.*egg|wheel/ artifact: /.*egg|wheel/
on: on:
APPVEYOR_REPO_NAME: python-pillow/Pillow
branch: master branch: master
deploy: YES deploy: YES

9
.codecov.yml Normal file
View File

@ -0,0 +1,9 @@
# Documentation: https://docs.codecov.io/docs/codecov-yaml
codecov:
# Avoid "Missing base report" due to committing CHANGES.rst with "[CI skip]"
# https://github.com/codecov/support/issues/363
# https://docs.codecov.io/v4.3.6/docs/comparing-commits
allow_coverage_offsets: true
comment: off

1
.gitattributes vendored
View File

@ -1,2 +1,3 @@
*.eps binary
*.ppm binary *.ppm binary
*.container binary *.container binary

View File

@ -4,7 +4,7 @@ Bug fixes, feature additions, tests, documentation and more can be contributed v
## Bug fixes, feature additions, etc. ## Bug fixes, feature additions, etc.
Please send a pull request to the master branch. Please include [documentation](https://pillow.readthedocs.io) and [tests](../Tests/README.rst) for new features. Tests or documentation without bug fixes or feature additions are welcome too. Feel free to ask questions [via issues](https://github.com/python-pillow/Pillow/issues/new) or irc://irc.freenode.net#pil Please send a pull request to the master branch. Please include [documentation](https://pillow.readthedocs.io) and [tests](../Tests/README.rst) for new features. Tests or documentation without bug fixes or feature additions are welcome too. Feel free to ask questions [via issues](https://github.com/python-pillow/Pillow/issues/new), [Gitter](https://gitter.im/python-pillow/Pillow) or irc://irc.freenode.net#pil
- Fork the Pillow repository. - Fork the Pillow repository.
- Create a branch from master. - Create a branch from master.
@ -21,7 +21,9 @@ Please send a pull request to the master branch. Please include [documentation](
## Reporting Issues ## Reporting Issues
When reporting issues, please include code that reproduces the issue and whenever possible, an image that demonstrates the issue. The best reproductions are self-contained scripts with minimal dependencies. When reporting issues, please include code that reproduces the issue and whenever possible, an image that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.
The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as plone, Django, or buildout, try to replicate the issue just using Pillow.
### Provide details ### Provide details

View File

@ -4,7 +4,11 @@
### What actually happened? ### What actually happened?
### What versions of Pillow and Python are you using? ### What are your OS, Python and Pillow versions?
* OS:
* Python:
* Pillow:
Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive. Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.

5
.gitignore vendored
View File

@ -32,7 +32,7 @@ htmlcov/
.tox/ .tox/
.coverage .coverage
.cache .cache
nosetests.xml .pytest_cache
coverage.xml coverage.xml
# Test files # Test files
@ -56,6 +56,9 @@ test_images
# Sphinx documentation # Sphinx documentation
docs/_build/ docs/_build/
# viewdoc output
.long-description.html
# Vim cruft # Vim cruft
.*.swp .*.swp

2
.readthedocs.yml Normal file
View File

@ -0,0 +1,2 @@
python:
pip_install: true

View File

@ -1,88 +1,102 @@
dist: xenial
language: python language: python
cache: pip
notifications: notifications:
irc: "chat.freenode.net#pil" irc: "chat.freenode.net#pil"
# Run slow PyPy* first, to give them a headstart and reduce waiting time. # Run fast lint first to get fast feedback.
# Run slow PyPy* next, to give them a headstart and reduce waiting time.
# Run latest 3.x and 2.x next, to get quick compatibility results. # Run latest 3.x and 2.x next, to get quick compatibility results.
# Then run the remainder, with fastest Docker jobs last. # Then run the remainder, with fastest Docker jobs last.
matrix: matrix:
fast_finish: true fast_finish: true
include: include:
- python: "pypy" - python: "3.6"
- python: "pypy3" name: "Lint"
- python: '3.6' env: LINT="true"
- python: "pypy2.7-6.0"
name: "PyPy2 Xenial"
dist: xenial
- python: "pypy3.5-6.0"
name: "PyPy3 Xenial"
dist: xenial
- python: '3.7'
name: "3.7 Xenial"
- python: '2.7' - python: '2.7'
- python: "2.7_with_system_site_packages" # For PyQt4 name: "2.7 Xenial"
- python: '3.5' - python: '2.7'
- python: '3.4' name: "2.7 Trusty"
- python: '3.7-dev'
- env: DOCKER="alpine" DOCKER_TAG="pytest"
- env: DOCKER="arch" DOCKER_TAG="pytest" # contains PyQt5
- env: DOCKER="ubuntu-trusty-x86" DOCKER_TAG="pytest"
- env: DOCKER="ubuntu-xenial-amd64" DOCKER_TAG="pytest"
- env: DOCKER="debian-stretch-x86" DOCKER_TAG="pytest"
- env: DOCKER="centos-6-amd64" DOCKER_TAG="pytest"
- env: DOCKER="centos-7-amd64" DOCKER_TAG="pytest"
- env: DOCKER="amazon-1-amd64" DOCKER_TAG="pytest"
- env: DOCKER="amazon-2-amd64" DOCKER_TAG="pytest"
- env: DOCKER="fedora-26-amd64" DOCKER_TAG="pytest"
- env: DOCKER="fedora-27-amd64" DOCKER_TAG="pytest"
dist: trusty dist: trusty
- python: "2.7_with_system_site_packages" # For PyQt4
sudo: required name: "2.7_with_system_site_packages Xenial"
services: xvfb
- python: "2.7_with_system_site_packages" # For PyQt4
name: "2.7_with_system_site_packages Trusty"
dist: trusty
- python: '3.6'
name: "3.6 Xenial"
- python: '3.6'
name: "3.6 Trusty PYTHONOPTIMIZE=1"
dist: trusty
env: PYTHONOPTIMIZE=1
- python: '3.5'
name: "3.5 Xenial"
- python: '3.5'
name: "3.5 Trusty PYTHONOPTIMIZE=2"
dist: trusty
env: PYTHONOPTIMIZE=2
- python: "3.8-dev"
name: "3.8-dev Xenial"
- env: DOCKER="alpine" DOCKER_TAG="master"
- env: DOCKER="arch" DOCKER_TAG="master" # contains PyQt5
- env: DOCKER="ubuntu-trusty-x86" DOCKER_TAG="master"
- env: DOCKER="ubuntu-xenial-amd64" DOCKER_TAG="master"
- env: DOCKER="debian-stretch-x86" DOCKER_TAG="master"
- env: DOCKER="centos-6-amd64" DOCKER_TAG="master"
- env: DOCKER="centos-7-amd64" DOCKER_TAG="master"
- env: DOCKER="amazon-1-amd64" DOCKER_TAG="master"
- env: DOCKER="amazon-2-amd64" DOCKER_TAG="master"
- env: DOCKER="fedora-28-amd64" DOCKER_TAG="master"
- env: DOCKER="fedora-29-amd64" DOCKER_TAG="master"
services: services:
- docker - docker
install:
- if [ "$DOCKER" == "" ]; then .travis/install.sh; fi
before_install: before_install:
- if [ "$DOCKER" ]; then docker pull pythonpillow/$DOCKER:$DOCKER_TAG; fi - if [ "$DOCKER" ]; then travis_retry docker pull pythonpillow/$DOCKER:$DOCKER_TAG; fi
install:
- |
if [ "$LINT" == "true" ]; then
pip install tox
elif [ "$DOCKER" == "" ]; then
.travis/install.sh;
fi
before_script: before_script:
# Qt needs a display for some of the tests, and it's only run on the system site packages install # Qt needs a display for some of the tests, and it's only run on the system site packages install
- "export DISPLAY=:99.0" - |
- "sh -e /etc/init.d/xvfb start" if [ "$TRAVIS_JOB_NAME" == "2.7_with_system_site_packages Trusty" ]; then
export DISPLAY=:99.0
sh -e /etc/init.d/xvfb start
fi
script: script:
- | - |
if [ "$DOCKER" == "" ]; then if [ "$LINT" == "true" ]; then
tox -e lint
elif [ "$DOCKER" == "" ]; then
.travis/script.sh .travis/script.sh
else elif [ "$DOCKER" ]; then
# the Pillow user in the docker container is UID 1000 # the Pillow user in the docker container is UID 1000
sudo chown -R 1000 $TRAVIS_BUILD_DIR sudo chown -R 1000 $TRAVIS_BUILD_DIR
docker run -v $TRAVIS_BUILD_DIR:/Pillow pythonpillow/$DOCKER:$DOCKER_TAG docker run -v $TRAVIS_BUILD_DIR:/Pillow pythonpillow/$DOCKER:$DOCKER_TAG
fi fi
after_success: after_success:
- .travis/after_success.sh
after_failure:
- | - |
if [ "$TRAVIS_REPO_SLUG" = "python-pillow/Pillow" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" = "false" ]; then if [ "$LINT" == "" ]; then
curl -Lo travis_after_all.py https://raw.github.com/dmakhno/travis_after_all/master/travis_after_all.py .travis/after_success.sh
python travis_after_all.py
export $(cat .to_export_back)
if [ "$BUILD_LEADER" = "YES" ]; then
if [ "$BUILD_AGGREGATE_STATUS" = "others_failed" ]; then
echo "All jobs failed"
else
echo "Some jobs failed"
fi fi
fi
fi
after_script:
- |
if [ "$TRAVIS_REPO_SLUG" = "python-pillow/Pillow" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
echo leader=$BUILD_LEADER status=$BUILD_AGGREGATE_STATUS
fi
env:
global:
# travis encrypt AUTH_TOKEN=
secure: "Vzm7aG1Qv0SDQcqiPzZMedNLn5ZmpL7IzF0DYnqcD+/l+zmKU22SnJBcX0uVXumo+r7eZfpsShpqfcdsZvMlvmQnwz+Y6AGKQru9tCKZbTMnuRjWKKXekC+tr8Xt9CKvRVtte5PyXW31paxUI3/e+fQGBwoFjEEC+6EpEOjeRfE="

View File

@ -15,35 +15,9 @@ pip install coveralls-merge
coveralls-merge coverage.c.json coveralls-merge coverage.c.json
codecov codecov
if [ "$DOCKER" == "" ]; then
pip install pyflakes pycodestyle
pyflakes *.py | tee >(wc -l)
pyflakes src/PIL/*.py | tee >(wc -l)
pyflakes Tests/*.py | tee >(wc -l)
pycodestyle --statistics --count src/PIL/*.py
pycodestyle --statistics --count Tests/*.py
fi
if [ "$TRAVIS_PYTHON_VERSION" == "2.7" ] && [ "$DOCKER" == "" ]; then if [ "$TRAVIS_PYTHON_VERSION" == "2.7" ] && [ "$DOCKER" == "" ]; then
# Coverage and quality reports on just the latest diff. # Coverage and quality reports on just the latest diff.
# (Installation is very slow on Py3, so just do it for Py2.) # (Installation is very slow on Py3, so just do it for Py2.)
depends/diffcover-install.sh depends/diffcover-install.sh
depends/diffcover-run.sh depends/diffcover-run.sh
fi fi
# after_all
if [ "$TRAVIS_REPO_SLUG" = "python-pillow/Pillow" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
curl -Lo travis_after_all.py https://raw.github.com/dmakhno/travis_after_all/master/travis_after_all.py
python travis_after_all.py
export $(cat .to_export_back)
if [ "$BUILD_LEADER" = "YES" ]; then
if [ "$BUILD_AGGREGATE_STATUS" = "others_succeeded" ]; then
echo "All jobs succeeded! Triggering macOS build..."
# Trigger a macOS build at the pillow-wheels repo
./build_children.sh
else
echo "Some jobs failed"
fi
fi
fi

View File

@ -7,7 +7,7 @@ sudo apt-get -qq install libfreetype6-dev liblcms2-dev python-tk\
python-qt4 ghostscript libffi-dev libjpeg-turbo-progs cmake imagemagick\ python-qt4 ghostscript libffi-dev libjpeg-turbo-progs cmake imagemagick\
libharfbuzz-dev libfribidi-dev libharfbuzz-dev libfribidi-dev
pip install cffi PYTHONOPTIMIZE=0 pip install cffi
pip install check-manifest pip install check-manifest
pip install coverage pip install coverage
pip install olefile pip install olefile
@ -15,6 +15,7 @@ pip install -U pytest
pip install -U pytest-cov pip install -U pytest-cov
pip install pyroma pip install pyroma
pip install test-image-results pip install test-image-results
pip install numpy
# docs only on Python 2.7 # docs only on Python 2.7
if [ "$TRAVIS_PYTHON_VERSION" == "2.7" ]; then pip install -r requirements.txt ; fi if [ "$TRAVIS_PYTHON_VERSION" == "2.7" ]; then pip install -r requirements.txt ; fi

View File

@ -2,12 +2,516 @@
Changelog (Pillow) Changelog (Pillow)
================== ==================
5.1.0 (unreleased) 6.0.0 (unreleased)
------------------ ------------------
- Remove unnecessary unittest.main() boilerplate from test files #3631
[jdufresne]
- Exif: Seek to IFD offset #3584
[radarhere]
- Deprecate PIL.*ImagePlugin.__version__ attributes #3628
[jdufresne]
- Docs: Add note about ImageDraw operations that exceed image bounds #3620
[radarhere]
- Allow for unknown PNG chunks after image data #3558
[radarhere]
- Changed EPS subprocess stdin from devnull to None #3611
[radarhere]
- Fix possible integer overflow #3609
[cgohlke]
- Catch BaseException for resource cleanup handlers #3574
[jdufresne]
- Improve pytest configuration to allow specific tests as CLI args #3579
[jdufresne]
- Drop support for Python 3.4 #3596
[hugovk]
- Remove deprecated PIL.OleFileIO #3598
[hugovk]
- Remove deprecated ImageOps undocumented functions #3599
[hugovk]
- Depends: Update libwebp to 1.0.2 #3602
[radarhere]
- Detect MIME types #3525
[radarhere]
5.4.1 (2019-01-06)
------------------
- File closing: Only close __fp if not fp #3540
[radarhere]
- Fix build for Termux #3529
[pslacerda]
- PNG: Detect MIME types #3525
[radarhere]
- PNG: Handle IDAT chunks after image end #3532
[radarhere]
5.4.0 (2019-01-01)
------------------
- Docs: Improved ImageChops documentation #3522
[radarhere]
- Allow RGB and RGBA values for P image putpixel #3519
[radarhere]
- Add APNG extension to PNG plugin #3501
[pirate486743186, radarhere]
- Lookup ld.so.cache instead of hardcoding search paths #3245
[pslacerda]
- Added custom string TIFF tags #3513
[radarhere]
- Improve setup.py configuration #3395
[diorcety]
- Read textual chunks located after IDAT chunks for PNG #3506
[radarhere]
- Performance: Don't try to hash value if enum is empty #3503
[Glandos]
- Added custom int and float TIFF tags #3350
[radarhere]
- Fixes for issues reported by static code analysis #3393
[frenzymadness]
- GIF: Wait until mode is normalized to copy im.info into encoderinfo #3187
[radarhere]
- Docs: Add page of deprecations and removals #3486
[hugovk]
- Travis CI: Upgrade PyPy from 5.8.0 to 6.0 #3488
[hugovk]
- Travis CI: Allow lint job to fail #3467
[hugovk]
- Resolve __fp when closing and deleting #3261
[radarhere]
- Close exclusive fp before discarding #3461
[radarhere]
- Updated open files documentation #3490
[radarhere]
- Added libjpeg_turbo to check_feature #3493
[radarhere]
- Change color table index background to tuple when saving as WebP #3471
[radarhere]
- Allow arbitrary number of comment extension subblocks #3479
[radarhere]
- Ensure previous FLI frame is loaded before seeking to the next #3478
[radarhere]
- ImageShow improvements #3450
[radarhere]
- Depends: Update libimagequant to 2.12.2 #3442, libtiff to 4.0.10 #3458, libwebp to 1.0.1 #3468, Tk Tcl to 8.6.9 #3465
[radarhere]
- Check quality_layers type #3464
[radarhere]
- Add context manager, __del__ and close methods to TarIO #3455
[radarhere]
- Test: Do not play sound when running screencapture command #3454
[radarhere]
- Close exclusive fp on open exception #3456
[radarhere]
- Only close existing fp in WebP if fp is exclusive #3418
[radarhere]
- Docs: Re-add the downloads badge #3443
[hugovk]
- Added negative index to PixelAccess #3406
[Nazime]
- Change tuple background to global color table index when saving as GIF #3385
[radarhere]
- Test: Improved ImageGrab tests #3424
[radarhere]
- Flake8 fixes #3422, #3440
[radarhere, hugovk]
- Only ask for YCbCr->RGB libtiff conversion for jpeg-compressed tiffs #3417
[kkopachev]
- Optimise ImageOps.fit by combining resize and crop #3409
[homm]
5.3.0 (2018-10-01)
------------------
- Changed Image size property to be read-only by default #3203
[radarhere]
- Add warnings if image file identification fails due to lack of WebP support #3169
[radarhere, hugovk]
- Hide the Ghostscript progress dialog popup on Windows #3378
[hugovk]
- Adding support to reading tiled and YcbCr jpeg tiffs through libtiff #3227
[kkopachev]
- Fixed None as TIFF compression argument #3310
[radarhere]
- Changed GIF seek to remove previous info items #3324
[radarhere]
- Improved PDF document info #3274
[radarhere]
- Add line width parameter to rectangle and ellipse-based shapes #3094
[hugovk, radarhere]
- Fixed decompression bomb check in _crop #3313
[dinkolubina, hugovk]
- Added support to ImageDraw.floodfill for non-RGB colors #3377
[radarhere]
- Tests: Avoid catching unexpected exceptions in tests #2203
[jdufresne]
- Use TextIOWrapper.detach() instead of NoCloseStream #2214
[jdufresne]
- Added transparency to matrix conversion #3205
[radarhere]
- Added ImageOps pad method #3364
[radarhere]
- Give correct extrema for I;16 format images #3359
[bz2]
- Added PySide2 #3279
[radarhere]
- Corrected TIFF tags #3369
[radarhere]
- CI: Install CFFI and pycparser without any PYTHONOPTIMIZE #3374
[hugovk]
- Read/Save RGB webp as RGB (instead of RGBX) #3298
[kkopachev]
- ImageDraw: Add line joints #3250
[radarhere]
- Improved performance of ImageDraw floodfill method #3294
[yo1995]
- Fix builds with --parallel #3272
[hsoft]
- Add more raw Tiff modes (RGBaX, RGBaXX, RGBAX, RGBAXX) #3335
[homm]
- Close existing WebP fp before setting new fp #3341
[radarhere]
- Add orientation, compression and id_section as TGA save keyword arguments #3327
[radarhere]
- Convert int values of RATIONAL TIFF tags to floats #3338
[radarhere, wiredfool]
- Fix code for PYTHONOPTIMIZE #3233
[hugovk]
- Changed ImageFilter.Kernel to subclass ImageFilter.BuiltinFilter, instead of the other way around #3273
[radarhere]
- Remove unused draw.draw_line, draw.draw_point and font.getabc methods #3232
[hugovk]
- Tests: Added ImageFilter tests #3295
[radarhere]
- Tests: Added ImageChops tests #3230
[hugovk, radarhere]
- AppVeyor: Download lib if not present in pillow-depends #3316
[radarhere]
- Travis CI: Add Python 3.7 and Xenial #3234
[hugovk]
- Docs: Added documentation for NumPy conversion #3301
[radarhere]
- Depends: Update libimagequant to 2.12.1 #3281
[radarhere]
- Add three-color support to ImageOps.colorize #3242
[tsennott]
- Tests: Add LA to TGA test modes #3222
[danpla]
- Skip outline if the draw operation fills with the same colour #2922
[radarhere]
- Flake8 fixes #3173, #3380
[radarhere]
- Avoid deprecated 'U' mode when opening files #2187
[jdufresne]
5.2.0 (2018-07-01)
------------------
- Fixed saving a multiframe image as a single frame PDF #3137
[radarhere]
- If a Qt version is already imported, attempt to use it first #3143
[radarhere]
- Fix transform fill color for alpha images #3147
[fozcode]
- TGA: Add support for writing RLE data #3186
[danpla]
- TGA: Read and write LA data #3178
[danpla]
- QuantOctree.c: Remove erroneous attempt to average over an empty range #3196
[tkoeppe]
- Changed ICNS format tests to pass on OS X 10.11 #3202
[radarhere]
- Fixed bug in ImageDraw.multiline_textsize() #3114
[tianyu139]
- Added getsize_multiline support for PIL.ImageFont #3113
[tianyu139]
- Added ImageFile get_format_mimetype method #3190
[radarhere]
- Changed mmap file pointer to use context manager #3216
[radarhere]
- Changed ellipse point calculations to be more evenly distributed #3142
[radarhere]
- Only extract first Exif segment #2946
[hugovk]
- Tests: Test ImageDraw2, WalImageFile #3135, #2989
[hugovk]
- Remove unnecessary '#if 0' code #3075
[hugovk]
- Tests: Added GD tests #1817
[radarhere]
- Fix collections ABCs DeprecationWarning in Python 3.7 #3123
[hugovk]
- unpack_from is faster than unpack of slice #3201
[landfillbaby]
- Docs: Add coordinate system links and file handling links in documentation #3204, #3214
[radarhere]
- Tests: TestFilePng: Fix test_save_l_transparency() #3182
[danpla]
- Docs: Correct argument name #3171
[radarhere]
- Docs: Update CMake download URL #3166
[radarhere]
- Docs: Improve Image.transform documentation #3164
[radarhere]
- Fix transform fillcolor argument when image mode is RGBA or LA #3163
[radarhere]
- Tests: More specific Exception testing #3158
[radarhere]
- Add getrgb HSB/HSV color strings #3148
[radarhere]
- Allow float values in getrgb HSL color string #3146
[radarhere]
- AppVeyor: Upgrade to Python 2.7.15 and 3.4.4 #3140
[radarhere]
- AppVeyor: Upgrade to PyPy 6.0.0 #3133
[hugovk]
- Deprecate PILLOW_VERSION and VERSION #3090
[hugovk]
- Support Python 3.7 #3076
[hugovk]
- Depends: Update freetype to 2.9.1, libjpeg to 9c, libwebp to 1.0.0 #3121, #3136, #3108
[radarhere]
- Build macOS wheels with Xcode 6.4, supporting older macOS versions #3068
[wiredfool]
- Fix _i2f compilation on some GCC versions #3067
[homm]
- Changed encoderinfo to have priority over info when saving GIF images #3086
[radarhere]
- Rename PIL.version to PIL._version and remove it from module #3083
[homm]
- Enable background colour parameter on rotate #3057
[storesource]
- Remove unnecessary `#if 1` directive #3072
[jdufresne]
- Remove unused Python class, Path #3070
[jdufresne]
- Fix dereferencing type-punned pointer will break strict-aliasing #3069
[jdufresne]
5.1.0 (2018-04-02)
------------------
- Close fp before return in ImagingSavePPM #3061
[kathryndavies]
- Added documentation for ICNS append_images #3051
[radarhere]
- Docs: Move intro text below its header #3021
[hugovk]
- CI: Rename appveyor.yml as .appveyor.yml #2978
[hugovk]
- Fix TypeError for JPEG2000 parser feed #3042
[hugovk]
- Certain corrupted jpegs can result in no data read #3023
[kkopachev]
- Add support for BLP file format #3007
[jleclanche]
- Simplify version checks #2998
[hugovk]
- Fix "invalid escape sequence" warning on Python 3.6+ #2996
[timgraham]
- Allow append_images to set .icns scaled images #3005
[radarhere]
- Support appending to existing PDFs #2965
[vashek]
- Fix and improve efficient saving of ICNS on macOS #3004
[radarhere]
- Build: Enable pip cache in AppVeyor build #3009
[thijstriemstra]
- Trim trailing whitespace #2985
[Metallicow]
- Docs: Correct reference to Image.new method #3000
[radarhere]
- Rearrange ImageFilter classes into alphabetical order #2990
[radarhere]
- Test: Remove duplicate line #2983
[radarhere]
- Build: Update AppVeyor PyPy version #3003
[radarhere]
- Tiff: Open 8 bit Tiffs with 5 or 6 channels, discarding extra channels #2938
[homm]
- Readme: Added Twitter badge #2930
[hugovk]
- Removed __main__ code from ImageCms #2942
[radarhere]
- Test: Changed assert statements to unittest calls #2961
[radarhere]
- Depends: Update libimagequant to 2.11.10, raqm to 0.5.0, freetype to 2.9 #3036, #3017, #2957
[radarhere]
- Remove _imaging.crc32 in favor of builtin Python crc32 implementation #2935
[wiredfool]
- Move Tk directory to src directory #2928
[hugovk]
- Enable pip cache in Travis CI #2933
[jdufresne]
- Remove unused and duplicate imports #2927
[radarhere]
- Docs: Changed documentation references to 2.x to 2.7 #2921 - Docs: Changed documentation references to 2.x to 2.7 #2921
[radarhere] [radarhere]
- Fix memory leak when opening webp files #2974
[wiredfool]
- Setup: Fix "TypeError: 'NoneType' object is not iterable" for PPC and CRUX #2951
[hugovk]
- Setup: Add libdirs for ppc64le and armv7l #2968
[nehaljwani]
5.0.0 (2018-01-01) 5.0.0 (2018-01-01)
------------------ ------------------
@ -89,7 +593,7 @@ Changelog (Pillow)
- Add eog support for Ubuntu Image Viewer #2864 - Add eog support for Ubuntu Image Viewer #2864
[NafisFaysal] [NafisFaysal]
- Test: Test on 3.7-dev on Travis.ci #2870 - Test: Test on 3.7-dev on Travis CI #2870
[hugovk] [hugovk]
- Dependencies: Update libtiff to 4.0.9 #2871 - Dependencies: Update libtiff to 4.0.9 #2871
@ -128,7 +632,7 @@ Changelog (Pillow)
- GIF: Permit LZW code lengths up to 12 bits in GIF decode #2813 - GIF: Permit LZW code lengths up to 12 bits in GIF decode #2813
[wiredfool] [wiredfool]
- Fix unterminiated string and unchecked exception in _font_text_asBytes. #2825 - Fix unterminated string and unchecked exception in _font_text_asBytes. #2825
[wiredfool] [wiredfool]
- PPM: Use fixed list of whitespace, rather relying on locale, fixes #272. #2831 - PPM: Use fixed list of whitespace, rather relying on locale, fixes #272. #2831
@ -218,7 +722,7 @@ Changelog (Pillow)
- Fixed doc syntax in ImageDraw #2752 - Fixed doc syntax in ImageDraw #2752
[radarhere] [radarhere]
- Fixed support for building on Windows/msys2. Added Appveyor CI coverage for python3 on msys2 #2476 - Fixed support for building on Windows/msys2. Added Appveyor CI coverage for python3 on msys2 #2746
[wiredfool] [wiredfool]
- Fix ValueError in Exif/Tiff IFD #2719 - Fix ValueError in Exif/Tiff IFD #2719
@ -290,7 +794,7 @@ Changelog (Pillow)
- Use RGBX rawmode for RGB JPEG images where possible #1989 - Use RGBX rawmode for RGB JPEG images where possible #1989
[homm] [homm]
- Remove palettes from non-palette modes in _new #2702 - Remove palettes from non-palette modes in _new #2704
[wiredfool] [wiredfool]
- Delete transparency info when convert'ing RGB/L to RGBA #2633 - Delete transparency info when convert'ing RGB/L to RGBA #2633
@ -581,7 +1085,7 @@ Changelog (Pillow)
- Doc: Reordered operating systems in Compatibility Matrix #2436 - Doc: Reordered operating systems in Compatibility Matrix #2436
[radarhere] [radarhere]
- Test: Additional tests for BurfStub, Eps, Container, GribStub, IPTC, Wmf, XVThumb, ImageDraw, ImageMorph ImageShow #2425 - Test: Additional tests for BufrStub, Eps, Container, GribStub, IPTC, Wmf, XVThumb, ImageDraw, ImageMorph, ImageShow #2425
[radarhere] [radarhere]
- Health fixes #2437 - Health fixes #2437
@ -713,10 +1217,10 @@ Changelog (Pillow)
- Add center and translate option to Image.rotate. #2328 - Add center and translate option to Image.rotate. #2328
[lambdafu] [lambdafu]
- Test: Relax WMF test condition, fixes #2323 - Test: Relax WMF test condition, fixes #2323. #2327
[wiredfool] [wiredfool]
- Allow 0 size images, Fixes #2259, Reverts to pre-3.4 behavior. - Allow 0 size images, Fixes #2259, Reverts to pre-3.4 behavior. #2262
[wiredfool] [wiredfool]
- SGI: Save uncompressed SGI/BW/RGB/RGBA files #2325 - SGI: Save uncompressed SGI/BW/RGB/RGBA files #2325
@ -1047,10 +1551,10 @@ Changelog (Pillow)
3.3.2 (2016-10-03) 3.3.2 (2016-10-03)
------------------ ------------------
- Fix negative image sizes in Storage.c #2105 - Fix negative image sizes in Storage.c #2146
[wiredfool] [wiredfool]
- Fix integer overflow in map.c #2105 - Fix integer overflow in map.c #2146
[wiredfool] [wiredfool]
3.3.1 (2016-08-18) 3.3.1 (2016-08-18)
@ -1188,7 +1692,7 @@ Changelog (Pillow)
- Skip tests that require libtiff if it is not installed #1893 (fixes #1866) - Skip tests that require libtiff if it is not installed #1893 (fixes #1866)
[wiredfool] [wiredfool]
- Skip test when icc profile is not available, fixes #1887 - Skip test when icc profile is not available, fixes #1887. #1892
[doko42] [doko42]
- Make deprecated functions raise NotImplementedError instead of Exception. #1862, #1890 - Make deprecated functions raise NotImplementedError instead of Exception. #1862, #1890
@ -1793,7 +2297,7 @@ Changelog (Pillow)
2.8.1 (2015-04-02) 2.8.1 (2015-04-02)
------------------ ------------------
- Bug fix: Catch struct.error on invalid JPEG, fixes #1163 - Bug fix: Catch struct.error on invalid JPEG, fixes #1163. #1165
[wiredfool, hugovk] [wiredfool, hugovk]
2.8.0 (2015-04-01) 2.8.0 (2015-04-01)
@ -1928,7 +2432,7 @@ Changelog (Pillow)
- Updated manifest #957 - Updated manifest #957
[wiredfool] [wiredfool]
- Fix PyPy 2.4 regression #952 - Fix PyPy 2.4 regression #958
[wiredfool] [wiredfool]
- Webp Metadata Skip Test comments #954 - Webp Metadata Skip Test comments #954
@ -1970,7 +2474,7 @@ Changelog (Pillow)
- Use redistributable ICC profiles for testing, skip if not available #923 - Use redistributable ICC profiles for testing, skip if not available #923
[wiredfool] [wiredfool]
- Additional documentation for JPEG info and save options #890 - Additional documentation for JPEG info and save options #922
[wiredfool] [wiredfool]
- Fix JPEG Encoding memory leak when exif or qtables were specified #921 - Fix JPEG Encoding memory leak when exif or qtables were specified #921
@ -3538,7 +4042,7 @@ Pre-fork
(1.1.3 final released) (1.1.3 final released)
+ Made setup.py look for old versions of zlib. For some back- + Made setup.py look for old versions of zlib. For some back-
ground, see: http://www.gzip.org/zlib/advisory-2002-03-11.txt ground, see: https://zlib.net/advisory-2002-03-11.txt
(1.1.3c2 released) (1.1.3c2 released)

View File

@ -5,7 +5,7 @@ The Python Imaging Library (PIL) is
Pillow is the friendly PIL fork. It is Pillow is the friendly PIL fork. It is
Copyright © 2010-2018 by Alex Clark and contributors Copyright © 2010-2019 by Alex Clark and contributors
Like PIL, Pillow is licensed under the open source PIL Software License: Like PIL, Pillow is licensed under the open source PIL Software License:

View File

@ -11,21 +11,20 @@ include LICENSE
include Makefile include Makefile
graft Tests graft Tests
graft src graft src
graft Tk
graft depends graft depends
graft winbuild graft winbuild
graft docs graft docs
prune docs/_static prune docs/_static
# build/src control detritus # build/src control detritus
exclude .appveyor.yml
exclude .coveragerc exclude .coveragerc
exclude codecov.yml exclude .codecov.yml
exclude .editorconfig exclude .editorconfig
exclude .landscape.yaml exclude .landscape.yaml
exclude .readthedocs.yml
exclude .travis exclude .travis
exclude .travis/* exclude .travis/*
exclude appveyor.yml
exclude build_children.sh
exclude tox.ini exclude tox.ini
global-exclude .git* global-exclude .git*
global-exclude *.pyc global-exclude *.pyc

View File

@ -94,7 +94,7 @@ test:
typecheck: typecheck:
mypy --ignore-missing-imports -2 src/PIL/Image.py mypy --ignore-missing-imports -2 src/PIL/Image.py
# https://docs.python.org/2/distutils/packageindex.html#the-pypirc-file # https://docs.python.org/3/distutils/packageindex.html#the-pypirc-file
upload-test: upload-test:
# [test] # [test]
# username: # username:

View File

@ -14,11 +14,11 @@ Pillow is the friendly PIL fork by `Alex Clark and Contributors <https://github.
* - docs * - docs
- |docs| - |docs|
* - tests * - tests
- | |linux| |macos| |windows| |coverage| - |linux| |macos| |windows| |coverage|
* - package * - package
- |zenodo| |version| - |zenodo| |tidelift| |version| |downloads|
* - chat * - social
- |gitter| - |gitter| |twitter|
.. |docs| image:: https://readthedocs.org/projects/pillow/badge/?version=latest .. |docs| image:: https://readthedocs.org/projects/pillow/badge/?version=latest
:target: https://pillow.readthedocs.io/?badge=latest :target: https://pillow.readthedocs.io/?badge=latest
@ -28,7 +28,7 @@ Pillow is the friendly PIL fork by `Alex Clark and Contributors <https://github.
:target: https://travis-ci.org/python-pillow/Pillow :target: https://travis-ci.org/python-pillow/Pillow
:alt: Travis CI build status (Linux) :alt: Travis CI build status (Linux)
.. |macos| image:: https://img.shields.io/travis/python-pillow/pillow-wheels/latest.svg?label=macOS%20build .. |macos| image:: https://img.shields.io/travis/python-pillow/pillow-wheels/master.svg?label=macOS%20build
:target: https://travis-ci.org/python-pillow/pillow-wheels :target: https://travis-ci.org/python-pillow/pillow-wheels
:alt: Travis CI build status (macOS) :alt: Travis CI build status (macOS)
@ -43,14 +43,25 @@ Pillow is the friendly PIL fork by `Alex Clark and Contributors <https://github.
.. |zenodo| image:: https://zenodo.org/badge/17549/python-pillow/Pillow.svg .. |zenodo| image:: https://zenodo.org/badge/17549/python-pillow/Pillow.svg
:target: https://zenodo.org/badge/latestdoi/17549/python-pillow/Pillow :target: https://zenodo.org/badge/latestdoi/17549/python-pillow/Pillow
.. |tidelift| image:: https://tidelift.com/badges/github/python-pillow/Pillow?style=flat
:target: https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=referral&utm_campaign=readme
.. |version| image:: https://img.shields.io/pypi/v/pillow.svg .. |version| image:: https://img.shields.io/pypi/v/pillow.svg
:target: https://pypi.python.org/pypi/Pillow/ :target: https://pypi.org/project/Pillow/
:alt: Latest PyPI version :alt: Latest PyPI version
.. |downloads| image:: https://img.shields.io/pypi/dm/pillow.svg
:target: https://pypi.org/project/Pillow/
:alt: Number of PyPI downloads
.. |gitter| image:: https://badges.gitter.im/python-pillow/Pillow.svg .. |gitter| image:: https://badges.gitter.im/python-pillow/Pillow.svg
:target: https://gitter.im/python-pillow/Pillow?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge :target: https://gitter.im/python-pillow/Pillow?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
:alt: Join the chat at https://gitter.im/python-pillow/Pillow :alt: Join the chat at https://gitter.im/python-pillow/Pillow
.. |twitter| image:: https://img.shields.io/badge/tweet-on%20Twitter-00aced.svg
:target: https://twitter.com/PythonPillow
:alt: Follow on https://twitter.com/PythonPillow
.. end-badges .. end-badges

View File

@ -4,52 +4,54 @@
Released quarterly on the first day of January, April, July, October. Released quarterly on the first day of January, April, July, October.
* [ ] Open a release ticket e.g. https://github.com/python-pillow/Pillow/issues/1174 * [ ] Open a release ticket e.g. https://github.com/python-pillow/Pillow/issues/3154
* [ ] Develop and prepare release in ``master`` branch. * [ ] Develop and prepare release in `master` branch.
* [ ] Check [Travis CI](https://travis-ci.org/python-pillow/Pillow) and [AppVeyor CI](https://ci.appveyor.com/project/python-pillow/Pillow) to confirm passing tests in ``master`` branch. * [ ] Check [Travis CI](https://travis-ci.org/python-pillow/Pillow) and [AppVeyor CI](https://ci.appveyor.com/project/python-pillow/Pillow) to confirm passing tests in `master` branch.
* [ ] Check that all of the wheel builds [Pillow Wheel Builder](https://github.com/python-pillow/pillow-wheels) pass the tests in Travis CI. * [ ] Check that all of the wheel builds [Pillow Wheel Builder](https://github.com/python-pillow/pillow-wheels) pass the tests in Travis CI.
* [ ] In compliance with https://www.python.org/dev/peps/pep-0440/, update version identifier in `PIL/version.py` * [ ] In compliance with [PEP 440](https://www.python.org/dev/peps/pep-0440/), update version identifier in `src/PIL/_version.py`
* [ ] Update `CHANGES.rst`. * [ ] Update `CHANGES.rst`.
* [ ] Run pre-release check via `make release-test` in a freshly cloned repo. * [ ] Run pre-release check via `make release-test` in a freshly cloned repo.
* [ ] Create branch and tag for release e.g.: * [ ] Create branch and tag for release e.g.:
``` ```bash
$ git branch 2.9.x git branch 5.2.x
$ git tag 2.9.0 git tag 5.2.0
$ git push --all git push --all
$ git push --tags git push --tags
``` ```
* [ ] Create source distributions e.g.: * [ ] Create source distributions e.g.:
```bash
make sdist
``` ```
$ make sdist * [ ] Create [binary distributions](https://github.com/python-pillow/Pillow/blob/master/RELEASING.md#binary-distributions)
``` * [ ] Upload all binaries and source distributions e.g. `twine upload dist/Pillow-5.2.0*`
* [ ] Create [binary distributions](#binary-distributions) * [ ] Create a [new release on GitHub](https://github.com/python-pillow/Pillow/releases/new)
* [ ] Upload all binaries and source distributions with ``twine upload dist/Pillow-4.1.0-*`` * [ ] In compliance with [PEP 440](https://www.python.org/dev/peps/pep-0440/), increment and append `.dev0` to version identifier in `src/PIL/_version.py`
* [ ] Manually hide old versions on PyPI such that only the latest major release is visible when viewing https://pypi.python.org/pypi/Pillow (https://pypi.python.org/pypi?:action=pkg_edit&name=Pillow)
## Point Release ## Point Release
Released as needed for security, installation or critical bug fixes. Released as needed for security, installation or critical bug fixes.
* [ ] Make necessary changes in ``master`` branch. * [ ] Make necessary changes in `master` branch.
* [ ] Update `CHANGES.rst`. * [ ] Update `CHANGES.rst`.
* [ ] Cherry pick individual commits from ``master`` branch to release branch e.g. ``2.9.x``.
* [ ] Check [Travis CI](https://travis-ci.org/python-pillow/Pillow) to confirm passing tests in release branch e.g. ``2.9.x``.
* [ ] Check out release branch e.g.: * [ ] Check out release branch e.g.:
```bash
git checkout -t remotes/origin/5.2.x
``` ```
git checkout -t remotes/origin/2.9.x * [ ] Cherry pick individual commits from `master` branch to release branch e.g. `5.2.x`.
``` * [ ] Check [Travis CI](https://travis-ci.org/python-pillow/Pillow) to confirm passing tests in release branch e.g. `5.2.x`.
* [ ] In compliance with https://www.python.org/dev/peps/pep-0440/, update version identifier in `PIL/version.py` * [ ] In compliance with [PEP 440](https://www.python.org/dev/peps/pep-0440/), update version identifier in `src/PIL/_version.py`
* [ ] Run pre-release check via `make release-test`. * [ ] Run pre-release check via `make release-test`.
* [ ] Create tag for release e.g.: * [ ] Create tag for release e.g.:
``` ```bash
$ git tag 2.9.1 git tag 5.2.1
$ git push --tags git push --tags
``` ```
* [ ] Create source distributions e.g.: * [ ] Create source distributions e.g.:
```bash
make sdist
``` ```
$ make sdist * [ ] Create [binary distributions](https://github.com/python-pillow/Pillow/blob/master/RELEASING.md#binary-distributions)
``` * [ ] Create a [new release on GitHub](https://github.com/python-pillow/Pillow/releases/new)
* [ ] Create [binary distributions](#binary-distributions)
## Embargoed Release ## Embargoed Release
@ -62,45 +64,49 @@ Released as needed privately to individual vendors for critical security-related
* [ ] Run pre-release check via `make release-test` * [ ] Run pre-release check via `make release-test`
* [ ] Amend any commits with the CVE # * [ ] Amend any commits with the CVE #
* [ ] On release date, tag and push to GitHub. * [ ] On release date, tag and push to GitHub.
``` ```bash
git checkout 2.5.x git checkout 2.5.x
git tag 2.5.3 git tag 2.5.3
git push origin 2.5.x git push origin 2.5.x
git push origin --tags git push origin --tags
``` ```
* [ ] Create source distributions e.g.: * [ ] Create source distributions e.g.:
```bash
make sdist
``` ```
$ make sdist * [ ] Create [binary distributions](https://github.com/python-pillow/Pillow/blob/master/RELEASING.md#binary-distributions)
``` * [ ] Create a [new release on GitHub](https://github.com/python-pillow/Pillow/releases/new)
* [ ] Create [binary distributions](#binary-distributions)
## Binary Distributions ## Binary Distributions
### Windows ### Windows
* [ ] Contact @cgohlke for Windows binaries via release ticket e.g. https://github.com/python-pillow/Pillow/issues/1174. * [ ] Contact `@cgohlke` for Windows binaries via release ticket e.g. https://github.com/python-pillow/Pillow/issues/1174.
* [ ] Download and extract tarball from @cgohlke and ``twine upload *``. * [ ] Download and extract tarball from `@cgohlke` and `twine upload *`.
### Mac and Linux ### Mac and Linux
* [ ] Use the [Pillow Wheel Builder](https://github.com/python-pillow/pillow-wheels): * [ ] Use the [Pillow Wheel Builder](https://github.com/python-pillow/pillow-wheels):
``` ```bash
$ git checkout https://github.com/python-pillow/pillow-wheels git clone https://github.com/python-pillow/pillow-wheels
$ cd pillow-wheels cd pillow-wheels
$ git submodule init git submodule init
$ git submodule update git submodule update Pillow
$ cd Pillow cd Pillow
$ git fetch --all git fetch --all
$ git checkout [[release tag]] git checkout [[release tag]]
$ cd .. cd ..
$ git commit -m "Pillow -> 2.9.0" Pillow git commit -m "Pillow -> 5.2.0" Pillow
$ git push git push
``` ```
* [ ] Download distributions from the [Pillow Wheel Builder container](http://a365fff413fe338398b6-1c8a9b3114517dc5fe17b7c3f8c63a43.r19.cf2.rackcdn.com/). * [ ] Download distributions from the [Pillow Wheel Builder container](http://a365fff413fe338398b6-1c8a9b3114517dc5fe17b7c3f8c63a43.r19.cf2.rackcdn.com/).
```bash
wget -m -A 'Pillow-<VERSION>*' \
http://a365fff413fe338398b6-1c8a9b3114517dc5fe17b7c3f8c63a43.r19.cf2.rackcdn.com
```
## Publicize Release ## Publicize Release
* [ ] Announce release availability via [Twitter](https://twitter.com/pythonpillow) e.g. https://twitter.com/aclark4life/status/583366798302691328. * [ ] Announce release availability via [Twitter](https://twitter.com/pythonpillow) e.g. https://twitter.com/PythonPillow/status/1013789184354603010
## Documentation ## Documentation
* [ ] Make sure the default version for Read the Docs is the latest release version, e.g. ``3.1.x`` rather than ``latest``: https://readthedocs.org/projects/pillow/versions/ * [ ] Make sure the default version for Read the Docs is the latest tagged release e.g. `d2d43879` (5.4.0)

View File

@ -13,28 +13,20 @@ Install::
Execution Execution
--------- ---------
**If Pillow has been built in-place**
To run an individual test:: To run an individual test::
python Tests/test_image.py pytest Tests/test_image.py
Run all the tests from the root of the Pillow source distribution:: Or::
pytest -vx Tests pytest -k test_image.py
Or with coverage::
pytest -vx --cov PIL --cov-report term Tests
coverage html
open htmlcov/index.html
**If Pillow has been installed**
To run an individual test::
pytest -k Tests/test_image.py
Run all the tests from the root of the Pillow source distribution:: Run all the tests from the root of the Pillow source distribution::
pytest pytest
Or with coverage::
pytest --cov PIL --cov-report term
coverage html
open htmlcov/index.html

0
Tests/__init__.py Normal file
View File

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, hopper from .helper import unittest, PillowTestCase, hopper
# Not running this test by default. No DOS against Travis CI. # Not running this test by default. No DOS against Travis CI.

View File

@ -1,4 +1,4 @@
import helper from . import helper
import timeit import timeit
import sys import sys
@ -14,6 +14,7 @@ def bench(mode):
get(xy) get(xy)
print(mode, timeit.default_timer() - t0, "us") print(mode, timeit.default_timer() - t0, "us")
bench("L") bench("L")
bench("I") bench("I")
bench("I;16") bench("I;16")

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase from .helper import unittest, PillowTestCase
from PIL import Image from PIL import Image
TEST_FILE = "Tests/images/fli_overflow.fli" TEST_FILE = "Tests/images/fli_overflow.fli"

View File

@ -2,10 +2,11 @@
# Run from anywhere that PIL is importable. # Run from anywhere that PIL is importable.
from PIL import Image from PIL import Image
from PIL._util import py3
from io import BytesIO from io import BytesIO
if bytes is str: if py3:
Image.open(BytesIO(bytes('icns\x00\x00\x00\x10hang\x00\x00\x00\x00')))
else:
Image.open(BytesIO(bytes('icns\x00\x00\x00\x10hang\x00\x00\x00\x00', Image.open(BytesIO(bytes('icns\x00\x00\x00\x10hang\x00\x00\x00\x00',
'latin-1'))) 'latin-1')))
else:
Image.open(BytesIO(bytes('icns\x00\x00\x00\x10hang\x00\x00\x00\x00')))

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
from __future__ import division from __future__ import division
from helper import unittest, PillowTestCase from .helper import unittest, PillowTestCase
import sys import sys
from PIL import Image from PIL import Image
@ -9,7 +9,7 @@ min_iterations = 100
max_iterations = 10000 max_iterations = 10000
@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or MacOS") @unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or macOS")
class TestImagingLeaks(PillowTestCase): class TestImagingLeaks(PillowTestCase):
def _get_mem_usage(self): def _get_mem_usage(self):
@ -25,9 +25,8 @@ class TestImagingLeaks(PillowTestCase):
if i < min_iterations: if i < min_iterations:
mem_limit = mem + 1 mem_limit = mem + 1
continue continue
self.assertLessEqual(mem, mem_limit, msg = 'memory usage limit exceeded after %d iterations' % (i + 1)
msg='memory usage limit exceeded after %d iterations' self.assertLessEqual(mem, mem_limit, msg)
% (i + 1))
def test_leak_putdata(self): def test_leak_putdata(self):
im = Image.new('RGB', (25, 25)) im = Image.new('RGB', (25, 25))
@ -40,5 +39,6 @@ class TestImagingLeaks(PillowTestCase):
# Pass a new list at each iteration. # Pass a new list at each iteration.
lambda: im.point(range(256))) lambda: im.point(range(256)))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -2,12 +2,14 @@
# Run from anywhere that PIL is importable. # Run from anywhere that PIL is importable.
from PIL import Image from PIL import Image
from PIL._util import py3
from io import BytesIO from io import BytesIO
if bytes is str: if py3:
Image.open(BytesIO(bytes(
'\x00\x00\x00\x0cjP\x20\x20\x0d\x0a\x87\x0a\x00\x00\x00\x00hang')))
else:
Image.open(BytesIO(bytes( Image.open(BytesIO(bytes(
'\x00\x00\x00\x0cjP\x20\x20\x0d\x0a\x87\x0a\x00\x00\x00\x00hang', '\x00\x00\x00\x0cjP\x20\x20\x0d\x0a\x87\x0a\x00\x00\x00\x00hang',
'latin-1'))) 'latin-1')))
else:
Image.open(BytesIO(bytes(
'\x00\x00\x00\x0cjP\x20\x20\x0d\x0a\x87\x0a\x00\x00\x00\x00hang')))

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase from .helper import unittest, PillowTestCase
import sys import sys
from PIL import Image from PIL import Image
from io import BytesIO from io import BytesIO
@ -11,7 +11,7 @@ codecs = dir(Image.core)
test_file = "Tests/images/rgb_trns_ycbc.jp2" test_file = "Tests/images/rgb_trns_ycbc.jp2"
@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or MacOS") @unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or macOS")
class TestJpegLeaks(PillowTestCase): class TestJpegLeaks(PillowTestCase):
def setUp(self): def setUp(self):
if "jpeg2k_encoder" not in codecs or "jpeg2k_decoder" not in codecs: if "jpeg2k_encoder" not in codecs or "jpeg2k_decoder" not in codecs:

View File

@ -1,5 +1,5 @@
from PIL import Image from PIL import Image
from helper import unittest, PillowTestCase from .helper import unittest, PillowTestCase
class TestJ2kEncodeOverflow(PillowTestCase): class TestJ2kEncodeOverflow(PillowTestCase):
@ -10,5 +10,6 @@ class TestJ2kEncodeOverflow(PillowTestCase):
with self.assertRaises(IOError): with self.assertRaises(IOError):
im.save(target) im.save(target)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, hopper from .helper import unittest, PillowTestCase, hopper
from io import BytesIO from io import BytesIO
import sys import sys
@ -9,13 +9,12 @@ iterations = 5000
When run on a system without the jpeg leak fixes, When run on a system without the jpeg leak fixes,
the valgrind runs look like this. the valgrind runs look like this.
NOSE_PROCESSES=0 NOSE_TIMEOUT=600 valgrind --tool=massif \ valgrind --tool=massif python test-installed.py -s -v Tests/check_jpeg_leaks.py
python test-installed.py -s -v Tests/check_jpeg_leaks.py
""" """
@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or MacOS") @unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or macOS")
class TestJpegLeaks(PillowTestCase): class TestJpegLeaks(PillowTestCase):
""" """

View File

@ -1,6 +1,6 @@
import sys import sys
from helper import unittest, PillowTestCase from .helper import unittest, PillowTestCase
# This test is not run automatically. # This test is not run automatically.
# #
@ -21,7 +21,7 @@ class LargeMemoryTest(PillowTestCase):
def _write_png(self, xdim, ydim): def _write_png(self, xdim, ydim):
f = self.tempfile('temp.png') f = self.tempfile('temp.png')
im = Image.new('L', (xdim, ydim), (0)) im = Image.new('L', (xdim, ydim), 0)
im.save(f) im.save(f)
def test_large(self): def test_large(self):

View File

@ -1,6 +1,6 @@
import sys import sys
from helper import unittest, PillowTestCase from .helper import unittest, PillowTestCase
# This test is not run automatically. # This test is not run automatically.
# #

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase from .helper import unittest, PillowTestCase
from PIL import Image from PIL import Image
TEST_FILE = "Tests/images/libtiff_segfault.tif" TEST_FILE = "Tests/images/libtiff_segfault.tif"

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase from .helper import unittest, PillowTestCase
from PIL import Image, PngImagePlugin, ImageFile from PIL import Image, PngImagePlugin, ImageFile
from io import BytesIO from io import BytesIO
import zlib import zlib
@ -36,7 +36,7 @@ class TestPngDos(PillowTestCase):
def test_dos_total_memory(self): def test_dos_total_memory(self):
im = Image.new('L', (1, 1)) im = Image.new('L', (1, 1))
compressed_data = zlib.compress('a'*1024*1023) compressed_data = zlib.compress(b'a'*1024*1023)
info = PngImagePlugin.PngInfo() info = PngImagePlugin.PngInfo()
@ -60,5 +60,6 @@ class TestPngDos(PillowTestCase):
self.assertLess(total_len, 64*1024*1024, self.assertLess(total_len, 64*1024*1024,
"Total text chunks greater than 64M") "Total text chunks greater than 64M")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -1,38 +0,0 @@
from __future__ import division
from helper import unittest, PillowTestCase
import sys
from PIL import Image
from io import BytesIO
# Limits for testing the leak
mem_limit = 16 # max increase in MB
iterations = 5000
test_file = "Tests/images/hopper.webp"
@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or MacOS")
class TestWebPLeaks(PillowTestCase):
def setUp(self):
try:
from PIL import _webp
except ImportError:
self.skipTest('WebP support not installed')
def _get_mem_usage(self):
from resource import getpagesize, getrusage, RUSAGE_SELF
mem = getrusage(RUSAGE_SELF).ru_maxrss
return mem * getpagesize() / 1024 / 1024
def test_leak_load(self):
with open(test_file, 'rb') as f:
im_data = f.read()
start_mem = self._get_mem_usage()
for _ in range(iterations):
with Image.open(BytesIO(im_data)) as im:
im.load()
mem = (self._get_mem_usage() - start_mem)
self.assertLess(mem, mem_limit, msg='memory usage limit exceeded')
if __name__ == '__main__':
unittest.main()

View File

@ -2,7 +2,6 @@
from __future__ import print_function from __future__ import print_function
import base64 import base64
import os import os
import sys
if __name__ == "__main__": if __name__ == "__main__":
# create font data chunk for embedding # create font data chunk for embedding
@ -10,7 +9,9 @@ if __name__ == "__main__":
print(" f._load_pilfont_data(") print(" f._load_pilfont_data(")
print(" # %s" % os.path.basename(font)) print(" # %s" % os.path.basename(font))
print(" BytesIO(base64.decodestring(b'''") print(" BytesIO(base64.decodestring(b'''")
base64.encode(open(font + ".pil", "rb"), sys.stdout) with open(font + ".pil", "rb") as fp:
print(base64.b64encode(fp.read()).decode())
print("''')), Image.open(BytesIO(base64.decodestring(b'''") print("''')), Image.open(BytesIO(base64.decodestring(b'''")
base64.encode(open(font + ".pbm", "rb"), sys.stdout) with open(font + ".pbm", "rb") as fp:
print(base64.b64encode(fp.read()).decode())
print("'''))))") print("'''))))")

View File

@ -8,6 +8,7 @@ import os
import unittest import unittest
from PIL import Image, ImageMath from PIL import Image, ImageMath
from PIL._util import py3
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -18,6 +19,7 @@ HAS_UPLOADER = False
if os.environ.get('SHOW_ERRORS', None): if os.environ.get('SHOW_ERRORS', None):
# local img.show for errors. # local img.show for errors.
HAS_UPLOADER = True HAS_UPLOADER = True
class test_image_results: class test_image_results:
@classmethod @classmethod
def upload(self, a, b): def upload(self, a, b):
@ -31,7 +33,6 @@ else:
pass pass
def convert_to_comparable(a, b): def convert_to_comparable(a, b):
new_a, new_b = a, b new_a, new_b = a, b
if a.mode == 'P': if a.mode == 'P':
@ -52,10 +53,6 @@ class PillowTestCase(unittest.TestCase):
# holds last result object passed to run method: # holds last result object passed to run method:
self.currentResult = None self.currentResult = None
# Nicer output for --verbose
def __str__(self):
return self.__class__.__name__ + "." + self._testMethodName
def run(self, result=None): def run(self, result=None):
self.currentResult = result # remember result for use later self.currentResult = result # remember result for use later
unittest.TestCase.run(self, result) # call superclass run method unittest.TestCase.run(self, result) # call superclass run method
@ -83,7 +80,7 @@ class PillowTestCase(unittest.TestCase):
self.assertTrue( self.assertTrue(
all(x == y for x, y in zip(a, b)), all(x == y for x, y in zip(a, b)),
msg or "got %s, expected %s" % (a, b)) msg or "got %s, expected %s" % (a, b))
except: except Exception:
self.assertEqual(a, b, msg) self.assertEqual(a, b, msg)
def assert_image(self, im, mode, size, msg=None): def assert_image(self, im, mode, size, msg=None):
@ -109,7 +106,7 @@ class PillowTestCase(unittest.TestCase):
try: try:
url = test_image_results.upload(a, b) url = test_image_results.upload(a, b)
logger.error("Url for test images: %s" % url) logger.error("Url for test images: %s" % url)
except Exception as msg: except Exception:
pass pass
self.fail(msg or "got different content") self.fail(msg or "got different content")
@ -148,11 +145,12 @@ class PillowTestCase(unittest.TestCase):
try: try:
url = test_image_results.upload(a, b) url = test_image_results.upload(a, b)
logger.error("Url for test images: %s" % url) logger.error("Url for test images: %s" % url)
except: except Exception:
pass pass
raise e raise e
def assert_image_similar_tofile(self, a, filename, epsilon, msg=None, mode=None): def assert_image_similar_tofile(self, a, filename, epsilon, msg=None,
mode=None):
with Image.open(filename) as img: with Image.open(filename) as img:
if mode: if mode:
img = img.convert(mode) img = img.convert(mode)
@ -161,7 +159,6 @@ class PillowTestCase(unittest.TestCase):
def assert_warning(self, warn_class, func, *args, **kwargs): def assert_warning(self, warn_class, func, *args, **kwargs):
import warnings import warnings
result = None
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
# Cause all warnings to always be triggered. # Cause all warnings to always be triggered.
warnings.simplefilter("always") warnings.simplefilter("always")
@ -173,7 +170,7 @@ class PillowTestCase(unittest.TestCase):
if warn_class is None: if warn_class is None:
self.assertEqual(len(w), 0, self.assertEqual(len(w), 0,
"Expected no warnings, got %s" % "Expected no warnings, got %s" %
list(v.category for v in w)) [v.category for v in w])
else: else:
self.assertGreaterEqual(len(w), 1) self.assertGreaterEqual(len(w), 1)
found = False found = False
@ -185,10 +182,20 @@ class PillowTestCase(unittest.TestCase):
return result return result
def assert_all_same(self, items, msg=None): def assert_all_same(self, items, msg=None):
self.assertTrue(items.count(items[0]) == len(items), msg) self.assertEqual(items.count(items[0]), len(items), msg)
def assert_not_all_same(self, items, msg=None): def assert_not_all_same(self, items, msg=None):
self.assertFalse(items.count(items[0]) == len(items), msg) self.assertNotEqual(items.count(items[0]), len(items), msg)
def assert_tuple_approx_equal(self, actuals, targets, threshold, msg):
"""Tests if actuals has values within threshold from targets"""
value = True
for i, target in enumerate(targets):
value *= (target - threshold <= actuals[i] <= target + threshold)
self.assertTrue(value,
msg + ': ' + repr(actuals) + ' != ' + repr(targets))
def skipKnownBadTest(self, msg=None, platform=None, def skipKnownBadTest(self, msg=None, platform=None,
travis=None, interpreter=None): travis=None, interpreter=None):
@ -227,25 +234,26 @@ class PillowTestCase(unittest.TestCase):
raise IOError() raise IOError()
@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or MacOS") @unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or macOS")
class PillowLeakTestCase(PillowTestCase): class PillowLeakTestCase(PillowTestCase):
# requires unix/osx # requires unix/macOS
iterations = 100 # count iterations = 100 # count
mem_limit = 512 # k mem_limit = 512 # k
def _get_mem_usage(self): def _get_mem_usage(self):
""" """
Gets the RUSAGE memory usage, returns in K. Encapsulates the difference Gets the RUSAGE memory usage, returns in K. Encapsulates the difference
between OSX and Linux rss reporting between macOS and Linux rss reporting
:returns; memory usage in kilobytes :returns: memory usage in kilobytes
""" """
from resource import getrusage, RUSAGE_SELF from resource import getrusage, RUSAGE_SELF
mem = getrusage(RUSAGE_SELF).ru_maxrss mem = getrusage(RUSAGE_SELF).ru_maxrss
if sys.platform == 'darwin': if sys.platform == 'darwin':
# man 2 getrusage: # man 2 getrusage:
# ru_maxrss the maximum resident set size utilized (in bytes). # ru_maxrss
# This is the maximum resident set size utilized (in bytes).
return mem / 1024 # Kb return mem / 1024 # Kb
else: else:
# linux # linux
@ -259,13 +267,16 @@ class PillowLeakTestCase(PillowTestCase):
for cycle in range(self.iterations): for cycle in range(self.iterations):
core() core()
mem = (self._get_mem_usage() - start_mem) mem = (self._get_mem_usage() - start_mem)
self.assertLess(mem, self.mem_limit, msg = 'memory usage limit exceeded in iteration %d' % cycle
msg='memory usage limit exceeded in iteration %d' % cycle) self.assertLess(mem, self.mem_limit, msg)
# helpers # helpers
py3 = (sys.version_info >= (3, 0)) if not py3:
# Remove DeprecationWarning in Python 3
PillowTestCase.assertRaisesRegex = PillowTestCase.assertRaisesRegexp
PillowTestCase.assertRegex = PillowTestCase.assertRegexpMatches
def fromstring(data): def fromstring(data):

Binary file not shown.

BIN
Tests/images/a_fli.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
Tests/images/balloon.jpf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
Tests/images/hopper.gd Normal file

Binary file not shown.

BIN
Tests/images/hopper.wal Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

View File

Before

Width:  |  Height:  |  Size: 232 B

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
Tests/images/iss634.apng Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

BIN
Tests/images/la.tga Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More