From 65b9f3f5a9cf65c6f2b6f0c609fa3f8524b769c2 Mon Sep 17 00:00:00 2001 From: Michael Mauderer Date: Wed, 8 Jan 2025 11:41:48 +0000 Subject: [PATCH] Update linting. --- colour/io/luts/clf.py | 143 +++++++++--------- colour/io/luts/lut.py | 6 +- .../io/luts/tests/clf_apply/test_asc_cdl.py | 13 +- .../io/luts/tests/clf_apply/test_exponent.py | 29 ++-- colour/io/luts/tests/clf_apply/test_helper.py | 7 +- colour/io/luts/tests/clf_apply/test_log.py | 19 +-- colour/io/luts/tests/clf_apply/test_lut1d.py | 15 +- colour/io/luts/tests/clf_apply/test_lut3d.py | 5 +- colour/io/luts/tests/clf_apply/test_matrix.py | 3 +- colour/io/luts/tests/clf_apply/test_range.py | 9 +- colour/io/luts/tests/test_clf_common.py | 41 +++-- 11 files changed, 156 insertions(+), 134 deletions(-) diff --git a/colour/io/luts/clf.py b/colour/io/luts/clf.py index bfcd3c1bf..ebf6e54b7 100644 --- a/colour/io/luts/clf.py +++ b/colour/io/luts/clf.py @@ -1,6 +1,10 @@ """ Define functionality to execute and run CLF workflows. """ + +from collections.abc import Callable +from typing import cast + import colour_clf_io as clf import numpy as np from numpy.typing import ArrayLike, NDArray @@ -46,51 +50,53 @@ def from_f16_to_uint16(array: npt.NDArray[np.float16]) -> npt.NDArray[np.uint16] return array # type: ignore -def apply_by_channel(value, f, params, extra_args=None) -> NDArray: +def apply_by_channel( + value: ArrayLike, f: Callable, params: Any, extra_args: Any = None +) -> NDArray: if params is None or len(params) == 0: return f(value, params, extra_args) - elif len(params) == 1 and params[0].channel is None: + if len(params) == 1 and params[0].channel is None: return f(value, params[0], extra_args) - else: - R, G, B = tsplit(value) - for param in params: - match param.channel: - case Channel.R: - R = f(R, param, extra_args) - case Channel.G: - G = f(G, param, extra_args) - case Channel.B: - B = f(B, param, extra_args) - return tstack([R, G, B]) - - -def get_interpolator_for_LUT3D(node: clf.LUT3D): + R, G, B = tsplit(value) + for param in params: + match param.channel: + case Channel.R: + R = f(R, param, extra_args) + case Channel.G: + G = f(G, param, extra_args) + case Channel.B: + B = f(B, param, extra_args) + return tstack([R, G, B]) + + +def get_interpolator_for_LUT3D( + node: clf.LUT3D, +) -> Callable: if node.interpolation == node.interpolation.TRILINEAR: return table_interpolation_trilinear - elif node.interpolation == node.interpolation.TETRAHEDRAL: + if node.interpolation == node.interpolation.TETRAHEDRAL: return table_interpolation_tetrahedral - else: - raise NotImplementedError + raise NotImplementedError class CLFNode(AbstractLUTSequenceOperator): node: clf.ProcessNode - def __init__(self, node: clf.ProcessNode): + def __init__(self, node: clf.ProcessNode) -> None: super().__init__(node.name, [node.description]) self.node = node - def from_input_range(self, value): - return value + def from_input_range(self, value: ArrayLike) -> NDArrayFloat: + return cast(NDArrayFloat, value) - def to_output_range(self, value): + def to_output_range(self, value: ArrayLike) -> NDArrayFloat: return value / self.node.out_bit_depth.scale_factor() class LUT3D(CLFNode): node: clf.LUT3D - def __init__(self, node: clf.LUT3D): + def __init__(self, node: clf.LUT3D) -> None: super().__init__(node) self.node = node @@ -115,14 +121,13 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: ARG002 extrapolator_kwargs=extrapolator_kwargs, interpolator=interpolator, ) - out = self.to_output_range(out) - return out + return self.to_output_range(out) class LUT1D(CLFNode): node: clf.LUT1D - def __init__(self, node: clf.LUT1D): + def __init__(self, node: clf.LUT1D) -> None: super().__init__(node) self.node = node @@ -142,14 +147,13 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: ARG002 lut = luts.LUT1D(table, size=size, domain=domain) extrapolator_kwargs = {"method": "Constant"} out = lut.apply(value_scaled, extrapolator_kwargs=extrapolator_kwargs) - out = self.to_output_range(out) - return out + return self.to_output_range(out) class Matrix(CLFNode): node: clf.Matrix - def __init__(self, node: clf.Matrix): + def __init__(self, node: clf.Matrix) -> None: super().__init__(node) self.node = node @@ -159,21 +163,25 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: ARG002 return matrix.dot(RGB) -def assert_range_correct(in_out, bit_depth_scale): +def assert_range_correct( + in_out: tuple[float | None, float | None], bit_depth_scale: float +) -> None: if None not in in_out: + in_out = cast(tuple[float, float], in_out) expected_out_value = in_out[0] * bit_depth_scale if in_out[1] != expected_out_value: - raise ValueError( + message = ( f"Inconsistent settings in range node. " f"Input value was {in_out[1]}. " f"Expected output value to be {expected_out_value}, but got {in_out[1]}" ) + raise ValueError(message) class Range(CLFNode): node: clf.LUT1D - def __init__(self, node: clf.LUT1D): + def __init__(self, node: clf.LUT1D) -> None: super().__init__(node) self.node = node @@ -190,11 +198,12 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: ARG002 if None in max_in_out or None in min_in_out: if not do_clamping: - raise ValueError( + message = ( "Inconsistent settings in range node. " "Clamping was not set, but not all values to calculate a " "range are supplied. " ) + raise ValueError(message) bit_depth_scale = ( node.out_bit_depth.scale_factor() / node.in_bit_depth.scale_factor() ) @@ -208,14 +217,15 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: ARG002 if do_clamping: result = np.clip(result, min_out, max_out) out = result - out = self.to_output_range(out) - return out + return self.to_output_range(out) FLT_MIN = 1.175494e-38 -def apply_log_internal(value: NDArrayFloat, params, extra_args) -> NDArrayFloat: +def apply_log_internal( # noqa: PLR0911 + value: NDArrayFloat, params: clf.LogParams, extra_args: Any +) -> NDArrayFloat: style, in_bit_depth, out_bit_depth = extra_args match style: case clf.LogStyle.LOG_10: @@ -298,13 +308,14 @@ def apply_log_internal(value: NDArrayFloat, params, extra_args) -> NDArrayFloat: linear_slope, ) case _: - raise ValueError(f"Invalid Log Style: {style}") + message = f"Invalid Log Style: {style}" + raise ValueError(message) class Log(CLFNode): node: clf.Log - def __init__(self, node: clf.Log): + def __init__(self, node: clf.Log) -> None: super().__init__(node) self.node = node @@ -320,11 +331,10 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: ARG002 params, extra_args, ) - out = self.to_output_range(out) - return out + return self.to_output_range(out) -def mon_curve_forward(x, exponent, offset): +def mon_curve_forward(x: NDArrayFloat, exponent: float, offset: float) -> NDArrayFloat: x_break = offset / (exponent - 1) s = ((exponent - 1) / offset) * ( (offset * exponent) / ((exponent - 1) * (1 + offset)) @@ -332,7 +342,7 @@ def mon_curve_forward(x, exponent, offset): return np.where(x >= x_break, ((x + offset) / (1 + offset)) ** exponent, x * s) -def mon_curve_reverse(x, exponent, offset): +def mon_curve_reverse(x: NDArrayFloat, exponent: float, offset: float) -> NDArrayFloat: y_break = ((offset * exponent) / ((exponent - 1) * (1 + offset))) ** exponent s = ((exponent - 1) / offset) * ( (offset * exponent) / ((exponent - 1) * (1 + offset)) @@ -340,8 +350,8 @@ def mon_curve_reverse(x, exponent, offset): return np.where(x >= y_break, (1 + offset) * x ** (1 / exponent) - offset, x / s) -def apply_exponent_internal( - value: NDArrayFloat, params: clf.ExponentParams, extra_args +def apply_exponent_internal( # noqa: PLR0911 + value: NDArrayFloat, params: clf.ExponentParams, extra_args: Any ) -> NDArrayFloat: exponent = params.exponent offset = params.offset @@ -376,13 +386,14 @@ def apply_exponent_internal( value, exponent, offset, "monCurveMirrorRev" ) case _: - raise ValueError(f"Invalid Exponent Style: {style}") + message = f"Invalid Exponent Style: {style}" + raise ValueError(message) class Exponent(CLFNode): node: clf.Exponent - def __init__(self, node: clf.Exponent): + def __init__(self, node: clf.Exponent) -> None: super().__init__(node) self.node = node @@ -392,22 +403,18 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: ARG002 style = node.style params = node.exponent_params out = apply_by_channel(RGB, apply_exponent_internal, params, extra_args=style) - out = self.to_output_range(out) - return out + return self.to_output_range(out) -def asc_cdl_luma(value): - # R, G, B = tsplit(value) - # luma = 0.2126 * R + 0.7152 * G + 0.0722 * B +def asc_cdl_luma(value: NDArrayFloat) -> NDArrayFloat: weights = [0.2126, 0.7152, 0.0722] - luma = np.sum(weights * value, axis=-1) - return luma + return np.sum(weights * value, axis=-1) class ASC_CDL(CLFNode): node: clf.ASC_CDL - def __init__(self, node: clf.ASC_CDL): + def __init__(self, node: clf.ASC_CDL) -> None: super().__init__(node) self.node = node @@ -425,18 +432,13 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: ARG002 power = np.array(sop.power) saturation = 1.0 if node.sat_node is None else node.sat_node.saturation - def clamp(x): + def clamp(x: NDArrayFloat) -> NDArrayFloat: return np.clip(x, 0.0, 1.0) match node.style: case clf.ASC_CDL_Style.FWD: - out_sop = ( - clamp( - RGB * slope + offset, - ) - ** power - ) - R, G, B = tsplit(out_sop) + value: NDArrayFloat = RGB # Needed to satisfy pywright, + out_sop = clamp(value * slope + offset) ** power luma = asc_cdl_luma(out_sop) out = clamp(luma + saturation * (out_sop - luma)) case clf.ASC_CDL_Style.FWD_NO_CLAMP: @@ -455,12 +457,14 @@ def clamp(x): out_pw = np.where(out_sat >= 0, (out_sat) ** (1 / power), out_sat) out = (out_pw - offset) / slope case _: - raise ValueError(f"Invalid ASC_CDL Style: {node.style}") - out = self.to_output_range(out) - return out + message = f"Invalid ASC_CDL Style: {node.style}" + raise ValueError(message) + return self.to_output_range(out) -def as_LUT_sequence_item(node: clf.ProcessNode) -> ProtocolLUTSequenceItem: +def as_LUT_sequence_item( # noqa: PLR0911 + node: clf.ProcessNode, +) -> ProtocolLUTSequenceItem: if isinstance(node, clf.LUT1D): return LUT1D(node) if isinstance(node, clf.LUT3D): @@ -475,13 +479,14 @@ def as_LUT_sequence_item(node: clf.ProcessNode) -> ProtocolLUTSequenceItem: return Exponent(node) if isinstance(node, clf.ASC_CDL): return ASC_CDL(node) - raise RuntimeError(f"No matching process node found for {node}.") + message = f"No matching process node found for {node}." + raise RuntimeError(message) def apply( process_list: clf.ProcessList, value: NDArrayFloat, - normalised_values=False, + normalised_values: bool = False, ) -> NDArrayFloat: """Apply the transformation described by the given ProcessList to the given value. diff --git a/colour/io/luts/lut.py b/colour/io/luts/lut.py index 86df30613..20a9cb753 100644 --- a/colour/io/luts/lut.py +++ b/colour/io/luts/lut.py @@ -996,9 +996,9 @@ def linear_table( return domain attest( - is_numeric(size), - f"Linear table size must be a numeric but is {size} instead!", - ) + is_numeric(size), + f"Linear table size must be a numeric but is {size} instead!", + ) return np.linspace(domain[0], domain[1], as_int_scalar(size)) diff --git a/colour/io/luts/tests/clf_apply/test_asc_cdl.py b/colour/io/luts/tests/clf_apply/test_asc_cdl.py index 378215540..83952e157 100644 --- a/colour/io/luts/tests/clf_apply/test_asc_cdl.py +++ b/colour/io/luts/tests/clf_apply/test_asc_cdl.py @@ -1,5 +1,6 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.io.clf` module.""" + import unittest __author__ = "Colour Developers" @@ -17,7 +18,7 @@ ) -def assert_snippet_consistency(snippet): +def assert_snippet_consistency(snippet: str) -> None: """ Evaluate the snippet with multiple values anc check that they are the same as the `ociochecklut` tools output. @@ -34,7 +35,7 @@ class TestASC_CDL: Define test for applying Exponent nodes from a CLF file. """ - def test_ocio_consistency_fwd(self): + def test_ocio_consistency_fwd(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -53,7 +54,7 @@ def test_ocio_consistency_fwd(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_rev(self): + def test_ocio_consistency_rev(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -72,7 +73,7 @@ def test_ocio_consistency_rev(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_fwd_no_clamp(self): + def test_ocio_consistency_fwd_no_clamp(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -91,7 +92,7 @@ def test_ocio_consistency_fwd_no_clamp(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_rev_no_clamp(self): + def test_ocio_consistency_rev_no_clamp(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -110,7 +111,7 @@ def test_ocio_consistency_rev_no_clamp(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_default_args(self): + def test_ocio_consistency_default_args(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ diff --git a/colour/io/luts/tests/clf_apply/test_exponent.py b/colour/io/luts/tests/clf_apply/test_exponent.py index ce1f80fa6..893df0ee7 100644 --- a/colour/io/luts/tests/clf_apply/test_exponent.py +++ b/colour/io/luts/tests/clf_apply/test_exponent.py @@ -1,5 +1,6 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.io.clf` module.""" + import unittest __author__ = "Colour Developers" @@ -17,7 +18,7 @@ ) -def assert_snippet_consistency(snippet): +def assert_snippet_consistency(snippet: str) -> None: """ Evaluate the snippet with multiple values anc check that they are the same as the `ociochecklut` tools output. @@ -37,7 +38,7 @@ class TestExponent: Define test for applying Exponent nodes from a CLF file. """ - def test_ocio_consistency_fwd(self): + def test_ocio_consistency_fwd(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -49,7 +50,7 @@ def test_ocio_consistency_fwd(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_rev(self): + def test_ocio_consistency_rev(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -61,7 +62,7 @@ def test_ocio_consistency_rev(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_mirror_fwd(self): + def test_ocio_consistency_mirror_fwd(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -73,7 +74,7 @@ def test_ocio_consistency_mirror_fwd(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_basic_mirror_rev(self): + def test_ocio_consistency_basic_mirror_rev(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -85,7 +86,7 @@ def test_ocio_consistency_basic_mirror_rev(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_basic_pass_thru_fwd(self): + def test_ocio_consistency_basic_pass_thru_fwd(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -97,7 +98,7 @@ def test_ocio_consistency_basic_pass_thru_fwd(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_basic_pass_thru_rev(self): + def test_ocio_consistency_basic_pass_thru_rev(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -109,7 +110,7 @@ def test_ocio_consistency_basic_pass_thru_rev(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_mon_curve_fwd(self): + def test_ocio_consistency_mon_curve_fwd(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -121,7 +122,7 @@ def test_ocio_consistency_mon_curve_fwd(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_mon_curve_rev(self): + def test_ocio_consistency_mon_curve_rev(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -133,7 +134,7 @@ def test_ocio_consistency_mon_curve_rev(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_mon_curve_rev_2(self): + def test_ocio_consistency_mon_curve_rev_2(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -145,7 +146,7 @@ def test_ocio_consistency_mon_curve_rev_2(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_mon_curve_mirror_fwd(self): + def test_ocio_consistency_mon_curve_mirror_fwd(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -157,7 +158,7 @@ def test_ocio_consistency_mon_curve_mirror_fwd(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_mon_curve_mirror_rev(self): + def test_ocio_consistency_mon_curve_mirror_rev(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -169,7 +170,7 @@ def test_ocio_consistency_mon_curve_mirror_rev(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_single_channel_application(self): + def test_ocio_consistency_single_channel_application(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -181,7 +182,7 @@ def test_ocio_consistency_single_channel_application(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_multi_channel_application(self): + def test_ocio_consistency_multi_channel_application(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ diff --git a/colour/io/luts/tests/clf_apply/test_helper.py b/colour/io/luts/tests/clf_apply/test_helper.py index 2e3fc72ae..02ef9b1e0 100644 --- a/colour/io/luts/tests/clf_apply/test_helper.py +++ b/colour/io/luts/tests/clf_apply/test_helper.py @@ -1,5 +1,6 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.io.clf` module.""" + import unittest __author__ = "Colour Developers" @@ -20,7 +21,7 @@ class TestHelpers: :func:`colour.io.luts.clf.from_f16_to_uint16` unit tests methods. """ - def test_uint16_to_f16(self): + def test_uint16_to_f16(self) -> None: """ Test :func:`colour.io.luts.clf.from_uint16_to_f16` method. """ @@ -29,7 +30,7 @@ def test_uint16_to_f16(self): expected = np.array([0, 1.0]) np.testing.assert_almost_equal(output, expected) - def test_f16_to_uint16(self): + def test_f16_to_uint16(self) -> None: """ Test :func:`colour.io.luts.clf.from_f16_to_uint16` method. """ @@ -38,7 +39,7 @@ def test_f16_to_uint16(self): expected = np.array([0, 15360]) np.testing.assert_almost_equal(output, expected) - def test_conversion_reversible(self): + def test_conversion_reversible(self) -> None: """ Test :func:`colour.io.luts.clf.from_uint16_to_f16` method with :func:`colour.io.luts.clf.from_f16_to_uint16`. diff --git a/colour/io/luts/tests/clf_apply/test_log.py b/colour/io/luts/tests/clf_apply/test_log.py index 1ac769278..7fa2e6078 100644 --- a/colour/io/luts/tests/clf_apply/test_log.py +++ b/colour/io/luts/tests/clf_apply/test_log.py @@ -1,5 +1,6 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.io.clf` module.""" + import unittest __author__ = "Colour Developers" @@ -17,7 +18,7 @@ ) -def assert_snippet_consistency(snippet): +def assert_snippet_consistency(snippet: str) -> None: """ Evaluate the snippet with multiple values anc check that they are the same as the `ociochecklut` tools output. @@ -34,7 +35,7 @@ class TestLog: Define test for applying Log nodes from a CLF file. """ - def test_ocio_consistency_log_10(self): + def test_ocio_consistency_log_10(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -45,7 +46,7 @@ def test_ocio_consistency_log_10(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_anti_log_10(self): + def test_ocio_consistency_anti_log_10(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -56,7 +57,7 @@ def test_ocio_consistency_anti_log_10(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_log_2(self): + def test_ocio_consistency_log_2(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -67,7 +68,7 @@ def test_ocio_consistency_log_2(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_anti_log_2(self): + def test_ocio_consistency_anti_log_2(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -78,7 +79,7 @@ def test_ocio_consistency_anti_log_2(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_lin_to_log(self): + def test_ocio_consistency_lin_to_log(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -92,7 +93,7 @@ def test_ocio_consistency_lin_to_log(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_log_to_lin(self): + def test_ocio_consistency_log_to_lin(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -106,7 +107,7 @@ def test_ocio_consistency_log_to_lin(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_camera_lin_to_log(self): + def test_ocio_consistency_camera_lin_to_log(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -121,7 +122,7 @@ def test_ocio_consistency_camera_lin_to_log(self): """ assert_snippet_consistency(example) - def test_ocio_consistency_camera_log_to_lin(self): + def test_ocio_consistency_camera_log_to_lin(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ diff --git a/colour/io/luts/tests/clf_apply/test_lut1d.py b/colour/io/luts/tests/clf_apply/test_lut1d.py index 825e546fa..3ac51af5c 100644 --- a/colour/io/luts/tests/clf_apply/test_lut1d.py +++ b/colour/io/luts/tests/clf_apply/test_lut1d.py @@ -1,5 +1,6 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.io.clf` module.""" + import os import unittest @@ -27,7 +28,7 @@ class TestHelpers: :func:`colour.io.luts.clf.from_f16_to_uint16` unit tests methods. """ - def test_uint16_to_f16(self): + def test_uint16_to_f16(self) -> None: """ Test :func:`colour.io.luts.clf.from_uint16_to_f16` method. """ @@ -36,7 +37,7 @@ def test_uint16_to_f16(self): expected = np.array([0, 1.0]) np.testing.assert_almost_equal(output, expected) - def test_f16_to_uint16(self): + def test_f16_to_uint16(self) -> None: """ Test :func:`colour.io.luts.clf.from_f16_to_uint16` method. """ @@ -45,7 +46,7 @@ def test_f16_to_uint16(self): expected = np.array([0, 15360]) np.testing.assert_almost_equal(output, expected) - def test_conversion_reversible(self): + def test_conversion_reversible(self) -> None: """ Test :func:`colour.io.luts.clf.from_uint16_to_f16` method with :func:`colour.io.luts.clf.from_f16_to_uint16`. @@ -84,7 +85,7 @@ class TestLUT1DWithBitDepth: """ - def test_ocio_consistency_simple(self, bit_depth): + def test_ocio_consistency_simple(self, bit_depth: str) -> None: """ Test that the execution of a simple 1D LUT is consistent with `ociochecklut`. """ @@ -122,7 +123,7 @@ def test_ocio_consistency_simple(self, bit_depth): """ - def test_ocio_consistency_multi_table(self, bit_depth): + def test_ocio_consistency_multi_table(self, bit_depth: str) -> None: """ Test that the execution of multiple 1D LUTs is consistent with `ociochecklut`. """ @@ -140,7 +141,7 @@ def test_ocio_consistency_multi_table(self, bit_depth): """ - def test_ocio_consistency_raw_halfs(self, bit_depth): + def test_ocio_consistency_raw_halfs(self, bit_depth: str) -> None: """ Test that the execution of a 1D LUT with the `raw_halfs` attribute is consistent with `ociochecklut`. @@ -156,7 +157,7 @@ class TestLUT1D: Define test for applying 1D LUTSs from a CLF file. """ - def test_ocio_consistency_half_domain(self): + def test_ocio_consistency_half_domain(self) -> None: """ Test that the execution of a 1D LUT with the `half_domain` attribute is consistent with `ociochecklut`. diff --git a/colour/io/luts/tests/clf_apply/test_lut3d.py b/colour/io/luts/tests/clf_apply/test_lut3d.py index 1d0168d4a..0357e2339 100644 --- a/colour/io/luts/tests/clf_apply/test_lut3d.py +++ b/colour/io/luts/tests/clf_apply/test_lut3d.py @@ -1,5 +1,6 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.io.clf` module.""" + import unittest __author__ = "Colour Developers" @@ -44,14 +45,14 @@ class TestLUT3D: """ - def test_ocio_consistency_simple(self): + def test_ocio_consistency_simple(self) -> None: """ Test that the execution of a simple 1D LUT is consistent with `ociochecklut`. """ value_rgb = np.array([1.0, 0.5, 0.0]) assert_ocio_consistency(value_rgb, self.EXAMPLE_SIMPLE) - def test_ocio_consistency_tetrahedral_interpolation(self): + def test_ocio_consistency_tetrahedral_interpolation(self) -> None: """ Test that the execution of a 1D LUT with tetrahedral interpolation is consistent with `ociochecklut`. diff --git a/colour/io/luts/tests/clf_apply/test_matrix.py b/colour/io/luts/tests/clf_apply/test_matrix.py index 78c27d40f..0e9866f1d 100644 --- a/colour/io/luts/tests/clf_apply/test_matrix.py +++ b/colour/io/luts/tests/clf_apply/test_matrix.py @@ -1,5 +1,6 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.io.clf` module.""" + import unittest __author__ = "Colour Developers" @@ -22,7 +23,7 @@ class TestMatrix: Define test for applying Matrix nodes from a CLF file. """ - def test_ocio_consistency_simple(self): + def test_ocio_consistency_simple(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ diff --git a/colour/io/luts/tests/clf_apply/test_range.py b/colour/io/luts/tests/clf_apply/test_range.py index e107dc065..af0eff024 100644 --- a/colour/io/luts/tests/clf_apply/test_range.py +++ b/colour/io/luts/tests/clf_apply/test_range.py @@ -1,5 +1,6 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.io.clf` module.""" + import unittest __author__ = "Colour Developers" @@ -22,7 +23,7 @@ class TestRange: Define test for applying Range nodes from a CLF file. """ - def test_ocio_consistency_simple(self): + def test_ocio_consistency_simple(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -40,7 +41,7 @@ def test_ocio_consistency_simple(self): value_rgb = np.array(rgb) assert_ocio_consistency(value_rgb, example, f"Input value was {rgb}") - def test_ocio_consistency_no_clamp(self): + def test_ocio_consistency_no_clamp(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -57,7 +58,7 @@ def test_ocio_consistency_no_clamp(self): value_rgb = np.array(rgb) assert_ocio_consistency(value_rgb, example, f"Input value was {rgb}") - def test_ocio_consistency_only_max_values(self): + def test_ocio_consistency_only_max_values(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ @@ -72,7 +73,7 @@ def test_ocio_consistency_only_max_values(self): value_rgb = np.array(rgb) assert_ocio_consistency(value_rgb, example, f"Input value was {rgb}") - def test_ocio_consistency_only_min_values(self): + def test_ocio_consistency_only_min_values(self) -> None: """ Test that the execution is consistent with `ociochecklut`. """ diff --git a/colour/io/luts/tests/test_clf_common.py b/colour/io/luts/tests/test_clf_common.py index 99cc2dcb9..c8d99d46d 100644 --- a/colour/io/luts/tests/test_clf_common.py +++ b/colour/io/luts/tests/test_clf_common.py @@ -1,9 +1,11 @@ """ Defines helper functionality for CLF tests. """ + import os import subprocess import tempfile +from collections.abc import Generator import colour_clf_io as clf import numpy as np @@ -16,6 +18,7 @@ "snippet_to_process_list", ] +from hints import NDArrayFloat EXAMPLE_WRAPPER = """ @@ -45,7 +48,7 @@ def snippet_to_process_list(snippet: str) -> clf.ProcessList: return clf.parse_clf(doc) -def snippet_as_tmp_file(snippet): +def snippet_as_tmp_file(snippet: str) -> str: doc = wrap_snippet(snippet) tmp_folder = tempfile.gettempdir() tmp_file_name = tempfile.mktemp(suffix=".clf") # noqa: S306 @@ -55,32 +58,38 @@ def snippet_as_tmp_file(snippet): return file_name -def ocio_outout_for_file(path: str, rgb: tuple[float, float, float] | None = None): +def ocio_output_for_file(path: str, rgb: NDArrayFloat | None = None) -> str: if rgb is None: - return subprocess.check_output(["ociochecklut", "--gpu", f"{path}"]) # noqa: S603 S607 - else: - return subprocess.check_output( - ["ociochecklut", f"{path}", f"{rgb[0]}", f"{rgb[1]}", f"{rgb[2]}"] # noqa: S603 S607 + return str(subprocess.check_output(["ociochecklut", "--gpu", f"{path}"])) # noqa: S603 S607 + return str( + subprocess.check_output( # noqa: S603 + ["ociochecklut", f"{path}", f"{rgb[0]}", f"{rgb[1]}", f"{rgb[2]}"] # noqa: S607 ) + ) -def ocio_output_for_snippet(snippet, rgb=tuple[float, float, float]): +def ocio_output_for_snippet( + snippet: str, rgb: tuple[float, float, float] +) -> NDArrayFloat: f = snippet_as_tmp_file(snippet) try: - return result_as_array(ocio_outout_for_file(f, rgb)) + return result_as_array(ocio_output_for_file(f, rgb)) finally: os.remove(f) -def result_as_array(result_text): - result_parts = result_text.decode("utf-8").strip().split() +def result_as_array(result_text: str) -> NDArrayFloat: + result_parts = result_text.strip().split() if len(result_parts) != 3: - raise RuntimeError(f"Invalid OCIO result: {result_text}") + message = f"Invalid OCIO result: {result_text}" + raise RuntimeError(message) result_values = list(map(float, result_parts)) return np.array(result_values) -def assert_ocio_consistency(value, snippet: str, err_msg=""): +def assert_ocio_consistency( + value: NDArrayFloat, snippet: str, err_msg: str = "" +) -> None: """Assert that the colour library calculates the same output os the `ociocheclut` tool for the given input. """ @@ -90,10 +99,10 @@ def assert_ocio_consistency(value, snippet: str, err_msg=""): ocio_output = ocio_output_for_snippet(snippet, value_tuple) np.testing.assert_array_almost_equal( process_list_output, ocio_output, err_msg=err_msg, decimal=4 - ) # TODO investighate why thete is a difference in the 5/6th digit for log and exp + ) # TODO investigate why there is a difference in the 5/6th digit for log and exp -def assert_ocio_consistency_for_file(value_rgb, clf_path): +def assert_ocio_consistency_for_file(value_rgb: NDArrayFloat, clf_path: str) -> None: """Assert that the colour library calculates the same output os the `ociocheclut` tool for the given input. """ @@ -101,11 +110,11 @@ def assert_ocio_consistency_for_file(value_rgb, clf_path): clf_data = read_clf(clf_path) process_list_output = apply(clf_data, value_rgb, normalised_values=True) - ocio_output = result_as_array(ocio_outout_for_file(clf_path, value_rgb)) + ocio_output = result_as_array(ocio_output_for_file(clf_path, value_rgb)) np.testing.assert_array_almost_equal(process_list_output, ocio_output) -def rgb_sample_iter(step=0.2): +def rgb_sample_iter(step: float = 0.2) -> Generator[tuple[float, float, float]]: for r in np.arange(0.0, 1.0, step): for g in np.arange(0.0, 1.0, step): for b in np.arange(0.0, 1.0, step):