Merge branch 'master' into master

This commit is contained in:
Andrew Murray 2020-12-30 13:05:35 +11:00 committed by GitHub
commit 86ad435ee4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
575 changed files with 18098 additions and 9000 deletions

View File

@ -6,81 +6,50 @@ init:
# 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
EXECUTABLE: python.exe EXECUTABLE: python.exe
PIP_DIR: Scripts
VENV: NO
TEST_OPTIONS: TEST_OPTIONS:
DEPLOY: YES DEPLOY: YES
matrix: matrix:
- PYTHON: C:/Python38 - PYTHON: C:/Python39
- PYTHON: C:/Python38-x64 ARCHITECTURE: x86
- PYTHON: C:/Python35 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- PYTHON: C:/Python35-x64 - PYTHON: C:/Python36-x64
- PYTHON: C:/msys64/mingw32 ARCHITECTURE: x64
EXECUTABLE: bin/python3 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
PIP_DIR: bin
TEST_OPTIONS: --processes=0
DEPLOY: NO
- PYTHON: C:/vp/pypy3
EXECUTABLE: bin/pypy.exe
PIP_DIR: bin
VENV: YES
install: install:
- curl -fsSL -o pillow-depends.zip https://github.com/python-pillow/pillow-depends/archive/master.zip - curl -fsSL -o pillow-depends.zip https://github.com/python-pillow/pillow-depends/archive/master.zip
- 7z x pillow-depends.zip -oc:\ - 7z x pillow-depends.zip -oc:\
- mv c:\pillow-depends-master c:\pillow-depends - mv c:\pillow-depends-master c:\pillow-depends
- xcopy c:\pillow-depends\*.zip c:\pillow\winbuild\ - xcopy /S /Y c:\pillow-depends\test_images\* c:\pillow\tests\images
- xcopy c:\pillow-depends\*.tar.gz c:\pillow\winbuild\ - 7z x ..\pillow-depends\nasm-2.14.02-win64.zip -oc:\
- xcopy /s c:\pillow-depends\test_images\* c:\pillow\tests\images - ..\pillow-depends\gs9533w32.exe /S
- path c:\nasm-2.14.02;C:\Program Files (x86)\gs\gs9.53.3\bin;%PATH%
- cd c:\pillow\winbuild\ - cd c:\pillow\winbuild\
- ps: | - ps: |
if ($env:PYTHON -eq "c:/vp/pypy3") c:\python37\python.exe c:\pillow\winbuild\build_prepare.py -v --depends=C:\pillow-depends\
{ c:\pillow\winbuild\build\build_dep_all.cmd
c:\pillow\winbuild\appveyor_install_pypy3.cmd
}
- ps: |
if ($env:PYTHON -eq "c:/msys64/mingw32")
{
c:\msys64\usr\bin\bash -l -c c:\\pillow\\winbuild\\appveyor_install_msys2_deps.sh
}
else
{
c:\python37\python.exe c:\pillow\winbuild\build_dep.py
c:\pillow\winbuild\build_deps.cmd
$host.SetShouldExit(0) $host.SetShouldExit(0)
} - path C:\pillow\winbuild\build\bin;%PATH%
- curl -fsSL -o gs952.exe https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs952/gs952w32.exe - '%PYTHON%\%EXECUTABLE% -m pip install -U "setuptools>=49.3.2"'
- gs952.exe /S
- path %path%;C:\Program Files (x86)\gs\gs9.52\bin
build_script: build_script:
- ps: | - ps: |
if ($env:PYTHON -eq "c:/msys64/mingw32") c:\pillow\winbuild\build\build_pillow.cmd install
{
c:\msys64\usr\bin\bash -l -c c:\\pillow\\winbuild\\appveyor_build_msys2.sh
Write-Host "through install"
$host.SetShouldExit(0) $host.SetShouldExit(0)
}
else
{
& $env:PYTHON/$env:EXECUTABLE c:\pillow\winbuild\build.py
$host.SetShouldExit(0)
}
- cd c:\pillow - cd c:\pillow
- '%PYTHON%\%EXECUTABLE% selftest.py --installed' - '%PYTHON%\%EXECUTABLE% selftest.py --installed'
test_script: test_script:
- cd c:\pillow - cd c:\pillow
- '%PYTHON%\%PIP_DIR%\pip.exe install pytest pytest-cov' - '%PYTHON%\%EXECUTABLE% -m pip install pytest pytest-cov'
- c:\"Program Files (x86)"\"Windows Kits"\10\Debuggers\x86\gflags.exe /p /enable %PYTHON%\%EXECUTABLE% - c:\"Program Files (x86)"\"Windows Kits"\10\Debuggers\x86\gflags.exe /p /enable %PYTHON%\%EXECUTABLE%
- '%PYTHON%\%EXECUTABLE% -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests' - '%PYTHON%\%EXECUTABLE% -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests'
#- '%PYTHON%\%EXECUTABLE% test-installed.py -v -s %TEST_OPTIONS%' TODO TEST_OPTIONS with pytest? #- '%PYTHON%\%EXECUTABLE% test-installed.py -v -s %TEST_OPTIONS%' TODO TEST_OPTIONS with pytest?
after_test: after_test:
- pip install codecov - python -m pip install codecov
- codecov --file coverage.xml --name %PYTHON% --flags AppVeyor - codecov --file coverage.xml --name %PYTHON% --flags AppVeyor
matrix: matrix:
@ -97,9 +66,9 @@ artifacts:
before_deploy: before_deploy:
- cd c:\pillow - cd c:\pillow
- '%PYTHON%\%PIP_DIR%\pip.exe install wheel' - '%PYTHON%\%EXECUTABLE% -m pip install wheel'
- cd c:\pillow\winbuild\ - cd c:\pillow\winbuild\
- '%PYTHON%\%EXECUTABLE% c:\pillow\winbuild\build.py --wheel' - c:\pillow\winbuild\build\build_pillow.cmd bdist_wheel
- cd c:\pillow - cd c:\pillow
- ps: Get-ChildItem .\dist\*.* | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } - ps: Get-ChildItem .\dist\*.* | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }

View File

@ -7,13 +7,3 @@ if [[ $MATRIX_DOCKER ]]; then
else else
coverage xml coverage xml
fi fi
if [[ $TRAVIS ]]; then
codecov --flags TravisCI
fi
if [ "$TRAVIS_PYTHON_VERSION" == "3.8" ]; then
# Coverage and quality reports on just the latest diff.
depends/diffcover-install.sh
depends/diffcover-run.sh
fi

View File

@ -1,32 +1,50 @@
#!/bin/bash #!/bin/bash
aptget_update()
{
if [ ! -z $1 ]; then
echo ""
echo "Retrying apt-get update..."
echo ""
fi
output=`sudo apt-get update 2>&1`
echo "$output"
if [[ $output == *[WE]:\ * ]]; then
return 1
fi
}
aptget_update || aptget_update retry || aptget_update retry
set -e set -e
sudo apt-get update
sudo apt-get -qq install libfreetype6-dev liblcms2-dev python3-tk\ sudo apt-get -qq install libfreetype6-dev liblcms2-dev python3-tk\
ghostscript libffi-dev libjpeg-turbo-progs libopenjp2-7-dev\ ghostscript libffi-dev libjpeg-turbo-progs libopenjp2-7-dev\
cmake imagemagick libharfbuzz-dev libfribidi-dev cmake imagemagick libharfbuzz-dev libfribidi-dev
PYTHONOPTIMIZE=0 pip install cffi python3 -m pip install --upgrade pip
pip install coverage PYTHONOPTIMIZE=0 python3 -m pip install cffi
pip install olefile python3 -m pip install coverage
pip install -U pytest python3 -m pip install olefile
pip install -U pytest-cov python3 -m pip install -U pytest
pip install pyroma python3 -m pip install -U pytest-cov
pip install test-image-results python3 -m pip install pyroma
pip install numpy python3 -m pip install test-image-results
if [[ $TRAVIS_PYTHON_VERSION == 3.* ]]; then # TODO Remove condition when numpy supports 3.10
if ! [ "$GHA_PYTHON_VERSION" == "3.10-dev" ]; then python3 -m pip install numpy ; fi
# TODO Remove when 3.8 / 3.9 includes setuptools 49.3.2+:
if [ "$GHA_PYTHON_VERSION" == "3.8" ]; then python3 -m pip install -U "setuptools>=49.3.2" ; fi
if [ "$GHA_PYTHON_VERSION" == "3.9" ]; then python3 -m pip install -U "setuptools>=49.3.2" ; fi
# PyQt5 doesn't support PyPy3
# Wheel doesn't yet support 3.10
if [[ $GHA_PYTHON_VERSION == 3.* && $GHA_PYTHON_VERSION != "3.10-dev" ]]; then
# arm64, ppc64le, s390x CPUs: # arm64, ppc64le, s390x CPUs:
# "ERROR: Could not find a version that satisfies the requirement pyqt5" # "ERROR: Could not find a version that satisfies the requirement pyqt5"
if [[ $TRAVIS_CPU_ARCH == "amd64" ]]; then sudo apt-get -qq install libxcb-xinerama0 pyqt5-dev-tools
sudo apt-get -qq install pyqt5-dev-tools python3 -m pip install pyqt5
pip install pyqt5!=5.14.1
fi
fi fi
# docs only on Python 3.8
if [ "$TRAVIS_PYTHON_VERSION" == "3.8" ]; then pip install -r requirements.txt ; fi
# webp # webp
pushd depends && ./install_webp.sh && popd pushd depends && ./install_webp.sh && popd

View File

@ -2,9 +2,4 @@
set -e set -e
python -m pytest -v -x -W always --cov PIL --cov Tests --cov-report term Tests python -bb -m pytest -v -x -W always --cov PIL --cov Tests --cov-report term Tests
# Docs
if [ "$TRAVIS_PYTHON_VERSION" == "3.8" ] && [ "$TRAVIS_CPU_ARCH" == "amd64" ]; then
make doccheck
fi

View File

@ -9,7 +9,7 @@ Please send a pull request to the master branch. Please include [documentation](
- Fork the Pillow repository. - Fork the Pillow repository.
- Create a branch from master. - Create a branch from master.
- Develop bug fixes, features, tests, etc. - Develop bug fixes, features, tests, etc.
- Run the test suite. You can enable [Travis CI](https://travis-ci.org/profile/) and [AppVeyor](https://ci.appveyor.com/projects/new) on your repo to catch test failures prior to the pull request, and [Codecov](https://codecov.io/gh) to see if the changed code is covered by tests. - Run the test suite. You can enable GitHub Actions (https://github.com/MY-USERNAME/Pillow/actions) and [AppVeyor](https://ci.appveyor.com/projects/new) on your repo to catch test failures prior to the pull request, and [Codecov](https://codecov.io/gh) to see if the changed code is covered by tests.
- Create a pull request to pull the changes from your branch to the Pillow master. - Create a pull request to pull the changes from your branch to the Pillow master.
### Guidelines ### Guidelines
@ -17,7 +17,7 @@ Please send a pull request to the master branch. Please include [documentation](
- Separate code commits from reformatting commits. - Separate code commits from reformatting commits.
- Provide tests for any newly added code. - Provide tests for any newly added code.
- Follow PEP 8. - Follow PEP 8.
- When committing only documentation changes please include [ci skip] in the commit message to avoid running tests on Travis-CI and AppVeyor. - When committing only documentation changes please include `[ci skip]` in the commit message to avoid running tests on AppVeyor.
## Reporting Issues ## Reporting Issues

13
.github/mergify.yml vendored Normal file
View File

@ -0,0 +1,13 @@
pull_request_rules:
- name: Automatic merge
conditions:
- "#approved-reviews-by>=1"
- label=automerge
- status-success=Lint
- status-success=Test Successful
- status-success=Docker Test Successful
- status-success=Windows Test Successful
- status-success=continuous-integration/appveyor/pr
actions:
merge:
method: merge

26
.github/release-drafter.yml vendored Normal file
View File

@ -0,0 +1,26 @@
name-template: "$NEXT_MINOR_VERSION"
tag-template: "$NEXT_MINOR_VERSION"
change-template: '- $TITLE #$NUMBER [@$AUTHOR]'
categories:
- title: "Dependencies"
label: "Dependency"
- title: "Deprecations"
label: "Deprecation"
- title: "Documentation"
label: "Documentation"
- title: "Removals"
label: "Removal"
- title: "Testing"
label: "Testing"
exclude-labels:
- "changelog: skip"
template: |
https://pillow.readthedocs.io/en/stable/releasenotes/$NEXT_MINOR_VERSION.html
## Changes
$CHANGES

View File

@ -6,17 +6,14 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8"]
name: Python ${{ matrix.python-version }} name: Lint
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2
- name: pip cache - name: pip cache
uses: actions/cache@v1 uses: actions/cache@v2
with: with:
path: ~/.cache/pip path: ~/.cache/pip
key: lint-pip-${{ hashFiles('**/setup.py') }} key: lint-pip-${{ hashFiles('**/setup.py') }}
@ -24,26 +21,28 @@ jobs:
lint-pip- lint-pip-
- name: pre-commit cache - name: pre-commit cache
uses: actions/cache@v1 uses: actions/cache@v2
with: with:
path: ~/.cache/pre-commit path: ~/.cache/pre-commit
key: lint-pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }} key: lint-pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }}
restore-keys: | restore-keys: |
lint-pre-commit- lint-pre-commit-
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python
uses: actions/setup-python@v1 uses: actions/setup-python@v2
with: with:
python-version: ${{ matrix.python-version }} python-version: 3.8
- name: Build system information - name: Build system information
run: python .github/workflows/system-info.py run: python .github/workflows/system-info.py
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install -U pip
python -m pip install --upgrade tox python -m pip install -U tox
- name: Lint - name: Lint
run: tox -e lint run: tox -e lint
env:
PRE_COMMIT_COLOR: always

