Skip to content

Commit 21566eb

Browse files
committed
add type hints to pyCms functions in ImageCms
1 parent a1a687c commit 21566eb

2 files changed

Lines changed: 56 additions & 40 deletions

File tree

docs/conf.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,10 @@
121121
# generating warnings in “nitpicky mode”. Note that type should include the domain name
122122
# if present. Example entries would be ('py:func', 'int') or
123123
# ('envvar', 'LD_LIBRARY_PATH').
124-
# nitpick_ignore = []
124+
nitpick_ignore = [
125+
# sphinx does not understand `typing.Literal[-1]`
126+
("py:obj", "typing.Literal[-1, 1]"),
127+
]
125128

126129

127130
# -- Options for HTML output ----------------------------------------------

src/PIL/ImageCms.py

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import sys
2424
from enum import IntEnum, IntFlag
2525
from functools import reduce
26-
from typing import Any, BinaryIO, SupportsInt
26+
from typing import Any, BinaryIO, Literal, SupportsFloat, SupportsInt, Union
2727

2828
from . import Image, __version__
2929
from ._deprecate import deprecate
@@ -366,6 +366,8 @@ def get_display_profile(handle: SupportsInt | None = None) -> ImageCmsProfile |
366366
# pyCMS compatible layer
367367
# --------------------------------------------------------------------.
368368

369+
_CmsProfileCompatible = Union[str, BinaryIO, core.CmsProfile, ImageCmsProfile]
370+
369371

