Merge branch 'master' into pr_2687
|
@ -1,117 +1,125 @@
|
||||||
version: '{build}'
|
version: '{build}'
|
||||||
clone_folder: c:\pillow
|
clone_folder: c:\pillow
|
||||||
init:
|
init:
|
||||||
- ECHO %PYTHON%
|
- ECHO %PYTHON%
|
||||||
#- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
#- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
# Uncomment previous line to get RDP access during the build.
|
# Uncomment previous line to get RDP access during the build.
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
X64_EXT: -x64
|
X64_EXT: -x64
|
||||||
EXECUTABLE: python.exe
|
EXECUTABLE: python.exe
|
||||||
PIP_DIR: Scripts
|
PIP_DIR: Scripts
|
||||||
VENV: NO
|
VENV: NO
|
||||||
TEST_OPTIONS:
|
TEST_OPTIONS:
|
||||||
DEPLOY: YES
|
DEPLOY: YES
|
||||||
matrix:
|
matrix:
|
||||||
- PYTHON: C:/vp/pypy2
|
- PYTHON: C:/vp/pypy2
|
||||||
EXECUTABLE: bin/pypy.exe
|
EXECUTABLE: bin/pypy.exe
|
||||||
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:/msys64/mingw32
|
- PYTHON: C:/Python36
|
||||||
EXECUTABLE: bin/python3
|
- PYTHON: C:/Python36-x64
|
||||||
PIP_DIR: bin
|
- PYTHON: C:/Python35
|
||||||
TEST_OPTIONS: --processes=0
|
- PYTHON: C:/Python35-x64
|
||||||
DEPLOY: NO
|
- PYTHON: C:/msys64/mingw32
|
||||||
|
EXECUTABLE: bin/python3
|
||||||
|
PIP_DIR: bin
|
||||||
install:
|
TEST_OPTIONS: --processes=0
|
||||||
- curl -fsSL -o pillow-depends.zip https://github.com/python-pillow/pillow-depends/archive/master.zip
|
DEPLOY: NO
|
||||||
- 7z x pillow-depends.zip -oc:\
|
|
||||||
- mv c:\pillow-depends-master c:\pillow-depends
|
|
||||||
- xcopy c:\pillow-depends\*.zip c:\pillow\winbuild\
|
install:
|
||||||
- xcopy c:\pillow-depends\*.tar.gz c:\pillow\winbuild\
|
- curl -fsSL -o pillow-depends.zip https://github.com/python-pillow/pillow-depends/archive/master.zip
|
||||||
- xcopy /s c:\pillow-depends\test_images\* c:\pillow\tests\images
|
- 7z x pillow-depends.zip -oc:\
|
||||||
- cd c:\pillow\winbuild\
|
- mv c:\pillow-depends-master c:\pillow-depends
|
||||||
- ps: |
|
- xcopy c:\pillow-depends\*.zip c:\pillow\winbuild\
|
||||||
if ($env:PYTHON -eq "c:/vp/pypy2")
|
- xcopy c:\pillow-depends\*.tar.gz c:\pillow\winbuild\
|
||||||
{
|
- xcopy /s c:\pillow-depends\test_images\* c:\pillow\tests\images
|
||||||
c:\pillow\winbuild\appveyor_install_pypy.cmd
|
- cd c:\pillow\winbuild\
|
||||||
}
|
- ps: |
|
||||||
- ps: |
|
if ($env:PYTHON -eq "c:/vp/pypy2")
|
||||||
if ($env:PYTHON -eq "c:/msys64/mingw32")
|
{
|
||||||
{
|
c:\pillow\winbuild\appveyor_install_pypy.cmd
|
||||||
c:\msys64\usr\bin\bash -l -c c:\\pillow\\winbuild\\appveyor_install_msys2_deps.sh
|
}
|
||||||
}
|
- ps: |
|
||||||
else
|
if ($env:PYTHON -eq "c:/msys64/mingw32")
|
||||||
{
|
{
|
||||||
c:\python34\python.exe c:\pillow\winbuild\build_dep.py
|
c:\msys64\usr\bin\bash -l -c c:\\pillow\\winbuild\\appveyor_install_msys2_deps.sh
|
||||||
c:\pillow\winbuild\build_deps.cmd
|
}
|
||||||
$host.SetShouldExit(0)
|
else
|
||||||
}
|
{
|
||||||
|
c:\python34\python.exe c:\pillow\winbuild\build_dep.py
|
||||||
build_script:
|
c:\pillow\winbuild\build_deps.cmd
|
||||||
- ps: |
|
$host.SetShouldExit(0)
|
||||||
if ($env:PYTHON -eq "c:/msys64/mingw32")
|
}
|
||||||
{
|
|
||||||
c:\msys64\usr\bin\bash -l -c c:\\pillow\\winbuild\\appveyor_build_msys2.sh
|
build_script:
|
||||||
Write-Host "through install"
|
- ps: |
|
||||||
$host.SetShouldExit(0)
|
if ($env:PYTHON -eq "c:/msys64/mingw32")
|
||||||
}
|
{
|
||||||
else
|
c:\msys64\usr\bin\bash -l -c c:\\pillow\\winbuild\\appveyor_build_msys2.sh
|
||||||
{
|
Write-Host "through install"
|
||||||
& $env:PYTHON/$env:EXECUTABLE c:\pillow\winbuild\build.py
|
$host.SetShouldExit(0)
|
||||||
$host.SetShouldExit(0)
|
}
|
||||||
}
|
else
|
||||||
- cd c:\pillow
|
{
|
||||||
- '%PYTHON%\%EXECUTABLE% selftest.py --installed'
|
& $env:PYTHON/$env:EXECUTABLE c:\pillow\winbuild\build.py
|
||||||
|
$host.SetShouldExit(0)
|
||||||
test_script:
|
}
|
||||||
- cd c:\pillow
|
- cd c:\pillow
|
||||||
- '%PYTHON%\%PIP_DIR%\pip.exe install pytest pytest-cov'
|
- '%PYTHON%\%EXECUTABLE% selftest.py --installed'
|
||||||
- '%PYTHON%\%EXECUTABLE% -m pytest -vx --cov PIL --cov-report term --cov-report xml Tests'
|
|
||||||
#- '%PYTHON%\%EXECUTABLE% test-installed.py -v -s %TEST_OPTIONS%' TODO TEST_OPTIONS with pytest?
|
test_script:
|
||||||
|
- cd c:\pillow
|
||||||
after_test:
|
- '%PYTHON%\%PIP_DIR%\pip.exe install pytest pytest-cov'
|
||||||
- pip install codecov
|
- '%PYTHON%\%EXECUTABLE% -m pytest -vx --cov PIL --cov-report term --cov-report xml Tests'
|
||||||
- codecov --file coverage.xml --name %PYTHON%
|
#- '%PYTHON%\%EXECUTABLE% test-installed.py -v -s %TEST_OPTIONS%' TODO TEST_OPTIONS with pytest?
|
||||||
|
|
||||||
matrix:
|
after_test:
|
||||||
fast_finish: true
|
- pip install codecov
|
||||||
|
- codecov --file coverage.xml --name %PYTHON%
|
||||||
artifacts:
|
|
||||||
- path: pillow\dist\*.egg
|
matrix:
|
||||||
name: egg
|
fast_finish: true
|
||||||
- path: pillow\dist\*.wheel
|
|
||||||
name: wheel
|
cache:
|
||||||
|
- '%LOCALAPPDATA%\pip\Cache'
|
||||||
before_deploy:
|
|
||||||
- cd c:\pillow
|
artifacts:
|
||||||
- '%PYTHON%\%PIP_DIR%\pip.exe install wheel'
|
- path: pillow\dist\*.egg
|
||||||
- cd c:\pillow\winbuild\
|
name: egg
|
||||||
- '%PYTHON%\%EXECUTABLE% c:\pillow\winbuild\build.py --wheel'
|
- path: pillow\dist\*.wheel
|
||||||
- cd c:\pillow
|
name: wheel
|
||||||
- ps: Get-ChildItem .\dist\*.* | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
|
||||||
|
before_deploy:
|
||||||
deploy:
|
- cd c:\pillow
|
||||||
provider: S3
|
- '%PYTHON%\%PIP_DIR%\pip.exe install wheel'
|
||||||
region: us-west-2
|
- cd c:\pillow\winbuild\
|
||||||
access_key_id: AKIAIRAXC62ZNTVQJMOQ
|
- '%PYTHON%\%EXECUTABLE% c:\pillow\winbuild\build.py --wheel'
|
||||||
secret_access_key:
|
- cd c:\pillow
|
||||||
secure: Hwb6klTqtBeMgxAjRoDltiiqpuH8xbwD4UooDzBSiCWXjuFj1lyl4kHgHwTCCGqi
|
- ps: Get-ChildItem .\dist\*.* | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||||
bucket: pillow-nightly
|
|
||||||
folder: win/$(APPVEYOR_BUILD_NUMBER)/
|
deploy:
|
||||||
artifact: /.*egg|wheel/
|
provider: S3
|
||||||
on:
|
region: us-west-2
|
||||||
branch: master
|
access_key_id: AKIAIRAXC62ZNTVQJMOQ
|
||||||
deploy: YES
|
secret_access_key:
|
||||||
|
secure: Hwb6klTqtBeMgxAjRoDltiiqpuH8xbwD4UooDzBSiCWXjuFj1lyl4kHgHwTCCGqi
|
||||||
|
bucket: pillow-nightly
|
||||||
# Uncomment the following lines to get RDP access after the build/test and block for
|
folder: win/$(APPVEYOR_BUILD_NUMBER)/
|
||||||
# up to the timeout limit (~1hr)
|
artifact: /.*egg|wheel/
|
||||||
#
|
on:
|
||||||
#on_finish:
|
APPVEYOR_REPO_NAME: python-pillow/Pillow
|
||||||
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
branch: master
|
||||||
|
deploy: YES
|
||||||
|
|
||||||
|
|
||||||
|
# Uncomment the following lines to get RDP access after the build/test and block for
|
||||||
|
# up to the timeout limit (~1hr)
|
||||||
|
#
|
||||||
|
#on_finish:
|
||||||
|
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
9
.codecov.yml
Normal 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
|
@ -1,2 +1,3 @@
|
||||||
|
*.eps binary
|
||||||
*.ppm binary
|
*.ppm binary
|
||||||
*.container binary
|
*.container binary
|
||||||
|
|
6
.github/CONTRIBUTING.md
vendored
|
@ -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
|
||||||
|
|
||||||
|
|
6
.github/ISSUE_TEMPLATE.md
vendored
|
@ -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
|
@ -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
|
@ -0,0 +1,2 @@
|
||||||
|
python:
|
||||||
|
pip_install: true
|
138
.travis.yml
|
@ -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'
|
||||||
|
name: "2.7 Xenial"
|
||||||
|
- python: '2.7'
|
||||||
|
name: "2.7 Trusty"
|
||||||
|
dist: trusty
|
||||||
- python: "2.7_with_system_site_packages" # For PyQt4
|
- python: "2.7_with_system_site_packages" # For PyQt4
|
||||||
|
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'
|
- python: '3.5'
|
||||||
- python: '3.4'
|
name: "3.5 Xenial"
|
||||||
- python: '3.7-dev'
|
- python: '3.5'
|
||||||
- env: DOCKER="alpine" DOCKER_TAG="pytest"
|
name: "3.5 Trusty PYTHONOPTIMIZE=2"
|
||||||
- env: DOCKER="arch" DOCKER_TAG="pytest" # contains PyQt5
|
dist: trusty
|
||||||
- env: DOCKER="ubuntu-trusty-x86" DOCKER_TAG="pytest"
|
env: PYTHONOPTIMIZE=2
|
||||||
- env: DOCKER="ubuntu-xenial-amd64" DOCKER_TAG="pytest"
|
- python: "3.8-dev"
|
||||||
- env: DOCKER="debian-stretch-x86" DOCKER_TAG="pytest"
|
name: "3.8-dev Xenial"
|
||||||
- env: DOCKER="centos-6-amd64" DOCKER_TAG="pytest"
|
- env: DOCKER="alpine" DOCKER_TAG="master"
|
||||||
- env: DOCKER="centos-7-amd64" DOCKER_TAG="pytest"
|
- env: DOCKER="arch" DOCKER_TAG="master" # contains PyQt5
|
||||||
- env: DOCKER="amazon-1-amd64" DOCKER_TAG="pytest"
|
- env: DOCKER="ubuntu-trusty-x86" DOCKER_TAG="master"
|
||||||
- env: DOCKER="amazon-2-amd64" DOCKER_TAG="pytest"
|
- env: DOCKER="ubuntu-xenial-amd64" DOCKER_TAG="master"
|
||||||
- env: DOCKER="fedora-26-amd64" DOCKER_TAG="pytest"
|
- env: DOCKER="debian-stretch-x86" DOCKER_TAG="master"
|
||||||
- env: DOCKER="fedora-27-amd64" DOCKER_TAG="pytest"
|
- env: DOCKER="centos-6-amd64" DOCKER_TAG="master"
|
||||||
|
- env: DOCKER="centos-7-amd64" DOCKER_TAG="master"
|
||||||
dist: trusty
|
- env: DOCKER="amazon-1-amd64" DOCKER_TAG="master"
|
||||||
|
- env: DOCKER="amazon-2-amd64" DOCKER_TAG="master"
|
||||||
sudo: required
|
- 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
|
||||||
.travis/script.sh
|
tox -e lint
|
||||||
else
|
elif [ "$DOCKER" == "" ]; then
|
||||||
# the Pillow user in the docker container is UID 1000
|
.travis/script.sh
|
||||||
sudo chown -R 1000 $TRAVIS_BUILD_DIR
|
elif [ "$DOCKER" ]; then
|
||||||
docker run -v $TRAVIS_BUILD_DIR:/Pillow pythonpillow/$DOCKER:$DOCKER_TAG
|
# the Pillow user in the docker container is UID 1000
|
||||||
fi
|
sudo chown -R 1000 $TRAVIS_BUILD_DIR
|
||||||
|
docker run -v $TRAVIS_BUILD_DIR:/Pillow pythonpillow/$DOCKER:$DOCKER_TAG
|
||||||
|
fi
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- .travis/after_success.sh
|
- |
|
||||||
|
if [ "$LINT" == "" ]; then
|
||||||
after_failure:
|
.travis/after_success.sh
|
||||||
- |
|
fi
|
||||||
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_failed" ]; then
|
|
||||||
echo "All jobs failed"
|
|
||||||
else
|
|
||||||
echo "Some jobs failed"
|
|
||||||
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="
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
546
CHANGES.rst
|
@ -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)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@ -22,13 +526,13 @@ Changelog (Pillow)
|
||||||
|
|
||||||
- Dynamically link libraqm #2753
|
- Dynamically link libraqm #2753
|
||||||
[wiredfool]
|
[wiredfool]
|
||||||
|
|
||||||
- Removed scripts directory #2901
|
- Removed scripts directory #2901
|
||||||
[wiredfool]
|
[wiredfool]
|
||||||
|
|
||||||
- TIFF: Run all compressed tiffs through libtiff decoder #2899
|
- TIFF: Run all compressed tiffs through libtiff decoder #2899
|
||||||
[wiredfool]
|
[wiredfool]
|
||||||
|
|
||||||
- GIF: Add disposal option when saving GIFs #2902
|
- GIF: Add disposal option when saving GIFs #2902
|
||||||
[linnil1, wiredfool]
|
[linnil1, wiredfool]
|
||||||
|
|
||||||
|
@ -45,7 +549,7 @@ Changelog (Pillow)
|
||||||
[wiredfool]
|
[wiredfool]
|
||||||
|
|
||||||
- Test: avoid random failure in test_effect_noise #2894
|
- Test: avoid random failure in test_effect_noise #2894
|
||||||
[hugovk]
|
[hugovk]
|
||||||
|
|
||||||
- Increased epsilon for test_file_eps.py:test_showpage due to Arch update. #2896
|
- Increased epsilon for test_file_eps.py:test_showpage due to Arch update. #2896
|
||||||
[wiredfool]
|
[wiredfool]
|
||||||
|
@ -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
|
||||||
|
@ -410,7 +914,7 @@ Changelog (Pillow)
|
||||||
- Doc: Clarified Image.save:append_images documentation #2604
|
- Doc: Clarified Image.save:append_images documentation #2604
|
||||||
[radarhere]
|
[radarhere]
|
||||||
|
|
||||||
- CI: Amazon Linux and Centos6 docker images added to TravisCI #2585
|
- CI: Amazon Linux and Centos6 docker images added to Travis CI #2585
|
||||||
[wiredfool]
|
[wiredfool]
|
||||||
|
|
||||||
- Image.alpha_composite added #2595
|
- Image.alpha_composite added #2595
|
||||||
|
@ -479,7 +983,7 @@ Changelog (Pillow)
|
||||||
- Update Feature Detection #2520
|
- Update Feature Detection #2520
|
||||||
[wiredfool]
|
[wiredfool]
|
||||||
|
|
||||||
- CI: Update pypy on TravisCI #2573
|
- CI: Update pypy on Travis CI #2573
|
||||||
[hugovk]
|
[hugovk]
|
||||||
|
|
||||||
- ImageMorph: Fix wrong expected size of MRLs read from disk #2561
|
- ImageMorph: Fix wrong expected size of MRLs read from disk #2561
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
|
2
LICENSE
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
2
Makefile
|
@ -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:
|
||||||
|
|
23
README.rst
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
126
RELEASING.md
|
@ -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 TravisCI.
|
* [ ] 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](#binary-distributions)
|
* [ ] Create [binary distributions](https://github.com/python-pillow/Pillow/blob/master/RELEASING.md#binary-distributions)
|
||||||
* [ ] Upload all binaries and source distributions with ``twine upload dist/Pillow-4.1.0-*``
|
* [ ] Upload all binaries and source distributions e.g. `twine upload dist/Pillow-5.2.0*`
|
||||||
* [ ] 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)
|
* [ ] Create a [new release on GitHub](https://github.com/python-pillow/Pillow/releases/new)
|
||||||
|
* [ ] 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`
|
||||||
|
|
||||||
## 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 out release branch e.g.:
|
||||||
* [ ] Check [Travis CI](https://travis-ci.org/python-pillow/Pillow) to confirm passing tests in release branch e.g. ``2.9.x``.
|
```bash
|
||||||
* [ ] Checkout release branch e.g.:
|
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](#binary-distributions)
|
* [ ] 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)
|
||||||
|
|
||||||
## 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](#binary-distributions)
|
* [ ] 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)
|
||||||
|
|
||||||
## 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)
|
||||||
|
|
|
@ -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
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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')))
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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')))
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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.
|
||||||
#
|
#
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
|
|
@ -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("'''))))")
|
||||||
|
|
|
@ -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__)
|
||||||
|
@ -16,8 +17,9 @@ logger = logging.getLogger(__name__)
|
||||||
HAS_UPLOADER = False
|
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")
|
||||||
|
@ -119,7 +116,7 @@ class PillowTestCase(unittest.TestCase):
|
||||||
if mode:
|
if mode:
|
||||||
img = img.convert(mode)
|
img = img.convert(mode)
|
||||||
self.assert_image_equal(a, img, msg)
|
self.assert_image_equal(a, img, msg)
|
||||||
|
|
||||||
def assert_image_similar(self, a, b, epsilon, msg=None):
|
def assert_image_similar(self, a, b, epsilon, msg=None):
|
||||||
epsilon = float(epsilon)
|
epsilon = float(epsilon)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
@ -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,26 +234,27 @@ 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
|
||||||
return mem / 1024 # Kb
|
# This is the maximum resident set size utilized (in bytes).
|
||||||
|
return mem / 1024 # Kb
|
||||||
else:
|
else:
|
||||||
# linux
|
# linux
|
||||||
# man 2 getrusage
|
# man 2 getrusage
|
||||||
|
@ -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):
|
||||||
|
|
BIN
Tests/images/16_bit_noise.tif
Normal file
BIN
Tests/images/a_fli.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
Tests/images/balloon.jpf
Normal file
BIN
Tests/images/blp/blp1_jpeg.blp
Normal file
BIN
Tests/images/blp/blp2_dxt1.blp
Normal file
BIN
Tests/images/blp/blp2_dxt1.png
Normal file
After Width: | Height: | Size: 761 B |
BIN
Tests/images/blp/blp2_dxt1a.blp
Normal file
BIN
Tests/images/blp/blp2_dxt1a.png
Normal file
After Width: | Height: | Size: 275 B |
BIN
Tests/images/blp/blp2_raw.blp
Normal file
BIN
Tests/images/blp/blp2_raw.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
Tests/images/bw_gradient.png
Normal file
After Width: | Height: | Size: 102 B |
BIN
Tests/images/exif-ifd-offset.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
Tests/images/hopper.gd
Normal file
BIN
Tests/images/hopper.wal
Normal file
BIN
Tests/images/hopper_idat_after_image_end.png
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
Tests/images/hopper_unknown_pixel_mode.tif
Normal file
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 48 KiB |
BIN
Tests/images/hopper_zero_comment_subblocks.gif
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
Tests/images/imagedraw2_text.png
Normal file
After Width: | Height: | Size: 974 B |
BIN
Tests/images/imagedraw_arc_width.png
Normal file
After Width: | Height: | Size: 439 B |
BIN
Tests/images/imagedraw_arc_width_fill.png
Normal file
After Width: | Height: | Size: 438 B |
BIN
Tests/images/imagedraw_chord_width.png
Normal file
After Width: | Height: | Size: 488 B |
BIN
Tests/images/imagedraw_chord_width_fill.png
Normal file
After Width: | Height: | Size: 507 B |
BIN
Tests/images/imagedraw_ellipse_width.png
Normal file
After Width: | Height: | Size: 452 B |
BIN
Tests/images/imagedraw_ellipse_width_fill.png
Normal file
After Width: | Height: | Size: 477 B |
BIN
Tests/images/imagedraw_floodfill_L.png
Normal file
After Width: | Height: | Size: 144 B |
Before Width: | Height: | Size: 232 B After Width: | Height: | Size: 232 B |
BIN
Tests/images/imagedraw_floodfill_RGBA.png
Normal file
After Width: | Height: | Size: 253 B |
BIN
Tests/images/imagedraw_line_joint_curve.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
Tests/images/imagedraw_outline_chord_L.png
Normal file
After Width: | Height: | Size: 212 B |
BIN
Tests/images/imagedraw_outline_chord_RGB.png
Normal file
After Width: | Height: | Size: 259 B |
BIN
Tests/images/imagedraw_outline_ellipse_L.png
Normal file
After Width: | Height: | Size: 290 B |
BIN
Tests/images/imagedraw_outline_ellipse_RGB.png
Normal file
After Width: | Height: | Size: 378 B |
BIN
Tests/images/imagedraw_outline_pieslice_L.png
Normal file
After Width: | Height: | Size: 266 B |
BIN
Tests/images/imagedraw_outline_pieslice_RGB.png
Normal file
After Width: | Height: | Size: 340 B |
BIN
Tests/images/imagedraw_outline_polygon_L.png
Normal file
After Width: | Height: | Size: 309 B |
BIN
Tests/images/imagedraw_outline_polygon_RGB.png
Normal file
After Width: | Height: | Size: 393 B |
BIN
Tests/images/imagedraw_outline_rectangle_L.png
Normal file
After Width: | Height: | Size: 125 B |
BIN
Tests/images/imagedraw_outline_rectangle_RGB.png
Normal file
After Width: | Height: | Size: 212 B |
BIN
Tests/images/imagedraw_outline_shape_L.png
Normal file
After Width: | Height: | Size: 263 B |
BIN
Tests/images/imagedraw_outline_shape_RGB.png
Normal file
After Width: | Height: | Size: 316 B |
BIN
Tests/images/imagedraw_pieslice_width.png
Normal file
After Width: | Height: | Size: 496 B |
BIN
Tests/images/imagedraw_pieslice_width_fill.png
Normal file
After Width: | Height: | Size: 523 B |
BIN
Tests/images/imagedraw_rectangle_width.png
Normal file
After Width: | Height: | Size: 228 B |
BIN
Tests/images/imagedraw_rectangle_width_fill.png
Normal file
After Width: | Height: | Size: 239 B |
BIN
Tests/images/imageops_pad_h_0.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Tests/images/imageops_pad_h_1.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Tests/images/imageops_pad_h_2.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Tests/images/imageops_pad_v_0.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Tests/images/imageops_pad_v_1.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Tests/images/imageops_pad_v_2.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Tests/images/iss634.apng
Normal file
After Width: | Height: | Size: 342 KiB |
BIN
Tests/images/la.tga
Normal file
BIN
Tests/images/rotate_45_no_fill.png
Normal file
After Width: | Height: | Size: 639 B |
BIN
Tests/images/rotate_45_with_fill.png
Normal file
After Width: | Height: | Size: 625 B |
BIN
Tests/images/sugarshack_ifd_offset.mpo
Normal file
After Width: | Height: | Size: 117 KiB |
BIN
Tests/images/tga/common/1x1_l.png
Normal file
After Width: | Height: | Size: 67 B |
BIN
Tests/images/tga/common/1x1_l_bl_raw.tga
Normal file
BIN
Tests/images/tga/common/1x1_l_bl_rle.tga
Normal file
BIN
Tests/images/tga/common/1x1_l_tl_raw.tga
Normal file
BIN
Tests/images/tga/common/1x1_l_tl_rle.tga
Normal file
BIN
Tests/images/tga/common/200x32_l.png
Normal file
After Width: | Height: | Size: 385 B |