add type hints to pyCms functions in ImageCms

This commit is contained in:
Nulano 2024-01-01 01:47:35 +01:00
parent a1a687c261
commit 21566ebcdc
2 changed files with 56 additions and 40 deletions

View File

@ -121,7 +121,10 @@ nitpicky = True
# generating warnings in “nitpicky mode”. Note that type should include the domain name # generating warnings in “nitpicky mode”. Note that type should include the domain name
# if present. Example entries would be ('py:func', 'int') or # if present. Example entries would be ('py:func', 'int') or
# ('envvar', 'LD_LIBRARY_PATH'). # ('envvar', 'LD_LIBRARY_PATH').
# nitpick_ignore = [] nitpick_ignore = [
# sphinx does not understand `typing.Literal[-1]`
("py:obj", "typing.Literal[-1, 1]"),
]
# -- Options for HTML output ---------------------------------------------- # -- Options for HTML output ----------------------------------------------

View File

@ -23,7 +23,7 @@ import operator
import sys import sys
from enum import IntEnum, IntFlag from enum import IntEnum, IntFlag
from functools import reduce from functools import reduce
from typing import Any, BinaryIO, SupportsInt from typing import Any, BinaryIO, Literal, SupportsFloat, SupportsInt, Union
from . import Image, __version__ from . import Image, __version__
from ._deprecate import deprecate from ._deprecate import deprecate
@ -366,6 +366,8 @@ def get_display_profile(handle: SupportsInt | None = None) -> ImageCmsProfile |
# pyCMS compatible layer # pyCMS compatible layer
# --------------------------------------------------------------------. # --------------------------------------------------------------------.
_CmsProfileCompatible = Union[str, BinaryIO, core.CmsProfile, ImageCmsProfile]
class PyCMSError(Exception): class PyCMSError(Exception):
"""(pyCMS) Exception class. """(pyCMS) Exception class.
@ -375,14 +377,14 @@ class PyCMSError(Exception):
def profileToProfile( def profileToProfile(
im, im: Image.Image,
inputProfile, inputProfile: _CmsProfileCompatible,
outputProfile, outputProfile: _CmsProfileCompatible,
renderingIntent=Intent.PERCEPTUAL, renderingIntent: Intent = Intent.PERCEPTUAL,
outputMode=None, outputMode: str | None = None,
inPlace=False, inPlace: bool = False,
flags=Flags.NONE, flags: Flags | int = Flags.NONE,
): ) -> Image.Image | None:
""" """
(pyCMS) Applies an ICC transformation to a given image, mapping from (pyCMS) Applies an ICC transformation to a given image, mapping from
``inputProfile`` to ``outputProfile``. ``inputProfile`` to ``outputProfile``.
@ -470,7 +472,9 @@ def profileToProfile(
return imOut return imOut
def getOpenProfile(profileFilename): def getOpenProfile(
profileFilename: str | BinaryIO | core.CmsProfile,
) -> ImageCmsProfile:
""" """
(pyCMS) Opens an ICC profile file. (pyCMS) Opens an ICC profile file.
@ -493,13 +497,13 @@ def getOpenProfile(profileFilename):
def buildTransform( def buildTransform(
inputProfile, inputProfile: _CmsProfileCompatible,
outputProfile, outputProfile: _CmsProfileCompatible,
inMode, inMode: str,
outMode, outMode: str,
renderingIntent=Intent.PERCEPTUAL, renderingIntent: Intent = Intent.PERCEPTUAL,
flags=Flags.NONE, flags: Flags | int = Flags.NONE,
): ) -> ImageCmsTransform:
""" """
(pyCMS) Builds an ICC transform mapping from the ``inputProfile`` to the (pyCMS) Builds an ICC transform mapping from the ``inputProfile`` to the
``outputProfile``. Use applyTransform to apply the transform to a given ``outputProfile``. Use applyTransform to apply the transform to a given
@ -576,15 +580,15 @@ def buildTransform(
def buildProofTransform( def buildProofTransform(
inputProfile, inputProfile: _CmsProfileCompatible,
outputProfile, outputProfile: _CmsProfileCompatible,
proofProfile, proofProfile: _CmsProfileCompatible,
inMode, inMode: str,
outMode, outMode: str,
renderingIntent=Intent.PERCEPTUAL, renderingIntent: Intent = Intent.PERCEPTUAL,
proofRenderingIntent=Intent.ABSOLUTE_COLORIMETRIC, proofRenderingIntent: Intent = Intent.ABSOLUTE_COLORIMETRIC,
flags=Flags.SOFTPROOFING, flags: Flags | int = Flags.SOFTPROOFING,
): ) -> ImageCmsTransform:
""" """
(pyCMS) Builds an ICC transform mapping from the ``inputProfile`` to the (pyCMS) Builds an ICC transform mapping from the ``inputProfile`` to the
``outputProfile``, but tries to simulate the result that would be ``outputProfile``, but tries to simulate the result that would be
@ -692,7 +696,9 @@ buildTransformFromOpenProfiles = buildTransform
buildProofTransformFromOpenProfiles = buildProofTransform buildProofTransformFromOpenProfiles = buildProofTransform
def applyTransform(im, transform, inPlace=False): def applyTransform(
im: Image.Image, transform: ImageCmsTransform, inPlace: bool = False
) -> Image.Image | None:
""" """
(pyCMS) Applies a transform to a given image. (pyCMS) Applies a transform to a given image.
@ -745,7 +751,9 @@ def applyTransform(im, transform, inPlace=False):
return imOut return imOut
def createProfile(colorSpace, colorTemp=-1): def createProfile(
colorSpace: Literal["LAB", "XYZ", "sRGB"], colorTemp: SupportsFloat = -1
) -> core.CmsProfile:
""" """
(pyCMS) Creates a profile. (pyCMS) Creates a profile.
@ -787,6 +795,9 @@ def createProfile(colorSpace, colorTemp=-1):
except (TypeError, ValueError) as e: except (TypeError, ValueError) as e:
msg = f'Color temperature must be numeric, "{colorTemp}" not valid' msg = f'Color temperature must be numeric, "{colorTemp}" not valid'
raise PyCMSError(msg) from e raise PyCMSError(msg) from e
else:
# colorTemp is unused if colorSpace != "LAB"
colorTemp = 0.0
try: try:
return core.createProfile(colorSpace, colorTemp) return core.createProfile(colorSpace, colorTemp)
@ -794,7 +805,7 @@ def createProfile(colorSpace, colorTemp=-1):
raise PyCMSError(v) from v raise PyCMSError(v) from v
def getProfileName(profile): def getProfileName(profile: _CmsProfileCompatible) -> str:
""" """
(pyCMS) Gets the internal product name for the given profile. (pyCMS) Gets the internal product name for the given profile.
@ -828,15 +839,15 @@ def getProfileName(profile):
if not (model or manufacturer): if not (model or manufacturer):
return (profile.profile.profile_description or "") + "\n" return (profile.profile.profile_description or "") + "\n"
if not manufacturer or len(model) > 30: if not manufacturer or len(model) > 30: # type: ignore[arg-type]
return model + "\n" return model + "\n" # type: ignore[operator]
return f"{model} - {manufacturer}\n" return f"{model} - {manufacturer}\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) from v raise PyCMSError(v) from v
def getProfileInfo(profile): def getProfileInfo(profile: _CmsProfileCompatible) -> str:
""" """
(pyCMS) Gets the internal product information for the given profile. (pyCMS) Gets the internal product information for the given profile.
@ -873,7 +884,7 @@ def getProfileInfo(profile):
raise PyCMSError(v) from v raise PyCMSError(v) from v
def getProfileCopyright(profile): def getProfileCopyright(profile: _CmsProfileCompatible) -> str:
""" """
(pyCMS) Gets the copyright for the given profile. (pyCMS) Gets the copyright for the given profile.
@ -901,7 +912,7 @@ def getProfileCopyright(profile):
raise PyCMSError(v) from v raise PyCMSError(v) from v
def getProfileManufacturer(profile): def getProfileManufacturer(profile: _CmsProfileCompatible) -> str:
""" """
(pyCMS) Gets the manufacturer for the given profile. (pyCMS) Gets the manufacturer for the given profile.
@ -929,7 +940,7 @@ def getProfileManufacturer(profile):
raise PyCMSError(v) from v raise PyCMSError(v) from v
def getProfileModel(profile): def getProfileModel(profile: _CmsProfileCompatible) -> str:
""" """
(pyCMS) Gets the model for the given profile. (pyCMS) Gets the model for the given profile.
@ -958,7 +969,7 @@ def getProfileModel(profile):
raise PyCMSError(v) from v raise PyCMSError(v) from v
def getProfileDescription(profile): def getProfileDescription(profile: _CmsProfileCompatible) -> str:
""" """
(pyCMS) Gets the description for the given profile. (pyCMS) Gets the description for the given profile.
@ -987,7 +998,7 @@ def getProfileDescription(profile):
raise PyCMSError(v) from v raise PyCMSError(v) from v
def getDefaultIntent(profile): def getDefaultIntent(profile: _CmsProfileCompatible) -> int:
""" """
(pyCMS) Gets the default intent name for the given profile. (pyCMS) Gets the default intent name for the given profile.
@ -1026,7 +1037,9 @@ def getDefaultIntent(profile):
raise PyCMSError(v) from v raise PyCMSError(v) from v
def isIntentSupported(profile, intent, direction): def isIntentSupported(
profile: _CmsProfileCompatible, intent: Intent, direction: Direction
) -> Literal[-1, 1]:
""" """
(pyCMS) Checks if a given intent is supported. (pyCMS) Checks if a given intent is supported.
@ -1077,7 +1090,7 @@ def isIntentSupported(profile, intent, direction):
raise PyCMSError(v) from v raise PyCMSError(v) from v
def versions(): def versions() -> tuple[str, str, str, str]:
""" """
(pyCMS) Fetches versions. (pyCMS) Fetches versions.
""" """