mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-14 10:30:55 +03:00
Merge branch 'main' into libavif-plugin
This commit is contained in:
commit
3730bf214b
1
.github/CONTRIBUTING.md
vendored
1
.github/CONTRIBUTING.md
vendored
|
@ -19,7 +19,6 @@ Please send a pull request to the `main` branch. Please include [documentation](
|
||||||
- Follow PEP 8.
|
- Follow PEP 8.
|
||||||
- When committing only documentation changes please include `[ci skip]` in the commit message to avoid running tests on AppVeyor.
|
- When committing only documentation changes please include `[ci skip]` in the commit message to avoid running tests on AppVeyor.
|
||||||
- Include [release notes](https://github.com/python-pillow/Pillow/tree/main/docs/releasenotes) as needed or appropriate with your bug fixes, feature additions and tests.
|
- Include [release notes](https://github.com/python-pillow/Pillow/tree/main/docs/releasenotes) as needed or appropriate with your bug fixes, feature additions and tests.
|
||||||
- Do not add to the [changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) for proposed changes, as that is updated after changes are merged.
|
|
||||||
|
|
||||||
## Reporting Issues
|
## Reporting Issues
|
||||||
|
|
||||||
|
|
11
.github/release-drafter.yml
vendored
11
.github/release-drafter.yml
vendored
|
@ -3,18 +3,19 @@ tag-template: "$NEXT_MINOR_VERSION"
|
||||||
change-template: '- $TITLE #$NUMBER [@$AUTHOR]'
|
change-template: '- $TITLE #$NUMBER [@$AUTHOR]'
|
||||||
|
|
||||||
categories:
|
categories:
|
||||||
- title: "Dependencies"
|
- title: "Removals"
|
||||||
label: "Dependency"
|
label: "Removal"
|
||||||
- title: "Deprecations"
|
- title: "Deprecations"
|
||||||
label: "Deprecation"
|
label: "Deprecation"
|
||||||
- title: "Documentation"
|
- title: "Documentation"
|
||||||
label: "Documentation"
|
label: "Documentation"
|
||||||
- title: "Removals"
|
- title: "Dependencies"
|
||||||
label: "Removal"
|
label: "Dependency"
|
||||||
- title: "Testing"
|
- title: "Testing"
|
||||||
label: "Testing"
|
label: "Testing"
|
||||||
- title: "Type hints"
|
- title: "Type hints"
|
||||||
label: "Type hints"
|
label: "Type hints"
|
||||||
|
- title: "Other changes"
|
||||||
|
|
||||||
exclude-labels:
|
exclude-labels:
|
||||||
- "changelog: skip"
|
- "changelog: skip"
|
||||||
|
@ -23,6 +24,4 @@ template: |
|
||||||
|
|
||||||
https://pillow.readthedocs.io/en/stable/releasenotes/$NEXT_MINOR_VERSION.html
|
https://pillow.readthedocs.io/en/stable/releasenotes/$NEXT_MINOR_VERSION.html
|
||||||
|
|
||||||
## Changes
|
|
||||||
|
|
||||||
$CHANGES
|
$CHANGES
|
||||||
|
|
15
.github/workflows/test.yml
vendored
15
.github/workflows/test.yml
vendored
|
@ -42,6 +42,7 @@ jobs:
|
||||||
]
|
]
|
||||||
python-version: [
|
python-version: [
|
||||||
"pypy3.10",
|
"pypy3.10",
|
||||||
|
"3.13t",
|
||||||
"3.13",
|
"3.13",
|
||||||
"3.12",
|
"3.12",
|
||||||
"3.11",
|
"3.11",
|
||||||
|
@ -52,14 +53,14 @@ jobs:
|
||||||
- { python-version: "3.11", PYTHONOPTIMIZE: 1, REVERSE: "--reverse" }
|
- { python-version: "3.11", PYTHONOPTIMIZE: 1, REVERSE: "--reverse" }
|
||||||
- { python-version: "3.10", PYTHONOPTIMIZE: 2 }
|
- { python-version: "3.10", PYTHONOPTIMIZE: 2 }
|
||||||
# Free-threaded
|
# Free-threaded
|
||||||
- { os: "ubuntu-latest", python-version: "3.13-dev", disable-gil: true }
|
- { python-version: "3.13t", disable-gil: true }
|
||||||
# M1 only available for 3.10+
|
# M1 only available for 3.10+
|
||||||
- { os: "macos-13", python-version: "3.9" }
|
- { os: "macos-13", python-version: "3.9" }
|
||||||
exclude:
|
exclude:
|
||||||
- { os: "macos-latest", python-version: "3.9" }
|
- { os: "macos-latest", python-version: "3.9" }
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
name: ${{ matrix.os }} Python ${{ matrix.python-version }} ${{ matrix.disable-gil && 'free-threaded' || '' }}
|
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
@ -67,8 +68,7 @@ jobs:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v5
|
uses: Quansight-Labs/setup-python@v5
|
||||||
if: "${{ !matrix.disable-gil }}"
|
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
allow-prereleases: true
|
allow-prereleases: true
|
||||||
|
@ -77,13 +77,6 @@ jobs:
|
||||||
".ci/*.sh"
|
".ci/*.sh"
|
||||||
"pyproject.toml"
|
"pyproject.toml"
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }} (free-threaded)
|
|
||||||
uses: deadsnakes/action@v3.2.0
|
|
||||||
if: "${{ matrix.disable-gil }}"
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.python-version }}
|
|
||||||
nogil: ${{ matrix.disable-gil }}
|
|
||||||
|
|
||||||
- name: Set PYTHON_GIL
|
- name: Set PYTHON_GIL
|
||||||
if: "${{ matrix.disable-gil }}"
|
if: "${{ matrix.disable-gil }}"
|
||||||
run: |
|
run: |
|
||||||
|
|
3
.github/workflows/wheels-dependencies.sh
vendored
3
.github/workflows/wheels-dependencies.sh
vendored
|
@ -78,10 +78,9 @@ function build_pkg_config {
|
||||||
|
|
||||||
function build_brotli {
|
function build_brotli {
|
||||||
if [ -e brotli-stamp ]; then return; fi
|
if [ -e brotli-stamp ]; then return; fi
|
||||||
local cmake=$(get_modern_cmake)
|
|
||||||
local out_dir=$(fetch_unpack https://github.com/google/brotli/archive/v$BROTLI_VERSION.tar.gz brotli-$BROTLI_VERSION.tar.gz)
|
local out_dir=$(fetch_unpack https://github.com/google/brotli/archive/v$BROTLI_VERSION.tar.gz brotli-$BROTLI_VERSION.tar.gz)
|
||||||
(cd $out_dir \
|
(cd $out_dir \
|
||||||
&& $cmake -DCMAKE_INSTALL_PREFIX=$BUILD_PREFIX -DCMAKE_INSTALL_LIBDIR=$BUILD_PREFIX/lib -DCMAKE_INSTALL_NAME_DIR=$BUILD_PREFIX/lib . \
|
&& cmake -DCMAKE_INSTALL_PREFIX=$BUILD_PREFIX -DCMAKE_INSTALL_LIBDIR=$BUILD_PREFIX/lib -DCMAKE_INSTALL_NAME_DIR=$BUILD_PREFIX/lib . \
|
||||||
&& make install)
|
&& make install)
|
||||||
touch brotli-stamp
|
touch brotli-stamp
|
||||||
}
|
}
|
||||||
|
|
22
CHANGES.rst
22
CHANGES.rst
|
@ -2,26 +2,12 @@
|
||||||
Changelog (Pillow)
|
Changelog (Pillow)
|
||||||
==================
|
==================
|
||||||
|
|
||||||
11.1.0 (unreleased)
|
11.1.0 and newer
|
||||||
-------------------
|
----------------
|
||||||
|
|
||||||
- Removed use of os.path.realpath #8545
|
See GitHub Releases:
|
||||||
[radarhere]
|
|
||||||
|
|
||||||
- Allow linking to zlib import library on Windows #8519
|
- https://github.com/python-pillow/Pillow/releases
|
||||||
[cubanpit, nulano]
|
|
||||||
|
|
||||||
- Detach PyQt6 QPixmap instance before returning #8509
|
|
||||||
[radarhere]
|
|
||||||
|
|
||||||
- Corrected EMF DPI #8485
|
|
||||||
[radarhere]
|
|
||||||
|
|
||||||
- Fix IFDRational with a zero denominator #8474
|
|
||||||
[radarhere]
|
|
||||||
|
|
||||||
- Fixed disabling a feature during install #8469
|
|
||||||
[radarhere]
|
|
||||||
|
|
||||||
11.0.0 (2024-10-15)
|
11.0.0 (2024-10-15)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
|
@ -107,7 +107,7 @@ The core image library is designed for fast access to data stored in a few basic
|
||||||
- [Issues](https://github.com/python-pillow/Pillow/issues)
|
- [Issues](https://github.com/python-pillow/Pillow/issues)
|
||||||
- [Pull requests](https://github.com/python-pillow/Pillow/pulls)
|
- [Pull requests](https://github.com/python-pillow/Pillow/pulls)
|
||||||
- [Release notes](https://pillow.readthedocs.io/en/stable/releasenotes/index.html)
|
- [Release notes](https://pillow.readthedocs.io/en/stable/releasenotes/index.html)
|
||||||
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
|
- [Changelog](https://github.com/python-pillow/Pillow/releases)
|
||||||
- [Pre-fork](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst#pre-fork)
|
- [Pre-fork](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst#pre-fork)
|
||||||
|
|
||||||
## Report a Vulnerability
|
## Report a Vulnerability
|
||||||
|
|
|
@ -12,7 +12,6 @@ Released quarterly on January 2nd, April 1st, July 1st and October 15th.
|
||||||
* [ ] 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 `main` 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 `main` branch.
|
||||||
* [ ] Check that all the wheel builds pass the tests in the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml) jobs by manually triggering them.
|
* [ ] Check that all the wheel builds pass the tests in the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml) jobs by manually triggering them.
|
||||||
* [ ] In compliance with [PEP 440](https://peps.python.org/pep-0440/), update version identifier in `src/PIL/_version.py`
|
* [ ] In compliance with [PEP 440](https://peps.python.org/pep-0440/), update version identifier in `src/PIL/_version.py`
|
||||||
* [ ] Update `CHANGES.rst`.
|
|
||||||
* [ ] Run pre-release check via `make release-test` in a freshly cloned repo.
|
* [ ] Run pre-release check via `make release-test` in a freshly cloned repo.
|
||||||
* [ ] Create branch and tag for release e.g.:
|
* [ ] Create branch and tag for release e.g.:
|
||||||
```bash
|
```bash
|
||||||
|
@ -34,7 +33,6 @@ Released quarterly on January 2nd, April 1st, July 1st and October 15th.
|
||||||
Released as needed for security, installation or critical bug fixes.
|
Released as needed for security, installation or critical bug fixes.
|
||||||
|
|
||||||
* [ ] Make necessary changes in `main` branch.
|
* [ ] Make necessary changes in `main` branch.
|
||||||
* [ ] Update `CHANGES.rst`.
|
|
||||||
* [ ] Check out release branch e.g.:
|
* [ ] Check out release branch e.g.:
|
||||||
```bash
|
```bash
|
||||||
git checkout -t remotes/origin/5.2.x
|
git checkout -t remotes/origin/5.2.x
|
||||||
|
|
|
@ -1098,6 +1098,25 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
|
|
||||||
assert_image_similar(base_im, im, 0.7)
|
assert_image_similar(base_im, im, 0.7)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"test_file",
|
||||||
|
[
|
||||||
|
"Tests/images/old-style-jpeg-compression-no-samplesperpixel.tif",
|
||||||
|
"Tests/images/old-style-jpeg-compression.tif",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_buffering(self, test_file: str) -> None:
|
||||||
|
# load exif first
|
||||||
|
with Image.open(open(test_file, "rb", buffering=1048576)) as im:
|
||||||
|
exif = dict(im.getexif())
|
||||||
|
|
||||||
|
# load image before exif
|
||||||
|
with Image.open(open(test_file, "rb", buffering=1048576)) as im2:
|
||||||
|
im2.load()
|
||||||
|
exif_after_load = dict(im2.getexif())
|
||||||
|
|
||||||
|
assert exif == exif_after_load
|
||||||
|
|
||||||
@pytest.mark.valgrind_known_error(reason="Backtrace in Python Core")
|
@pytest.mark.valgrind_known_error(reason="Backtrace in Python Core")
|
||||||
def test_sampleformat_not_corrupted(self) -> None:
|
def test_sampleformat_not_corrupted(self) -> None:
|
||||||
# Assert that a TIFF image with SampleFormat=UINT tag is not corrupted
|
# Assert that a TIFF image with SampleFormat=UINT tag is not corrupted
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Documentation: https://docs.codecov.com/docs/codecov-yaml
|
# Documentation: https://docs.codecov.com/docs/codecov-yaml
|
||||||
|
|
||||||
codecov:
|
codecov:
|
||||||
# Avoid "Missing base report" due to committing CHANGES.rst with "[CI skip]"
|
# Avoid "Missing base report" due to committing with "[CI skip]"
|
||||||
# https://github.com/codecov/support/issues/363
|
# https://github.com/codecov/support/issues/363
|
||||||
# https://docs.codecov.com/docs/comparing-commits
|
# https://docs.codecov.com/docs/comparing-commits
|
||||||
allow_coverage_offsets: true
|
allow_coverage_offsets: true
|
||||||
|
|
|
@ -164,13 +164,7 @@ Many of Pillow's features require external libraries:
|
||||||
The easiest way to install external libraries is via `Homebrew
|
The easiest way to install external libraries is via `Homebrew
|
||||||
<https://brew.sh/>`_. After you install Homebrew, run::
|
<https://brew.sh/>`_. After you install Homebrew, run::
|
||||||
|
|
||||||
brew install libjpeg libtiff little-cms2 openjpeg webp
|
brew install libjpeg libraqm libtiff little-cms2 openjpeg webp
|
||||||
|
|
||||||
To install libraqm on macOS use Homebrew to install its dependencies::
|
|
||||||
|
|
||||||
brew install freetype harfbuzz fribidi
|
|
||||||
|
|
||||||
Then see ``depends/install_raqm_cmake.sh`` to install libraqm.
|
|
||||||
|
|
||||||
To install libavif on macOS use Homebrew to install its build dependencies::
|
To install libavif on macOS use Homebrew to install its build dependencies::
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ optional-dependencies.typing = [
|
||||||
optional-dependencies.xmp = [
|
optional-dependencies.xmp = [
|
||||||
"defusedxml",
|
"defusedxml",
|
||||||
]
|
]
|
||||||
urls.Changelog = "https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst"
|
urls.Changelog = "https://github.com/python-pillow/Pillow/releases"
|
||||||
urls.Documentation = "https://pillow.readthedocs.io"
|
urls.Documentation = "https://pillow.readthedocs.io"
|
||||||
urls.Funding = "https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=pypi"
|
urls.Funding = "https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=pypi"
|
||||||
urls.Homepage = "https://python-pillow.org"
|
urls.Homepage = "https://python-pillow.org"
|
||||||
|
|
|
@ -1216,10 +1216,6 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
def _seek(self, frame: int) -> None:
|
def _seek(self, frame: int) -> None:
|
||||||
self.fp = self._fp
|
self.fp = self._fp
|
||||||
|
|
||||||
# reset buffered io handle in case fp
|
|
||||||
# was passed to libtiff, invalidating the buffer
|
|
||||||
self.fp.tell()
|
|
||||||
|
|
||||||
while len(self._frame_pos) <= frame:
|
while len(self._frame_pos) <= frame:
|
||||||
if not self.__next:
|
if not self.__next:
|
||||||
msg = "no more images in TIFF file"
|
msg = "no more images in TIFF file"
|
||||||
|
@ -1303,10 +1299,6 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
if not self.is_animated:
|
if not self.is_animated:
|
||||||
self._close_exclusive_fp_after_loading = True
|
self._close_exclusive_fp_after_loading = True
|
||||||
|
|
||||||
# reset buffered io handle in case fp
|
|
||||||
# was passed to libtiff, invalidating the buffer
|
|
||||||
self.fp.tell()
|
|
||||||
|
|
||||||
# load IFD data from fp before it is closed
|
# load IFD data from fp before it is closed
|
||||||
exif = self.getexif()
|
exif = self.getexif()
|
||||||
for key in TiffTags.TAGS_V2_GROUPS:
|
for key in TiffTags.TAGS_V2_GROUPS:
|
||||||
|
@ -1381,8 +1373,17 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
logger.debug("have fileno, calling fileno version of the decoder.")
|
logger.debug("have fileno, calling fileno version of the decoder.")
|
||||||
if not close_self_fp:
|
if not close_self_fp:
|
||||||
self.fp.seek(0)
|
self.fp.seek(0)
|
||||||
|
# Save and restore the file position, because libtiff will move it
|
||||||
|
# outside of the Python runtime, and that will confuse
|
||||||
|
# io.BufferedReader and possible others.
|
||||||
|
# NOTE: This must use os.lseek(), and not fp.tell()/fp.seek(),
|
||||||
|
# because the buffer read head already may not equal the actual
|
||||||
|
# file position, and fp.seek() may just adjust it's internal
|
||||||
|
# pointer and not actually seek the OS file handle.
|
||||||
|
pos = os.lseek(fp, 0, os.SEEK_CUR)
|
||||||
# 4 bytes, otherwise the trace might error out
|
# 4 bytes, otherwise the trace might error out
|
||||||
n, err = decoder.decode(b"fpfp")
|
n, err = decoder.decode(b"fpfp")
|
||||||
|
os.lseek(fp, pos, os.SEEK_SET)
|
||||||
else:
|
else:
|
||||||
# we have something else.
|
# we have something else.
|
||||||
logger.debug("don't have fileno or getvalue. just reading")
|
logger.debug("don't have fileno or getvalue. just reading")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user