View File

@ -2,16 +2,23 @@
set -e set -e
brew install libtiff libjpeg openjpeg libimagequant webp little-cms2 freetype brew install libtiff libjpeg openjpeg libimagequant webp little-cms2 freetype openblas libraqm
PYTHONOPTIMIZE=0 pip install cffi PYTHONOPTIMIZE=0 python3 -m pip install cffi
pip install coverage python3 -m pip install coverage
pip install olefile python3 -m pip install olefile
pip install -U pytest python3 -m pip install -U pytest
pip install -U pytest-cov python3 -m pip install -U pytest-cov
pip install pyroma python3 -m pip install pyroma
pip install test-image-results python3 -m pip install test-image-results
pip install numpy
echo -e "[openblas]\nlibraries = openblas\nlibrary_dirs = /usr/local/opt/openblas/lib" >> ~/.numpy-site.cfg
# TODO Remove condition when numpy supports 3.10
if ! [ "$GHA_PYTHON_VERSION" == "3.10-dev" ]; then python3 -m pip install numpy ; fi
# TODO Remove when 3.8 / 3.9 includes setuptools 49.3.2+:
if [ "$GHA_PYTHON_VERSION" == "3.8" ]; then python3 -m pip install -U "setuptools>=49.3.2" ; fi
if [ "$GHA_PYTHON_VERSION" == "3.9" ]; then python3 -m pip install -U "setuptools>=49.3.2" ; fi
# extra test images # extra test images
pushd depends && ./install_extra_test_images.sh && popd pushd depends && ./install_extra_test_images.sh && popd

17
.github/workflows/release-drafter.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: Release drafter
on:
push:
# branches to consider in the event; optional, defaults to all
branches:
- master
jobs:
update_release_draft:
if: github.repository == 'python-pillow/Pillow'
runs-on: ubuntu-latest
steps:
# Drafts your next release notes as pull requests are merged into "master"
- uses: release-drafter/release-drafter@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -10,30 +10,44 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
docker: [ docker: [
# Run slower jobs first to give them a headstart and reduce waiting time
ubuntu-20.04-focal-arm64v8,
ubuntu-20.04-focal-ppc64le,
ubuntu-20.04-focal-s390x,
# Then run the remainder
alpine, alpine,
amazon-2-amd64,
arch, arch,
ubuntu-16.04-xenial-amd64,
ubuntu-18.04-bionic-amd64,
debian-9-stretch-x86,
debian-10-buster-x86,
centos-6-amd64,
centos-7-amd64, centos-7-amd64,
centos-8-amd64, centos-8-amd64,
amazon-1-amd64, debian-10-buster-x86,
amazon-2-amd64, fedora-32-amd64,
fedora-30-amd64, fedora-33-amd64,
fedora-31-amd64, ubuntu-18.04-bionic-amd64,
ubuntu-20.04-focal-amd64,
] ]
dockerTag: [master] dockerTag: [master]
include:
- docker: "ubuntu-20.04-focal-arm64v8"
qemu-arch: "aarch64"
- docker: "ubuntu-20.04-focal-ppc64le"
qemu-arch: "ppc64le"
- docker: "ubuntu-20.04-focal-s390x"
qemu-arch: "s390x"
name: ${{ matrix.docker }} name: ${{ matrix.docker }}
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2
- name: Build system information - name: Build system information
run: python .github/workflows/system-info.py run: python .github/workflows/system-info.py
- name: Set up QEMU
if: "matrix.qemu-arch"
run: |
docker run --rm --privileged aptman/qus -s -- -p ${{ matrix.qemu-arch }}
- name: Docker pull - name: Docker pull
run: | run: |
docker pull pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }} docker pull pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
@ -46,7 +60,6 @@ jobs:
sudo chown -R runner $GITHUB_WORKSPACE sudo chown -R runner $GITHUB_WORKSPACE
- name: After success - name: After success
if: success()
run: | run: |
PATH="$PATH:~/.local/bin" PATH="$PATH:~/.local/bin"
docker start pillow_container docker start pillow_container
@ -59,8 +72,15 @@ jobs:
MATRIX_DOCKER: ${{ matrix.docker }} MATRIX_DOCKER: ${{ matrix.docker }}
- name: Upload coverage - name: Upload coverage
if: success()
uses: codecov/codecov-action@v1 uses: codecov/codecov-action@v1
with: with:
flags: GHA_Docker flags: GHA_Docker
name: ${{ matrix.docker }} name: ${{ matrix.docker }}
success:
needs: build
runs-on: ubuntu-latest
name: Docker Test Successful
steps:
- name: Success
run: echo Docker Test Successful

View File