370372
class PyCMSError(Exception):
371373
"""(pyCMS) Exception class.
@@ -375,14 +377,14 @@ class PyCMSError(Exception):
375377

376378

377379
def profileToProfile(
378-
im,
379-
inputProfile,
380-
outputProfile,
381-
renderingIntent=Intent.PERCEPTUAL,
382-
outputMode=None,
383-
inPlace=False,
384-
flags=Flags.NONE,
385-
):
380+
im: Image.Image,
381+
inputProfile: _CmsProfileCompatible,
382+
outputProfile: _CmsProfileCompatible,
383+
renderingIntent: Intent = Intent.PERCEPTUAL,
384+
outputMode: str | None = None,
385+
inPlace: bool = False,
386+
flags: Flags | int = Flags.NONE,
387+
) -> Image.Image | None:
386388
"""
387389
(pyCMS) Applies an ICC transformation to a given image, mapping from
388390
``inputProfile`` to ``outputProfile``.
@@ -470,7 +472,9 @@ def profileToProfile(
470472
return imOut
471473

472474

473-
def getOpenProfile(profileFilename):
475+
def getOpenProfile(
476+
profileFilename: str | BinaryIO | core.CmsProfile,
477+
) -> ImageCmsProfile:
474478
"""
475479
(pyCMS) Opens an ICC profile file.
476480
@@ -493,13 +497,13 @@ def getOpenProfile(profileFilename):
493497

494498

495499
def buildTransform(
496-
inputProfile,
497-
outputProfile,
498-
inMode,
499-
outMode,
500-
renderingIntent=Intent.PERCEPTUAL,
501-
flags=Flags.NONE,
502-
):
500+
inputProfile: _CmsProfileCompatible,
501+
outputProfile: _CmsProfileCompatible,
502+
inMode: str,
503+
outMode: str,
504+
renderingIntent: Intent = Intent.PERCEPTUAL,
505+
flags: Flags | int = Flags.NONE,
506+
) -> ImageCmsTransform:
503507
"""
504508
(pyCMS) Builds an ICC transform mapping from the ``inputProfile`` to the
505509
``outputProfile``. Use applyTransform to apply the transform to a given
@@ -576,15 +580,15 @@ def buildTransform(
576580

577581

578582
def buildProofTransform(
579-
inputProfile,
580-
outputProfile,
581-
proofProfile,
582-
inMode,
583-
outMode,
584-
renderingIntent=Intent.PERCEPTUAL,
585-
proofRenderingIntent=Intent.ABSOLUTE_COLORIMETRIC,
586-
flags=Flags.SOFTPROOFING,
587-
):
583+
inputProfile: _CmsProfileCompatible,
584+
outputProfile: _CmsProfileCompatible,
585+
proofProfile: _CmsProfileCompatible,
586+
inMode: str,
587+
outMode: str,
588+
renderingIntent: Intent = Intent.PERCEPTUAL,
589+
proofRenderingIntent: Intent = Intent.ABSOLUTE_COLORIMETRIC,
590+
flags: Flags | int = Flags.SOFTPROOFING,
591+
) -> ImageCmsTransform:
588592
"""
589593
(pyCMS) Builds an ICC transform mapping from the ``inputProfile`` to the
590594
``outputProfile``, but tries to simulate the result that would be
@@ -692,7 +696,9 @@ def buildProofTransform(
692696
buildProofTransformFromOpenProfiles = buildProofTransform
693697

694698

695-
def applyTransform(im, transform, inPlace=False):
699+
def applyTransform(
700+
im: Image.Image, transform: ImageCmsTransform, inPlace: bool = False
701+
) -> Image.Image | None:
696702
"""
697703
(pyCMS) Applies a transform to a given image.
698704
@@ -745,7 +751,9 @@ def applyTransform(im, transform, inPlace=False):
745751
return imOut
746752

747753

748-
def createProfile(colorSpace, colorTemp=-1):
754+
def createProfile(
755+
colorSpace: Literal["LAB", "XYZ", "sRGB"], colorTemp: SupportsFloat = -1
756+
) -> core.CmsProfile:
749757
"""
750758
(pyCMS) Creates a profile.
751759
@@ -787,14 +795,17 @@ def createProfile(colorSpace, colorTemp=-1):
787795
except (TypeError, ValueError) as e:
788796
msg = f'Color temperature must be numeric, "{colorTemp}" not valid'
789797
raise PyCMSError(msg) from e
798+
else:
799+
# colorTemp is unused if colorSpace != "LAB"
800+
colorTemp = 0.0
790801

791802
try:
792803
return core.createProfile(colorSpace, colorTemp)
793804
except (TypeError, ValueError) as v:
794805
raise PyCMSError(v) from v
795806

796807

797-
def getProfileName(profile):
808+
def getProfileName(profile: _CmsProfileCompatible) -> str:
798809
"""
799810
800811
(pyCMS) Gets the internal product name for the given profile.
@@ -828,15 +839,15 @@ def getProfileName(profile):
828839

829840
if not (model or manufacturer):
830841
return (profile.profile.profile_description or "") + "\n"
831-
if not manufacturer or len(model) > 30:
832-
return model + "\n"
842+
if not manufacturer or len(model) > 30: # type: ignore[arg-type]
843+
return model + "\n" # type: ignore[operator]
833844
return f"{model} - {manufacturer}\n"
834845

835846
except (AttributeError, OSError, TypeError, ValueError) as v:
836847
raise PyCMSError(v) from v
837848

838849

839-
def getProfileInfo(profile):
850+
def getProfileInfo(profile: _CmsProfileCompatible) -> str:
840851
"""
841852
(pyCMS) Gets the internal product information for the given profile.
842853
@@ -873,7 +884,7 @@ def getProfileInfo(profile):
873884
raise PyCMSError(v) from v
874885

875886

876-
def getProfileCopyright(profile):
887+
def getProfileCopyright(profile: _CmsProfileCompatible) -> str:
877888
"""
878889
(pyCMS) Gets the copyright for the given profile.
879890
@@ -901,7 +912,7 @@ def getProfileCopyright(profile):
901912
raise PyCMSError(v) from v
902913

903914

904-
def getProfileManufacturer(profile):
915+
def getProfileManufacturer(profile: _CmsProfileCompatible) -> str:
905916
"""
906917
(pyCMS) Gets the manufacturer for the given profile.
907918
@@ -929,7 +940,7 @@ def getProfileManufacturer(profile):
929940
raise PyCMSError(v) from v
930941

931942

932-
def getProfileModel(profile):
943+
def getProfileModel(profile: _CmsProfileCompatible) -> str:
933944
"""
934945
(pyCMS) Gets the model for the given profile.
935946
@@ -958,7 +969,7 @@ def getProfileModel(profile):
958969
raise PyCMSError(v) from v
959970

960971

961-
def getProfileDescription(profile):
972+
def getProfileDescription(profile: _CmsProfileCompatible) -> str:
962973
"""
963974
(pyCMS) Gets the description for the given profile.
964975
@@ -987,7 +998,7 @@ def getProfileDescription(profile):
987998
raise PyCMSError(v) from v
988999

9891000

990-
def getDefaultIntent(profile):
1001+
def getDefaultIntent(profile: _CmsProfileCompatible) -> int:
9911002
"""
9921003
(pyCMS) Gets the default intent name for the given profile.
9931004
@@ -1026,7 +1037,9 @@ def getDefaultIntent(profile):
10261037
raise PyCMSError(v) from v
10271038

10281039

1029-
def isIntentSupported(profile, intent, direction):
1040+
def isIntentSupported(
1041+
profile: _CmsProfileCompatible, intent: Intent, direction: Direction
1042+
) -> Literal[-1, 1]:
10301043
"""
10311044
(pyCMS) Checks if a given intent is supported.
10321045
@@ -1077,7 +1090,7 @@ def isIntentSupported(profile, intent, direction):
10771090
raise PyCMSError(v) from v
10781091

10791092

1080-
def versions():
1093+
def versions() -> tuple[str, str, str, str]:
10811094
"""
10821095
(pyCMS) Fetches versions.
10831096
"""

0 commit comments

Comments
 (0)