Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

removed python3.8 support #293

Merged
merged 1 commit into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .github/workflows/analysis-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ jobs:

coverage-pi-heif:
runs-on: ubuntu-22.04
name: Pi-Heif Coverage(Linux) • 🐍3.8
name: Pi-Heif Coverage(Linux) • 🐍3.13

steps:
- uses: actions/checkout@v4
Expand All @@ -297,7 +297,8 @@ jobs:

- uses: actions/setup-python@v5
with:
python-version: '3.8'
python-version: '3.13'
allow-prereleases: true

- name: Prepare system
run: |
Expand Down Expand Up @@ -333,7 +334,7 @@ jobs:

test-pi-heif:
runs-on: ubuntu-22.04
name: Pi-Heif Test(Linux) • 🐍3.8
name: Pi-Heif Test(Linux) • 🐍3.13

steps:
- uses: actions/checkout@v4
Expand All @@ -344,7 +345,8 @@ jobs:

- uses: actions/setup-python@v5
with:
python-version: '3.8'
python-version: '3.13'
allow-prereleases: true

- name: Prepare system
run: |
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test-wheels-pi_heif.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["pypy-3.9", "pypy-3.10", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["pypy-3.9", "pypy-3.10", "3.9", "3.10", "3.11", "3.12", "3.13"]
env:
PH_LIGHT_ACTION: 1

Expand Down Expand Up @@ -105,7 +105,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["pypy-3.9", "pypy-3.10", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["pypy-3.9", "pypy-3.10", "3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- name: Delay, waiting Pypi to update.
Expand Down Expand Up @@ -138,7 +138,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["pypy-3.9", "pypy-3.10", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["pypy-3.9", "pypy-3.10", "3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- name: Delay, waiting Pypi to update.
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
runs-on: windows-2019
strategy:
matrix:
python-version: ["pypy-3.9", "pypy-3.10", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["pypy-3.9", "pypy-3.10", "3.9", "3.10", "3.11", "3.12", "3.13"]
env:
PH_FULL_ACTION: 1

Expand Down Expand Up @@ -103,7 +103,7 @@ jobs:
runs-on: macos-12
strategy:
matrix:
python-version: ["pypy-3.9", "pypy-3.10", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["pypy-3.9", "pypy-3.10", "3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- name: Delay, waiting Pypi to update.
Expand Down Expand Up @@ -134,7 +134,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: ["pypy-3.9", "pypy-3.10", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["pypy-3.9", "pypy-3.10", "3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- name: Delay, waiting Pypi to update.
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![docs](https://readthedocs.org/projects/pillow-heif/badge/?version=latest)](https://pillow-heif.readthedocs.io/en/latest/?badge=latest)
[![codecov](https://codecov.io/gh/bigcat88/pillow_heif/branch/master/graph/badge.svg?token=JY64F2OL6V)](https://codecov.io/gh/bigcat88/pillow_heif)

![PythonVersion](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)
![PythonVersion](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)
![impl](https://img.shields.io/pypi/implementation/pillow_heif)
![pypi](https://img.shields.io/pypi/v/pillow_heif.svg)
[![Downloads](https://static.pepy.tech/personalized-badge/pillow-heif?period=total&units=international_system&left_color=grey&right_color=orange&left_text=Downloads)](https://pepy.tech/project/pillow-heif)
Expand Down Expand Up @@ -145,7 +145,6 @@ if im.info["depth_images"]:

| **_Wheels table_** | macOS<br/>Intel | macOS<br/>Silicon | Windows<br/> | musllinux* | manylinux* |
|--------------------|:---------------:|:-----------------:|:------------:|:----------:|:----------:|
| CPython 3.8 | ✅ | N/A | ✅ | ✅ | ✅ |
| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅ |
Expand Down
3 changes: 1 addition & 2 deletions pi-heif/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![Analysis & Coverage](https://github.com/bigcat88/pillow_heif/actions/workflows/analysis-coverage.yml/badge.svg)](https://github.com/bigcat88/pillow_heif/actions/workflows/analysis-coverage.yml)
[![Wheels test(Pi-Heif)](https://github.com/bigcat88/pillow_heif/actions/workflows/test-wheels-pi_heif.yml/badge.svg)](https://github.com/bigcat88/pillow_heif/actions/workflows/test-wheels-pi_heif.yml)

![PythonVersion](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)
![PythonVersion](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)
![impl](https://img.shields.io/pypi/implementation/pi_heif)
![pypi](https://img.shields.io/pypi/v/pi_heif.svg)
[![Downloads](https://static.pepy.tech/personalized-badge/pi-heif?period=total&units=international_system&left_color=grey&right_color=orange&left_text=Downloads)](https://pepy.tech/project/pi-heif)
Expand Down Expand Up @@ -86,7 +86,6 @@ if im.info["depth_images"]:

| **_Wheels table_** | macOS<br/>Intel | macOS<br/>Silicon | Windows<br/> | musllinux* | manylinux* |
|--------------------|:---------------:|:-----------------:|:------------:|:----------:|:----------:|
| CPython 3.8 | ✅ | N/A | ✅ | ✅ | ✅ |
| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅ |
Expand Down
4 changes: 2 additions & 2 deletions pi-heif/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ classifiers =
Topic :: Multimedia :: Graphics
Topic :: Multimedia :: Graphics :: Graphics Conversion
Programming Language :: Python :: 3
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: 3.13
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: Implementation :: PyPy
License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
Expand All @@ -33,7 +33,7 @@ project_urls =
Changelog=https://github.com/bigcat88/pillow_heif/blob/master/CHANGELOG.md

[options]
python_requires = >=3.8
python_requires = >=3.9
zip_safe = False
packages = find:
install_requires =
Expand Down
2 changes: 1 addition & 1 deletion pillow_heif/_version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Version of pillow_heif/pi_heif."""

__version__ = "0.19.0.dev0"
__version__ = "0.20.0.dev0"
24 changes: 13 additions & 11 deletions pillow_heif/as_plugin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"""Plugins for the Pillow library."""

from __future__ import annotations

from itertools import chain
from typing import Union
from typing import IO
from warnings import warn

from PIL import Image, ImageFile, ImageSequence
Expand Down Expand Up @@ -32,7 +34,7 @@
class _LibHeifImageFile(ImageFile.ImageFile):
"""Base class with all functionality for ``HeifImageFile`` and ``AvifImageFile`` classes."""

_heif_file: Union[HeifFile, None] = None
_heif_file: HeifFile | None = None
_close_exclusive_fp_after_loading = True
_mode: str # only for Pillow 10.1+

Expand Down Expand Up @@ -85,7 +87,7 @@ def getxmp(self) -> dict:
return self._getxmp(xmp_data[0]) # pylint: disable=no-member
return {}

def seek(self, frame):
def seek(self, frame: int):
if not self._seek_check(frame):
return
self.__frame = frame
Expand All @@ -94,7 +96,7 @@ def seek(self, frame):
if _exif is not None and getattr(_exif, "_loaded", None):
_exif._loaded = False # pylint: disable=protected-access

def tell(self):
def tell(self) -> int:
return self.__frame

def verify(self) -> None:
Expand All @@ -113,7 +115,7 @@ def is_animated(self) -> bool:
"""Returns ``True`` if this image contains more than one frame, or ``False`` otherwise."""
return self.n_frames > 1

def _seek_check(self, frame):
def _seek_check(self, frame: int):
if frame < 0 or frame >= self.n_frames:
raise EOFError("attempt to seek outside sequence")
return self.tell() != frame
Expand All @@ -140,11 +142,11 @@ def _is_supported_heif(fp) -> bool:
return magic[8:12] in (b"heic", b"heix", b"heim", b"heis", b"hevc", b"hevx", b"hevm", b"hevs", b"mif1", b"msf1")


def _save_heif(im, fp, _filename):
def _save_heif(im: Image.Image, fp: IO[bytes], _filename: str | bytes):
__save_one(im, fp, HeifCompressionFormat.HEVC)


def _save_all_heif(im, fp, _filename):
def _save_all_heif(im: Image.Image, fp: IO[bytes], _filename: str | bytes):
__save_all(im, fp, HeifCompressionFormat.HEVC)


Expand Down Expand Up @@ -183,11 +185,11 @@ def _is_supported_avif(fp) -> bool:
# return False


def _save_avif(im, fp, _filename):
def _save_avif(im: Image.Image, fp: IO[bytes], _filename: str | bytes):
__save_one(im, fp, HeifCompressionFormat.AV1)


def _save_all_avif(im, fp, _filename):
def _save_all_avif(im: Image.Image, fp: IO[bytes], _filename: str | bytes):
__save_all(im, fp, HeifCompressionFormat.AV1)


Expand Down Expand Up @@ -234,13 +236,13 @@ def __options_update(**kwargs):
warn(f"Unknown option: {k}", stacklevel=1)


def __save_one(im, fp, compression_format: HeifCompressionFormat):
def __save_one(im: Image.Image, fp: IO[bytes], compression_format: HeifCompressionFormat):
ctx_write = CtxEncode(compression_format, **im.encoderinfo)
_pil_encode_image(ctx_write, im, True, **im.encoderinfo)
ctx_write.save(fp)


def __save_all(im, fp, compression_format: HeifCompressionFormat):
def __save_all(im: Image.Image, fp: IO[bytes], compression_format: HeifCompressionFormat):
ctx_write = CtxEncode(compression_format, **im.encoderinfo)
current_frame = im.tell() if hasattr(im, "tell") else None
append_images = im.encoderinfo.get("append_images", [])
Expand Down
30 changes: 15 additions & 15 deletions pillow_heif/heif.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
"""Functions and classes for heif images to read and write."""

from __future__ import annotations

from copy import copy, deepcopy
from io import SEEK_SET
from typing import Any, Dict, List, Optional, Tuple
from typing import Any

from PIL import Image

Expand Down Expand Up @@ -38,7 +40,7 @@
class BaseImage:
"""Base class for :py:class:`HeifImage` and :py:class:`HeifDepthImage`."""

size: tuple
size: tuple[int, int]
"""Width and height of the image."""

mode: str
Expand Down Expand Up @@ -82,7 +84,7 @@ def __array_interface__(self):
else:
width = int(width / 2)
typestr = "<u2"
shape: Tuple[Any, ...] = (self.size[1], width)
shape: tuple[Any, ...] = (self.size[1], width)
if MODE_INFO[self.mode][0] > 1:
shape += (MODE_INFO[self.mode][0],)
return {"shape": shape, "typestr": typestr, "version": 3, "data": self.data}
Expand Down Expand Up @@ -143,13 +145,11 @@ class HeifImage(BaseImage):

def __init__(self, c_image):
super().__init__(c_image)
_metadata: List[dict] = c_image.metadata
_metadata: list[dict] = c_image.metadata
_exif = _retrieve_exif(_metadata)
_xmp = _retrieve_xmp(_metadata)
_thumbnails: List[Optional[int]] = (
[i for i in c_image.thumbnails if i is not None] if options.THUMBNAILS else []
)
_depth_images: List[Optional[HeifDepthImage]] = (
_thumbnails: list[int | None] = [i for i in c_image.thumbnails if i is not None] if options.THUMBNAILS else []
_depth_images: list[HeifDepthImage | None] = (
[HeifDepthImage(i) for i in c_image.depth_image_list if i is not None] if options.DEPTH_IMAGES else []
)
_heif_meta = _get_heif_meta(c_image)
Expand All @@ -166,7 +166,7 @@ def __init__(self, c_image):
if _heif_meta:
self.info["heif"] = _heif_meta
save_colorspace_chroma(c_image, self.info)
_color_profile: Dict[str, Any] = c_image.color_profile
_color_profile: dict[str, Any] = c_image.color_profile
if _color_profile:
if _color_profile["type"] in ("rICC", "prof"):
self.info["icc_profile"] = _color_profile["data"]
Expand Down Expand Up @@ -248,7 +248,7 @@ def __init__(self, fp=None, convert_hdr_to_8bit=True, bgr_mode=False, **kwargs):
preferred_decoder,
)
self.mimetype = mimetype
self._images: List[HeifImage] = [HeifImage(i) for i in images if i is not None]
self._images: list[HeifImage] = [HeifImage(i) for i in images if i is not None]
self.primary_index = 0
for index, _ in enumerate(self._images):
if _.info.get("primary", False):
Expand Down Expand Up @@ -385,7 +385,7 @@ def __delitem__(self, key):
raise IndexError(f"invalid image index: {key}")
del self._images[key]

def add_frombytes(self, mode: str, size: tuple, data, **kwargs):
def add_frombytes(self, mode: str, size: tuple[int, int], data, **kwargs):
"""Adds image from bytes to container.

.. note:: Supports ``stride`` value if needed.
Expand Down Expand Up @@ -549,7 +549,7 @@ def read_heif(fp, convert_hdr_to_8bit=True, bgr_mode=False, **kwargs) -> HeifFil
return ret


def encode(mode: str, size: tuple, data, fp, **kwargs) -> None:
def encode(mode: str, size: tuple[int, int], data, fp, **kwargs) -> None:
"""Encodes data in a ``fp``.

:param mode: `BGR(A);16`, `RGB(A);16`, LA;16`, `L;16`, `I;16L`, `BGR(A)`, `RGB(A)`, `LA`, `L`
Expand All @@ -560,12 +560,12 @@ def encode(mode: str, size: tuple, data, fp, **kwargs) -> None:
_encode_images([HeifImage(MimCImage(mode, size, data, **kwargs))], fp, **kwargs)


def _encode_images(images: List[HeifImage], fp, **kwargs) -> None:
def _encode_images(images: list[HeifImage], fp, **kwargs) -> None:
compression = kwargs.get("format", "HEIF")
compression_format = HeifCompressionFormat.AV1 if compression == "AVIF" else HeifCompressionFormat.HEVC
if not _pillow_heif.get_lib_info()[compression]:
raise RuntimeError(f"No {compression} encoder found.")
images_to_save: List[HeifImage] = images + kwargs.get("append_images", [])
images_to_save: list[HeifImage] = images + kwargs.get("append_images", [])
if not kwargs.get("save_all", True):
images_to_save = images_to_save[:1]
if not images_to_save:
Expand Down Expand Up @@ -603,7 +603,7 @@ def from_pillow(pil_image: Image.Image) -> HeifFile:
return _


def from_bytes(mode: str, size: tuple, data, **kwargs) -> HeifFile:
def from_bytes(mode: str, size: tuple[int, int], data, **kwargs) -> HeifFile:
"""Creates :py:class:`~pillow_heif.HeifFile` from bytes.

.. note:: Supports ``stride`` value if needed.
Expand Down
Loading
Loading