@ -4,12 +4,11 @@ on: [push, pull_request]
jobs: jobs:
build: build:
runs-on: windows-2019 runs-on: windows-2019
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
python-version: ["3.5", "3.6", "3.7", "3.8", "pypy3"] python-version: ["pypy-3.6", "pypy-3.7", "3.6", "3.7", "3.8", "3.9", "3.10-dev"]
architecture: ["x86", "x64"] architecture: ["x86", "x64"]
include: include:
- architecture: "x86" - architecture: "x86"
@ -20,22 +19,26 @@ jobs:
platform-msbuild: "x64" platform-msbuild: "x64"
exclude: exclude:
# PyPy does not support 64-bit on Windows # PyPy does not support 64-bit on Windows
- python-version: "pypy3" - python-version: "pypy-3.6"
architecture: "x64"
- python-version: "pypy-3.7"
architecture: "x64" architecture: "x64"
timeout-minutes: 30 timeout-minutes: 30
name: Python ${{ matrix.python-version }} ${{ matrix.architecture }} name: Python ${{ matrix.python-version }} ${{ matrix.architecture }}
steps: steps:
- uses: actions/checkout@v1 - name: Checkout Pillow
uses: actions/checkout@v2
- uses: actions/checkout@v1 - name: Checkout cached dependencies
uses: actions/checkout@v2
with: with:
repository: python-pillow/pillow-depends repository: python-pillow/pillow-depends
ref: master path: winbuild\depends
- name: Cache - name: Cache pip
uses: actions/cache@v1 uses: actions/cache@v2
with: with:
path: ~\AppData\Local\pip\Cache path: ~\AppData\Local\pip\Cache
key: key:
@ -46,296 +49,125 @@ jobs:
# sets env: pythonLocation # sets env: pythonLocation
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v1 uses: actions/setup-python@v2
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }} architecture: ${{ matrix.architecture }}
- name: Build system information - name: Print build system information
run: python .github/workflows/system-info.py run: python .github/workflows/system-info.py
- name: pip install wheel pytest pytest-cov - name: python -m pip install wheel pytest pytest-cov
run: python -m pip install wheel pytest pytest-cov
# TODO Remove when 3.8 / 3.9 includes setuptools 49.3.2+:
- name: Upgrade setuptools
if: "contains(matrix.python-version, '3.8') || contains(matrix.python-version, '3.9')"
run: python -m pip install -U "setuptools>=49.3.2"
- name: Install dependencies
id: install
run: | run: |
"%pythonLocation%\python.exe" -m pip install wheel pytest pytest-cov 7z x winbuild\depends\nasm-2.14.02-win64.zip "-o$env:RUNNER_WORKSPACE\"
shell: cmd echo "$env:RUNNER_WORKSPACE\nasm-2.14.02" >> $env:GITHUB_PATH
- name: Fetch dependencies winbuild\depends\gs9533w32.exe /S
run: | echo "C:\Program Files (x86)\gs\gs9.53.3\bin" >> $env:GITHUB_PATH
7z x ..\pillow-depends\nasm-2.14.02-win64.zip "-o$env:RUNNER_WORKSPACE\"
Write-Host "`#`#[add-path]$env:RUNNER_WORKSPACE\nasm-2.14.02"
Write-Host "::add-path::$env:RUNNER_WORKSPACE\nasm-2.14.02"
..\pillow-depends\gs950w32.exe /S xcopy /S /Y winbuild\depends\test_images\* Tests\images\
Write-Host "`#`#[add-path]C:\Program Files (x86)\gs\gs9.50\bin"
Write-Host "::add-path::C:\Program Files (x86)\gs\gs9.50\bin"
$env:PYTHON=$env:pythonLocation # make cache key depend on VS version
xcopy ..\pillow-depends\*.zip $env:GITHUB_WORKSPACE\winbuild\ & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" | find """catalog_buildVersion""" | ForEach-Object { $a = $_.split(" ")[1]; echo "::set-output name=vs::$a" }
xcopy ..\pillow-depends\*.tar.gz $env:GITHUB_WORKSPACE\winbuild\
xcopy /s ..\pillow-depends\test_images\* $env:GITHUB_WORKSPACE\tests\images\
cd $env:GITHUB_WORKSPACE/winbuild/
python.exe $env:GITHUB_WORKSPACE\winbuild\build_dep.py
env:
EXECUTABLE: bin\python.exe
shell: pwsh shell: pwsh
- name: Build dependencies / libjpeg - name: Cache build
if: false id: build-cache
run: | uses: actions/cache@v2
REM FIXME uses /MT not /MD, see makefile.vc and win32.mak for more info with:
path: winbuild\build
key:
${{ hashFiles('winbuild\build_prepare.py') }}-${{ hashFiles('.github\workflows\test-windows.yml') }}-${{ env.pythonLocation }}-${{ steps.install.outputs.vs }}
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include - name: Prepare build
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32 if: steps.build-cache.outputs.cache-hit != 'true'
set BUILD=%GITHUB_WORKSPACE%\winbuild\build run: |
cd /D %BUILD%\jpeg-9d & python.exe winbuild\build_prepare.py -v --python=$env:pythonLocation --srcdir
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }} shell: pwsh
echo on
nmake -nologo -f makefile.vc setup-vc6
nmake -nologo -f makefile.vc clean
nmake -nologo -f makefile.vc nodebug=1 libjpeg.lib cjpeg.exe djpeg.exe
copy /Y /B j*.h %INCLIB%
copy /Y /B *.lib %INCLIB%
copy /Y /B *.exe %INCLIB%
shell: cmd
- name: Build dependencies / libjpeg-turbo - name: Build dependencies / libjpeg-turbo
run: | if: steps.build-cache.outputs.cache-hit != 'true'
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include run: "& winbuild\\build\\build_dep_libjpeg.cmd"
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build
cd /D %BUILD%\libjpeg-turbo-2.0.3
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
echo on
set CMAKE=cmake.exe -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_RULE_MESSAGES:BOOL=OFF
set CMAKE=%CMAKE% -DENABLE_SHARED:BOOL=OFF -DWITH_JPEG8:BOOL=TRUE -DWITH_CRT_DLL:BOOL=TRUE -DCMAKE_BUILD_TYPE=Release
%CMAKE% -G "NMake Makefiles" .
nmake -nologo -f Makefile clean
nmake -nologo -f Makefile jpeg-static cjpeg-static djpeg-static
copy /Y /B j*.h %INCLIB%
copy /Y /B jpeg-static.lib %INCLIB%\libjpeg.lib
copy /Y /B cjpeg-static.exe %INCLIB%\cjpeg.exe
copy /Y /B djpeg-static.exe %INCLIB%\djpeg.exe
shell: cmd
- name: Build dependencies / zlib - name: Build dependencies / zlib
run: | if: steps.build-cache.outputs.cache-hit != 'true'
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include run: "& winbuild\\build\\build_dep_zlib.cmd"
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build
cd /D %BUILD%\zlib-1.2.11
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
echo on
nmake -nologo -f win32\Makefile.msc clean
nmake -nologo -f win32\Makefile.msc zlib.lib
copy /Y /B z*.h %INCLIB%
copy /Y /B *.lib %INCLIB%
copy /Y /B zlib.lib %INCLIB%\z.lib
shell: cmd
- name: Build dependencies / LibTIFF - name: Build dependencies / LibTiff
run: | if: steps.build-cache.outputs.cache-hit != 'true'
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include run: "& winbuild\\build\\build_dep_libtiff.cmd"
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build
cd /D %BUILD%\tiff-4.1.0
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
echo on
copy %GITHUB_WORKSPACE%\winbuild\tiff.opt nmake.opt
nmake -nologo -f makefile.vc clean
nmake -nologo -f makefile.vc lib
copy /Y /B libtiff\tiff*.h %INCLIB%
copy /Y /B libtiff\*.dll %INCLIB%
copy /Y /B libtiff\*.lib %INCLIB%
shell: cmd
- name: Build dependencies / WebP - name: Build dependencies / WebP
run: | if: steps.build-cache.outputs.cache-hit != 'true'
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include run: "& winbuild\\build\\build_dep_libwebp.cmd"
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build # for FreeType CBDT font support
cd /D %BUILD%\libwebp-1.1.0 - name: Build dependencies / libpng
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }} if: steps.build-cache.outputs.cache-hit != 'true'
echo on run: "& winbuild\\build\\build_dep_libpng.cmd"
rmdir /S /Q output\release-static
nmake -nologo -f Makefile.vc CFG=release-static OBJDIR=output ARCH=${{ matrix.architecture }} all
mkdir %INCLIB%\webp
copy /Y /B src\webp\*.h %INCLIB%\webp
copy /Y /B output\release-static\${{ matrix.architecture }}\lib\* %INCLIB%
shell: cmd
- name: Build dependencies / FreeType - name: Build dependencies / FreeType
run: | if: steps.build-cache.outputs.cache-hit != 'true'
REM Toolkit v100 not available; missing VCTargetsPath; Clean fails run: "& winbuild\\build\\build_dep_freetype.cmd"
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build
cd /D %BUILD%\freetype-2.10.1
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
echo on
rmdir /S /Q objs
set DefaultPlatformToolset=v142
set VCTargetsPath=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\
set MSBUILD="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe"
powershell -Command "(gc builds\windows\vc2010\freetype.vcxproj) -replace 'MultiThreaded<', 'MultiThreadedDLL<' | Out-File -encoding ASCII builds\windows\vc2010\freetype.vcxproj"
%MSBUILD% builds\windows\vc2010\freetype.sln /t:Build /p:Configuration="Release Static" /p:Platform=${{ matrix.platform-msbuild }} /m
xcopy /Y /E /Q include %INCLIB%
copy /Y /B "objs\${{ matrix.platform-msbuild }}\Release Static\freetype.lib" %INCLIB%
shell: cmd
- name: Build dependencies / LCMS2 - name: Build dependencies / LCMS2
run: | if: steps.build-cache.outputs.cache-hit != 'true'
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include run: "& winbuild\\build\\build_dep_lcms2.cmd"
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build
cd /D %BUILD%\lcms2-2.8
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
echo on
rmdir /S /Q Lib
rmdir /S /Q Projects\VC2015\Release
set VCTargetsPath=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\
set MSBUILD="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe"
powershell %GITHUB_WORKSPACE%\winbuild\lcms2_patch.ps1
%MSBUILD% Projects\VC2015\lcms2.sln /t:Clean;lcms2_static /p:Configuration="Release" /p:Platform=${{ matrix.platform-msbuild }} /m
xcopy /Y /E /Q include %INCLIB%
copy /Y /B Lib\MS\*.lib %INCLIB%
shell: cmd
- name: Build dependencies / OpenJPEG - name: Build dependencies / OpenJPEG
run: | if: steps.build-cache.outputs.cache-hit != 'true'
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include run: "& winbuild\\build\\build_dep_openjpeg.cmd"
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build
cd /D %BUILD%\openjpeg-2.3.1msvcr10-x32
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
echo on
set CMAKE=cmake.exe -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_RULE_MESSAGES:BOOL=OFF
set CMAKE=%CMAKE% -DBUILD_THIRDPARTY:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=OFF
set CMAKE=%CMAKE% -DCMAKE_BUILD_TYPE=Release
%CMAKE% -G "NMake Makefiles" .
nmake -nologo -f Makefile clean
nmake -nologo -f Makefile
mkdir %INCLIB%\openjpeg-2.3.1
copy /Y /B src\lib\openjp2\*.h %INCLIB%\openjpeg-2.3.1
copy /Y /B bin\*.lib %INCLIB%
shell: cmd
# GPL licensed; skip if building wheels # GPL licensed
- name: Build dependencies / libimagequant - name: Build dependencies / libimagequant
if: "github.event_name != 'push' || contains(matrix.python-version, 'pypy')" if: steps.build-cache.outputs.cache-hit != 'true'
run: | run: "& winbuild\\build\\build_dep_libimagequant.cmd"
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build
rem e5d454b: Merge tag '2.12.6' into msvc
cd /D %BUILD%\libimagequant-e5d454bc7f5eb63ee50c84a83a7fa5ac94f68ec4
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
echo on
echo (gc CMakeLists.txt) -replace 'add_library', "add_compile_options(-openmp-)`r`nadd_library" ^| Out-File -encoding ASCII CMakeLists.txt > patch.ps1
echo (gc CMakeLists.txt) -replace ' SHARED', ' STATIC' ^| Out-File -encoding ASCII CMakeLists.txt >> patch.ps1
powershell .\patch.ps1
set CMAKE=cmake.exe -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_RULE_MESSAGES:BOOL=OFF
set CMAKE=%CMAKE% -DCMAKE_BUILD_TYPE=Release
%CMAKE% -G "NMake Makefiles" .
nmake -nologo -f Makefile clean
nmake -nologo -f Makefile
copy /Y /B *.h %INCLIB%
copy /Y /B *.lib %INCLIB%
shell: cmd
# for Raqm # Raqm dependencies
- name: Build dependencies / HarfBuzz - name: Build dependencies / HarfBuzz
run: | if: steps.build-cache.outputs.cache-hit != 'true'
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include run: "& winbuild\\build\\build_dep_harfbuzz.cmd"
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build
set INCLUDE=%INCLUDE%;%INCLIB%
set LIB=%LIB%;%INCLIB%
cd /D %BUILD%\harfbuzz-2.6.4
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
echo on
set CMAKE=cmake.exe -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_RULE_MESSAGES:BOOL=OFF
set CMAKE=%CMAKE% -DHB_HAVE_FREETYPE:BOOL=ON -DCMAKE_BUILD_TYPE=Release
%CMAKE% -G "NMake Makefiles" .
nmake -nologo -f Makefile clean
nmake -nologo -f Makefile harfbuzz
copy /Y /B src\*.h %INCLIB%
copy /Y /B *.lib %INCLIB%
shell: cmd
# for Raqm
- name: Build dependencies / FriBidi - name: Build dependencies / FriBidi
run: | if: steps.build-cache.outputs.cache-hit != 'true'
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include run: "& winbuild\\build\\build_dep_fribidi.cmd"
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build
cd /D %BUILD%\fribidi-1.0.9
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
echo on
copy /Y /B %GITHUB_WORKSPACE%\winbuild\fribidi.cmake CMakeLists.txt
set CMAKE=cmake.exe -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_RULE_MESSAGES:BOOL=OFF
set CMAKE=%CMAKE% -DCMAKE_BUILD_TYPE=Release
%CMAKE% -G "NMake Makefiles" .
nmake -nologo -f Makefile clean
nmake -nologo -f Makefile fribidi
copy /Y /B lib\*.h %INCLIB%
copy /Y /B *.lib %INCLIB%
shell: cmd
- name: Build dependencies / Raqm - name: Build dependencies / Raqm
run: | if: steps.build-cache.outputs.cache-hit != 'true'
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include run: "& winbuild\\build\\build_dep_libraqm.cmd"
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
set BUILD=%GITHUB_WORKSPACE%\winbuild\build # trim ~150MB x 9
set INCLUDE=%INCLUDE%;%INCLIB% - name: Optimize build cache
set LIB=%LIB%;%INCLIB% if: steps.build-cache.outputs.cache-hit != 'true'
cd /D %BUILD%\libraqm-0.7.0 run: rmdir /S /Q winbuild\build\src
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
echo on
copy /Y /B %GITHUB_WORKSPACE%\winbuild\raqm.cmake CMakeLists.txt
set CMAKE=cmake.exe -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_RULE_MESSAGES:BOOL=OFF
set CMAKE=%CMAKE% -DCMAKE_BUILD_TYPE=Release
%CMAKE% -G "NMake Makefiles" .
nmake -nologo -f Makefile clean
nmake -nologo -f Makefile libraqm
copy /Y /B src\*.h %INCLIB%
copy /Y /B libraqm.dll %INCLIB%
shell: cmd shell: cmd
- name: Build Pillow - name: Build Pillow
run: | run: |
set PYTHON=%pythonLocation% $FLAGS=""
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include if ('${{ github.event_name }}' -eq 'push') { $FLAGS="--disable-imagequant" }
set MPLSRC=%GITHUB_WORKSPACE% & winbuild\build\build_pillow.cmd $FLAGS install
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32 & $env:pythonLocation\python.exe selftest.py --installed
cd /D %GITHUB_WORKSPACE% shell: pwsh
set LIB=%INCLIB%;%PYTHON%\tcl
set INCLUDE=%INCLIB%;%GITHUB_WORKSPACE%\depends\tcl86\include;%INCLUDE%
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
set MSSdk=1
set DISTUTILS_USE_SDK=1
set py_vcruntime_redist=true
%PYTHON%\python.exe setup.py build_ext install
rem Add libraqm.dll (copied to INCLIB) to PATH.
path %INCLIB%;%PATH%
%PYTHON%\python.exe selftest.py --installed
shell: cmd
# failing with PyPy3 # failing with PyPy3
- name: Enable heap verification - name: Enable heap verification
if: "!contains(matrix.python-version, 'pypy')" if: "!contains(matrix.python-version, 'pypy')"
run: | run: "& 'C:\\Program Files (x86)\\Windows Kits\\10\\Debuggers\\x86\\gflags.exe' /p /enable $env:pythonLocation\\python.exe"
c:\"Program Files (x86)"\"Windows Kits"\10\Debuggers\x86\gflags.exe /p /enable %PYTHON%\python.exe
shell: cmd
- name: Test Pillow - name: Test Pillow
run: | run: |
set PYTHON=%pythonLocation% path %GITHUB_WORKSPACE%\\winbuild\\build\\bin;%PATH%
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32 python.exe -m pytest -vx -W always --cov PIL --cov Tests --cov-report term --cov-report xml Tests
rem Add libraqm.dll (copied to INCLIB) to PATH.
path %INCLIB%;%PATH%
cd /D %GITHUB_WORKSPACE%
%PYTHON%\python.exe -m pytest -vx -W always --cov PIL --cov Tests --cov-report term --cov-report xml Tests
shell: cmd shell: cmd
- name: Prepare to upload errors - name: Prepare to upload errors
@ -345,45 +177,117 @@ jobs:
shell: pwsh shell: pwsh
- name: Upload errors - name: Upload errors
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
if: failure() if: failure()
with: with:
name: errors name: errors
path: Tests/errors path: Tests/errors
- name: After success - name: After success
if: success()
run: | run: |
.ci/after_success.sh .ci/after_success.sh
shell: pwsh shell: pwsh
- name: Upload coverage - name: Upload coverage
if: success()
uses: codecov/codecov-action@v1 uses: codecov/codecov-action@v1
with: with:
file: ./coverage.xml file: ./coverage.xml
flags: GHA_Windows flags: GHA_Windows
name: ${{ runner.os }} Python ${{ matrix.python-version }} name: ${{ runner.os }} Python ${{ matrix.python-version }} ${{ matrix.architecture }}
- name: Build wheel - name: Build wheel
id: wheel id: wheel
if: "github.event_name == 'push' && !contains(matrix.python-version, 'pypy')" # Skip wheels on 3.10 due to https://github.com/pypa/wheel/issues/354
if: "github.event_name == 'push' && !contains(matrix.python-version, '3.10')"
run: | run: |
for /f "tokens=3 delims=/" %%a in ("${{ github.ref }}") do echo ##[set-output name=dist;]dist-%%a
for /f "tokens=3 delims=/" %%a in ("${{ github.ref }}") do echo ::set-output name=dist::dist-%%a for /f "tokens=3 delims=/" %%a in ("${{ github.ref }}") do echo ::set-output name=dist::dist-%%a
set PYTHON=%pythonLocation% winbuild\\build\\build_pillow.cmd --disable-imagequant bdist_wheel
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include
set MPLSRC=%GITHUB_WORKSPACE%
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
cd /D %GITHUB_WORKSPACE%
set LIB=%INCLIB%;%PYTHON%\tcl
set INCLUDE=%INCLIB%;%GITHUB_WORKSPACE%\depends\tcl86\include;%INCLUDE%
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
%PYTHON%\python.exe setup.py bdist_wheel
shell: cmd shell: cmd
- uses: actions/upload-artifact@v1 - uses: actions/upload-artifact@v2
if: "github.event_name == 'push' && !contains(matrix.python-version, 'pypy')" # Skip wheels on 3.10 due to https://github.com/pypa/wheel/issues/354
if: "github.event_name == 'push' && !contains(matrix.python-version, '3.10')"
with: with:
name: ${{ steps.wheel.outputs.dist }} name: ${{ steps.wheel.outputs.dist }}
path: dist path: dist\*.whl
msys:
runs-on: windows-2019
strategy:
fail-fast: false
matrix:
mingw: ["MINGW32", "MINGW64"]
include:
- mingw: "MINGW32"
name: "MSYS2 MinGW 32-bit"
package: "mingw-w64-i686"
- mingw: "MINGW64"
name: "MSYS2 MinGW 64-bit"
package: "mingw-w64-x86_64"
defaults:
run:
shell: bash.exe --login -eo pipefail "{0}"
env:
MSYSTEM: ${{ matrix.mingw }}
CHERE_INVOKING: 1
timeout-minutes: 30
name: ${{ matrix.name }}
steps:
- uses: actions/checkout@v2
- name: Set up shell
run: echo "C:\msys64\usr\bin\" >> $env:GITHUB_PATH
shell: pwsh
- name: Install Dependencies
run: |
pacman -S --noconfirm \
${{ matrix.package }}-python3-cffi \
${{ matrix.package }}-python3-numpy \
${{ matrix.package }}-python3-olefile \
${{ matrix.package }}-python3-pip \
${{ matrix.package }}-python3-pyqt5 \
${{ matrix.package }}-python3-pytest \
${{ matrix.package }}-python3-pytest-cov \
${{ matrix.package }}-python3-setuptools \
${{ matrix.package }}-freetype \
${{ matrix.package }}-ghostscript \
${{ matrix.package }}-lcms2 \
${{ matrix.package }}-libimagequant \
${{ matrix.package }}-libjpeg-turbo \
${{ matrix.package }}-libraqm \
${{ matrix.package }}-libtiff \
${{ matrix.package }}-libwebp \
${{ matrix.package }}-openjpeg2 \
subversion
python3 -m pip install pyroma
pushd depends && ./install_extra_test_images.sh && popd
- name: Build Pillow
run: CFLAGS="-coverage" python3 setup.py build_ext install
- name: Test Pillow
run: |
python3 selftest.py --installed
python3 -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests
- name: Upload coverage
run: |
python3 -m pip install codecov
bash <(curl -s https://codecov.io/bash) -F GHA_Windows
env:
CODECOV_NAME: ${{ matrix.name }}
success:
needs: [build, msys]
runs-on: ubuntu-latest
name: Windows Test Successful
steps:
- name: Success
run: echo Windows Test Successful

View File

@ -13,17 +13,19 @@ jobs:
"macOS-latest", "macOS-latest",
] ]
python-version: [ python-version: [
"pypy3", "pypy-3.7",
"pypy-3.6",
"3.10-dev",
"3.9",
"3.8", "3.8",
"3.7", "3.7",
"3.6", "3.6",
"3.5",
] ]
include: include:
- python-version: "3.5"
env: PYTHONOPTIMIZE=2
- python-version: "3.6" - python-version: "3.6"
env: PYTHONOPTIMIZE=1 PYTHONOPTIMIZE: 1
- python-version: "3.7"
PYTHONOPTIMIZE: 2
# Include new variables for Codecov # Include new variables for Codecov
- os: ubuntu-latest - os: ubuntu-latest
codecov-flag: GHA_Ubuntu codecov-flag: GHA_Ubuntu
@ -36,31 +38,25 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Ubuntu cache
uses: actions/cache@v1
if: startsWith(matrix.os, 'ubuntu')
with:
path: ~/.cache/pip
key:
${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/.ci/*.sh') }}
restore-keys: |
${{ matrix.os }}-${{ matrix.python-version }}-
- name: macOS cache
uses: actions/cache@v1
if: startsWith(matrix.os, 'macOS')
with:
path: ~/Library/Caches/pip
key:
${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/.ci/*.sh') }}
restore-keys: |
${{ matrix.os }}-${{ matrix.python-version }}-
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1 uses: actions/setup-python@v2
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Get pip cache dir
id: pip-cache
run: |
echo "::set-output name=dir::$(python3 -m pip cache dir)"
- name: pip cache
uses: actions/cache@v2
with:
path: ${{ steps.pip-cache.outputs.dir }}
key:
${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/.ci/*.sh') }}
restore-keys: |
${{ matrix.os }}-${{ matrix.python-version }}-
- name: Build system information - name: Build system information
run: python .github/workflows/system-info.py run: python .github/workflows/system-info.py
@ -68,11 +64,15 @@ jobs:
if: startsWith(matrix.os, 'ubuntu') if: startsWith(matrix.os, 'ubuntu')
run: | run: |
.ci/install.sh .ci/install.sh
env:
GHA_PYTHON_VERSION: ${{ matrix.python-version }}
- name: Install macOS dependencies - name: Install macOS dependencies
if: startsWith(matrix.os, 'macOS') if: startsWith(matrix.os, 'macOS')
run: | run: |
.github/workflows/macos-install.sh .github/workflows/macos-install.sh
env:
GHA_PYTHON_VERSION: ${{ matrix.python-version }}
- name: Build - name: Build
run: | run: |
@ -80,7 +80,13 @@ jobs:
- name: Test - name: Test
run: | run: |
.ci/test.sh if [ "${{ matrix.os }}" = "ubuntu-latest" ]; then
xvfb-run -s '-screen 0 1024x768x24' .ci/test.sh
else
.ci/test.sh
fi
env:
PYTHONOPTIMIZE: ${{ matrix.PYTHONOPTIMIZE }}
- name: Prepare to upload errors - name: Prepare to upload errors
if: failure() if: failure()
@ -89,19 +95,31 @@ jobs:
shell: pwsh shell: pwsh
- name: Upload errors - name: Upload errors
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
if: failure() if: failure()
with: with:
name: errors name: errors
path: Tests/errors path: Tests/errors
- name: Docs
if: startsWith(matrix.os, 'ubuntu') && matrix.python-version == 3.9
run: |
python3 -m pip install sphinx-issues sphinx-removed-in sphinx-rtd-theme
make doccheck
- name: After success - name: After success
if: success()
run: | run: |
.ci/after_success.sh .ci/after_success.sh
- name: Upload coverage - name: Upload coverage
if: success()
run: bash <(curl -s https://codecov.io/bash) -F ${{ matrix.codecov-flag }} run: bash <(curl -s https://codecov.io/bash) -F ${{ matrix.codecov-flag }}
env: env:
CODECOV_NAME: ${{ matrix.os }} Python ${{ matrix.python-version }} CODECOV_NAME: ${{ matrix.os }} Python ${{ matrix.python-version }}
success:
needs: build
runs-on: ubuntu-latest
name: Test Successful
steps:
- name: Success
run: echo Test Successful

4
.gitignore vendored
View File

@ -81,6 +81,10 @@ docs/_build/
# Extra test images installed from pillow-depends/test_images # Extra test images installed from pillow-depends/test_images
Tests/images/README.md Tests/images/README.md
Tests/images/crash_1.tif
Tests/images/crash_2.tif
Tests/images/string_dimension.tiff
Tests/images/jpeg2000
Tests/images/msp Tests/images/msp
Tests/images/picins Tests/images/picins
Tests/images/sunraster Tests/images/sunraster

View File

@ -1,32 +1,43 @@
repos: repos:
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 19.10b0 rev: e66be67b9b6811913470f70c28b4d50f94d05b22 # frozen: 20.8b1
hooks: hooks:
- id: black - id: black
args: ["--target-version", "py35"] args: ["--target-version", "py36"]
# Only .py files, until https://github.com/psf/black/issues/402 resolved # Only .py files, until https://github.com/psf/black/issues/402 resolved
files: \.py$ files: \.py$
types: [] types: []
- repo: https://github.com/PyCQA/isort
rev: 377d260ffa6f746693f97b46d95025afc4bd8275 # frozen: 5.4.2
hooks:
- id: isort
- repo: https://github.com/asottile/yesqa
rev: 7a009f3ee493c796827ee334f9058b110a0e0db8 # frozen: v1.2.1
hooks:
- id: yesqa
- repo: https://github.com/Lucas-C/pre-commit-hooks
rev: f30f4974a08a6b2f6a1eeaf30a4d501cf909163a # frozen: v1.1.9
hooks:
- id: remove-tabs
exclude: (Makefile$|\.bat$|\.cmake$|\.eps$|\.fits$|\.opt$)
- repo: https://gitlab.com/pycqa/flake8 - repo: https://gitlab.com/pycqa/flake8
rev: 3.7.9 rev: 05f6544aef321e2fee03a1277ce2eef8880fb927 # frozen: 3.8.3
hooks: hooks:
- id: flake8 - id: flake8
additional_dependencies: [flake8-2020, flake8-implicit-str-concat] additional_dependencies: [flake8-2020, flake8-implicit-str-concat]
- repo: https://github.com/timothycrosley/isort
rev: 4.3.21
hooks:
- id: isort
- repo: https://github.com/pre-commit/pygrep-hooks - repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.5.1 rev: eae6397e4c259ed3d057511f6dd5330b92867e62 # frozen: v1.6.0
hooks: hooks:
- id: python-check-blanket-noqa - id: python-check-blanket-noqa
- id: rst-backticks - id: rst-backticks
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.5.0 rev: e1668fe86af3810fbca72b8653fe478e66a0afdc # frozen: v3.2.0
hooks: hooks:
- id: check-merge-conflict - id: check-merge-conflict
- id: check-yaml - id: check-yaml

View File

@ -1,67 +0,0 @@
dist: xenial
language: python
cache:
pip: true
directories:
- $HOME/.cache/pre-commit
notifications:
irc: "chat.freenode.net#pil"
# Run fast lint first to get fast feedback.
# Run slower CPUs next, to give them a headstart and reduce waiting time.
# Then run the remainder.
matrix:
fast_finish: true
include:
- python: "3.6"
name: "Lint"
env: LINT="true"
- python: "3.6"
arch: arm64
- python: "3.7"
arch: ppc64le
- python: "3.5"
arch: s390x
- python: "pypy3"
name: "PyPy3 Xenial"
- python: "3.8"
name: "3.8 Xenial"
services: xvfb
- python: '3.7'
name: "3.7 Xenial"
services: xvfb
- python: '3.6'
name: "3.6 Xenial PYTHONOPTIMIZE=1"
env: PYTHONOPTIMIZE=1
services: xvfb
- python: '3.5'
name: "3.5 Xenial PYTHONOPTIMIZE=2"
env: PYTHONOPTIMIZE=2
services: xvfb
install:
- |
if [ "$LINT" == "true" ]; then
pip install tox
else
.ci/install.sh;
fi
script:
- |
if [ "$LINT" == "true" ]; then
tox -e lint
else
.ci/build.sh
.ci/test.sh
fi
after_success:
- |
if [ "$LINT" == "" ]; then
.ci/after_success.sh
fi

View File

@ -2,6 +2,264 @@
Changelog (Pillow) Changelog (Pillow)
================== ==================
8.1.0 (unreleased)
------------------
- Use previous disposal method in GIF load_end #5125
[radarhere]
- Allow putpalette to accept 1024 integers to include alpha values #5089
[radarhere]
- Fix OOB Read when writing TIFF with custom Metadata #5148
[wiredfool]
- Added append_images support for ICO #4568
[ziplantil, radarhere]
- Block TIFFTAG_SUBIFD #5120
[radarhere]
- Fixed dereferencing potential null pointers #5108, #5111
[cgohlke, radarhere]
- Deprecate FreeType 2.7 #5098
[hugovk, radarhere]
- Moved warning to end of execution #4965
[radarhere]
- Removed unused fromstring and tostring C methods #5026
[radarhere]
- init() if one of the formats is unrecognised #5037
[radarhere]
- Moved string_dimension CVE image to pillow-depends #4993
[radarhere]
- Support raw rgba8888 for DDS #4760
[qiankanglai]
8.0.1 (2020-10-22)
------------------
- Update FreeType used in binary wheels to 2.10.4 to fix CVE-2020-15999.
[radarhere]
- Moved string_dimension image to pillow-depends #4993
[radarhere]
8.0.0 (2020-10-15)
------------------
- Drop support for EOL Python 3.5 #4746, #4794
[hugovk, radarhere, nulano]
- Drop support for PyPy3 < 7.2.0 #4964
[nulano]
- Remove ImageCms.CmsProfile attributes deprecated since 3.2.0 #4768
[hugovk, radarhere]
- Remove long-deprecated Image.py functions #4798
[hugovk, nulano, radarhere]
- Add support for 16-bit precision JPEG quantization values #4918
[gofr]
- Added reading of IFD tag type #4979
[radarhere]
- Initialize offset memory for PyImagingPhotoPut #4806
[nqbit]
- Fix TiffDecode comparison warnings #4756
[nulano]
- Docs: Add dark mode #4968
[hugovk, nulano]
- Added macOS SDK install path to library and include directories #4974
[radarhere, fxcoudert]
- Imaging.h: prevent confusion with system #4923
[ax3l, ,radarhere]
- Avoid using pkg_resources in PIL.features.pilinfo #4975
[nulano]
- Add getlength and getbbox functions for TrueType fonts #4959
[nulano, radarhere, hugovk]
- Allow tuples with one item to give single color value in getink #4927
[radarhere, nulano]
- Add support for CBDT and COLR fonts #4955
[nulano, hugovk]
- Removed OSError in favour of DecompressionBombError for BMP #4966
[radarhere]
- Implemented another ellipse drawing algorithm #4523
[xtsm, radarhere]
- Removed unused JpegImagePlugin._fixup_dict function #4957
[radarhere]
- Added reading and writing of private PNG chunks #4292
[radarhere]
- Implement anchor for TrueType fonts #4930
[nulano, hugovk]
- Fixed bug in Exif __delitem__ #4942
[radarhere]
- Fix crash in ImageTk.PhotoImage on MinGW 64-bit #4946
[nulano]
- Moved CVE images to pillow-depends #4929
[radarhere]
- Refactor font_getsize and font_render #4910
[nulano]
- Fixed loading profile with non-ASCII path on Windows #4914
[radarhere]
- Fixed effect_spread bug for zero distance #4908
[radarhere, hugovk]
- Added formats parameter to Image.open #4837
[nulano, radarhere]
- Added regular_polygon draw method #4846
[comhar]
- Raise proper TypeError in putpixel #4882
[nulano, hugovk]
- Added writing of subIFDs #4862
[radarhere]
- Fix IFDRational __eq__ bug #4888
[luphord, radarhere]
- Fixed duplicate variable name #4885
[liZe, radarhere]
- Added homebrew zlib include directory #4842
[radarhere]
- Corrected inverted PDF CMYK colors #4866
[radarhere]
- Do not try to close file pointer if file pointer is empty #4823
[radarhere]
- ImageOps.autocontrast: add mask parameter #4843
[navneeth, hugovk]
- Read EXIF data tEXt chunk into info as bytes instead of string #4828
[radarhere]
- Replaced distutils with setuptools #4797, #4809, #4814, #4817, #4829, #4890
[hugovk, radarhere]
- Add MIME type to PsdImagePlugin #4788
[samamorgan]
- Allow ImageOps.autocontrast to specify low and high cutoffs separately #4749
[millionhz, radarhere]
7.2.0 (2020-07-01)
------------------
- Do not convert I;16 images when showing PNGs #4744
[radarhere]
- Fixed ICNS file pointer saving #4741
[radarhere]
- Fixed loading non-RGBA mode APNGs with dispose background #4742
[radarhere]
- Deprecated _showxv #4714
[radarhere]
- Deprecate Image.show(command="...") #4646
[nulano, hugovk, radarhere]
- Updated JPEG magic number #4707
[Cykooz, radarhere]
- Change STRIPBYTECOUNTS to LONG if necessary when saving #4626
[radarhere, hugovk]
- Write JFIF header when saving JPEG #4639
[radarhere]
- Replaced tiff_jpeg with jpeg compression when saving TIFF images #4627
[radarhere]
- Writing TIFF tags: improved BYTE, added UNDEFINED #4605
[radarhere]
- Consider transparency when pasting text on an RGBA image #4566
[radarhere]
- Added method argument to single frame WebP saving #4547
[radarhere]
- Use ImageFileDirectory_v2 in Image.Exif #4637
[radarhere]
- Corrected reading EXIF metadata without prefix #4677
[radarhere]
- Fixed drawing a jointed line with a sequence of numeric values #4580
[radarhere]
- Added support for 1-D NumPy arrays #4608
[radarhere]
- Parse orientation from XMP tags #4560
[radarhere]
- Speed up text layout by not rendering glyphs #4652
[nulano]
- Fixed ZeroDivisionError in Image.thumbnail #4625
[radarhere]
- Replaced TiffImagePlugin DEBUG with logging #4550
[radarhere]
- Fix repeatedly loading .gbr #4620
[ElinksFr, radarhere]
- JPEG: Truncate icclist instead of setting to None #4613
[homm]
- Fixes default offset for Exif #4594
[rodrigob, radarhere]
- Fixed bug when unpickling TIFF images #4565
[radarhere]
- Fix pickling WebP #4561
[hugovk, radarhere]
- Replace IOError and WindowsError aliases with OSError #4536
[hugovk, radarhere]
7.1.2 (2020-04-25)
------------------
- Raise an EOFError when seeking too far in PNG #4528
[radarhere]
7.1.1 (2020-04-02) 7.1.1 (2020-04-02)
------------------ ------------------
@ -3814,8 +4072,8 @@ Changelog (Pillow)
1.0 (07/30/2010) 1.0 (07/30/2010)
---------------- ----------------
- Remove support for ``import Image``, etc. from the standard namespace. ``from PIL import Image`` etc. now required. - Remove support for ``import Image``. ``from PIL import Image`` now required.
- Forked PIL based on `Hanno Schlichting's re-packaging <https://dist.plone.org/thirdparty/PIL-1.1.7.tar.gz>`_ - Forked PIL based on `Chris McDonough and Hanno Schlichting's setuptools compatible re-packaging <https://dist.plone.org/thirdparty/PIL-1.1.7.tar.gz>`_
[aclark4life] [aclark4life]
Pre-fork Pre-fork
@ -3861,7 +4119,7 @@ Pre-fork
This section may not be fully complete. For changes since this file This section may not be fully complete. For changes since this file
was last updated, see the repository revision history: was last updated, see the repository revision history:
https://bitbucket.org/effbot/pil-2009-raclette/commits/all http://svn.effbot.org/public/pil/
(1.1.7 final) (1.1.7 final)
@ -5295,23 +5553,23 @@ Pre-fork
+ Added keyword options to the "save" method. The following options + Added keyword options to the "save" method. The following options
are currently supported: are currently supported:
format option description Format Option Description
-------------------------------------------------------- --------------------------------------------------------
JPEG optimize minimize output file at the JPEG optimize Minimize output file at the
expense of compression speed. expense of compression speed.
JPEG progressive enable progressive output. the JPEG progressive Enable progressive output.
option value is ignored. The option value is ignored.
JPEG quality set compression quality (1-100). JPEG quality Set compression quality (1-100).
the default value is 75. The default value is 75.
JPEG smooth smooth dithered images. value JPEG smooth Smooth dithered images.
is strength (1-100). default is Value is strength (1-100).
off (0). Default is off (0).
PNG optimize minimize output file at the PNG optimize Minimize output file at the
expense of compression speed. expense of compression speed.
Expect more options in future releases. Also note that Expect more options in future releases. Also note that
file writers silently ignore unknown options. file writers silently ignore unknown options.
@ -5332,31 +5590,31 @@ Pre-fork
+ Various improvements to the sample scripts: + Various improvements to the sample scripts:
"pilconvert" Carries out some extra tricks in order to make "pilconvert" Carries out some extra tricks in order to make
the resulting file as small as possible. the resulting file as small as possible.
"explode" (NEW) Split an image sequence into individual frames. "explode" (NEW) Split an image sequence into individual frames.
"gifmaker" (NEW) Convert a sequence file into a GIF animation. "gifmaker" (NEW) Convert a sequence file into a GIF animation.
Note that the GIF encoder create "uncompressed" GIF Note that the GIF encoder create "uncompressed" GIF
files, so animations created by this script are files, so animations created by this script are
rather large (typically 2-5 times the compressed rather large (typically 2-5 times the compressed
sizes). sizes).
"image2py" (NEW) Convert a single image to a python module. See "image2py" (NEW) Convert a single image to a python module. See
comments in this script for details. comments in this script for details.
"player" If multiple images are given on the command line, "player" If multiple images are given on the command line,
they are interpreted as frames in a sequence. The they are interpreted as frames in a sequence. The
script assumes that they all have the same size. script assumes that they all have the same size.
Also note that this script now can play FLI/FLC Also note that this script now can play FLI/FLC
and GIF animations. and GIF animations.
This player can also execute embedded Python This player can also execute embedded Python
animation applets (ARG format only). animation applets (ARG format only).
"viewer" Transparent images ("P" with transparency property, "viewer" Transparent images ("P" with transparency property,
and "RGBA") are superimposed on the standard Tk back- and "RGBA") are superimposed on the standard Tk back-
ground. ground.
+ Fixed colour argument to "new". For multilayer images, pass a + Fixed colour argument to "new". For multilayer images, pass a
tuple: (Red, Green, Blue), (Red, Green, Blue, Alpha), or (Cyan, tuple: (Red, Green, Blue), (Red, Green, Blue, Alpha), or (Cyan,
@ -5494,7 +5752,7 @@ Pre-fork
any other pixel value means opaque. This is faster than using an any other pixel value means opaque. This is faster than using an
"L" transparency mask. "L" transparency mask.
+ Properly writes EPS files (and properly prints images to postscript + Properly writes EPS files (and properly prints images to PostScript
printers as well). printers as well).
+ Reads 4-bit BMP files, as well as 4 and 8-bit Windows ICO and CUR + Reads 4-bit BMP files, as well as 4 and 8-bit Windows ICO and CUR
@ -5577,7 +5835,7 @@ Pre-fork
+ Added the "pilfile" utility, which quickly identifies image files + Added the "pilfile" utility, which quickly identifies image files
(without loading them, in most cases). (without loading them, in most cases).
+ Added the "pilprint" utility, which prints image files to Postscript + Added the "pilprint" utility, which prints image files to PostScript
printers. printers.
+ Added a rudimentary version of the "pilview" utility, which is + Added a rudimentary version of the "pilview" utility, which is
@ -5591,5 +5849,5 @@ Pre-fork
Jack). This allows you to read images through the Img extensions file Jack). This allows you to read images through the Img extensions file
format handlers. See the file "Lib/ImgExtImagePlugin.py" for details. format handlers. See the file "Lib/ImgExtImagePlugin.py" for details.
+ Postscript printing is provided through the PSDraw module. See the + PostScript printing is provided through the PSDraw module. See the
handbook for details. handbook for details.

View File

@ -7,7 +7,7 @@ Pillow is the friendly PIL fork. It is
Copyright © 2010-2020 by Alex Clark and contributors Copyright © 2010-2020 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 HPND License:
By obtaining, using, and/or copying this software and/or its associated By obtaining, using, and/or copying this software and/or its associated
documentation, you agree that you have read, understood, and will comply documentation, you agree that you have read, understood, and will comply

View File

@ -21,10 +21,8 @@ exclude .appveyor.yml
exclude .coveragerc exclude .coveragerc
exclude .editorconfig exclude .editorconfig
exclude .readthedocs.yml exclude .readthedocs.yml
exclude azure-pipelines.yml
exclude codecov.yml exclude codecov.yml
global-exclude .git* global-exclude .git*
global-exclude *.pyc global-exclude *.pyc
global-exclude *.so global-exclude *.so
prune .azure-pipelines
prune .ci prune .ci

View File

@ -1,7 +1,6 @@
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
.PHONY: clean coverage doc docserve help inplace install install-req release-test sdist test upload upload-test
.DEFAULT_GOAL := release-test .DEFAULT_GOAL := release-test
.PHONY: clean
clean: clean:
python3 setup.py clean python3 setup.py clean
rm src/PIL/*.so || true rm src/PIL/*.so || true
@ -9,28 +8,34 @@ clean:
find . -name __pycache__ | xargs rm -r || true find . -name __pycache__ | xargs rm -r || true
BRANCHES=`git branch -a | grep -v HEAD | grep -v master | grep remote` BRANCHES=`git branch -a | grep -v HEAD | grep -v master | grep remote`
.PHONY: co
co: co:
-for i in $(BRANCHES) ; do \ -for i in $(BRANCHES) ; do \
git checkout -t $$i ; \ git checkout -t $$i ; \
done done
.PHONY: coverage
coverage: coverage:
pytest -qq pytest -qq
rm -r htmlcov || true rm -r htmlcov || true
coverage report coverage report
.PHONY: doc
doc: doc:
$(MAKE) -C docs html $(MAKE) -C docs html
.PHONY: doccheck
doccheck: doccheck:
$(MAKE) -C docs html $(MAKE) -C docs html
# Don't make our tests rely on the links in the docs being up every single build. # Don't make our tests rely on the links in the docs being up every single build.
# We don't control them. But do check, and update them to the target of their redirects. # We don't control them. But do check, and update them to the target of their redirects.
$(MAKE) -C docs linkcheck || true $(MAKE) -C docs linkcheck || true
.PHONY: docserve
docserve: docserve:
cd docs/_build/html && python3 -mSimpleHTTPServer 2> /dev/null& cd docs/_build/html && python3 -m http.server 2> /dev/null&
.PHONY: help
help: help:
@echo "Welcome to Pillow development. Please use \`make <target>\` where <target> is one of" @echo "Welcome to Pillow development. Please use \`make <target>\` where <target> is one of"
@echo " clean remove build products" @echo " clean remove build products"
@ -48,17 +53,21 @@ help:
@echo " upload build and upload sdists to PyPI" @echo " upload build and upload sdists to PyPI"
@echo " upload-test build and upload sdists to test.pythonpackages.com" @echo " upload-test build and upload sdists to test.pythonpackages.com"
.PHONY: inplace
inplace: clean inplace: clean
python3 setup.py develop build_ext --inplace python3 setup.py develop build_ext --inplace
.PHONY: install
install: install:
python3 setup.py install python3 setup.py install
python3 selftest.py python3 selftest.py
.PHONY: install-coverage
install-coverage: install-coverage:
CFLAGS="-coverage" python3 setup.py build_ext install CFLAGS="-coverage -Werror=implicit-function-declaration" python3 setup.py build_ext install
python3 selftest.py python3 selftest.py
.PHONY: debug
debug: debug:
# make a debug version if we don't have a -dbg python. Leaves in symbols # make a debug version if we don't have a -dbg python. Leaves in symbols
# for our stuff, kills optimization, and redirects to dev null so we # for our stuff, kills optimization, and redirects to dev null so we
@ -66,40 +75,37 @@ debug:
make clean > /dev/null make clean > /dev/null
CFLAGS='-g -O0' python3 setup.py build_ext install > /dev/null CFLAGS='-g -O0' python3 setup.py build_ext install > /dev/null
.PHONY: install-req
install-req: install-req:
pip install -r requirements.txt python3 -m pip install -r requirements.txt
.PHONY: install-venv
install-venv: install-venv:
virtualenv . virtualenv .
bin/pip install -r requirements.txt bin/pip install -r requirements.txt
.PHONY: release-test
release-test: release-test:
$(MAKE) install-req $(MAKE) install-req
python3 setup.py develop python3 setup.py develop
python3 selftest.py python3 selftest.py
python3 -m pytest Tests python3 -m pytest Tests
python3 setup.py install python3 setup.py install
-rm dist/*.egg
-rmdir dist
python3 -m pytest -qq python3 -m pytest -qq
check-manifest check-manifest
pyroma . pyroma .
viewdoc $(MAKE) readme
.PHONY: sdist
sdist: sdist:
python3 setup.py sdist --format=gztar python3 setup.py sdist --format=gztar
.PHONY: test
test: test:
pytest -qq pytest -qq
# https://docs.python.org/3/distutils/packageindex.html#the-pypirc-file .PHONY: readme
upload-test:
# [test]
# username:
# password:
# repository = http://test.pythonpackages.com
python3 setup.py sdist --format=gztar upload -r test
upload:
python3 setup.py sdist --format=gztar upload
readme: readme:
viewdoc python3 setup.py --long-description | markdown2 > .long-description.html && open .long-description.html

102
README.md Normal file
View File

@ -0,0 +1,102 @@
<p align="center">
<img width="248" height="250" src="https://raw.githubusercontent.com/python-pillow/pillow-logo/master/pillow-logo-248x250.png" alt="Pillow logo">
</p>
# Pillow
## Python Imaging Library (Fork)
Pillow is the friendly PIL fork by [Alex Clark and
Contributors](https://github.com/python-pillow/Pillow/graphs/contributors).
PIL is the Python Imaging Library by Fredrik Lundh and Contributors.
As of 2019, Pillow development is
[supported by Tidelift](https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=readme&utm_campaign=enterprise).
<table>
<tr>
<th>docs</th>
<td>
<a href="https://pillow.readthedocs.io/?badge=latest"><img
alt="Documentation Status"
src="https://readthedocs.org/projects/pillow/badge/?version=latest"></a>
</td>
</tr>
<tr>
<th>tests</th>
<td>
<a href="https://github.com/python-pillow/Pillow/actions?query=workflow%3ALint"><img
alt="GitHub Actions build status (Lint)"
src="https://github.com/python-pillow/Pillow/workflows/Lint/badge.svg"></a>
<a href="https://github.com/python-pillow/Pillow/actions?query=workflow%3ATest"><img
alt="GitHub Actions build status (Test Linux and macOS)"
src="https://github.com/python-pillow/Pillow/workflows/Test/badge.svg"></a>
<a href="https://github.com/python-pillow/Pillow/actions?query=workflow%3A%22Test+Windows%22"><img
alt="GitHub Actions build status (Test Windows)"
src="https://github.com/python-pillow/Pillow/workflows/Test%20Windows/badge.svg"></a>
<a href="https://github.com/python-pillow/Pillow/actions?query=workflow%3A%22Test+Docker%22"><img
alt="GitHub Actions build status (Test Docker)"
src="https://github.com/python-pillow/Pillow/workflows/Test%20Docker/badge.svg"></a>
<a href="https://ci.appveyor.com/project/python-pillow/Pillow"><img
alt="AppVeyor CI build status (Windows)"
src="https://img.shields.io/appveyor/build/python-pillow/Pillow/master.svg?label=Windows%20build"></a>
<a href="https://travis-ci.com/github/python-pillow/pillow-wheels"><img
alt="Travis CI build status (macOS)"
src="https://img.shields.io/travis/com/python-pillow/pillow-wheels/master.svg?label=macOS%20build"></a>
<a href="https://codecov.io/gh/python-pillow/Pillow"><img
alt="Code coverage"
src="https://codecov.io/gh/python-pillow/Pillow/branch/master/graph/badge.svg"></a>
</td>
</tr>
<tr>
<th>package</th>
<td>
<a href="https://zenodo.org/badge/latestdoi/17549/python-pillow/Pillow"><img
alt="Zenodo"
src="https://zenodo.org/badge/17549/python-pillow/Pillow.svg"></a>
<a href="https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=badge"><img
alt="Tidelift"
src="https://tidelift.com/badges/package/pypi/Pillow?style=flat"></a>
<a href="https://pypi.org/project/Pillow/"><img
alt="Newest PyPI version"
src="https://img.shields.io/pypi/v/pillow.svg"></a>
<a href="https://pypi.org/project/Pillow/"><img
alt="Number of PyPI downloads"
src="https://img.shields.io/pypi/dm/pillow.svg"></a>
</td>
</tr>
<tr>
<th>social</th>
<td>
<a href="https://gitter.im/python-pillow/Pillow?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img
alt="Join the chat at https://gitter.im/python-pillow/Pillow"
src="https://badges.gitter.im/python-pillow/Pillow.svg"></a>
<a href="https://twitter.com/PythonPillow"><img
alt="Follow on https://twitter.com/PythonPillow"
src="https://img.shields.io/badge/tweet-on%20Twitter-00aced.svg"></a>
</td>
</tr>
</table>
## Overview
The Python Imaging Library adds image processing capabilities to your Python interpreter.
This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities.
The core image library is designed for fast access to data stored in a few basic pixel formats. It should provide a solid foundation for a general image processing tool.
## More Information
- [Documentation](https://pillow.readthedocs.io/)
- [Installation](https://pillow.readthedocs.io/en/latest/installation.html)
- [Handbook](https://pillow.readthedocs.io/en/latest/handbook/index.html)
- [Contribute](https://github.com/python-pillow/Pillow/blob/master/.github/CONTRIBUTING.md)
- [Issues](https://github.com/python-pillow/Pillow/issues)
- [Pull requests](https://github.com/python-pillow/Pillow/pulls)
- [Release notes](https://pillow.readthedocs.io/en/stable/releasenotes/index.html)
- [Changelog](https://github.com/python-pillow/Pillow/blob/master/CHANGES.rst)
- [Pre-fork](https://github.com/python-pillow/Pillow/blob/master/CHANGES.rst#pre-fork)
## Report a Vulnerability
To report a security vulnerability, please follow the procedure described in the [Tidelift security policy](https://tidelift.com/docs/security).

View File

@ -1,103 +0,0 @@
Pillow
======
Python Imaging Library (Fork)
-----------------------------
Pillow is the friendly PIL fork by `Alex Clark and Contributors <https://github.com/python-pillow/Pillow/graphs/contributors>`_. PIL is the Python Imaging Library by Fredrik Lundh and Contributors. As of 2019, Pillow development is `supported by Tidelift <https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=readme&utm_campaign=enterprise>`_.
.. start-badges
.. list-table::
:stub-columns: 1
* - docs
- |docs|
* - tests
- |linux| |macos| |windows| |gha_lint| |gha| |gha_windows| |gha_docker| |coverage|
* - package
- |zenodo| |tidelift| |version| |downloads|
* - social
- |gitter| |twitter|
.. end-badges
More Information
----------------
- `Documentation <https://pillow.readthedocs.io/>`_
- `Installation <https://pillow.readthedocs.io/en/latest/installation.html>`_
- `Handbook <https://pillow.readthedocs.io/en/latest/handbook/index.html>`_
- `Contribute <https://github.com/python-pillow/Pillow/blob/master/.github/CONTRIBUTING.md>`_
- `Issues <https://github.com/python-pillow/Pillow/issues>`_
- `Pull requests <https://github.com/python-pillow/Pillow/pulls>`_
- `Changelog <https://github.com/python-pillow/Pillow/blob/master/CHANGES.rst>`_
- `Pre-fork <https://github.com/python-pillow/Pillow/blob/master/CHANGES.rst#pre-fork>`_
Report a Vulnerability
----------------------
To report a security vulnerability, please follow the procedure described in the `Tidelift security policy <https://tidelift.com/docs/security>`_.
.. |docs| image:: https://readthedocs.org/projects/pillow/badge/?version=latest
:target: https://pillow.readthedocs.io/?badge=latest
:alt: Documentation Status
.. |linux| image:: https://img.shields.io/travis/python-pillow/Pillow/master.svg?label=Linux%20build
:target: https://travis-ci.org/python-pillow/Pillow
:alt: Travis CI build status (Linux)
.. |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
:alt: Travis CI build status (macOS)
.. |windows| image:: https://img.shields.io/appveyor/build/python-pillow/Pillow/master.svg?label=Windows%20build
:target: https://ci.appveyor.com/project/python-pillow/Pillow
:alt: AppVeyor CI build status (Windows)
.. |gha_lint| image:: https://github.com/python-pillow/Pillow/workflows/Lint/badge.svg
:target: https://github.com/python-pillow/Pillow/actions?query=workflow%3ALint
:alt: GitHub Actions build status (Lint)
.. |gha_docker| image:: https://github.com/python-pillow/Pillow/workflows/Test%20Docker/badge.svg
:target: https://github.com/python-pillow/Pillow/actions?query=workflow%3A%22Test+Docker%22
:alt: GitHub Actions build status (Test Docker)
.. |gha| image:: https://github.com/python-pillow/Pillow/workflows/Test/badge.svg
:target: https://github.com/python-pillow/Pillow/actions?query=workflow%3ATest
:alt: GitHub Actions build status (Test Linux and macOS)
.. |gha_windows| image:: https://github.com/python-pillow/Pillow/workflows/Test%20Windows/badge.svg
:target: https://github.com/python-pillow/Pillow/actions?query=workflow%3A%22Test+Windows%22
:alt: GitHub Actions build status (Test Windows)
.. |coverage| image:: https://codecov.io/gh/python-pillow/Pillow/branch/master/graph/badge.svg
:target: https://codecov.io/gh/python-pillow/Pillow
:alt: Code coverage
.. |zenodo| image:: https://zenodo.org/badge/17549/python-pillow/Pillow.svg
:target: https://zenodo.org/badge/latestdoi/17549/python-pillow/Pillow
.. |tidelift| image:: https://tidelift.com/badges/package/pypi/Pillow?style=flat
:target: https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=badge
.. |version| image:: https://img.shields.io/pypi/v/pillow.svg
:target: https://pypi.org/project/Pillow/
: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
: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
.. |twitter| image:: https://img.shields.io/badge/tweet-on%20Twitter-00aced.svg
:target: https://twitter.com/PythonPillow
:alt: Follow on https://twitter.com/PythonPillow

View File

@ -1,13 +1,16 @@
# Release Checklist # Release Checklist
See https://pillow.readthedocs.io/en/stable/releasenotes/versioning.html for
information about how the version numbers line up with releases.
## Main Release ## Main Release
Released quarterly on January 2nd, April 1st, July 1st and October 15th. Released quarterly on January 2nd, April 1st, July 1st and October 15th.
* [ ] Open a release ticket e.g. https://github.com/python-pillow/Pillow/issues/3154 * [ ] 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 [GitHub Actions](https://github.com/python-pillow/Pillow/actions) and [AppVeyor](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 and GitHub Actions.
* [ ] In compliance with [PEP 440](https://www.python.org/dev/peps/pep-0440/), update version identifier in `src/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.
@ -18,13 +21,18 @@ Released quarterly on January 2nd, April 1st, July 1st and October 15th.
git push --all git push --all
git push --tags git push --tags
``` ```
* [ ] Create source distributions e.g.: * [ ] Create and check source distribution:
```bash ```bash
make sdist make sdist
twine check dist/*
``` ```
* [ ] Create [binary distributions](https://github.com/python-pillow/Pillow/blob/master/RELEASING.md#binary-distributions) * [ ] 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*` * [ ] Check and upload all binaries and source distributions e.g.:
* [ ] Create a [new release on GitHub](https://github.com/python-pillow/Pillow/releases/new) ```bash
twine check dist/*
twine upload dist/Pillow-5.2.0*
```
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases)
* [ ] 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` * [ ] 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
@ -37,22 +45,31 @@ Released as needed for security, installation or critical bug fixes.
```bash ```bash
git checkout -t remotes/origin/5.2.x git checkout -t remotes/origin/5.2.x
``` ```
* [ ] Cherry pick individual commits from `master` branch to release branch e.g. `5.2.x`. * [ ] Cherry pick individual commits from `master` branch to release branch e.g. `5.2.x`, then `git push`.
* [ ] Check [Travis CI](https://travis-ci.org/python-pillow/Pillow) to confirm passing tests in release branch e.g. `5.2.x`.
* [ ] Check [GitHub Actions](https://github.com/python-pillow/Pillow/actions) and [AppVeyor](https://ci.appveyor.com/project/python-pillow/Pillow) to confirm passing tests in release branch e.g. `5.2.x`.
* [ ] In compliance with [PEP 440](https://www.python.org/dev/peps/pep-0440/), update version identifier in `src/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 ```bash
git tag 5.2.1 git tag 5.2.1
git push
git push --tags git push --tags
``` ```
* [ ] Create source distributions e.g.: * [ ] Create and check source distribution:
```bash ```bash
make sdist make sdist
twine check dist/*
``` ```
* [ ] Create [binary distributions](https://github.com/python-pillow/Pillow/blob/master/RELEASING.md#binary-distributions) * [ ] 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.1*` * [ ] Check and upload all binaries and source distributions e.g.:
* [ ] Create a [new release on GitHub](https://github.com/python-pillow/Pillow/releases/new) ```bash
twine check dist/*
twine upload dist/Pillow-5.2.1*
```
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases)
## Embargoed Release ## Embargoed Release
@ -71,18 +88,19 @@ Released as needed privately to individual vendors for critical security-related
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 and check source distribution:
```bash ```bash
make sdist make sdist
twine check dist/*
``` ```
* [ ] Create [binary distributions](https://github.com/python-pillow/Pillow/blob/master/RELEASING.md#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) * [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases)
## 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 copy into `dist/`
### 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):
@ -91,11 +109,8 @@ Released as needed privately to individual vendors for critical security-related
cd pillow-wheels cd pillow-wheels
./update-pillow-tag.sh [[release tag]] ./update-pillow-tag.sh [[release tag]]
``` ```
* [ ] Download distributions from the [Pillow Wheel Builder container](http://a365fff413fe338398b6-1c8a9b3114517dc5fe17b7c3f8c63a43.r19.cf2.rackcdn.com/). * [ ] Download wheels from the [Pillow Wheel Builder release](https://github.com/python-pillow/pillow-wheels/releases)
```bash and copy into `dist/`
wget -m -A 'Pillow-<VERSION>-*' \
http://a365fff413fe338398b6-1c8a9b3114517dc5fe17b7c3f8c63a43.r19.cf2.rackcdn.com
```
## Publicize Release ## Publicize Release
@ -104,3 +119,12 @@ Released as needed privately to individual vendors for critical security-related
## Documentation ## Documentation
* [ ] Make sure the [default version for Read the Docs](https://pillow.readthedocs.io/en/stable/) is up-to-date with the release changes * [ ] Make sure the [default version for Read the Docs](https://pillow.readthedocs.io/en/stable/) is up-to-date with the release changes
## Docker Images
* [ ] Update Pillow in the Docker Images repository
```bash
git clone https://github.com/python-pillow/docker-images
cd docker-images
./update-pillow-tag.sh [[release tag]]
```

View File

@ -4,7 +4,7 @@ from PIL import PyAccess
from .helper import hopper from .helper import hopper
# Not running this test by default. No DOS against Travis CI. # Not running this test by default. No DOS against CI.
def iterate_get(size, access): def iterate_get(size, access):
@ -28,15 +28,17 @@ def timer(func, label, *args):
func(*args) func(*args)
if time.time() - starttime > 10: if time.time() - starttime > 10:
print( print(
"%s: breaking at %s iterations, %.6f per iteration" "{}: breaking at {} iterations, {:.6f} per iteration".format(
% (label, x + 1, (time.time() - starttime) / (x + 1.0)) label, x + 1, (time.time() - starttime) / (x + 1.0)
)
) )
break break
if x == iterations - 1: if x == iterations - 1:
endtime = time.time() endtime = time.time()
print( print(
"%s: %.4f s %.6f per iteration" "{}: {:.4f} s {:.6f} per iteration".format(
% (label, endtime - starttime, (endtime - starttime) / (x + 1.0)) label, endtime - starttime, (endtime - starttime) / (x + 1.0)
)
) )

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
import pytest import pytest
from PIL import Image from PIL import Image
from .helper import is_win32 from .helper import is_win32
@ -11,7 +12,7 @@ pytestmark = pytest.mark.skipif(is_win32(), reason="requires Unix or macOS")
def _get_mem_usage(): def _get_mem_usage():
from resource import getpagesize, getrusage, RUSAGE_SELF from resource import RUSAGE_SELF, getpagesize, getrusage
mem = getrusage(RUSAGE_SELF).ru_maxrss mem = getrusage(RUSAGE_SELF).ru_maxrss
return mem * getpagesize() / 1024 / 1024 return mem * getpagesize() / 1024 / 1024
@ -25,7 +26,7 @@ def _test_leak(min_iterations, max_iterations, fn, *args, **kwargs):
if i < min_iterations: if i < min_iterations:
mem_limit = mem + 1 mem_limit = mem + 1
continue continue
msg = "memory usage limit exceeded after %d iterations" % (i + 1) msg = f"memory usage limit exceeded after {i + 1} iterations"
assert mem <= mem_limit, msg assert mem <= mem_limit, msg

View File

@ -1,6 +1,7 @@
from io import BytesIO from io import BytesIO
import pytest import pytest
from PIL import Image from PIL import Image
from .helper import is_win32, skip_unless_feature from .helper import is_win32, skip_unless_feature
@ -18,7 +19,7 @@ pytestmark = [
def test_leak_load(): def test_leak_load():
from resource import setrlimit, RLIMIT_AS, RLIMIT_STACK from resource import RLIMIT_AS, RLIMIT_STACK, setrlimit
setrlimit(RLIMIT_STACK, (stack_size, stack_size)) setrlimit(RLIMIT_STACK, (stack_size, stack_size))
setrlimit(RLIMIT_AS, (mem_limit, mem_limit)) setrlimit(RLIMIT_AS, (mem_limit, mem_limit))
@ -28,7 +29,7 @@ def test_leak_load():
def test_leak_save(): def test_leak_save():
from resource import setrlimit, RLIMIT_AS, RLIMIT_STACK from resource import RLIMIT_AS, RLIMIT_STACK, setrlimit
setrlimit(RLIMIT_STACK, (stack_size, stack_size)) setrlimit(RLIMIT_STACK, (stack_size, stack_size))
setrlimit(RLIMIT_AS, (mem_limit, mem_limit)) setrlimit(RLIMIT_AS, (mem_limit, mem_limit))

View File

@ -1,9 +1,10 @@
import pytest import pytest
from PIL import Image from PIL import Image
def test_j2k_overflow(tmp_path): def test_j2k_overflow(tmp_path):
im = Image.new("RGBA", (1024, 131584)) im = Image.new("RGBA", (1024, 131584))
target = str(tmp_path / "temp.jpc") target = str(tmp_path / "temp.jpc")
with pytest.raises(IOError): with pytest.raises(OSError):
im.save(target) im.save(target)

View File

@ -119,60 +119,59 @@ def test_qtables_leak():
def test_exif_leak(): def test_exif_leak():
""" """
pre patch: pre patch:
MB MB
177.1^ # 177.1^ #
| @@@# | @@@#
| :@@@@@@# | :@@@@@@#
| ::::@@@@@@# | ::::@@@@@@#
| ::::::::@@@@@@# | ::::::::@@@@@@#
| @@::::: ::::@@@@@@# | @@::::: ::::@@@@@@#
| @@@@ ::::: ::::@@@@@@# | @@@@ ::::: ::::@@@@@@#
| @@@@@@@ ::::: ::::@@@@@@# | @@@@@@@ ::::: ::::@@@@@@#
| @@::@@@@@@@ ::::: ::::@@@@@@# | @@::@@@@@@@ ::::: ::::@@@@@@#
| @@@@ : @@@@@@@ ::::: ::::@@@@@@# | @@@@ : @@@@@@@ ::::: ::::@@@@@@#
| @@@@@@ @@ : @@@@@@@ ::::: ::::@@@@@@# | @@@@@@ @@ : @@@@@@@ ::::: ::::@@@@@@#
| @@@@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# | @@@@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
| @::@@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# | @::@@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
| ::::@: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# | ::::@: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
| :@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# | :@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
| ::@@::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# | ::@@::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
| @@::: @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# | @@::: @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
| @::@ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# | @::@ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
| :::@: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# | :::@: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
| @@@:: @: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# | @@@:: @: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@#
0 +----------------------------------------------------------------------->Gi 0 +----------------------------------------------------------------------->Gi
0 11.37 0 11.37
post patch: post patch:
MB MB
21.06^ ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: 21.06^ ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| ##::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | ##::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @@@@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @@@@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
| @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@::::::
0 +----------------------------------------------------------------------->Gi 0 +----------------------------------------------------------------------->Gi
0 11.33 0 11.33
"""
"""
im = hopper("RGB") im = hopper("RGB")
exif = b"12345678" * 4096 exif = b"12345678" * 4096
@ -183,31 +182,30 @@ post patch:
def test_base_save(): def test_base_save():
""" """
base case: base case:
MB MB
20.99^ ::::: :::::::::::::::::::::::::::::::::::::::::::@::: 20.99^ ::::: :::::::::::::::::::::::::::::::::::::::::::@:::
| ##: : ::::::@::::::: :::: :::: : : : : : : :::::::::::: :::@::: | ##: : ::::::@::::::: :::: :::: : : : : : : :::::::::::: :::@:::
| # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| @@# : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | @@# : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| @@@ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | @@@ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| @ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | @ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| :@@@@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | :@@@@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
| :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@:::
0 +----------------------------------------------------------------------->Gi 0 +----------------------------------------------------------------------->Gi
0 7.882 0 7.882"""
"""
im = hopper("RGB") im = hopper("RGB")
for _ in range(iterations): for _ in range(iterations):

View File

@ -1,6 +1,7 @@
import sys import sys
import pytest import pytest
from PIL import Image from PIL import Image
# This test is not run automatically. # This test is not run automatically.

View File

@ -1,6 +1,7 @@
import sys import sys
import pytest import pytest
from PIL import Image from PIL import Image
# This test is not run automatically. # This test is not run automatically.

View File

@ -1,14 +1,15 @@
import pytest import pytest
from PIL import Image from PIL import Image
TEST_FILE = "Tests/images/libtiff_segfault.tif" TEST_FILE = "Tests/images/libtiff_segfault.tif"
def test_libtiff_segfault(): def test_libtiff_segfault():
""" This test should not segfault. It will on Pillow <= 3.1.0 and """This test should not segfault. It will on Pillow <= 3.1.0 and
libtiff >= 4.0.0 libtiff >= 4.0.0
""" """
with pytest.raises(IOError): with pytest.raises(OSError):
with Image.open(TEST_FILE) as im: with Image.open(TEST_FILE) as im:
im.load() im.load()

View File

@ -42,8 +42,8 @@ def test_dos_total_memory():
info = PngImagePlugin.PngInfo() info = PngImagePlugin.PngInfo()
for x in range(64): for x in range(64):
info.add_text("t%s" % x, compressed_data, zip=True) info.add_text(f"t{x}", compressed_data, zip=True)
info.add_itxt("i%s" % x, compressed_data, zip=True) info.add_itxt(f"i{x}", compressed_data, zip=True)
b = BytesIO() b = BytesIO()
im.save(b, "PNG", pnginfo=info) im.save(b, "PNG", pnginfo=info)

View File

@ -1,29 +0,0 @@
#!/usr/bin/env python
# Reproductions/tests for crashes/read errors in TiffDecode.c
# When run in python, all of these images should fail for
# one reason or another, either as a buffer overrun,
# unrecognized datastream, or truncated image file.
# There shouldn't be any segfaults.
#
# if run like
# `valgrind --tool=memcheck python check_tiff_crashes.py 2>&1 | grep TiffDecode.c`
# the output should be empty. There may be python issues
# in the valgrind especially if run in a debug python
# version.
from PIL import Image
repro_read_strip = (
"images/crash_1.tif",
"images/crash_2.tif",
)
for path in repro_read_strip:
with Image.open(path) as im:
try:
im.load()
except Exception as msg:
print(msg)

View File

@ -9,4 +9,4 @@ def pytest_report_header(config):
features.pilinfo(out=out, supported_formats=False) features.pilinfo(out=out, supported_formats=False)
return out.getvalue() return out.getvalue()
except Exception as e: except Exception as e:
return "pytest_report_header failed: %s" % e return f"pytest_report_header failed: {e}"

View File

@ -6,7 +6,7 @@ if __name__ == "__main__":
# create font data chunk for embedding # create font data chunk for embedding
font = "Tests/images/courB08" font = "Tests/images/courB08"
print(" f._load_pilfont_data(") print(" f._load_pilfont_data(")
print(" # %s" % os.path.basename(font)) print(f" # {os.path.basename(font)}")
print(" BytesIO(base64.decodestring(b'''") print(" BytesIO(base64.decodestring(b'''")
with open(font + ".pil", "rb") as fp: with open(font + ".pil", "rb") as fp:
print(base64.b64encode(fp.read()).decode()) print(base64.b64encode(fp.read()).decode())

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,13 +1,22 @@
NotoNastaliqUrdu-Regular.ttf and NotoSansSymbols-Regular.ttf, from https://github.com/googlei18n/noto-fonts NotoNastaliqUrdu-Regular.ttf and NotoSansSymbols-Regular.ttf, from https://github.com/googlei18n/noto-fonts
NotoSans-Regular.ttf, from https://www.google.com/get/noto/
NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/ NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/
NotoColorEmoji.ttf, from https://github.com/googlefonts/noto-emoji
AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype
TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny
ArefRuqaa-Regular.ttf, from https://github.com/google/fonts/tree/master/ofl/arefruqaa ArefRuqaa-Regular.ttf, from https://github.com/google/fonts/tree/master/ofl/arefruqaa
ter-x20b.pcf, from http://terminus-font.sourceforge.net/ ter-x20b.pcf, from http://terminus-font.sourceforge.net/
BungeeColor-Regular_colr_Windows.ttf, from https://github.com/djrrb/bungee
All of the above fonts are published under the SIL Open Font License (OFL) v1.1 (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), which allows you to copy, modify, and redistribute them if you need to. All of the above fonts are published under the SIL Open Font License (OFL) v1.1 (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), which allows you to copy, modify, and redistribute them if you need to.
FreeMono.ttf is licensed under GPLv3, with the GPL font exception.
OpenSansCondensed-LightItalic.tt, from https://fonts.google.com/specimen/Open+Sans, under Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
DejaVuSans-24-{1,2,4,8}-stripped.ttf are based on DejaVuSans.ttf converted using FontForge to add bitmap strikes and keep only the ASCII range.
10x20-ISO8859-1.pcf, from https://packages.ubuntu.com/xenial/xfonts-base 10x20-ISO8859-1.pcf, from https://packages.ubuntu.com/xenial/xfonts-base

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -6,10 +6,13 @@ import logging
import os import os
import shutil import shutil
import sys import sys
import sysconfig
import tempfile import tempfile
from io import BytesIO from io import BytesIO
import pytest import pytest
from packaging.version import parse as parse_version
from PIL import Image, ImageMath, features from PIL import Image, ImageMath, features
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -66,37 +69,31 @@ def convert_to_comparable(a, b):
def assert_deep_equal(a, b, msg=None): def assert_deep_equal(a, b, msg=None):
try: try:
assert len(a) == len(b), msg or "got length {}, expected {}".format( assert len(a) == len(b), msg or f"got length {len(a)}, expected {len(b)}"
len(a), len(b)
)
except Exception: except Exception:
assert a == b, msg assert a == b, msg
def assert_image(im, mode, size, msg=None): def assert_image(im, mode, size, msg=None):
if mode is not None: if mode is not None:
assert im.mode == mode, msg or "got mode {!r}, expected {!r}".format( assert im.mode == mode, (
im.mode, mode msg or f"got mode {repr(im.mode)}, expected {repr(mode)}"
) )
if size is not None: if size is not None:
assert im.size == size, msg or "got size {!r}, expected {!r}".format( assert im.size == size, (
im.size, size msg or f"got size {repr(im.size)}, expected {repr(size)}"
) )
def assert_image_equal(a, b, msg=None): def assert_image_equal(a, b, msg=None):
assert a.mode == b.mode, msg or "got mode {!r}, expected {!r}".format( assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
a.mode, b.mode assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
)
assert a.size == b.size, msg or "got size {!r}, expected {!r}".format(
a.size, b.size
)
if a.tobytes() != b.tobytes(): if a.tobytes() != b.tobytes():
if HAS_UPLOADER: if HAS_UPLOADER:
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(f"Url for test images: {url}")
except Exception: except Exception:
pass pass
@ -111,12 +108,8 @@ def assert_image_equal_tofile(a, filename, msg=None, mode=None):
def assert_image_similar(a, b, epsilon, msg=None): def assert_image_similar(a, b, epsilon, msg=None):
assert a.mode == b.mode, msg or "got mode {!r}, expected {!r}".format( assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
a.mode, b.mode assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
)
assert a.size == b.size, msg or "got size {!r}, expected {!r}".format(
a.size, b.size
)
a, b = convert_to_comparable(a, b) a, b = convert_to_comparable(a, b)
@ -128,13 +121,14 @@ def assert_image_similar(a, b, epsilon, msg=None):
ave_diff = diff / (a.size[0] * a.size[1]) ave_diff = diff / (a.size[0] * a.size[1])
try: try:
assert epsilon >= ave_diff, ( assert epsilon >= ave_diff, (
msg or "" (msg or "")
) + " average pixel value difference %.4f > epsilon %.4f" % (ave_diff, epsilon) + f" average pixel value difference {ave_diff:.4f} > epsilon {epsilon:.4f}"
)
except Exception as e: except Exception as e:
if HAS_UPLOADER: if HAS_UPLOADER:
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(f"Url for test images: {url}")
except Exception: except Exception:
pass pass
raise e raise e
@ -164,17 +158,21 @@ def assert_tuple_approx_equal(actuals, targets, threshold, msg):
assert value, msg + ": " + repr(actuals) + " != " + repr(targets) assert value, msg + ": " + repr(actuals) + " != " + repr(targets)
def skip_known_bad_test(msg=None):
# Skip if PILLOW_RUN_KNOWN_BAD is not true in the environment.
if not os.environ.get("PILLOW_RUN_KNOWN_BAD", False):
pytest.skip(msg or "Known bad test")
def skip_unless_feature(feature): def skip_unless_feature(feature):
reason = "%s not available" % feature reason = f"{feature} not available"
return pytest.mark.skipif(not features.check(feature), reason=reason) return pytest.mark.skipif(not features.check(feature), reason=reason)
def skip_unless_feature_version(feature, version_required, reason=None):
if not features.check(feature):
return pytest.mark.skip(f"{feature} not available")
if reason is None:
reason = f"{feature} is older than {version_required}"
version_required = parse_version(version_required)
version_available = parse_version(features.version(feature))
return pytest.mark.skipif(version_available < version_required, reason=reason)
@pytest.mark.skipif(sys.platform.startswith("win32"), reason="Requires Unix or macOS") @pytest.mark.skipif(sys.platform.startswith("win32"), reason="Requires Unix or macOS")
class PillowLeakTestCase: class PillowLeakTestCase:
# requires unix/macOS # requires unix/macOS
@ -189,7 +187,7 @@ class PillowLeakTestCase:
:returns: memory usage in kilobytes :returns: memory usage in kilobytes
""" """
from resource import getrusage, RUSAGE_SELF from resource import RUSAGE_SELF, getrusage
mem = getrusage(RUSAGE_SELF).ru_maxrss mem = getrusage(RUSAGE_SELF).ru_maxrss
if sys.platform == "darwin": if sys.platform == "darwin":
@ -209,7 +207,7 @@ class PillowLeakTestCase:
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
msg = "memory usage limit exceeded in iteration %d" % cycle msg = f"memory usage limit exceeded in iteration {cycle}"
assert mem < self.mem_limit, msg assert mem < self.mem_limit, msg
@ -272,18 +270,20 @@ def on_github_actions():
def on_ci(): def on_ci():
# Travis and AppVeyor have "CI" # GitHub Actions and AppVeyor have "CI"
# Azure Pipelines has "TF_BUILD" return "CI" in os.environ
# GitHub Actions has "GITHUB_ACTIONS"
return (
"CI" in os.environ or "TF_BUILD" in os.environ or "GITHUB_ACTIONS" in os.environ
)
def is_big_endian(): def is_big_endian():
return sys.byteorder == "big" return sys.byteorder == "big"
def is_ppc64le():
import platform
return platform.machine() == "ppc64le"
def is_win32(): def is_win32():
return sys.platform.startswith("win32") return sys.platform.startswith("win32")
@ -292,6 +292,10 @@ def is_pypy():
return hasattr(sys, "pypy_translation_info") return hasattr(sys, "pypy_translation_info")
def is_mingw():
return sysconfig.get_platform() == "mingw"
if sys.platform == "win32": if sys.platform == "win32":
IMCONVERT = os.environ.get("MAGICK_HOME", "") IMCONVERT = os.environ.get("MAGICK_HOME", "")
if IMCONVERT: if IMCONVERT:

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
Tests/images/exif_text.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 B

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 B

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 B

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 438 B

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 B

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 B

After

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 427 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 B

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 B

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 B

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 B

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 496 B

After

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 519 B

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