diff --git a/.coveragerc b/.coveragerc index 755710da..281bd93e 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,5 +1,6 @@ [run] source = colour_hdri +sigterm = True [report] exclude_lines = pragma: no cover diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 8dd399ab..00000000 --- a/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -max-line-length = 88 -extend-ignore = E203 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 18e0fca3..32e3642c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -15,11 +15,11 @@ is available to guide the process: https://www.colour-science.org/contributing/. **Code Style and Quality** - [ ] Unit tests have been implemented and passed. -- [ ] Mypy static checking has been run and passed. +- [ ] Pyright static checking has been run and passed. - [ ] Pre-commit hooks have been run and passed. - + **Documentation** diff --git a/.github/workflows/continuous-integration-documentation.yml b/.github/workflows/continuous-integration-documentation.yml index 8b36d5f4..e1cb43ca 100644 --- a/.github/workflows/continuous-integration-documentation.yml +++ b/.github/workflows/continuous-integration-documentation.yml @@ -16,7 +16,7 @@ jobs: - name: Environment Variables run: | echo "CI_PYTHON_VERSION=${{ matrix.python-version }}" >> $GITHUB_ENV - echo "CI_PACKAGE=colour" >> $GITHUB_ENV + echo "CI_PACKAGE=colour_hdri" >> $GITHUB_ENV echo "CI_SHA=${{ github.sha }}" >> $GITHUB_ENV echo "MPLBACKEND=AGG" >> $GITHUB_ENV echo "COLOUR_SCIENCE__DOCUMENTATION_BUILD=True" >> $GITHUB_ENV @@ -30,6 +30,8 @@ jobs: sudo apt-get update sudo apt-get --yes install latexmk texlive-full - name: Install Poetry + env: + POETRY_VERSION: 1.4.0 run: | curl -sSL https://install.python-poetry.org | POETRY_HOME=$HOME/.poetry python3 - echo "$HOME/.poetry/bin" >> $GITHUB_PATH @@ -37,7 +39,7 @@ jobs: - name: Install Package Dependencies run: | poetry run python -m pip install --upgrade pip - poetry install --extras "read-the-docs" + poetry install poetry run python -c "import imageio;imageio.plugins.freeimage.download()" shell: bash - name: Build Documentation diff --git a/.github/workflows/continuous-integration-quality-unit-tests.yml b/.github/workflows/continuous-integration-quality-unit-tests.yml index 7f7eef9f..0954c4b4 100644 --- a/.github/workflows/continuous-integration-quality-unit-tests.yml +++ b/.github/workflows/continuous-integration-quality-unit-tests.yml @@ -66,6 +66,8 @@ jobs: echo "C:\Program Files\Adobe\Adobe DNG Converter" >> $GITHUB_PATH shell: bash - name: Install Poetry + env: + POETRY_VERSION: 1.4.0 run: | curl -sSL https://install.python-poetry.org | POETRY_HOME=$HOME/.poetry python3 - echo "$HOME/.poetry/bin" >> $GITHUB_PATH @@ -73,7 +75,7 @@ jobs: - name: Install Package Dependencies run: | poetry run python -m pip install --upgrade pip - poetry install --extras "plotting" + poetry install poetry run python -c "import imageio;imageio.plugins.freeimage.download()" shell: bash - name: Pre-Commit (All Files) @@ -86,7 +88,7 @@ jobs: shell: bash - name: Test with Pytest run: | - poetry run python -W ignore -m pytest --disable-warnings --doctest-modules --ignore=$CI_PACKAGE/examples --cov=$CI_PACKAGE $CI_PACKAGE + poetry run python -W ignore -m pytest --doctest-modules --ignore=$CI_PACKAGE/examples --cov=$CI_PACKAGE $CI_PACKAGE shell: bash - name: Upload Coverage to coveralls.io run: | diff --git a/.github/workflows/continuous-integration-static-type-checking.yml b/.github/workflows/continuous-integration-static-type-checking.yml index 5d60490a..6a7da84f 100644 --- a/.github/workflows/continuous-integration-static-type-checking.yml +++ b/.github/workflows/continuous-integration-static-type-checking.yml @@ -26,4 +26,4 @@ jobs: pip install -r requirements.txt - name: Static Type Checking run: | - mypy --install-types --non-interactive --show-error-codes --warn-unused-ignores --warn-redundant-casts $CI_PACKAGE + pyright --skipunannotated diff --git a/.gitignore b/.gitignore index f8177b80..485f5e68 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,10 @@ *.pyc *.pyo .DS_Store -.coverage -.dmypy.json +.coverage* .fleet .idea .ipynb_checkpoints -.mypy_cache .sandbox .vs .vscode diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3743cf63..b527df66 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,14 @@ repos: -- repo: https://github.com/asottile/pyupgrade - rev: v3.2.2 - hooks: - - id: pyupgrade - args: [--py39-plus] - repo: https://github.com/ikamensh/flynt/ - rev: '0.77' + rev: '1.0.1' hooks: - id: flynt +- repo: https://github.com/charliermarsh/ruff-pre-commit + rev: 'v0.0.285' + hooks: + - id: ruff - repo: https://github.com/psf/black - rev: 22.10.0 + rev: 23.7.0 hooks: - id: black language_version: python3.9 @@ -18,14 +17,3 @@ repos: hooks: - id: blackdoc language_version: python3.9 -- repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 - hooks: - - id: flake8 -- repo: https://github.com/pycqa/pydocstyle - rev: 6.1.1 - hooks: - - id: pydocstyle - args: - - --convention=numpy - - --add-ignore=D104,D200,D202,D205,D301,D400 diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 28343659..c93eb8a7 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -13,8 +13,5 @@ formats: - pdf python: - install: - - method: pip - path: . - extra_requirements: - - read-the-docs \ No newline at end of file + install: + - requirements: docs/requirements.txt \ No newline at end of file diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 72b36f11..703f6ae2 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -13,5 +13,5 @@ About | **Colour - HDRI** by Colour Developers | Copyright 2015 Colour Developers – `colour-developers@colour-science.org `__ -| This software is released under terms of New BSD License: https://opensource.org/licenses/BSD-3-Clause +| This software is released under terms of BSD-3-Clause: https://opensource.org/licenses/BSD-3-Clause | `https://github.com/colour-science/colour-hdri `__ diff --git a/LICENSE b/LICENSE index dc96ecce..1f83226a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,24 +1,11 @@ Copyright 2015 Colour Developers -All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the Colour Developers nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL COLOUR DEVELOPERS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE diff --git a/README.rst b/README.rst index 5b19f5b8..7e064410 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ Colour - HDRI |actions| |coveralls| |codacy| |version| -.. |actions| image:: https://img.shields.io/github/workflow/status/colour-science/colour-hdri/Continuous%20Integration%20-%20Quality%20&%20Unit%20Tests?label=actions&logo=github&style=flat-square +.. |actions| image:: https://img.shields.io/github/actions/workflow/status/colour-science/colour-hdri/.github/workflows/continuous-integration-quality-unit-tests.yml?branch=develop&style=flat-square :target: https://github.com/colour-science/colour-hdri/actions :alt: Develop Build Status .. |coveralls| image:: http://img.shields.io/coveralls/colour-science/colour-hdri/develop.svg?style=flat-square @@ -20,11 +20,11 @@ Colour - HDRI .. end-badges -A `Python `__ package implementing various +A `Python `__ package implementing various HDRI processing algorithms. It is open source and freely available under the -`New BSD License `__ terms. +`BSD-3-Clause `__ terms. .. image:: https://raw.githubusercontent.com/colour-science/colour-hdri/master/docs/_static/Radiance_001.png @@ -74,20 +74,20 @@ Primary Dependencies **Colour - HDRI** requires various dependencies in order to run: -- `python >= 3.8, < 4 `__ -- `colour-science >= 4 `__ -- `imageio >= 2, < 3 `__ -- `numpy >= 1.19, < 2 `__ -- `scipy >= 1.5, < 2 `__ +- `python >= 3.9, < 4 `__ +- `colour-science >= 4.3 `__ +- `imageio >= 2, < 3 `__ +- `numpy >= 1.22, < 2 `__ +- `scipy >= 1.8, < 2 `__ Optional Features Dependencies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- `colour-demosaicing `__ +- `colour-demosaicing `__ - `Adobe DNG Converter `__ -- `dcraw `__ -- `ExifTool `__ -- `rawpy `__ +- `dcraw `__ +- `ExifTool `__ +- `rawpy `__ Pypi ~~~~ @@ -114,7 +114,7 @@ Contributing ^^^^^^^^^^^^ If you would like to contribute to `Colour - HDRI `__, -please refer to the following `Contributing `__ +please refer to the following `Contributing `__ guide for `Colour `__. Bibliography @@ -146,7 +146,7 @@ Software **C/C++** -- `OpenCV `__ by Bradski, G. +- `OpenCV `__ by Bradski, G. - `Piccante `__ by Banterle, F. and Benedetti, L., *Piccante* was used to verify the Grossberg (2003) Histogram Based Image Sampling. @@ -159,7 +159,7 @@ Code of Conduct --------------- The *Code of Conduct*, adapted from the `Contributor Covenant 1.4 `__, -is available on the `Code of Conduct `__ page. +is available on the `Code of Conduct `__ page. Contact & Social ---------------- @@ -167,7 +167,6 @@ Contact & Social The *Colour Developers* can be reached via different means: - `Email `__ -- `Discourse `__ - `Facebook `__ - `Github Discussions `__ - `Gitter `__ @@ -178,5 +177,5 @@ About | **Colour - HDRI** by Colour Developers | Copyright 2015 Colour Developers – `colour-developers@colour-science.org `__ -| This software is released under terms of New BSD License: https://opensource.org/licenses/BSD-3-Clause +| This software is released under terms of BSD-3-Clause: https://opensource.org/licenses/BSD-3-Clause | `https://github.com/colour-science/colour-hdri `__ diff --git a/TODO.rst b/TODO.rst index d47275dd..f4617424 100644 --- a/TODO.rst +++ b/TODO.rst @@ -6,12 +6,12 @@ TODO - colour_hdri/__init__.py - - Line 265 : # TODO: Remove legacy printing support when deemed appropriate. + - Line 291 : # TODO: Remove legacy printing support when deemed appropriate. - colour_hdri/tonemapping/global_operators/operators.py - - Line 593 : # TODO: Implement automatic *p* and *non-uniform* computations support. + - Line 585 : # TODO: Implement automatic *p* and *non-uniform* computations support. - colour_hdri/utilities/exif.py @@ -21,13 +21,12 @@ TODO - colour_hdri/utilities/image.py - - Line 131 : # TODO: Remove pragma when https://github.com/python/mypy/issues/3004 is resolved. - - Line 442 : # TODO: Revise then "MixinDataclassArray" is improved. + - Line 443 : # TODO: Revise then "MixinDataclassArray" is improved. About ----- | **Colour - HDRI** by Colour Developers -| Copyright 2015 Colour Developers – `colour-developers@colour-science.org `__ -| This software is released under terms of New BSD License: https://opensource.org/licenses/BSD-3-Clause +| Copyright 2015 Colour Developers - `colour-developers@colour-science.org `__ +| This software is released under terms of BSD-3-Clause: https://opensource.org/licenses/BSD-3-Clause | `https://github.com/colour-science/colour-hdri `__ diff --git a/colour_hdri/__init__.py b/colour_hdri/__init__.py index 60f031df..85452a65 100644 --- a/colour_hdri/__init__.py +++ b/colour_hdri/__init__.py @@ -21,6 +21,9 @@ - utilities: Various utilities and data structures. """ +from __future__ import annotations + +import contextlib import sys from colour.utilities.deprecation import ModuleAPI, build_API_changes @@ -30,7 +33,7 @@ import numpy as np import os -import subprocess # nosec +import subprocess import colour @@ -126,9 +129,30 @@ tonemapping_operator_Tumblin1999, ) +from colour.utilities import is_matplotlib_installed + +# Exposing "colour.plotting" sub-package if "Matplotlib" is available. +if is_matplotlib_installed(): + import colour_hdri.plotting as plotting # noqa: F401, PLR0402 +else: + + class MockPlotting: # pragma: no cover + """ + Mock object for :mod:`colour_hdri.plotting` sub-package raising an exception + if the sub-package is accessed but *Matplotlib* is not installed. + """ + + def __getattr__(self, attribute) -> Any: + """Return the value from the attribute with given name.""" + + is_matplotlib_installed(raise_exception=True) + + globals()["plotting"] = MockPlotting() # pragma: no cover + + __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -228,11 +252,11 @@ "tonemapping_operator_Tumblin1999", ] -ROOT_RESOURCES = os.path.join(os.path.dirname(__file__), "resources") -ROOT_RESOURCES_EXAMPLES = os.path.join( +ROOT_RESOURCES: str = os.path.join(os.path.dirname(__file__), "resources") +ROOT_RESOURCES_EXAMPLES: str = os.path.join( ROOT_RESOURCES, "colour-hdri-examples-datasets" ) -ROOT_RESOURCES_TESTS = os.path.join( +ROOT_RESOURCES_TESTS: str = os.path.join( ROOT_RESOURCES, "colour-hdri-tests-datasets" ) @@ -240,15 +264,15 @@ __major_version__ = "0" __minor_version__ = "2" -__change_version__ = "1" +__change_version__ = "2" __version__ = ".".join( (__major_version__, __minor_version__, __change_version__) ) try: _version: str = ( - subprocess.check_output( # nosec - ["git", "describe"], + subprocess.check_output( + ["git", "describe"], # noqa: S603,S607 cwd=os.path.dirname(__file__), stderr=subprocess.STDOUT, ) @@ -256,17 +280,17 @@ .decode("utf-8") ) except Exception: - _version: str = __version__ # type: ignore[no-redef] + _version: str = __version__ -colour.utilities.ANCILLARY_COLOUR_SCIENCE_PACKAGES["colour-hdri"] = _version +colour.utilities.ANCILLARY_COLOUR_SCIENCE_PACKAGES[ # pyright: ignore + "colour-hdri" +] = _version del _version # TODO: Remove legacy printing support when deemed appropriate. -try: +with contextlib.suppress(TypeError): np.set_printoptions(legacy="1.13") -except TypeError: - pass # ----------------------------------------------------------------------------# @@ -301,7 +325,7 @@ def __getattr__(self, attribute) -> Any: """Defines the *colour_hdri* package API changes.""" if not is_documentation_building(): - sys.modules["colour_hdri"] = colour_hdri( # type: ignore[assignment] + sys.modules["colour_hdri"] = colour_hdri( # pyright: ignore sys.modules["colour_hdri"], build_API_changes(API_CHANGES) ) diff --git a/colour_hdri/calibration/absolute_luminance.py b/colour_hdri/calibration/absolute_luminance.py index 0f2a99e9..d2b770e6 100644 --- a/colour_hdri/calibration/absolute_luminance.py +++ b/colour_hdri/calibration/absolute_luminance.py @@ -22,12 +22,12 @@ import numpy as np from colour import RGB_COLOURSPACES, RGB_Colourspace, RGB_luminance -from colour.hints import ArrayLike, Floating, Integer, NDArray +from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import as_float_array __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -41,7 +41,7 @@ def upper_hemisphere_illuminance_Lagarde2016( RGB: ArrayLike, colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"] -) -> Floating: +) -> float: """ Compute upper hemisphere illuminance :math:`E_v` of given RGB panoramic image. @@ -88,8 +88,8 @@ def upper_hemisphere_illuminance_Lagarde2016( def upper_hemisphere_illuminance_weights_Lagarde2016( - height: Integer, width: Integer -) -> NDArray: + height: int, width: int +) -> NDArrayFloat: """ Compute upper hemisphere illuminance weights for use with applications unable to perform the computation directly, i.e. *Adobe Photoshop*. @@ -150,9 +150,9 @@ def upper_hemisphere_illuminance_weights_Lagarde2016( def absolute_luminance_calibration_Lagarde2016( RGB: ArrayLike, - measured_illuminance: Floating, + measured_illuminance: float, colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"], -) -> NDArray: +) -> NDArrayFloat: """ Perform absolute *Luminance* calibration of given *RGB* panoramic image using *Lagarde (2016)* method. diff --git a/colour_hdri/calibration/debevec1997.py b/colour_hdri/calibration/debevec1997.py index eaa3347a..a05d70ea 100644 --- a/colour_hdri/calibration/debevec1997.py +++ b/colour_hdri/calibration/debevec1997.py @@ -29,13 +29,9 @@ from colour.hints import ( Any, ArrayLike, - Boolean, Callable, Dict, - Floating, - Integer, - NDArray, - Optional, + NDArrayFloat, Tuple, ) from colour.utilities import as_float_array, as_int_array, tstack @@ -47,7 +43,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -62,10 +58,10 @@ def g_solve( Z: ArrayLike, B: ArrayLike, - l_s: Floating = 30, + l_s: float = 30, w: Callable = weighting_function_Debevec1997, - n: Integer = 256, -) -> Tuple[NDArray, NDArray]: + n: int = 256, +) -> Tuple[NDArrayFloat, NDArrayFloat]: """ Given a set of pixel values observed for several pixels in several images with different exposure times, this function returns the imaging system's @@ -135,9 +131,9 @@ def g_solve( def extrapolating_function_polynomial( crfs: ArrayLike, weighting_function: Callable, - degree: Integer = 7, - **kwargs: Any, -) -> NDArray: + degree: int = 7, + **kwargs: Any, # noqa: ARG001 +) -> NDArrayFloat: """ Polynomial extrapolating function used to handle zero-weighted data of given camera response functions. @@ -181,15 +177,15 @@ def extrapolating_function_polynomial( def camera_response_functions_Debevec1997( image_stack: ImageStack, sampling_function: Callable = samples_Grossberg2003, - sampling_function_kwargs: Optional[Dict] = None, + sampling_function_kwargs: Dict | None = None, weighting_function: Callable = weighting_function_Debevec1997, - weighting_function_kwargs: Optional[Dict] = None, + weighting_function_kwargs: Dict | None = None, extrapolating_function: Callable = extrapolating_function_polynomial, - extrapolating_function_kwargs: Optional[Dict] = None, - l_s: Floating = 30, - n: Integer = 256, - normalise: Boolean = True, -) -> NDArray: + extrapolating_function_kwargs: Dict | None = None, + l_s: float = 30, + n: int = 256, + normalise: bool = True, +) -> NDArrayFloat: """ Return the camera response functions for given image stack using *Debevec (1997)* method. diff --git a/colour_hdri/calibration/tests/test_absolute_luminance.py b/colour_hdri/calibration/tests/test_absolute_luminance.py index f871b69f..5a711aed 100644 --- a/colour_hdri/calibration/tests/test_absolute_luminance.py +++ b/colour_hdri/calibration/tests/test_absolute_luminance.py @@ -23,7 +23,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/calibration/tests/test_debevec1997.py b/colour_hdri/calibration/tests/test_debevec1997.py index f07bd523..2a36c7b1 100644 --- a/colour_hdri/calibration/tests/test_debevec1997.py +++ b/colour_hdri/calibration/tests/test_debevec1997.py @@ -23,7 +23,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/distortion/tests/test_vignette.py b/colour_hdri/distortion/tests/test_vignette.py index 7e7ea9cf..d588f7bd 100644 --- a/colour_hdri/distortion/tests/test_vignette.py +++ b/colour_hdri/distortion/tests/test_vignette.py @@ -29,7 +29,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/distortion/vignette.py b/colour_hdri/distortion/vignette.py index b4caee0a..d6b15373 100644 --- a/colour_hdri/distortion/vignette.py +++ b/colour_hdri/distortion/vignette.py @@ -46,12 +46,9 @@ from colour.hints import ( ArrayLike, Callable, - Floating, - Integer, Literal, - NDArray, + NDArrayFloat, Tuple, - Union, cast, ) from colour.utilities import ( @@ -68,7 +65,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -100,10 +97,10 @@ def apply_radial_gradient( image: ArrayLike, scale: ArrayLike = (1, 1), offset: ArrayLike = (0.5, 0.5), - intensity: Floating = 1, - bias: Floating = 1, - noise: Floating = 0, -) -> NDArray: + intensity: float = 1, + bias: float = 1, + noise: float = 0, +) -> NDArrayFloat: """ Apply a radial gradient on given image. @@ -139,7 +136,8 @@ def apply_radial_gradient( [ 0. , 0.023, 0.212, 0.286, 0.212, 0.023, 0. ]]) """ - image = np.atleast_3d(image) + image = as_float_array(np.atleast_3d(image)) + scale_x, scale_y = tsplit(scale) offset_x, offset_y = tsplit(offset) @@ -153,8 +151,9 @@ def apply_radial_gradient( samples_y *= 1 / scale_y samples_y += offset_y - 0.5 - distance = np.sqrt( - (samples_x**2)[..., None] + (samples_y**2)[None, ...] + distance = cast( + NDArrayFloat, + np.sqrt((samples_x**2)[..., None] + (samples_y**2)[None, ...]), ) image *= 1 - distance[..., None] * intensity @@ -166,8 +165,8 @@ def apply_radial_gradient( def vignette_principal_point( - image: ArrayLike, threshold: Floating = 0.99 -) -> NDArray: + image: ArrayLike, threshold: float = 0.99 +) -> NDArrayFloat: """ Return the vignette principal point for given image. @@ -197,19 +196,19 @@ def vignette_principal_point( M = np.median(image, axis=-1) thresholded = zeros(M.shape) - thresholded[M > np.max(M) * threshold] = 1 + thresholded[np.max(M) * threshold < M] = 1 return center_of_mass(thresholded) / as_float_array([shape_x, shape_y]) def parabolic_2D_function( x_y: Tuple, - a_x2: Floating, - a_x1: Floating, - a_x0: Floating, - a_y2: Floating, - a_y1: Floating, - a_y0: Floating, + a_x2: float, + a_x1: float, + a_x0: float, + a_y2: float, + a_y1: float, + a_y0: float, ): """ Evaluate a parabolic 2D function on given coordinate matrices from @@ -270,11 +269,11 @@ def parabolic_2D_function( def hyperbolic_cosine_2D_function( x_y: Tuple, - r_x: Floating, - x_0: Floating, - r_y: Floating, - y_0: Floating, - c: Floating, + r_x: float, + x_0: float, + r_y: float, + y_0: float, + c: float, ): """ Evaluate a hyperbolic cosine 2D function on given coordinate matrices from @@ -352,8 +351,8 @@ class FunctionVignetteCharacterisation(MixinDataclassIterable): """ function: Callable - p0: NDArray - bounds: NDArray + p0: NDArrayFloat + bounds: NDArrayFloat VIGNETTE_CHARACTERISATION_2D_FUNCTIONS: CanonicalMapping = CanonicalMapping( @@ -390,9 +389,7 @@ class FunctionVignetteCharacterisation(MixinDataclassIterable): @dataclass -class DataVignetteCharacterisation( - MixinDataclassIterable -): # noqa: D405,D407,D410,D411,D414 +class DataVignetteCharacterisation(MixinDataclassIterable): """ Define the data of a vignette characterisation process. @@ -402,7 +399,7 @@ class DataVignetteCharacterisation( Vignette characterisation parameters. principal_point Vignette principal point. - """ + """ # noqa: D405, D407, D410, D411, D414 parameters: ArrayLike principal_point: ArrayLike @@ -410,9 +407,7 @@ class DataVignetteCharacterisation( def characterise_vignette_2D_function( image: ArrayLike, - function: Union[ - Literal["Parabolic", "Hyperbolic Cosine"], str - ] = "Parabolic", + function: Literal["Parabolic", "Hyperbolic Cosine"] | str = "Parabolic", ) -> DataVignetteCharacterisation: """ Characterise the vignette of given image using a given 2D function. @@ -442,7 +437,7 @@ def characterise_vignette_2D_function( image = np.atleast_3d(image) function = validate_method( function, - VIGNETTE_CHARACTERISATION_2D_FUNCTIONS, + tuple(VIGNETTE_CHARACTERISATION_2D_FUNCTIONS.keys()), '"{0}" function is invalid, it must be one of {1}!', ) @@ -484,10 +479,8 @@ def characterise_vignette_2D_function( def correct_vignette_2D_function( image: ArrayLike, characterisation_data: DataVignetteCharacterisation, - function: Union[ - Literal["Parabolic", "Hyperbolic Cosine"], str - ] = "Parabolic", -) -> NDArray: + function: Literal["Parabolic", "Hyperbolic Cosine"] | str = "Parabolic", +) -> NDArrayFloat: """ Correct the vignette of given image using given characterisation for a 2D function. @@ -524,7 +517,7 @@ def correct_vignette_2D_function( function = validate_method( function, - VIGNETTE_CHARACTERISATION_2D_FUNCTIONS, + tuple(VIGNETTE_CHARACTERISATION_2D_FUNCTIONS.keys()), '"{0}" function is invalid, it must be one of {1}!', ) @@ -552,10 +545,10 @@ def correct_vignette_2D_function( def characterise_vignette_bivariate_spline( image: ArrayLike, - pre_denoise_sigma: Floating = 6, - post_denoise_sigma: Floating = 1, - samples: Integer = 50, - degree: Integer = 3, + pre_denoise_sigma: float = 6, + post_denoise_sigma: float = 1, + samples: int = 50, + degree: int = 3, ) -> DataVignetteCharacterisation: """ Characterise the vignette of given image using a bivariate spline. @@ -633,8 +626,8 @@ def characterise_vignette_bivariate_spline( def correct_vignette_bivariate_spline( image: ArrayLike, characterisation_data: DataVignetteCharacterisation, - degree: Integer = 3, -) -> NDArray: + degree: int = 3, +) -> NDArrayFloat: """ Correct the vignette of given image using given characterisation for a bivariate spline. @@ -688,11 +681,11 @@ def correct_vignette_bivariate_spline( def radial_sampling_function( - samples_rho: Integer = 7, - samples_phi: Integer = 21, - radius: Floating = 1, - radial_bias: Floating = 1, -) -> NDArray: + samples_rho: int = 7, + samples_phi: int = 21, + radius: float = 1, + radial_bias: float = 1, +) -> NDArrayFloat: """ Return a series of radial samples. @@ -729,15 +722,15 @@ def radial_sampling_function( def vignette_sampling_coordinates( principal_point: ArrayLike = np.array([0.5, 0.5]), - aspect_ratio: Floating = 1, - diagonal_samples: Integer = 10, - diagonal_selection: Integer = 2, - edge_samples: Integer = 10, - samples_rho: Integer = 7, - samples_phi: Integer = 21, - radius: Floating = 0.9, - radial_bias: Floating = 1, -) -> NDArray: + aspect_ratio: float = 1, + diagonal_samples: int = 10, + diagonal_selection: int = 2, + edge_samples: int = 10, + samples_rho: int = 7, + samples_phi: int = 21, + radius: float = 0.9, + radial_bias: float = 1, +) -> NDArrayFloat: """ Return a series of sampling coordinates appropriate for radial basis function (RBF) interpolation of a vignette function. @@ -807,7 +800,7 @@ def vignette_sampling_coordinates( radial_samples = radial_sampling_function( samples_rho, samples_phi, - 1 + (np.max(principal_point - 0.5) * 2), + cast(float, 1 + (np.max(principal_point - 0.5) * 2)), radial_bias, ) # NOTE: Some randomisation is required to avoid a @@ -833,7 +826,7 @@ def vignette_sampling_coordinates( def characterise_vignette_RBF( - image: ArrayLike, denoise_sigma: Floating = 6 + image: ArrayLike, denoise_sigma: float = 6 ) -> DataVignetteCharacterisation: """ Characterise the vignette of given image using a series of sampling @@ -891,7 +884,7 @@ def characterise_vignette_RBF( def correct_vignette_RBF( image: ArrayLike, characterisation_data: DataVignetteCharacterisation, - smoothing: Floating = 0.001, + smoothing: float = 0.001, kernel: Literal[ "linear", "thin_plate_spline", @@ -902,8 +895,8 @@ def correct_vignette_RBF( "inverse_quadratic", "gaussian", ] = "cubic", - epsilon: Floating = 1, -) -> NDArray: + epsilon: float = 1, +) -> NDArrayFloat: """ Correct the vignette of given image using given characterisation for radial basis function (RBF) interpolation. @@ -986,9 +979,7 @@ def correct_vignette_RBF( def characterise_vignette( image: ArrayLike, - method: Union[ - Literal["2D Function", "Bivariate Spline", "RBF"], str - ] = "RBF", + method: Literal["2D Function", "Bivariate Spline", "RBF"] | str = "RBF", **kwargs, ) -> DataVignetteCharacterisation: """ @@ -1061,7 +1052,9 @@ def characterise_vignette( array([ 0.4983333..., 0.49875 ]) """ - method = validate_method(method, VIGNETTE_CHARACTERISATION_METHODS) + method = validate_method( + method, tuple(VIGNETTE_CHARACTERISATION_METHODS.keys()) + ) return VIGNETTE_CHARACTERISATION_METHODS[method](image, **kwargs) @@ -1081,11 +1074,9 @@ def characterise_vignette( def correct_vignette( image: ArrayLike, characterisation_data: DataVignetteCharacterisation, - method: Union[ - Literal["2D Function", "Bivariate Spline", "RBF"], str - ] = "RBF", + method: Literal["2D Function", "Bivariate Spline", "RBF"] | str = "RBF", **kwargs, -) -> NDArray: +) -> NDArrayFloat: """ Correct the vignette of given image using given method. @@ -1172,7 +1163,7 @@ def correct_vignette( [ 0. , 0.345, 3.059, 4.072, 3.059, 0.345, 0. ]]) """ - method = validate_method(method, VIGNETTE_CORRECTION_METHODS) + method = validate_method(method, tuple(VIGNETTE_CORRECTION_METHODS.keys())) return VIGNETTE_CORRECTION_METHODS[method]( image, characterisation_data, **kwargs diff --git a/colour_hdri/exposure/common.py b/colour_hdri/exposure/common.py index 7876f99f..62508bbd 100644 --- a/colour_hdri/exposure/common.py +++ b/colour_hdri/exposure/common.py @@ -22,13 +22,13 @@ import numpy as np -from colour.hints import FloatingOrArrayLike, FloatingOrNDArray +from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import as_float, as_float_array __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -43,11 +43,11 @@ def average_luminance( - N: FloatingOrArrayLike, - t: FloatingOrArrayLike, - S: FloatingOrArrayLike, - k: FloatingOrArrayLike = 12.5, -) -> FloatingOrNDArray: + N: ArrayLike, + t: ArrayLike, + S: ArrayLike, + k: ArrayLike = 12.5, +) -> NDArrayFloat: """ Compute the average luminance :math:`L` in :math:`cd\\cdot m^{-2}` from given relative aperture *F-Number* :math:`N`, *Exposure Time* :math:`t`, @@ -71,7 +71,7 @@ def average_luminance( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Average luminance :math:`L` in :math:`cd\\cdot m^{-2}`. References @@ -95,11 +95,11 @@ def average_luminance( def average_illuminance( - N: FloatingOrArrayLike, - t: FloatingOrArrayLike, - S: FloatingOrArrayLike, - c: FloatingOrArrayLike = 250, -) -> FloatingOrNDArray: + N: ArrayLike, + t: ArrayLike, + S: ArrayLike, + c: ArrayLike = 250, +) -> NDArrayFloat: """ Compute the average illuminance :math:`E` in :math:`Lux` from given relative aperture *F-Number* :math:`N`, *Exposure Time* :math:`t`, *ISO* @@ -125,7 +125,7 @@ def average_illuminance( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Average illuminance :math:`E` in :math:`Lux`. References @@ -149,10 +149,10 @@ def average_illuminance( def luminance_to_exposure_value( - L: FloatingOrArrayLike, - S: FloatingOrArrayLike, - k: FloatingOrArrayLike = 12.5, -) -> FloatingOrNDArray: + L: ArrayLike, + S: ArrayLike, + k: ArrayLike = 12.5, +) -> NDArrayFloat: """ Compute the exposure value :math:`EV` from given scene luminance :math:`L` in :math:`cd\\cdot m^{-2}`, *ISO* arithmetic speed :math:`S` and @@ -173,7 +173,7 @@ def luminance_to_exposure_value( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Exposure value :math:`EV`. Notes @@ -203,10 +203,10 @@ def luminance_to_exposure_value( def illuminance_to_exposure_value( - E: FloatingOrArrayLike, - S: FloatingOrArrayLike, - c: FloatingOrArrayLike = 250, -) -> FloatingOrNDArray: + E: ArrayLike, + S: ArrayLike, + c: ArrayLike = 250, +) -> NDArrayFloat: """ Compute the exposure value :math:`EV` from given scene illuminance :math:`E` in :math:`Lux`, *ISO* arithmetic speed :math:`S` and @@ -229,7 +229,7 @@ def illuminance_to_exposure_value( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Exposure value :math:`EV`. Notes @@ -258,9 +258,7 @@ def illuminance_to_exposure_value( return as_float(EV) -def adjust_exposure( - a: FloatingOrArrayLike, EV: FloatingOrArrayLike -) -> FloatingOrNDArray: +def adjust_exposure(a: ArrayLike, EV: ArrayLike) -> NDArrayFloat: """ Adjust given array exposure using given :math:`EV` exposure value. @@ -273,7 +271,7 @@ def adjust_exposure( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Exposure adjusted array. Examples diff --git a/colour_hdri/exposure/dsc.py b/colour_hdri/exposure/dsc.py index ea23c1ff..6f6a1016 100644 --- a/colour_hdri/exposure/dsc.py +++ b/colour_hdri/exposure/dsc.py @@ -24,7 +24,7 @@ import numpy as np -from colour.hints import FloatingOrArrayLike, FloatingOrNDArray +from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import as_float, as_float_array from colour_hdri.exposure import ( @@ -34,7 +34,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -51,10 +51,10 @@ def q_factor( - T: FloatingOrArrayLike = 9 / 10, - f_v: FloatingOrArrayLike = 98 / 100, - theta: FloatingOrArrayLike = 10, -) -> FloatingOrNDArray: + T: ArrayLike = 9 / 10, + f_v: ArrayLike = 98 / 100, + theta: ArrayLike = 10, +) -> NDArrayFloat: """ Compute the :math:`q` factor modeling the total lens vignetting and transmission attenuation. @@ -70,7 +70,7 @@ def q_factor( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` :math:`q` factor. References @@ -91,16 +91,16 @@ def q_factor( def focal_plane_exposure( - L: FloatingOrArrayLike, - A: FloatingOrArrayLike, - t: FloatingOrArrayLike, - F: FloatingOrArrayLike, - i: FloatingOrArrayLike, - H_f: FloatingOrArrayLike, - T: FloatingOrArrayLike = 9 / 10, - f_v: FloatingOrArrayLike = 98 / 100, - theta: FloatingOrArrayLike = 10, -) -> FloatingOrNDArray: + L: ArrayLike, + A: ArrayLike, + t: ArrayLike, + F: ArrayLike, + i: ArrayLike, + H_f: ArrayLike, + T: ArrayLike = 9 / 10, + f_v: ArrayLike = 98 / 100, + theta: ArrayLike = 10, +) -> NDArrayFloat: """ Compute the focal plane exposure :math:`H` in lux-seconds (:math:`lx.s`). @@ -128,7 +128,7 @@ def focal_plane_exposure( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Focal plane exposure :math:`H` in lux-seconds (:math:`lx.s`). Notes @@ -168,8 +168,8 @@ def focal_plane_exposure( def arithmetic_mean_focal_plane_exposure( - L_a: FloatingOrArrayLike, A: FloatingOrArrayLike, t: FloatingOrArrayLike -) -> FloatingOrNDArray: + L_a: ArrayLike, A: ArrayLike, t: ArrayLike +) -> NDArrayFloat: """ Compute the arithmetic mean focal plane exposure :math:`H_a` for a camera focused on infinity, :math:`H_f << H`, :math:`T=9/10`, @@ -186,7 +186,7 @@ def arithmetic_mean_focal_plane_exposure( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Focal plane exposure :math:`H_a`. Notes @@ -217,17 +217,17 @@ def arithmetic_mean_focal_plane_exposure( def saturation_based_speed_focal_plane_exposure( - L: FloatingOrArrayLike, - A: FloatingOrArrayLike, - t: FloatingOrArrayLike, - S: FloatingOrArrayLike, - F: FloatingOrArrayLike = 50 / 1000, - i: FloatingOrArrayLike = 1 / (-1 / 5 + 1 / (50 / 1000)), - H_f: FloatingOrArrayLike = 0, - T: FloatingOrArrayLike = 9 / 10, - f_v: FloatingOrArrayLike = 98 / 100, - theta: FloatingOrArrayLike = 10, -) -> FloatingOrNDArray: + L: ArrayLike, + A: ArrayLike, + t: ArrayLike, + S: ArrayLike, + F: ArrayLike = 50 / 1000, + i: ArrayLike = 1 / (-1 / 5 + 1 / (50 / 1000)), + H_f: ArrayLike = 0, + T: ArrayLike = 9 / 10, + f_v: ArrayLike = 98 / 100, + theta: ArrayLike = 10, +) -> NDArrayFloat: """ Compute the Saturation-Based Speed (SBS) focal plane exposure :math:`H_{SBS}` in lux-seconds (:math:`lx.s`). @@ -261,7 +261,7 @@ def saturation_based_speed_focal_plane_exposure( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Saturation-Based Speed focal plane exposure :math:`H_{SBS}` in lux-seconds (:math:`lx.s`). @@ -310,7 +310,7 @@ def saturation_based_speed_focal_plane_exposure( return as_float(H_SBS) -def exposure_index_values(H_a: FloatingOrArrayLike) -> FloatingOrNDArray: +def exposure_index_values(H_a: ArrayLike) -> NDArrayFloat: """ Compute the exposure index values :math:`I_{EI}` from given focal plane exposure :math:`H_a`. @@ -322,7 +322,7 @@ def exposure_index_values(H_a: FloatingOrArrayLike) -> FloatingOrNDArray: Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Exposure index values :math:`I_{EI}`. References @@ -339,8 +339,8 @@ def exposure_index_values(H_a: FloatingOrArrayLike) -> FloatingOrNDArray: def exposure_value_100( - N: FloatingOrArrayLike, t: FloatingOrArrayLike, S: FloatingOrArrayLike -) -> FloatingOrNDArray: + N: ArrayLike, t: ArrayLike, S: ArrayLike +) -> NDArrayFloat: """ Compute the exposure value :math:`EV100` from given relative aperture *F-Number* :math:`N`, *Exposure Time* :math:`t` and *ISO* arithmetic @@ -357,7 +357,7 @@ def exposure_value_100( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Exposure value :math:`EV100`. References @@ -384,11 +384,11 @@ def exposure_value_100( def photometric_exposure_scale_factor_Lagarde2014( - EV100: FloatingOrArrayLike, - T: FloatingOrArrayLike = 9 / 10, - f_v: FloatingOrArrayLike = 98 / 100, - theta: FloatingOrArrayLike = 10, -) -> FloatingOrNDArray: + EV100: ArrayLike, + T: ArrayLike = 9 / 10, + f_v: ArrayLike = 98 / 100, + theta: ArrayLike = 10, +) -> NDArrayFloat: """ Convert the exposure value :math:`EV100` to photometric exposure scale factor using *Lagarde and de Rousiers (2014)* formulation derived from the @@ -410,7 +410,7 @@ def photometric_exposure_scale_factor_Lagarde2014( Returns ------- - :class:`np.floating` or :class:`numpy.ndarray` + :class:`numpy.ndarray` Photometric exposure in lux-seconds (:math:`lx.s`). Notes diff --git a/colour_hdri/exposure/tests/test_common.py b/colour_hdri/exposure/tests/test_common.py index ae910a5a..1f3dba4d 100644 --- a/colour_hdri/exposure/tests/test_common.py +++ b/colour_hdri/exposure/tests/test_common.py @@ -14,7 +14,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/exposure/tests/test_dsc.py b/colour_hdri/exposure/tests/test_dsc.py index cf7d075a..d8095f89 100644 --- a/colour_hdri/exposure/tests/test_dsc.py +++ b/colour_hdri/exposure/tests/test_dsc.py @@ -16,7 +16,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/generation/__init__.py b/colour_hdri/generation/__init__.py index dc0cd16c..24305a93 100644 --- a/colour_hdri/generation/__init__.py +++ b/colour_hdri/generation/__init__.py @@ -47,7 +47,7 @@ def __getattr__(self, attribute) -> Any: """Defines the *colour_hdri.generation* sub-package API changes.""" if not is_documentation_building(): - sys.modules["colour_hdri.generation"] = generation( # type: ignore[assignment] + sys.modules["colour_hdri.generation"] = generation( # pyright: ignore sys.modules["colour_hdri.generation"], build_API_changes(API_CHANGES) ) diff --git a/colour_hdri/generation/hdri.py b/colour_hdri/generation/hdri.py index f5ff653c..f5d0c50d 100644 --- a/colour_hdri/generation/hdri.py +++ b/colour_hdri/generation/hdri.py @@ -25,7 +25,7 @@ import numpy as np from colour.utilities import as_float_array, tsplit, tstack, warning -from colour.hints import ArrayLike, Callable, NDArray, Optional +from colour.hints import ArrayLike, Callable, NDArrayFloat from colour_hdri.exposure import average_luminance from colour_hdri.generation import weighting_function_Debevec1997 @@ -33,7 +33,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -46,8 +46,8 @@ def image_stack_to_HDRI( image_stack: ImageStack, weighting_function: Callable = weighting_function_Debevec1997, - camera_response_functions: Optional[ArrayLike] = None, -) -> Optional[NDArray]: + camera_response_functions: ArrayLike | None = None, +) -> NDArrayFloat | None: """ Generate a HDRI from given image stack. @@ -80,8 +80,8 @@ def image_stack_to_HDRI( :cite:`Banterle2011n` """ - image_c: Optional[NDArray] = None - weight_c: Optional[NDArray] = None + image_c: NDArrayFloat | None = None + weight_c: NDArrayFloat | None = None for i, image in enumerate(image_stack): if image.data is not None and image.metadata is not None: if image_c is None: diff --git a/colour_hdri/generation/tests/test_hdri.py b/colour_hdri/generation/tests/test_hdri.py index 3d6e1452..61addf4e 100644 --- a/colour_hdri/generation/tests/test_hdri.py +++ b/colour_hdri/generation/tests/test_hdri.py @@ -17,7 +17,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/generation/tests/test_weighting_functions.py b/colour_hdri/generation/tests/test_weighting_functions.py index 1d1370dc..614f8b86 100644 --- a/colour_hdri/generation/tests/test_weighting_functions.py +++ b/colour_hdri/generation/tests/test_weighting_functions.py @@ -15,7 +15,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/generation/weighting_functions.py b/colour_hdri/generation/weighting_functions.py index c14a56c6..ba35845f 100644 --- a/colour_hdri/generation/weighting_functions.py +++ b/colour_hdri/generation/weighting_functions.py @@ -20,13 +20,13 @@ import numpy as np -from colour.hints import ArrayLike, Floating, NDArray +from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import as_float_array __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -39,8 +39,8 @@ def normal_distribution_function( - a: ArrayLike, mu: Floating = 0.5, sigma: Floating = 0.15 -) -> NDArray: + a: ArrayLike, mu: float = 0.5, sigma: float = 0.15 +) -> NDArrayFloat: """ Return given array weighted by a normal distribution function. @@ -70,7 +70,7 @@ def normal_distribution_function( return np.exp(-np.power(a - mu, 2) / (2 * np.power(sigma, 2))) -def hat_function(a: ArrayLike) -> NDArray: +def hat_function(a: ArrayLike) -> NDArrayFloat: """ Return given array weighted by a hat function. @@ -93,12 +93,12 @@ def hat_function(a: ArrayLike) -> NDArray: a = as_float_array(a) - return 1 - (2 * a - 1) ** 12 + return 1 - (2 * a - 1) ** 12 # pyright: ignore def weighting_function_Debevec1997( - a: ArrayLike, domain_l: Floating = 0.01, domain_h: Floating = 0.99 -) -> NDArray: + a: ArrayLike, domain_l: float = 0.01, domain_h: float = 0.99 +) -> NDArrayFloat: """ Return given array weighted by *Debevec (1997)* function. diff --git a/colour_hdri/models/__init__.py b/colour_hdri/models/__init__.py index bd8f589e..e34de0b1 100644 --- a/colour_hdri/models/__init__.py +++ b/colour_hdri/models/__init__.py @@ -5,7 +5,7 @@ from colour.hints import Any -from .datasets import * # noqa +from .datasets import * # noqa: F403 from . import datasets from .dng import ( xy_to_camera_neutral, @@ -57,7 +57,7 @@ def __getattr__(self, attribute) -> Any: """Defines the *colour_hdri.models* sub-package API changes.""" if not is_documentation_building(): - sys.modules["colour_hdri.models"] = models( # type: ignore[assignment] + sys.modules["colour_hdri.models"] = models( # pyright: ignore sys.modules["colour_hdri.models"], build_API_changes(API_CHANGES) ) diff --git a/colour_hdri/models/datasets/dng.py b/colour_hdri/models/datasets/dng.py index 4f0a1f8a..436e0b4f 100644 --- a/colour_hdri/models/datasets/dng.py +++ b/colour_hdri/models/datasets/dng.py @@ -26,12 +26,12 @@ from __future__ import annotations from colour.colorimetry import CCS_ILLUMINANTS -from colour.hints import Dict, NDArray +from colour.hints import Dict, NDArrayFloat from colour.utilities import CanonicalMapping __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -42,7 +42,7 @@ "LIGHT_SOURCE_TAG_TO_DNG_ILLUMINANTS", ] -CCS_ILLUMINANT_ADOBEDNG: NDArray = CCS_ILLUMINANTS[ +CCS_ILLUMINANT_ADOBEDNG: NDArrayFloat = CCS_ILLUMINANTS[ "CIE 1931 2 Degree Standard Observer" ]["D50"] """*Adobe DNG SDK* default illuminant for *CIE XYZ* colourspace.""" diff --git a/colour_hdri/models/dng.py b/colour_hdri/models/dng.py index 859a692f..f7413088 100644 --- a/colour_hdri/models/dng.py +++ b/colour_hdri/models/dng.py @@ -119,7 +119,7 @@ matrix_dot, vector_dot, ) -from colour.hints import ArrayLike, Floating, Literal, NDArray, Union +from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.constants import EPSILON from colour.models import UCS_to_uv, XYZ_to_UCS, XYZ_to_xy, xy_to_XYZ from colour.utilities import as_float_array, tstack @@ -129,7 +129,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -144,12 +144,12 @@ def matrix_interpolated( - CCT: Floating, - CCT_1: Floating, - CCT_2: Floating, + CCT: float, + CCT_1: float, + CCT_2: float, M_1: ArrayLike, M_2: ArrayLike, -) -> NDArray: +) -> NDArrayFloat: """ Compute the matrix interpolated from :math:`CCT_1` and :math:`CCT_2` correlated colour temperatures to respectively :math:`M_T` and :math:`M_R` @@ -204,10 +204,13 @@ def matrix_interpolated( [-0.1336946..., 0.1767874..., 0.6654045...]]) """ + M_1 = as_float_array(M_1) + M_2 = as_float_array(M_2) + if CCT <= CCT_1: - return as_float_array(M_1) + return M_1 elif CCT >= CCT_2: - return as_float_array(M_2) + return M_2 else: return linear_conversion( 1e6 / CCT, (1e6 / CCT_1, 1e6 / CCT_2), tstack([M_1, M_2]) @@ -216,14 +219,14 @@ def matrix_interpolated( def xy_to_camera_neutral( xy: ArrayLike, - CCT_calibration_illuminant_1: Floating, - CCT_calibration_illuminant_2: Floating, + CCT_calibration_illuminant_1: float, + CCT_calibration_illuminant_2: float, M_color_matrix_1: ArrayLike, M_color_matrix_2: ArrayLike, M_camera_calibration_1: ArrayLike, M_camera_calibration_2: ArrayLike, analog_balance: ArrayLike, -) -> NDArray: +) -> NDArrayFloat: """ Convert given *xy* white balance chromaticity coordinates to *Camera Neutral* coordinates. @@ -308,15 +311,15 @@ def xy_to_camera_neutral( def camera_neutral_to_xy( camera_neutral: ArrayLike, - CCT_calibration_illuminant_1: Floating, - CCT_calibration_illuminant_2: Floating, + CCT_calibration_illuminant_1: float, + CCT_calibration_illuminant_2: float, M_color_matrix_1: ArrayLike, M_color_matrix_2: ArrayLike, M_camera_calibration_1: ArrayLike, M_camera_calibration_2: ArrayLike, analog_balance: ArrayLike, - epsilon: Floating = EPSILON, -) -> NDArray: + epsilon: float = EPSILON, +) -> NDArrayFloat: """ Convert given *Camera Neutral* coordinates to *xy* white balance chromaticity coordinates. @@ -420,14 +423,14 @@ def camera_neutral_to_xy( def matrix_XYZ_to_camera_space( xy: ArrayLike, - CCT_calibration_illuminant_1: Floating, - CCT_calibration_illuminant_2: Floating, + CCT_calibration_illuminant_1: float, + CCT_calibration_illuminant_2: float, M_color_matrix_1: ArrayLike, M_color_matrix_2: ArrayLike, M_camera_calibration_1: ArrayLike, M_camera_calibration_2: ArrayLike, analog_balance: ArrayLike, -) -> NDArray: +) -> NDArrayFloat: """ Return the *CIE XYZ* to *Camera Space* matrix for given *xy* white balance chromaticity coordinates. @@ -535,8 +538,8 @@ def matrix_XYZ_to_camera_space( def matrix_camera_space_to_XYZ( xy: ArrayLike, - CCT_calibration_illuminant_1: Floating, - CCT_calibration_illuminant_2: Floating, + CCT_calibration_illuminant_1: float, + CCT_calibration_illuminant_2: float, M_color_matrix_1: ArrayLike, M_color_matrix_2: ArrayLike, M_camera_calibration_1: ArrayLike, @@ -544,24 +547,22 @@ def matrix_camera_space_to_XYZ( analog_balance: ArrayLike, M_forward_matrix_1: ArrayLike, M_forward_matrix_2: ArrayLike, - chromatic_adaptation_transform: Union[ - Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ], - str, - ] = "Bradford", -) -> NDArray: + chromatic_adaptation_transform: Literal[ + "Bianco 2010", + "Bianco PC 2010", + "Bradford", + "CAT02 Brill 2008", + "CAT02", + "CAT16", + "CMCCAT2000", + "CMCCAT97", + "Fairchild", + "Sharp", + "Von Kries", + "XYZ Scaling", + ] + | str = "Bradford", +) -> NDArrayFloat: """ Return the *Camera Space* to *CIE XYZ* matrix for given *xy* white balance chromaticity coordinates. diff --git a/colour_hdri/models/rgb.py b/colour_hdri/models/rgb.py index 5a5d382c..215821e8 100644 --- a/colour_hdri/models/rgb.py +++ b/colour_hdri/models/rgb.py @@ -13,12 +13,12 @@ import numpy as np from colour.algebra import matrix_dot, vector_dot -from colour.hints import ArrayLike, NDArray +from colour.hints import ArrayLike, NDArrayFloat from colour.models import RGB_COLOURSPACES __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -33,7 +33,7 @@ def camera_space_to_RGB( RGB: ArrayLike, M_XYZ_to_camera_space: ArrayLike, matrix_RGB_to_XYZ: ArrayLike, -) -> NDArray: +) -> NDArrayFloat: """ Convert given *RGB* array from *camera space* to given *RGB* colourspace. @@ -86,7 +86,7 @@ def camera_space_to_RGB( def camera_space_to_sRGB( RGB: ArrayLike, M_XYZ_to_camera_space: ArrayLike -) -> NDArray: +) -> NDArrayFloat: """ Convert given *RGB* array from *camera space* to *sRGB* colourspace. diff --git a/colour_hdri/models/tests/test_adobe_dng.py b/colour_hdri/models/tests/test_adobe_dng.py index 81e2cd70..5cee96da 100644 --- a/colour_hdri/models/tests/test_adobe_dng.py +++ b/colour_hdri/models/tests/test_adobe_dng.py @@ -13,7 +13,7 @@ import numpy as np import unittest -from colour.hints import Floating, NDArray +from colour.hints import NDArrayFloat from colour_hdri.models.dng import matrix_interpolated from colour_hdri.models import ( @@ -25,7 +25,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -47,17 +47,17 @@ "TestMatrix_Camera_space_to_XYZ", ] -CCT_CALIBRATION_ILLUMINANT_1: Floating = 2850 -CCT_CALIBRATION_ILLUMINANT_2: Floating = 6500 +CCT_CALIBRATION_ILLUMINANT_1: float = 2850 +CCT_CALIBRATION_ILLUMINANT_2: float = 6500 -M_COLOR_MATRIX_1: NDArray = np.array( +M_COLOR_MATRIX_1: NDArrayFloat = np.array( [ [0.5309, -0.0229, -0.0336], [-0.6241, 1.3265, 0.3337], [-0.0817, 0.1215, 0.6664], ] ) -M_COLOR_MATRIX_2: NDArray = np.array( +M_COLOR_MATRIX_2: NDArrayFloat = np.array( [ [0.4716, 0.0603, -0.0830], [-0.7798, 1.5474, 0.2480], @@ -65,14 +65,14 @@ ] ) -M_CAMERA_CALIBRATION_1: NDArray = np.array( +M_CAMERA_CALIBRATION_1: NDArrayFloat = np.array( [ [0.9603, 0.0000, 0.0000], [0.0000, 1.0000, 0.0000], [0.0000, 0.0000, 0.9664], ] ) -M_CAMERA_CALIBRATION_2: NDArray = np.array( +M_CAMERA_CALIBRATION_2: NDArrayFloat = np.array( [ [0.9603, 0.0000, 0.0000], [0.0000, 1.0000, 0.0000], @@ -80,16 +80,16 @@ ] ) -ANALOG_BALANCE: NDArray = np.ones(3) +ANALOG_BALANCE: NDArrayFloat = np.ones(3) -M_FORWARD_MATRIX_1: NDArray = np.array( +M_FORWARD_MATRIX_1: NDArrayFloat = np.array( [ [0.8924, -0.1041, 0.1760], [0.4351, 0.6621, -0.0972], [0.0505, -0.1562, 0.9308], ] ) -M_FORWARD_MATRIX_2: NDArray = np.array( +M_FORWARD_MATRIX_2: NDArrayFloat = np.array( [ [0.8924, -0.1041, 0.1760], [0.4351, 0.6621, -0.0972], diff --git a/colour_hdri/models/tests/test_rgb.py b/colour_hdri/models/tests/test_rgb.py index 7c6baf16..3bd9759c 100644 --- a/colour_hdri/models/tests/test_rgb.py +++ b/colour_hdri/models/tests/test_rgb.py @@ -8,7 +8,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/plotting/conftest.py b/colour_hdri/plotting/conftest.py index 64b70f84..62a1d63f 100644 --- a/colour_hdri/plotting/conftest.py +++ b/colour_hdri/plotting/conftest.py @@ -7,14 +7,14 @@ *VSCode*. """ -import matplotlib +import matplotlib as mpl import pytest from colour.hints import Generator __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -38,7 +38,7 @@ def mpl_headless_backend() -> Generator[None, None, None]: *Matplotlib* unit tests. """ - current_backend = matplotlib.get_backend() - matplotlib.use("AGG") + current_backend = mpl.get_backend() + mpl.use("AGG") yield - matplotlib.use(current_backend) + mpl.use(current_backend) diff --git a/colour_hdri/plotting/hdri.py b/colour_hdri/plotting/hdri.py index 32c475b8..5c769f91 100644 --- a/colour_hdri/plotting/hdri.py +++ b/colour_hdri/plotting/hdri.py @@ -9,11 +9,11 @@ from __future__ import annotations -import matplotlib +import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np -from colour.hints import Any, ArrayLike, Callable, Floating, Integer, Tuple +from colour.hints import Any, ArrayLike, Callable, Tuple from colour.plotting import CONSTANTS_COLOUR_STYLE, override_style, render from colour.utilities import as_float_array @@ -21,7 +21,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -34,8 +34,8 @@ @override_style() def plot_HDRI_strip( image: ArrayLike, - count: Integer = 5, - ev_steps: Floating = -2, + count: int = 5, + ev_steps: float = -2, cctf_encoding: Callable = CONSTANTS_COLOUR_STYLE.colour.colourspace.cctf_encoding, **kwargs: Any, ) -> Tuple[plt.Figure, plt.Axes]: @@ -68,7 +68,7 @@ def plot_HDRI_strip( image = as_float_array(image) - grid = matplotlib.gridspec.GridSpec(1, count) + grid = mpl.gridspec.GridSpec(1, count) # pyright: ignore grid.update(wspace=0, hspace=0) height, width, _channel = image.shape diff --git a/colour_hdri/plotting/tonemapping.py b/colour_hdri/plotting/tonemapping.py index f248781b..58958330 100644 --- a/colour_hdri/plotting/tonemapping.py +++ b/colour_hdri/plotting/tonemapping.py @@ -9,12 +9,11 @@ from __future__ import annotations -import matplotlib import matplotlib.pyplot as plt import matplotlib.ticker import numpy as np -from colour.hints import Any, ArrayLike, Boolean, Callable, Dict, Tuple +from colour.hints import Any, ArrayLike, Callable, Dict, Tuple from colour.plotting import ( CONSTANTS_COLOUR_STYLE, artist, @@ -25,7 +24,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -39,7 +38,7 @@ def plot_tonemapping_operator_image( image: ArrayLike, luminance_function: ArrayLike, - log_scale: Boolean = False, + log_scale: bool = False, cctf_encoding: Callable = CONSTANTS_COLOUR_STYLE.colour.colourspace.cctf_encoding, **kwargs: Any, ) -> Tuple[plt.Figure, plt.Axes]: diff --git a/colour_hdri/process/dng.py b/colour_hdri/process/dng.py index 1f4fe840..001b7761 100644 --- a/colour_hdri/process/dng.py +++ b/colour_hdri/process/dng.py @@ -18,17 +18,9 @@ import platform import re import shlex -import subprocess # nosec - -from colour.hints import ( - Callable, - Boolean, - List, - Mapping, - Optional, - Sequence, - Tuple, -) +import subprocess + +from colour.hints import Callable, List, Mapping, Sequence, Tuple from colour.utilities import CanonicalMapping, optional from colour.utilities.documentation import ( DocstringText, @@ -46,7 +38,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -63,10 +55,10 @@ "read_dng_files_exif_tags", ] -_IS_MACOS_PLATFORM: Boolean = platform.system() == "Darwin" +_IS_MACOS_PLATFORM: bool = platform.system() == "Darwin" """Whether the current platform is *macOS*.""" -_IS_WINDOWS_PLATFORM: Boolean = platform.system() in ("Windows", "Microsoft") +_IS_WINDOWS_PLATFORM: bool = platform.system() in ("Windows", "Microsoft") """Whether the current platform is *Windows*.""" RAW_CONVERTER: str = "dcraw" @@ -112,10 +104,10 @@ "MacOS/Adobe DNG Converter" ) elif _IS_WINDOWS_PLATFORM: - DNG_CONVERTER: str = "Adobe DNG Converter" # type: ignore[no-redef] + DNG_CONVERTER: str = "Adobe DNG Converter" else: # https://rawpedia.rawtherapee.com/How_to_convert_raw_formats_to_DNG - DNG_CONVERTER: str = "Adobe-DNG-Converter" # type: ignore[no-redef] + DNG_CONVERTER: str = "Adobe-DNG-Converter" if is_documentation_building(): # pragma: no cover DNG_CONVERTER = DocstringText(DNG_CONVERTER) @@ -235,8 +227,8 @@ def convert_raw_files_to_dng_files( raw_files: Sequence[str], output_directory: str, - dng_converter: Optional[str] = None, - dng_converter_arguments: Optional[str] = None, + dng_converter: str | None = None, + dng_converter_arguments: str | None = None, ) -> List[str]: """ Convert given raw files to *dng* files using given output directory. @@ -282,16 +274,22 @@ def convert_raw_files_to_dng_files( if path_exists(dng_file): os.remove(dng_file) - logging.info(f'Converting "{raw_file}" file to "{dng_file}" file.') + logging.info( + 'Converting "{raw_file}" file to "{dng_file}" file.', + extra={"raw_file": raw_file, "dng_file": dng_file}, + ) - command = [dng_converter] + shlex.split( - dng_converter_arguments.format( - output_directory=output_directory, raw_file=raw_file + command = [ + dng_converter, + *shlex.split( + dng_converter_arguments.format( + output_directory=output_directory, raw_file=raw_file + ), + posix=not _IS_WINDOWS_PLATFORM, ), - posix=not _IS_WINDOWS_PLATFORM, - ) + ] - subprocess.call(command, shell=_IS_WINDOWS_PLATFORM) # nosec + subprocess.call(command, shell=_IS_WINDOWS_PLATFORM) # noqa: S603 dng_files.append(dng_file) @@ -301,8 +299,8 @@ def convert_raw_files_to_dng_files( def convert_dng_files_to_intermediate_files( dng_files: Sequence[str], output_directory: str, - raw_converter: Optional[str] = None, - raw_converter_arguments: Optional[str] = None, + raw_converter: str | None = None, + raw_converter_arguments: str | None = None, ) -> List[str]: """ Convert given *dng* files to intermediate *tiff* files using given output @@ -339,17 +337,24 @@ def convert_dng_files_to_intermediate_files( os.remove(intermediate_file) logging.info( - f'Converting "{dng_file}" file to "{intermediate_file}" file.' + 'Converting "{dng_file}" file to "{intermediate_file}" file.', + extra={ + "dng_file": dng_file, + "intermediate_file": intermediate_file, + }, ) - command = [raw_converter] + shlex.split( - raw_converter_arguments.format( - output_directory=output_directory, raw_file=dng_file + command = [ + raw_converter, + *shlex.split( + raw_converter_arguments.format( + output_directory=output_directory, raw_file=dng_file + ), + posix=not _IS_WINDOWS_PLATFORM, ), - posix=not _IS_WINDOWS_PLATFORM, - ) + ] - subprocess.call(command, shell=_IS_WINDOWS_PLATFORM) # nosec + subprocess.call(command, shell=_IS_WINDOWS_PLATFORM) # noqa: S603 tiff_file = os.path.join( output_directory, os.path.basename(intermediate_file) @@ -368,7 +373,7 @@ def convert_dng_files_to_intermediate_files( def read_dng_files_exif_tags( dng_files: Sequence[str], exif_tags_binding: Mapping[ - str, Mapping[str, Tuple[Callable, Optional[str]]] + str, Mapping[str, Tuple[Callable, str | None]] ] = DNG_EXIF_TAGS_BINDING, ) -> List[CanonicalMapping]: """ diff --git a/colour_hdri/process/tests/test_dng.py b/colour_hdri/process/tests/test_dng.py index 98b8b6e9..01345493 100644 --- a/colour_hdri/process/tests/test_dng.py +++ b/colour_hdri/process/tests/test_dng.py @@ -24,7 +24,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/recovery/highlights.py b/colour_hdri/recovery/highlights.py index 357315fd..0fc4d76f 100644 --- a/colour_hdri/recovery/highlights.py +++ b/colour_hdri/recovery/highlights.py @@ -24,7 +24,7 @@ import numpy as np from colour.algebra import vector_dot -from colour.hints import ArrayLike, Floating, NDArray, Optional +from colour.hints import ArrayLike, NDArrayFloat from colour.models import ( RGB_Colourspace, LCHab_to_Lab, @@ -39,7 +39,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -51,8 +51,8 @@ def highlights_recovery_blend( - RGB: ArrayLike, multipliers: ArrayLike, threshold: Floating = 0.99 -) -> NDArray: + RGB: ArrayLike, multipliers: ArrayLike, threshold: float = 0.99 +) -> NDArrayFloat: """ Perform highlights recovery using *Coffin (1997)* method from *dcraw*. @@ -104,9 +104,9 @@ def highlights_recovery_blend( def highlights_recovery_LCHab( RGB: ArrayLike, - threshold: Optional[Floating] = None, + threshold: float | None = None, RGB_colourspace: RGB_Colourspace = RGB_COLOURSPACE_sRGB, -) -> NDArray: +) -> NDArrayFloat: """ Perform highlights recovery in *CIE L\\*C\\*Hab* colourspace. @@ -129,12 +129,7 @@ def highlights_recovery_LCHab( L, _C, H = tsplit( Lab_to_LCHab( XYZ_to_Lab( - RGB_to_XYZ( - RGB, - RGB_colourspace.whitepoint, - RGB_colourspace.whitepoint, - RGB_colourspace.matrix_RGB_to_XYZ, - ), + RGB_to_XYZ(RGB, RGB_colourspace), RGB_colourspace.whitepoint, ) ) @@ -145,9 +140,7 @@ def highlights_recovery_LCHab( XYZ_to_Lab( RGB_to_XYZ( np.clip(RGB, 0, threshold), - RGB_colourspace.whitepoint, - RGB_colourspace.whitepoint, - RGB_colourspace.matrix_RGB_to_XYZ, + RGB_colourspace, ), RGB_colourspace.whitepoint, ) @@ -158,7 +151,5 @@ def highlights_recovery_LCHab( Lab_to_XYZ( LCHab_to_Lab(tstack([L, C_c, H])), RGB_colourspace.whitepoint ), - RGB_colourspace.whitepoint, - RGB_colourspace.whitepoint, - RGB_colourspace.matrix_XYZ_to_RGB, + RGB_colourspace, ) diff --git a/colour_hdri/recovery/tests/test_recovery.py b/colour_hdri/recovery/tests/test_recovery.py index 728f45dd..51166082 100644 --- a/colour_hdri/recovery/tests/test_recovery.py +++ b/colour_hdri/recovery/tests/test_recovery.py @@ -9,12 +9,12 @@ import re import shlex import shutil -import subprocess # nosec +import subprocess import tempfile import unittest from colour import read_image -from colour.hints import Boolean, List, NDArray +from colour.hints import List, NDArrayFloat from colour_hdri import ROOT_RESOURCES_TESTS from colour_hdri.process import ( @@ -30,7 +30,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -44,7 +44,7 @@ "TestHighlightsRecoveryLCHab", ] -_IS_WINDOWS_PLATFORM: Boolean = platform.system() in ("Windows", "Microsoft") +_IS_WINDOWS_PLATFORM: bool = platform.system() in ("Windows", "Microsoft") """Whether the current platform is *Windows*.""" ROOT_RESOURCES_FROBISHER_001: str = os.path.join( @@ -57,7 +57,7 @@ IMAGES_RAW: List[str] = filter_files(ROOT_RESOURCES_FROBISHER_001, ("CR2",)) -matrix_XYZ_to_camera_space: NDArray = np.array( +matrix_XYZ_to_camera_space: NDArrayFloat = np.array( [ [0.47160000, 0.06030000, -0.08300000], [-0.77980000, 1.54740000, 0.24800000], @@ -96,12 +96,17 @@ def test_highlights_recovery_blend(self): self._temporary_directory, os.path.basename(reference_raw_file) ) shutil.copyfile(reference_raw_file, test_raw_file) - command = [RAW_CONVERTER] + shlex.split( - RAW_CONVERTER_ARGUMENTS_DEMOSAICING.format(raw_file=test_raw_file), - posix=not _IS_WINDOWS_PLATFORM, - ) - - subprocess.call(command) # nosec + command = [ + RAW_CONVERTER, + *shlex.split( + RAW_CONVERTER_ARGUMENTS_DEMOSAICING.format( + raw_file=test_raw_file + ), + posix=not _IS_WINDOWS_PLATFORM, + ), + ] + + subprocess.call(command) # noqa: S603 test_tiff_file = read_image( str(re.sub("\\.CR2$", ".tiff", test_raw_file)) @@ -153,12 +158,17 @@ def test_highlights_recovery_LCHab(self): self._temporary_directory, os.path.basename(reference_raw_file) ) shutil.copyfile(reference_raw_file, test_raw_file) - command = [RAW_CONVERTER] + shlex.split( - RAW_CONVERTER_ARGUMENTS_DEMOSAICING.format(raw_file=test_raw_file), - posix=not _IS_WINDOWS_PLATFORM, - ) - - subprocess.call(command) # nosec + command = [ + RAW_CONVERTER, + *shlex.split( + RAW_CONVERTER_ARGUMENTS_DEMOSAICING.format( + raw_file=test_raw_file + ), + posix=not _IS_WINDOWS_PLATFORM, + ), + ] + + subprocess.call(command) # noqa: S603 test_tiff_file = read_image( str(re.sub("\\.CR2$", ".tiff", test_raw_file)) diff --git a/colour_hdri/sampling/grossberg2003.py b/colour_hdri/sampling/grossberg2003.py index 146b5406..ed9f21ab 100644 --- a/colour_hdri/sampling/grossberg2003.py +++ b/colour_hdri/sampling/grossberg2003.py @@ -20,12 +20,12 @@ import numpy as np -from colour.hints import ArrayLike, Integer, NDArray +from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import as_float_array, tsplit, tstack __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -36,8 +36,8 @@ def samples_Grossberg2003( - image_stack: ArrayLike, samples: Integer = 1000, n: Integer = 256 -) -> NDArray: + image_stack: ArrayLike, samples: int = 1000, n: int = 256 +) -> NDArrayFloat: """ Return the samples for given image stack intensity histograms using *Grossberg (2003)* method. @@ -63,10 +63,7 @@ def samples_Grossberg2003( image_stack = as_float_array(image_stack) - if image_stack.ndim == 3: - channels_c = 1 - else: - channels_c = image_stack.shape[-2] + channels_c = 1 if image_stack.ndim == 3 else image_stack.shape[-2] cdf_i = [] for image in tsplit(image_stack): diff --git a/colour_hdri/sampling/tests/test_grossberg2003.py b/colour_hdri/sampling/tests/test_grossberg2003.py index 147ec652..01cceaa3 100644 --- a/colour_hdri/sampling/tests/test_grossberg2003.py +++ b/colour_hdri/sampling/tests/test_grossberg2003.py @@ -18,7 +18,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/sampling/tests/test_variance_minimization.py b/colour_hdri/sampling/tests/test_variance_minimization.py index b4f2b786..fed64e82 100644 --- a/colour_hdri/sampling/tests/test_variance_minimization.py +++ b/colour_hdri/sampling/tests/test_variance_minimization.py @@ -24,7 +24,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/sampling/variance_minimization.py b/colour_hdri/sampling/variance_minimization.py index 19ac12da..6bdb8788 100644 --- a/colour_hdri/sampling/variance_minimization.py +++ b/colour_hdri/sampling/variance_minimization.py @@ -18,12 +18,13 @@ import numpy as np from collections import namedtuple -from colour.models import RGB_COLOURSPACES, RGB_luminance -from colour.utilities import as_float_array, centroid, warning +from colour.hints import ArrayLike, List, NDArrayFloat, Tuple +from colour.models import RGB_COLOURSPACES, RGB_Colourspace, RGB_luminance +from colour.utilities import as_float_array, as_float_scalar, centroid, warning __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -54,18 +55,18 @@ class Light_Specification( """ -def luminance_variance(a): +def luminance_variance(a: ArrayLike) -> float: """ Compute the Luminance variance of given :math:`a` 2-D array. Parameters ---------- - a : array_like + a :math:`a` 2-D array to compute the Luminance variation. Returns ------- - numeric + :class:`float` :math:`a` 2-D array Luminance variance. Examples @@ -83,24 +84,26 @@ def luminance_variance(a): np.sum(a * ((y - y_centroid) ** 2 + (x - x_centroid) ** 2)) ) - return variance + return as_float_scalar(variance) -def find_regions_variance_minimization_Viriyothai2009(a, n=4): +def find_regions_variance_minimization_Viriyothai2009( + a: ArrayLike, n: int = 4 +) -> List[Tuple[int, int, int, int]]: """ Find the :math:`2^n` regions using *Viriyothai (2009)* variance minimization light probe sampling algorithm on given :math:`a` 2-D array. Parameters ---------- - a : array_like + a :math:`a` 2-D array to find the regions. - n : int + n Iterations count, the total regions count is :math:`2^n`. Returns ------- - list + :class:`list` Regions with variance minimized. """ @@ -149,12 +152,14 @@ def find_regions_variance_minimization_Viriyothai2009(a, n=4): regions = sub_regions - return regions + return regions # pyright: ignore def highlight_regions_variance_minimization( - a, regions, highlight_colour=np.array([0, 1, 0]) -): + a: ArrayLike, + regions: List[Tuple[int, int, int, int]], + highlight_colour=np.array([0, 1, 0]), +) -> NDArrayFloat: """ Highlight regions using with variance minimized on given :math:`a` 3-D array. @@ -170,7 +175,7 @@ def highlight_regions_variance_minimization( Returns ------- - ndarray + :class:`numpy.ndarray` :math:`a` 3-D array with highlighted regions. """ @@ -188,24 +193,26 @@ def highlight_regions_variance_minimization( def light_probe_sampling_variance_minimization_Viriyothai2009( - light_probe, lights_count=16, colourspace=RGB_COLOURSPACES["sRGB"] -): + light_probe: ArrayLike, + lights_count: int = 16, + colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"], +) -> List[Light_Specification]: """ Sample given light probe to find lights using *Viriyothai (2009)* variance minimization light probe sampling algorithm. Parameters ---------- - light_probe : array_like + light_probe Array to sample for lights. - lights_count : int + lights_count Amount of lights to generate. - colourspace : `colour.RGB_Colourspace`, optional + colourspace *RGB* colourspace used for internal *Luminance* computation. Returns ------- - list + :class:`list` list of :class:`colour_hdri.sampling.variance_minimization.Light_Specification` lights. diff --git a/colour_hdri/tonemapping/__init__.py b/colour_hdri/tonemapping/__init__.py index 6ec0b359..f439e727 100644 --- a/colour_hdri/tonemapping/__init__.py +++ b/colour_hdri/tonemapping/__init__.py @@ -1,4 +1,4 @@ -from .global_operators import * # noqa +from .global_operators import * # noqa: F403 from . import global_operators __all__ = global_operators.__all__ diff --git a/colour_hdri/tonemapping/global_operators/operators.py b/colour_hdri/tonemapping/global_operators/operators.py index 28be6b94..1930340b 100644 --- a/colour_hdri/tonemapping/global_operators/operators.py +++ b/colour_hdri/tonemapping/global_operators/operators.py @@ -53,19 +53,13 @@ import numpy as np from colour.constants import EPSILON -from colour.hints import ( - ArrayLike, - Floating, - FloatingOrArrayLike, - FloatingOrNDArray, - NDArray, -) +from colour.hints import ArrayLike, NDArrayFloat, cast from colour.models import RGB_COLOURSPACES, RGB_Colourspace, RGB_luminance from colour.utilities import as_float_array __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -86,9 +80,7 @@ ] -def log_average( - a: FloatingOrArrayLike, epsilon: Floating = EPSILON -) -> FloatingOrNDArray: +def log_average(a: ArrayLike, epsilon: float = EPSILON) -> NDArrayFloat: """ Compute the log average of given array. @@ -117,7 +109,7 @@ def log_average( return average -def tonemapping_operator_simple(RGB: ArrayLike) -> NDArray: +def tonemapping_operator_simple(RGB: ArrayLike) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using the simple method: :math:`\\cfrac{RGB}{RGB + 1}`. @@ -166,7 +158,7 @@ def tonemapping_operator_simple(RGB: ArrayLike) -> NDArray: def tonemapping_operator_normalisation( RGB: ArrayLike, colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"] -) -> NDArray: +) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using the normalisation method. @@ -218,8 +210,8 @@ def tonemapping_operator_normalisation( def tonemapping_operator_gamma( - RGB: ArrayLike, gamma: Floating = 1, EV: Floating = 0 -) -> NDArray: + RGB: ArrayLike, gamma: float = 1, EV: float = 0 +) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using the gamma and exposure correction method. @@ -277,10 +269,10 @@ def tonemapping_operator_gamma( def tonemapping_operator_logarithmic( RGB: ArrayLike, - q: Floating = 1, - k: Floating = 1, + q: float = 1, + k: float = 1, colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"], -) -> NDArray: +) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using the logarithmic method. @@ -345,10 +337,10 @@ def tonemapping_operator_logarithmic( def tonemapping_operator_exponential( RGB: ArrayLike, - q: Floating = 1, - k: Floating = 1, + q: float = 1, + k: float = 1, colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"], -) -> NDArray: +) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using the exponential method. @@ -413,10 +405,10 @@ def tonemapping_operator_exponential( def tonemapping_operator_logarithmic_mapping( RGB: ArrayLike, - p: Floating = 1, - q: Floating = 1, + p: float = 1, + q: float = 1, colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"], -) -> NDArray: +) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using the logarithmic mapping method. @@ -479,10 +471,10 @@ def tonemapping_operator_logarithmic_mapping( def tonemapping_operator_exponentiation_mapping( RGB: ArrayLike, - p: Floating = 1, - q: Floating = 1, + p: float = 1, + q: float = 1, colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"], -) -> NDArray: +) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using the exponentiation mapping method. @@ -543,9 +535,9 @@ def tonemapping_operator_exponentiation_mapping( def tonemapping_operator_Schlick1994( RGB: ArrayLike, - p: Floating = 1, + p: float = 1, colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"], -) -> NDArray: +) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using *Schlick (1994)* method. @@ -605,11 +597,11 @@ def tonemapping_operator_Schlick1994( def tonemapping_operator_Tumblin1999( RGB: ArrayLike, - L_da: Floating = 20, - C_max: Floating = 100, - L_max: Floating = 100, + L_da: float = 20, + C_max: float = 100, + L_max: float = 100, colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"], -) -> NDArray: +) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using *Tumblin, Hodgins and Guenter (1999)* method. @@ -665,7 +657,7 @@ def tonemapping_operator_Tumblin1999( RGB_luminance(RGB, colourspace.primaries, colourspace.whitepoint) ) - def f(x: FloatingOrNDArray) -> FloatingOrNDArray: + def f(x: float | NDArrayFloat) -> NDArrayFloat: return np.where( x > 100, 2.655, 1.855 + 0.4 * np.log10(x + 2.3 * 10**-5) ) @@ -684,12 +676,12 @@ def f(x: FloatingOrNDArray) -> FloatingOrNDArray: def tonemapping_operator_Reinhard2004( RGB: ArrayLike, - f: Floating = 0, - m: Floating = 0.3, - a: Floating = 0, - c: Floating = 0, + f: float = 0, + m: float = 0.3, + a: float = 0, + c: float = 0, colourspace: RGB_Colourspace = RGB_COLOURSPACES["sRGB"], -) -> NDArray: +) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using *Reinhard and Devlin (2004)* method. @@ -783,15 +775,15 @@ def tonemapping_operator_Reinhard2004( def tonemapping_operator_filmic( RGB: ArrayLike, - shoulder_strength: Floating = 0.22, - linear_strength: Floating = 0.3, - linear_angle: Floating = 0.1, - toe_strength: Floating = 0.2, - toe_numerator: Floating = 0.01, - toe_denominator: Floating = 0.3, - exposure_bias: Floating = 2, - linear_whitepoint: Floating = 11.2, -) -> NDArray: + shoulder_strength: float = 0.22, + linear_strength: float = 0.3, + linear_angle: float = 0.1, + toe_strength: float = 0.2, + toe_numerator: float = 0.01, + toe_denominator: float = 0.3, + exposure_bias: float = 2, + linear_whitepoint: float = 11.2, +) -> NDArrayFloat: """ Perform given *RGB* array tonemapping using *Habble (2010)* method. @@ -857,11 +849,21 @@ def tonemapping_operator_filmic( E = toe_numerator F = toe_denominator - def f(x: FloatingOrNDArray, A, B, C, D, E, F) -> FloatingOrNDArray: + def f( + x: float | NDArrayFloat, + A: float, + B: float, + C: float, + D: float, + E: float, + F: float, + ) -> float | NDArrayFloat: return ( (x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F) ) - E / F RGB = f(RGB * exposure_bias, A, B, C, D, E, F) - return RGB * (1 / as_float_array(f(linear_whitepoint, A, B, C, D, E, F))) + return cast( + NDArrayFloat, RGB * (1 / f(linear_whitepoint, A, B, C, D, E, F)) + ) diff --git a/colour_hdri/tonemapping/global_operators/tests/test_operators.py b/colour_hdri/tonemapping/global_operators/tests/test_operators.py index 0c596d79..30c42dc3 100644 --- a/colour_hdri/tonemapping/global_operators/tests/test_operators.py +++ b/colour_hdri/tonemapping/global_operators/tests/test_operators.py @@ -24,7 +24,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/colour_hdri/utilities/common.py b/colour_hdri/utilities/common.py index 7ee027ca..a8bd0f78 100644 --- a/colour_hdri/utilities/common.py +++ b/colour_hdri/utilities/common.py @@ -11,11 +11,11 @@ import re from collections import defaultdict -from colour.hints import Boolean, Dict, List, Optional, Sequence, Union +from colour.hints import Dict, List, Sequence __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -50,7 +50,7 @@ def vivification() -> defaultdict: return defaultdict(vivification) -def vivified_to_dict(vivified: Union[Dict, defaultdict]) -> Dict: +def vivified_to_dict(vivified: Dict | defaultdict) -> Dict: """ Convert given vivified data-structure to dictionary. @@ -78,7 +78,7 @@ def vivified_to_dict(vivified: Union[Dict, defaultdict]) -> Dict: return vivified -def path_exists(path: Optional[str]) -> Boolean: +def path_exists(path: str | None) -> bool: """ Return whether given path exists. diff --git a/colour_hdri/utilities/exif.py b/colour_hdri/utilities/exif.py index 9d847349..24bf79cd 100644 --- a/colour_hdri/utilities/exif.py +++ b/colour_hdri/utilities/exif.py @@ -19,25 +19,20 @@ import numpy as np import platform import re -import subprocess # nosec +import subprocess from collections import defaultdict from dataclasses import dataclass, field from fractions import Fraction from colour.hints import ( - Boolean, - DTypeFloating, - DTypeNumber, - Floating, + DTypeFloat, + DTypeReal, List, NDArray, - Number, - Optional, + Real, Sequence, SupportsIndex, Type, - Union, - cast, ) from colour.constants import DEFAULT_FLOAT_DTYPE @@ -51,7 +46,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -72,7 +67,7 @@ "write_exif_tag", ] -_IS_WINDOWS_PLATFORM: Boolean = platform.system() in ("Windows", "Microsoft") +_IS_WINDOWS_PLATFORM: bool = platform.system() in ("Windows", "Microsoft") """Whether the current platform is *Windows*.""" EXIF_EXECUTABLE: str = "exiftool" @@ -100,10 +95,10 @@ class EXIFTag: EXIF tag identifier. """ - group: Optional[str] = field(default_factory=lambda: None) - name: Optional[str] = field(default_factory=lambda: None) - value: Optional[str] = field(default_factory=lambda: None) - identifier: Optional[str] = field(default_factory=lambda: None) + group: str | None = field(default_factory=lambda: None) + name: str | None = field(default_factory=lambda: None) + value: str | None = field(default_factory=lambda: None) + identifier: str | None = field(default_factory=lambda: None) def parse_exif_string(exif_tag: EXIFTag) -> str: @@ -125,8 +120,8 @@ def parse_exif_string(exif_tag: EXIFTag) -> str: def parse_exif_number( - exif_tag: EXIFTag, dtype: Optional[Type[DTypeNumber]] = None -) -> Number: + exif_tag: EXIFTag, dtype: Type[DTypeReal] | None = None +) -> Real: """ Parse given EXIF tag assuming it is a number type and return its value. @@ -143,14 +138,14 @@ def parse_exif_number( Parsed EXIF tag value. """ - dtype = cast(Type[DTypeNumber], optional(dtype, DEFAULT_FLOAT_DTYPE)) + dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) - return dtype(exif_tag.value) # type: ignore[arg-type, return-value] + return dtype(exif_tag.value) # pyright: ignore def parse_exif_fraction( - exif_tag: EXIFTag, dtype: Optional[Type[DTypeFloating]] = None -) -> Floating: + exif_tag: EXIFTag, dtype: Type[DTypeFloat] | None = None +) -> float: """ Parse given EXIF tag assuming it is a fraction and return its value. @@ -167,7 +162,7 @@ def parse_exif_fraction( Parsed EXIF tag value. """ - dtype = cast(Type[DTypeFloating], optional(dtype, DEFAULT_FLOAT_DTYPE)) + dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) value = ( exif_tag.value @@ -175,13 +170,13 @@ def parse_exif_fraction( else float(Fraction(exif_tag.value)) ) - return as_float_scalar(value, dtype) # type: ignore[arg-type] + return as_float_scalar(value, dtype) # pyright: ignore def parse_exif_array( exif_tag: EXIFTag, - dtype: Optional[Type[DTypeNumber]] = None, - shape: Optional[Union[SupportsIndex, Sequence[SupportsIndex]]] = None, + dtype: Type[DTypeReal] | None = None, + shape: SupportsIndex | Sequence[SupportsIndex] | None = None, ) -> NDArray: """ Parse given EXIF tag assuming it is an array and return its value. @@ -201,13 +196,13 @@ def parse_exif_array( Parsed EXIF tag value. """ - dtype = cast(Type[DTypeNumber], optional(dtype, DEFAULT_FLOAT_DTYPE)) + dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) value = ( exif_tag.value if exif_tag.value is None else exif_tag.value.split() ) - return np.reshape(as_array(value, dtype), shape) # type: ignore[arg-type] + return np.reshape(as_array(value, dtype), shape) # pyright: ignore def parse_exif_data(data: str) -> List: @@ -264,13 +259,13 @@ def read_exif_tags(image: str) -> defaultdict: EXIF tags. """ - logging.info(f"Reading '{image}' image EXIF data.") + logging.info("Reading '{image}' image EXIF data.", extra={"image": image}) exif_tags = vivification() lines = str( - subprocess.check_output( # nosec + subprocess.check_output( [EXIF_EXECUTABLE, "-D", "-G", "-a", "-u", "-n", image], - shell=_IS_WINDOWS_PLATFORM, + shell=_IS_WINDOWS_PLATFORM, # noqa: S603 ), "utf-8", "ignore", @@ -290,7 +285,7 @@ def read_exif_tags(image: str) -> defaultdict: return exif_tags -def copy_exif_tags(source: str, target: str) -> Boolean: +def copy_exif_tags(source: str, target: str) -> bool: """ Copy given source image file EXIF tag to given image target. @@ -307,17 +302,22 @@ def copy_exif_tags(source: str, target: str) -> Boolean: Definition success. """ - logging.info(f"Copying '{source}' file EXIF data to '{target}' file.") + logging.info( + "Copying '{source}' file EXIF data to '{target}' file.", + extra={"source": source, "target": target}, + ) arguments = [EXIF_EXECUTABLE, "-overwrite_original", "-TagsFromFile"] arguments += [source, target] - subprocess.check_output(arguments, shell=_IS_WINDOWS_PLATFORM) # nosec + subprocess.check_output( + arguments, shell=_IS_WINDOWS_PLATFORM # noqa: S603 + ) return True # TODO: Find a better name. -def update_exif_tags(images: Sequence[Sequence[str]]) -> Boolean: +def update_exif_tags(images: Sequence[Sequence[str]]) -> bool: """ Update given images pairs EXIF tags. @@ -333,13 +333,13 @@ def update_exif_tags(images: Sequence[Sequence[str]]) -> Boolean: """ success = 1 - for (source, target) in images: + for source, target in images: success *= int(copy_exif_tags(source, target)) return bool(success) -def delete_exif_tags(image: str) -> Boolean: +def delete_exif_tags(image: str) -> bool: """ Delete all given image EXIF tags. @@ -354,11 +354,11 @@ def delete_exif_tags(image: str) -> Boolean: Definition success. """ - logging.info(f"Deleting '{image}' image EXIF tags.") + logging.info("Deleting '{image}' image EXIF tags.", extra={"image": image}) - subprocess.check_output( # nosec + subprocess.check_output( [EXIF_EXECUTABLE, "-overwrite_original", "-all=", image], - shell=_IS_WINDOWS_PLATFORM, + shell=_IS_WINDOWS_PLATFORM, # noqa: S603 ) return True @@ -383,8 +383,9 @@ def read_exif_tag(image: str, tag: str) -> str: value = ( str( - subprocess.check_output( # nosec - [EXIF_EXECUTABLE, f"-{tag}", image], shell=_IS_WINDOWS_PLATFORM + subprocess.check_output( + [EXIF_EXECUTABLE, f"-{tag}", image], + shell=_IS_WINDOWS_PLATFORM, # noqa: S603 ), "utf-8", "ignore", @@ -394,12 +395,15 @@ def read_exif_tag(image: str, tag: str) -> str: .strip() ) - logging.info(f"Reading '{image}' image '{tag}' EXIF tag value: '{value}'") + logging.info( + "Reading '{image}' image '{tag}' EXIF tag value: '{value}'", + extra={"image": image, "tag": tag, "value": value}, + ) return value -def write_exif_tag(image: str, tag: str, value: str) -> Boolean: +def write_exif_tag(image: str, tag: str, value: str) -> bool: """ Set given image EXIF tag value. @@ -419,11 +423,14 @@ def write_exif_tag(image: str, tag: str, value: str) -> Boolean: """ logging.info( - f"Writing '{image}' image '{tag}' EXIF tag with '{value}' value." + "Writing '{image}' image '{tag}' EXIF tag with '{value}' value.", + extra={"image": image, "tag": tag, "value": value}, ) arguments = [EXIF_EXECUTABLE, "-overwrite_original"] arguments += [f"-{tag}={value}", image] - subprocess.check_output(arguments, shell=_IS_WINDOWS_PLATFORM) # nosec + subprocess.check_output( + arguments, shell=_IS_WINDOWS_PLATFORM # noqa: S603 + ) return True diff --git a/colour_hdri/utilities/image.py b/colour_hdri/utilities/image.py index 34ea8e92..e9c2f2e0 100644 --- a/colour_hdri/utilities/image.py +++ b/colour_hdri/utilities/image.py @@ -20,19 +20,17 @@ Any, ArrayLike, Callable, - FloatingOrNDArray, - Integer, List, - NDArray, - Optional, + NDArrayFloat, + Real, Sequence, - Union, cast, ) from colour import read_image from colour.utilities import ( MixinDataclassArray, as_float_array, + attest, is_string, tsplit, tstack, @@ -49,7 +47,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -83,12 +81,12 @@ class Metadata(MixinDataclassArray): Image white balance multipliers, usually the *As Shot Neutral* matrix. """ - f_number: Optional[NDArray] = field(default_factory=lambda: None) - exposure_time: Optional[NDArray] = field(default_factory=lambda: None) - iso: Optional[NDArray] = field(default_factory=lambda: None) - black_level: Optional[NDArray] = field(default_factory=lambda: None) - white_level: Optional[NDArray] = field(default_factory=lambda: None) - white_balance_multipliers: Optional[NDArray] = field( + f_number: Real | None = field(default_factory=lambda: None) + exposure_time: Real | None = field(default_factory=lambda: None) + iso: Real | None = field(default_factory=lambda: None) + black_level: NDArrayFloat | None = field(default_factory=lambda: None) + white_level: NDArrayFloat | None = field(default_factory=lambda: None) + white_balance_multipliers: NDArrayFloat | None = field( default_factory=lambda: None ) @@ -122,21 +120,19 @@ class Image: def __init__( self, - path: Optional[str] = None, - data: Optional[ArrayLike] = None, - metadata: Optional[Metadata] = None, + path: str | None = None, + data: ArrayLike | None = None, + metadata: Metadata | None = None, ) -> None: - self._path: Optional[str] = None + self._path: str | None = None self.path = path - # TODO: Remove pragma when https://github.com/python/mypy/issues/3004 - # is resolved. - self._data: Optional[NDArray] = None - self.data = data # type: ignore[assignment] - self._metadata: Optional[Metadata] = None + self._data: NDArrayFloat | None = None + self.data = data + self._metadata: Metadata | None = None self.metadata = metadata @property - def path(self) -> Optional[str]: + def path(self) -> str | None: """ Getter and setter property for the image path. @@ -154,18 +150,19 @@ def path(self) -> Optional[str]: return self._path @path.setter - def path(self, value: Optional[str]): + def path(self, value: str | None): """Setter for the **self._path** property.""" if value is not None: - assert is_string( - value - ), f'"path" property: "{value}" type is not "str"!' + attest( + is_string(value), + f'"path" property: "{value}" type is not "str"!', + ) self._path = value @property - def data(self) -> Optional[NDArray]: + def data(self) -> NDArrayFloat | None: """ Getter and setter property for the image data. @@ -183,13 +180,16 @@ def data(self) -> Optional[NDArray]: return self._data @data.setter - def data(self, value: Optional[ArrayLike]): + def data(self, value: ArrayLike | None): """Setter for the **self._data** property.""" if value is not None: - assert isinstance(value, (tuple, list, np.ndarray, np.matrix)), ( - f'"data" property: "{value!r}" is not a "tuple", "list", "ndarray" ' - 'or "matrix" instance!' + attest( + isinstance(value, (tuple, list, np.ndarray, np.matrix)), + ( + f'"data" property: "{value!r}" is not a "tuple", "list", ' + f'"ndarray" or "matrix" instance!' + ), ) value = as_float_array(value) @@ -197,7 +197,7 @@ def data(self, value: Optional[ArrayLike]): self._data = value @property - def metadata(self) -> Optional[Metadata]: + def metadata(self) -> Metadata | None: """ Getter and setter property for the image metadata. @@ -219,13 +219,14 @@ def metadata(self, value): """Setter for the **self._metadata** property.""" if value is not None: - assert isinstance( - value, Metadata - ), f'"metadata" property: "{value}" is not a "Metadata" instance!' + attest( + isinstance(value, Metadata), + f'"metadata" property: "{value}" is not a "Metadata" instance!', + ) self._metadata = value - def read_data(self, cctf_decoding: Optional[Callable] = None) -> NDArray: + def read_data(self, cctf_decoding: Callable | None = None) -> NDArrayFloat: """ Read image pixel data at :attr:`Image.path` attribute. @@ -247,7 +248,7 @@ def read_data(self, cctf_decoding: Optional[Callable] = None) -> NDArray: """ if self._path is not None: - logging.info(f'Reading "{self._path}" image.') + logging.info('Reading "{path}" image.', extra={"path": self._path}) data = read_image(str(self._path)) if cctf_decoding is not None: @@ -255,7 +256,7 @@ def read_data(self, cctf_decoding: Optional[Callable] = None) -> NDArray: self.data = data - return data + return cast(NDArrayFloat, data) else: raise ValueError('The image "path" is undefined!') @@ -275,7 +276,9 @@ def read_metadata(self) -> Metadata: """ if self._path is not None: - logging.info(f'Reading "{self._path}" image metadata.') + logging.info( + 'Reading "{path}" image metadata.', extra={"path": self._path} + ) exif_data = read_exif_tags(self._path) @@ -359,9 +362,7 @@ class ImageStack(MutableSequence): def __init__(self) -> None: self._data: List = [] - def __getitem__( - self, index: Union[Integer, slice] - ) -> Union[Any, MutableSequence[Any]]: + def __getitem__(self, index: int | slice) -> Any | MutableSequence[Any]: """ Return the :class:`colour_hdri.Image` class instance at given index. @@ -378,7 +379,7 @@ def __getitem__( return self._data[index] - def __setitem__(self, index: Union[Integer, slice], value: Any): + def __setitem__(self, index: int | slice, value: Any): """ Set given :class:`colour_hdri.Image` class instance at given index. @@ -392,7 +393,7 @@ def __setitem__(self, index: Union[Integer, slice], value: Any): self._data[index] = value - def __delitem__(self, index: Union[Integer, slice]): + def __delitem__(self, index: int | slice): """ Delete the :class:`colour_hdri.Image` class instance at given index. @@ -404,7 +405,7 @@ def __delitem__(self, index: Union[Integer, slice]): del self._data[index] - def __len__(self) -> Integer: + def __len__(self) -> int: """ Return the :class:`colour_hdri.Image` class instances count. @@ -432,7 +433,7 @@ def __getattr__(self, attribute: str) -> Any: try: return self.__dict__[attribute] - except KeyError: + except KeyError as error: if hasattr(Image, attribute): value = [getattr(image, attribute) for image in self] if attribute == "data": @@ -447,7 +448,7 @@ def __getattr__(self, attribute: str) -> Any: raise AttributeError( f"'{self.__class__.__name__}' object has no attribute " f"'{attribute}'" - ) + ) from error def __setattr__(self, attribute: str, value: Any): """ @@ -475,7 +476,7 @@ def __setattr__(self, attribute: str, value: Any): else: super().__setattr__(attribute, value) - def insert(self, index: Integer, value: Any): + def insert(self, index: int, value: Any): """ Insert given :class:`colour_hdri.Image` class instance at given index. @@ -489,7 +490,7 @@ def insert(self, index: Integer, value: Any): self._data.insert(index, value) - def sort(self, key: Optional[Callable] = None): + def sort(self, key: Callable | None = None): """ Sort the underlying data structure. @@ -504,7 +505,7 @@ def sort(self, key: Optional[Callable] = None): @staticmethod def from_files( - image_files: Sequence[str], cctf_decoding: Optional[Callable] = None + image_files: Sequence[str], cctf_decoding: Callable | None = None ) -> ImageStack: """ Return a :class:`colour_hdri.ImageStack` instance from given image @@ -530,7 +531,7 @@ def from_files( image.read_metadata() image_stack.append(image) - def luminance_average_key(image: Image) -> Optional[FloatingOrNDArray]: + def luminance_average_key(image: Image) -> NDArrayFloat | None: """Comparison key function.""" metadata = cast(Metadata, image.metadata) diff --git a/colour_hdri/utilities/tests/test_common.py b/colour_hdri/utilities/tests/test_common.py index 77bfdf32..155ff511 100644 --- a/colour_hdri/utilities/tests/test_common.py +++ b/colour_hdri/utilities/tests/test_common.py @@ -16,7 +16,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -61,7 +61,7 @@ def test_vivified_to_dict(self): vivified = vivification() vivified["my"]["attribute"] = 1 vivified_as_dict = vivified_to_dict(vivified) - self.assertIsInstance(dict(), type(vivified_as_dict)) + self.assertIsInstance({}, type(vivified_as_dict)) self.assertIn("attribute", vivified_as_dict["my"].keys()) self.assertEqual(vivified_as_dict["my"]["attribute"], 1) diff --git a/colour_hdri/utilities/tests/test_exif.py b/colour_hdri/utilities/tests/test_exif.py index 296998e3..068264e5 100644 --- a/colour_hdri/utilities/tests/test_exif.py +++ b/colour_hdri/utilities/tests/test_exif.py @@ -28,7 +28,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -198,7 +198,7 @@ def test_read_exif_tags(self): ] exif_data = vivified_to_dict(read_exif_tags(test_jpg_image)) - self.assertIsInstance(exif_data, type(dict())) + self.assertIsInstance(exif_data, type({})) self.assertListEqual( sorted(exif_data.keys()), diff --git a/colour_hdri/utilities/tests/test_image.py b/colour_hdri/utilities/tests/test_image.py index a7093cc6..64af336f 100644 --- a/colour_hdri/utilities/tests/test_image.py +++ b/colour_hdri/utilities/tests/test_image.py @@ -13,7 +13,7 @@ __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" diff --git a/docs/colour_hdri.process.rst b/docs/colour_hdri.process.rst index 000eb803..1c20170b 100644 --- a/docs/colour_hdri.process.rst +++ b/docs/colour_hdri.process.rst @@ -31,6 +31,6 @@ DNG Files convert_dng_files_to_intermediate_files DNG_CONVERTER - DNG_CONVERSION_ARGUMENTS + DNG_CONVERTER_ARGUMENTS DNG_EXIF_TAGS_BINDING read_dng_files_exif_tags diff --git a/docs/conf.py b/docs/conf.py index eaef539a..3335d992 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,8 +4,12 @@ """ import re +import sys +from pathlib import Path -import colour_hdri as package +sys.path.append(str(Path(__file__).parent.parent)) + +import colour_hdri as package # noqa: E402 basename = re.sub( "_(\\w)", lambda x: x.group(1).upper(), package.__name__.title() @@ -45,27 +49,20 @@ autodoc_typehints = "both" autodoc_type_aliases = { "ArrayLike": "ArrayLike", - "Boolean": "Boolean", - "BooleanOrArrayLike": "BooleanOrArrayLike", - "BooleanOrNDArray": "BooleanOrNDArray", "DType": "DType", "DTypeBoolean": "DTypeBoolean", "DTypeComplex": "DTypeComplex", - "DTypeFloating": "DTypeFloating", - "DTypeInteger": "DTypeInteger", - "DTypeNumber": "DTypeNumber", - "Floating": "Floating", - "FloatingOrArrayLike": "FloatingOrArrayLike", - "FloatingOrNDArray": "FloatingOrNDArray", - "Integer": "Integer", - "IntegerOrArrayLike": "IntegerOrArrayLike", - "IntegerOrNDArray": "IntegerOrNDArray", - "NestedSequence": "NestedSequence", - "Number": "Number", - "NumberOrArrayLike": "NumberOrArrayLike", - "NumberOrNDArray": "NumberOrNDArray", - "StrOrArrayLike": "StrOrArrayLike", - "StrOrNDArray": "StrOrNDArray", + "DTypeFloat": "DTypeFloat", + "DTypeInt": "DTypeInt", + "DTypeReal": "DTypeReal", + "Dataclass": "Dataclass", + "NDArrayBoolean": "NDArrayBoolean", + "NDArrayComplex": "NDArrayComplex", + "NDArrayFloat": "NDArrayFloat", + "NDArrayInt": "NDArrayInt", + "NDArrayReal": "NDArrayReal", + "NDArrayStr": "NDArrayStr", + "Real": "Real", } autodoc_preserve_defaults = True @@ -83,7 +80,7 @@ master_doc = "index" project = package.__application_name__ -copyright = package.__copyright__.replace("Copyright (C)", "") +copyright = package.__copyright__.replace("Copyright (C)", "") # noqa: A001 version = f"{package.__major_version__}.{package.__minor_version__}" release = package.__version__ @@ -192,19 +189,3 @@ epub_publisher = package.__author__ epub_copyright = package.__copyright__.replace("Copyright (C)", "") epub_exclude_files = ["search.html"] - - -def autodoc_process_docstring(app, what, name, obj, options, lines): - """Process the docstrings to remove the *# noqa* *flake8* pragma.""" - - for i, line in enumerate(lines): - lines[i] = line.replace("# noqa", "") - - -def setup(app): - """ - Prepare the extension and linking resources that Sphinx uses in the - build process. - """ - - app.connect("autodoc-process-docstring", autodoc_process_docstring) diff --git a/docs/index.rst b/docs/index.rst index 639a1967..7154dfd1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,11 +1,11 @@ Colour - HDRI ============= -A `Python `__ package implementing various +A `Python `__ package implementing various HDRI processing algorithms. It is open source and freely available under the -`New BSD License `__ terms. +`BSD-3-Clause `__ terms. .. image:: https://raw.githubusercontent.com/colour-science/colour-hdri/master/docs/_static/Radiance_001.png @@ -65,7 +65,7 @@ Software **C/C++** -- `OpenCV `__ by Bradski, G. +- `OpenCV `__ by Bradski, G. - `Piccante `__ by Banterle, F. and Benedetti, L., *Piccante* was used to verify the Grossberg (2003) Histogram Based Image Sampling. @@ -78,7 +78,7 @@ Code of Conduct --------------- The *Code of Conduct*, adapted from the `Contributor Covenant 1.4 `__, -is available on the `Code of Conduct `__ page. +is available on the `Code of Conduct `__ page. Contact & Social ---------------- @@ -86,7 +86,7 @@ Contact & Social The *Colour Developers* can be reached via different means: - `Email `__ -- `Discourse `__ +- `Discourse `__ - `Facebook `__ - `Github Discussions `__ - `Gitter `__ @@ -97,5 +97,5 @@ About | **Colour - HDRI** by Colour Developers | Copyright 2015 Colour Developers – `colour-developers@colour-science.org `__ -| This software is released under terms of New BSD License: https://opensource.org/licenses/BSD-3-Clause +| This software is released under terms of BSD-3-Clause: https://opensource.org/licenses/BSD-3-Clause | `https://github.com/colour-science/colour-hdri `__ diff --git a/docs/installation.rst b/docs/installation.rst index 95598dae..5a830402 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -13,20 +13,20 @@ Primary Dependencies **Colour - HDRI** requires various dependencies in order to run: -- `python >= 3.8, < 4 `__ -- `colour-science >= 4 `__ -- `imageio >= 2, < 3 `__ -- `numpy >= 1.19, < 2 `__ -- `scipy >= 1.5, < 2 `__ +- `python >= 3.9, < 4 `__ +- `colour-science >= 4.3 `__ +- `imageio >= 2, < 3 `__ +- `numpy >= 1.22, < 2 `__ +- `scipy >= 1.8, < 2 `__ Optional Features Dependencies ------------------------------ -- `colour-demosaicing `__ +- `colour-demosaicing `__ - `Adobe DNG Converter `__ -- `dcraw `__ -- `ExifTool `__ -- `rawpy `__ +- `dcraw `__ +- `ExifTool `__ +- `rawpy `__ Pypi ---- diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..fcac47d6 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,51 @@ +accessible-pygments==0.0.4 ; python_version >= "3.9" and python_version < "3.12" +alabaster==0.7.13 ; python_version >= "3.9" and python_version < "3.12" +babel==2.12.1 ; python_version >= "3.9" and python_version < "3.12" +beautifulsoup4==4.12.2 ; python_version >= "3.9" and python_version < "3.12" +biblib-simple==0.1.2 ; python_version >= "3.9" and python_version < "3.12" +certifi==2023.7.22 ; python_version >= "3.9" and python_version < "3.12" +charset-normalizer==3.2.0 ; python_version >= "3.9" and python_version < "3.12" +colorama==0.4.6 ; python_version >= "3.9" and python_version < "3.12" and sys_platform == "win32" +colour-demosaicing==0.2.4 ; python_version >= "3.9" and python_version < "3.12" +colour-science==0.4.3 ; python_version >= "3.9" and python_version < "3.12" +contourpy==1.1.0 ; python_version >= "3.9" and python_version < "3.12" +cycler==0.11.0 ; python_version >= "3.9" and python_version < "3.12" +docutils==0.17.1 ; python_version >= "3.9" and python_version < "3.12" +fonttools==4.42.1 ; python_version >= "3.9" and python_version < "3.12" +idna==3.4 ; python_version >= "3.9" and python_version < "3.12" +imageio==2.31.2 ; python_version >= "3.9" and python_version < "3.12" +imagesize==1.4.1 ; python_version >= "3.9" and python_version < "3.12" +importlib-metadata==6.8.0 ; python_version >= "3.9" and python_version < "3.10" +importlib-resources==6.0.1 ; python_version >= "3.9" and python_version < "3.10" +jinja2==3.1.2 ; python_version >= "3.9" and python_version < "3.12" +kiwisolver==1.4.5 ; python_version >= "3.9" and python_version < "3.12" +latexcodec==2.0.1 ; python_version >= "3.9" and python_version < "3.12" +markupsafe==2.1.3 ; python_version >= "3.9" and python_version < "3.12" +matplotlib==3.7.2 ; python_version >= "3.9" and python_version < "3.12" +numpy==1.25.2 ; python_version >= "3.9" and python_version < "3.12" +packaging==23.1 ; python_version >= "3.9" and python_version < "3.12" +pillow==10.0.0 ; python_version >= "3.9" and python_version < "3.12" +pybtex-docutils==1.0.3 ; python_version >= "3.9" and python_version < "3.12" +pybtex==0.24.0 ; python_version >= "3.9" and python_version < "3.12" +pydata-sphinx-theme==0.13.3 ; python_version >= "3.9" and python_version < "3.12" +pygments==2.16.1 ; python_version >= "3.9" and python_version < "3.12" +pyparsing==3.0.9 ; python_version >= "3.9" and python_version < "3.12" +python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "3.12" +pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "3.12" +requests==2.31.0 ; python_version >= "3.9" and python_version < "3.12" +restructuredtext-lint==1.4.0 ; python_version >= "3.9" and python_version < "3.12" +scipy==1.11.2 ; python_version >= "3.9" and python_version < "3.12" +six==1.16.0 ; python_version >= "3.9" and python_version < "3.12" +snowballstemmer==2.2.0 ; python_version >= "3.9" and python_version < "3.12" +soupsieve==2.4.1 ; python_version >= "3.9" and python_version < "3.12" +sphinx==4.5.0 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-applehelp==1.0.4 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-bibtex==2.6.0 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-devhelp==1.0.2 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-htmlhelp==2.0.1 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-jsmath==1.0.1 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-qthelp==1.0.3 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-serializinghtml==1.1.5 ; python_version >= "3.9" and python_version < "3.12" +typing-extensions==4.7.1 ; python_version >= "3.9" and python_version < "3.12" +urllib3==2.0.4 ; python_version >= "3.9" and python_version < "3.12" +zipp==3.16.2 ; python_version >= "3.9" and python_version < "3.10" diff --git a/pyproject.toml b/pyproject.toml index 0d04cdfc..004622e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "colour-hdri" -version = "0.2.1" +version = "0.2.2" description = "HDRI processing algorithms for Python" license = "BSD-3-Clause" authors = [ "Colour Developers " ] @@ -59,95 +59,45 @@ exclude = [ [tool.poetry.dependencies] python = ">= 3.9, < 3.12" -colour-science = ">= 0.4.2" +colour-science = ">= 0.4.3" imageio = ">= 2, < 3" -numpy = ">= 1.20, < 2" -scipy = ">= 1.7, < 2" -typing-extensions = ">= 4, < 5" # Convenience for Google Colab. +numpy = ">= 1.22, < 2" +scipy = ">= 1.8, < 2" +typing-extensions = ">= 4, < 5" -colour-demosaicing = { version = ">= 0.2.3", optional = true } -matplotlib = { version = ">= 3.5, != 3.5.0, != 3.5.1", optional = true } +[tool.poetry.group.optional.dependencies] +colour-demosaicing = ">= 0.2.4" +matplotlib = ">= 3.5, != 3.5.0, != 3.5.1" -biblib-simple = { version = "*", optional = true } # Development dependency. -black = { version = "*", optional = true } # Development dependency. -blackdoc = { version = "*", optional = true } # Development dependency. -coverage = { version = "!= 6.3", optional = true } # Development dependency. -coveralls = { version = "*", optional = true } # Development dependency. -flake8 = { version = "*", optional = true } # Development dependency. -flynt = { version = "*", optional = true } # Development dependency. -invoke = { version = "*", optional = true } # Development dependency. -jupyter = { version = "*", optional = true } # Development dependency. -mypy = { version = "*", optional = true } # Development dependency. -pre-commit = { version = "*", optional = true } # Development dependency. -pydata-sphinx-theme = { version = "*", optional = true } # Development dependency. -pydocstyle = { version = "*", optional = true } # Development dependency. -pytest = { version = "*", optional = true } # Development dependency. -pytest-cov = { version = "*", optional = true } # Development dependency. -pytest-xdist = { version = "*", optional = true} #Development dependency -restructuredtext-lint = { version = "*", optional = true } # Development dependency. -sphinx = { version = ">= 4, < 5", optional = true } # Development dependency. -sphinxcontrib-bibtex = { version = "*", optional = true } # Development dependency. -toml = { version = "*", optional = true } # Development dependency. -twine = { version = "*", optional = true } # Development dependency. - -[tool.poetry.dev-dependencies] -biblib-simple = "*" +[tool.poetry.group.dev.dependencies] black = "*" blackdoc = "*" coverage = "!= 6.3" coveralls = "*" -flake8 = "*" flynt = "*" invoke = "*" jupyter = "*" -mypy = "*" pre-commit = "*" -pydata-sphinx-theme = "*" -pydocstyle = "*" +pyright = "*" pytest = "*" pytest-cov = "*" pytest-xdist = "*" -pyupgrade = "*" -restructuredtext-lint = "*" -sphinx = ">= 4, < 5" -sphinxcontrib-bibtex = "*" +ruff = "*" toml = "*" twine = "*" -[tool.poetry.extras] -development = [ - "biblib-simple", - "black", - "blackdoc", - "coverage", - "coveralls", - "flake8", - "flynt", - "invoke", - "jupyter", - "mypy", - "pre-commit", - "pydata-sphinx-theme", - "pydocstyle", - "pytest", - "pytest-cov", - "pyupgrade", - "restructuredtext-lint", - "sphinx", - "sphinxcontrib-bibtex", - "toml", - "twine", -] -optional = [ "colour-demosaicing" ] -plotting = [ "matplotlib" ] -read-the-docs = [ "matplotlib", "pydata-sphinx-theme", "sphinxcontrib-bibtex" ] +[tool.poetry.group.docs.dependencies] +biblib-simple = "*" +pydata-sphinx-theme = "*" +restructuredtext-lint = "*" +sphinx = ">= 4, < 5" +sphinxcontrib-bibtex = "*" [tool.black] line-length = 79 exclude = ''' /( \.git - | \.mypy_cache | build | dist )/ @@ -156,17 +106,110 @@ exclude = ''' [tool.flynt] line_length=999 -[tool.mypy] -plugins = "numpy.typing.mypy_plugin" -ignore_missing_imports = true - -[tool.pydocstyle] -convention = "numpy" -add-ignore = "D104,D200,D202,D205,D301,D400" +[tool.pyright] +reportMissingImports = false +reportMissingModuleSource = false +reportUnboundVariable = false +reportUnnecessaryCast = true +reportUnnecessaryTypeIgnoreComment = true +reportUnsupportedDunderAll = false +reportUnusedExpression = false [tool.pytest.ini_options] addopts = "--durations=5" +[tool.ruff] +target-version = "py39" +line-length = 88 +select = [ + "A", # flake8-builtins + "ARG", # flake8-unused-arguments + # "ANN", # flake8-annotations + "B", # flake8-bugbear + # "BLE", # flake8-blind-except + "C4", # flake8-comprehensions + # "C90", # mccabe + # "COM", # flake8-commas + "DTZ", # flake8-datetimez + "D", # pydocstyle + "E", # pydocstyle + # "ERA", # eradicate + # "EM", # flake8-errmsg + "EXE", # flake8-executable + "F", # flake8 + # "FBT", # flake8-boolean-trap + "G", # flake8-logging-format + "I", # isort + "ICN", # flake8-import-conventions + "INP", # flake8-no-pep420 + "ISC", # flake8-implicit-str-concat + "N", # pep8-naming + # "PD", # pandas-vet + "PIE", # flake8-pie + "PGH", # pygrep-hooks + "PL", # pylint + # "PT", # flake8-pytest-style + # "PTH", # flake8-use-pathlib [Enable] + "Q", # flake8-quotes + "RET", # flake8-return + "RUF", # Ruff + "S", # flake8-bandit + "SIM", # flake8-simplify + "T10", # flake8-debugger + "T20", # flake8-print + # "TCH", # flake8-type-checking + "TID", # flake8-tidy-imports + "TRY", # tryceratops + "UP", # pyupgrade + "W", # pydocstyle + "YTT" # flake8-2020 +] +ignore = [ + "B008", + "B905", + "D104", + "D200", + "D202", + "D205", + "D301", + "D400", + "I001", + "N801", + "N802", + "N803", + "N806", + "N813", + "N815", + "N816", + "PGH003", + "PIE804", + "PLE0605", + "PLR0911", + "PLR0912", + "PLR0913", + "PLR0915", + "PLR2004", + "RET504", + "RET505", + "RET506", + "RET507", + "RET508", + "TRY003", + "TRY300", +] +typing-modules = ["colour.hints"] +fixable = ["B", "C", "E", "F", "PIE", "RUF", "SIM", "UP", "W"] + +[tool.ruff.pydocstyle] +convention = "numpy" + +[tool.ruff.per-file-ignores] +"colour_hdri/examples/*" = ["INP", "T201", "T203"] +"docs/*" = ["INP"] +"tasks.py" = ["INP"] +"utilities/*" = ["EXE001", "INP"] +"utilities/unicode_to_ascii.py" = ["RUF001"] + [build-system] requires = [ "poetry_core>=1.0.0" ] build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt index bf03a4d1..3784040f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,161 +1,181 @@ -alabaster==0.7.12 -anyio==3.6.2 -appnope==0.1.3 -argon2-cffi==21.3.0 -argon2-cffi-bindings==21.2.0 -astor==0.8.1 -asttokens==2.2.0 -attrs==22.1.0 -Babel==2.11.0 -backcall==0.2.0 -beautifulsoup4==4.11.1 -biblib-simple==0.1.2 -black==22.10.0 -blackdoc==0.3.8 -bleach==5.0.1 -certifi==2022.9.24 -cffi==1.15.1 -cfgv==3.3.1 -charset-normalizer==2.1.1 -click==8.1.3 -colour-demosaicing==0.2.3 -colour-science==0.4.2 -commonmark==0.9.1 -contourpy==1.0.6 -coverage==6.5.0 -coveralls==3.3.1 -cycler==0.11.0 -debugpy==1.6.4 -decorator==5.1.1 -defusedxml==0.7.1 -distlib==0.3.6 -docopt==0.6.2 -docutils==0.17.1 -entrypoints==0.4 -execnet==1.9.0 -executing==1.2.0 -fastjsonschema==2.16.2 -filelock==3.8.0 -flake8==6.0.0 -flynt==0.77 -fonttools==4.38.0 -identify==2.5.9 -idna==3.4 -imageio==2.22.4 -imagesize==1.4.1 -importlib-metadata==5.1.0 -iniconfig==1.1.1 -invoke==1.7.3 -ipykernel==6.17.1 -ipython==8.7.0 -ipython-genutils==0.2.0 -ipywidgets==8.0.2 -jaraco.classes==3.2.3 -jedi==0.18.2 -Jinja2==3.1.2 -jsonschema==4.17.3 -jupyter==1.0.0 -jupyter_client==7.4.7 -jupyter-console==6.4.4 -jupyter_core==5.1.0 -jupyter-server==1.23.3 -jupyterlab-pygments==0.2.2 -jupyterlab-widgets==3.0.3 -keyring==23.11.0 -kiwisolver==1.4.4 -latexcodec==2.0.1 -MarkupSafe==2.1.1 -matplotlib==3.6.2 -matplotlib-inline==0.1.6 -mccabe==0.7.0 -mistune==2.0.4 -more-itertools==9.0.0 -mypy==0.991 -mypy-extensions==0.4.3 -nbclassic==0.4.8 -nbclient==0.7.2 -nbconvert==7.2.5 -nbformat==5.7.0 -nest-asyncio==1.5.6 -nodeenv==1.7.0 -notebook==6.5.2 -notebook_shim==0.2.2 -numpy==1.23.5 -packaging==21.3 -pandocfilters==1.5.0 -parso==0.8.3 -pathspec==0.10.2 -pexpect==4.8.0 -pickleshare==0.7.5 -Pillow==9.3.0 -pip==22.3.1 -pkginfo==1.9.2 -platformdirs==2.5.4 -pluggy==1.0.0 -pre-commit==2.20.0 -prometheus-client==0.15.0 -prompt-toolkit==3.0.33 -psutil==5.9.4 -ptyprocess==0.7.0 -pure-eval==0.2.2 -pybtex==0.24.0 -pybtex-docutils==1.0.2 -pycodestyle==2.10.0 -pycparser==2.21 -pydata-sphinx-theme==0.12.0 -pydocstyle==6.1.1 -pyflakes==3.0.1 -Pygments==2.13.0 -pyparsing==3.0.9 -pyrsistent==0.19.2 -pytest==7.2.0 -pytest-cov==4.0.0 -pytest-xdist==3.0.2 -python-dateutil==2.8.2 -pytz==2022.6 -pyupgrade==3.3.0 -PyYAML==6.0 -pyzmq==24.0.1 -qtconsole==5.4.0 -QtPy==2.3.0 -readme-renderer==37.3 -requests==2.28.1 -requests-toolbelt==0.10.1 -restructuredtext-lint==1.4.0 -rfc3986==2.0.0 -rich==12.6.0 -scipy==1.9.3 -Send2Trash==1.8.0 -setuptools==65.6.3 -setuptools-scm==7.0.5 -six==1.16.0 -sniffio==1.3.0 -snowballstemmer==2.2.0 -soupsieve==2.3.2.post1 -Sphinx==4.5.0 -sphinxcontrib-applehelp==1.0.2 -sphinxcontrib-bibtex==2.5.0 -sphinxcontrib-devhelp==1.0.2 -sphinxcontrib-htmlhelp==2.0.0 -sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-qthelp==1.0.3 -sphinxcontrib-serializinghtml==1.1.5 -stack-data==0.6.2 -terminado==0.17.0 -tinycss2==1.2.1 -tokenize-rt==5.0.0 -toml==0.10.2 -tomli==2.0.1 -tornado==6.2 -traitlets==5.6.0 -twine==4.0.2 -types-setuptools==65.6.0.1 -typing_extensions==4.4.0 -urllib3==1.26.13 -virtualenv==20.17.0 -wcwidth==0.2.5 -webencodings==0.5.1 -websocket-client==1.4.2 -wheel==0.38.4 -widgetsnbextension==4.0.3 -zipp==3.11.0 +accessible-pygments==0.0.4 ; python_version >= "3.9" and python_version < "3.12" +alabaster==0.7.13 ; python_version >= "3.9" and python_version < "3.12" +anyio==3.7.1 ; python_version >= "3.9" and python_version < "3.12" +appnope==0.1.3 ; python_version >= "3.9" and python_version < "3.12" and (platform_system == "Darwin" or sys_platform == "darwin") +argon2-cffi-bindings==21.2.0 ; python_version >= "3.9" and python_version < "3.12" +argon2-cffi==23.1.0 ; python_version >= "3.9" and python_version < "3.12" +arrow==1.2.3 ; python_version >= "3.9" and python_version < "3.12" +astor==0.8.1 ; python_version >= "3.9" and python_version < "3.12" +asttokens==2.2.1 ; python_version >= "3.9" and python_version < "3.12" +async-lru==2.0.4 ; python_version >= "3.9" and python_version < "3.12" +attrs==23.1.0 ; python_version >= "3.9" and python_version < "3.12" +babel==2.12.1 ; python_version >= "3.9" and python_version < "3.12" +backcall==0.2.0 ; python_version >= "3.9" and python_version < "3.12" +beautifulsoup4==4.12.2 ; python_version >= "3.9" and python_version < "3.12" +biblib-simple==0.1.2 ; python_version >= "3.9" and python_version < "3.12" +black==23.7.0 ; python_version >= "3.9" and python_version < "3.12" +blackdoc==0.3.8 ; python_version >= "3.9" and python_version < "3.12" +bleach==6.0.0 ; python_version >= "3.9" and python_version < "3.12" +certifi==2023.7.22 ; python_version >= "3.9" and python_version < "3.12" +cffi==1.15.1 ; python_version >= "3.9" and python_version < "3.12" +cfgv==3.4.0 ; python_version >= "3.9" and python_version < "3.12" +charset-normalizer==3.2.0 ; python_version >= "3.9" and python_version < "3.12" +click==8.1.7 ; python_version >= "3.9" and python_version < "3.12" +colorama==0.4.6 ; python_version >= "3.9" and python_version < "3.12" and (sys_platform == "win32" or platform_system == "Windows") +colour-demosaicing==0.2.4 ; python_version >= "3.9" and python_version < "3.12" +colour-science==0.4.3 ; python_version >= "3.9" and python_version < "3.12" +comm==0.1.4 ; python_version >= "3.9" and python_version < "3.12" +contourpy==1.1.0 ; python_version >= "3.9" and python_version < "3.12" +coverage==6.5.0 ; python_version >= "3.9" and python_version < "3.12" +coverage[toml]==6.5.0 ; python_version >= "3.9" and python_version < "3.12" +coveralls==3.3.1 ; python_version >= "3.9" and python_version < "3.12" +cryptography==41.0.3 ; python_version >= "3.9" and python_version < "3.12" and sys_platform == "linux" +cycler==0.11.0 ; python_version >= "3.9" and python_version < "3.12" +debugpy==1.6.7.post1 ; python_version >= "3.9" and python_version < "3.12" +decorator==5.1.1 ; python_version >= "3.9" and python_version < "3.12" +defusedxml==0.7.1 ; python_version >= "3.9" and python_version < "3.12" +distlib==0.3.7 ; python_version >= "3.9" and python_version < "3.12" +docopt==0.6.2 ; python_version >= "3.9" and python_version < "3.12" +docutils==0.17.1 ; python_version >= "3.9" and python_version < "3.12" +exceptiongroup==1.1.3 ; python_version >= "3.9" and python_version < "3.11" +execnet==2.0.2 ; python_version >= "3.9" and python_version < "3.12" +executing==1.2.0 ; python_version >= "3.9" and python_version < "3.12" +fastjsonschema==2.18.0 ; python_version >= "3.9" and python_version < "3.12" +filelock==3.12.2 ; python_version >= "3.9" and python_version < "3.12" +flynt==1.0.1 ; python_version >= "3.9" and python_version < "3.12" +fonttools==4.42.1 ; python_version >= "3.9" and python_version < "3.12" +fqdn==1.5.1 ; python_version >= "3.9" and python_version < "3.12" +identify==2.5.27 ; python_version >= "3.9" and python_version < "3.12" +idna==3.4 ; python_version >= "3.9" and python_version < "3.12" +imageio==2.31.2 ; python_version >= "3.9" and python_version < "3.12" +imagesize==1.4.1 ; python_version >= "3.9" and python_version < "3.12" +importlib-metadata==6.8.0 ; python_version >= "3.9" and python_version < "3.12" +importlib-resources==6.0.1 ; python_version >= "3.9" and python_version < "3.10" +iniconfig==2.0.0 ; python_version >= "3.9" and python_version < "3.12" +invoke==2.2.0 ; python_version >= "3.9" and python_version < "3.12" +ipykernel==6.25.1 ; python_version >= "3.9" and python_version < "3.12" +ipython-genutils==0.2.0 ; python_version >= "3.9" and python_version < "3.12" +ipython==8.14.0 ; python_version >= "3.9" and python_version < "3.12" +ipywidgets==8.1.0 ; python_version >= "3.9" and python_version < "3.12" +isoduration==20.11.0 ; python_version >= "3.9" and python_version < "3.12" +jaraco-classes==3.3.0 ; python_version >= "3.9" and python_version < "3.12" +jedi==0.19.0 ; python_version >= "3.9" and python_version < "3.12" +jeepney==0.8.0 ; python_version >= "3.9" and python_version < "3.12" and sys_platform == "linux" +jinja2==3.1.2 ; python_version >= "3.9" and python_version < "3.12" +json5==0.9.14 ; python_version >= "3.9" and python_version < "3.12" +jsonpointer==2.4 ; python_version >= "3.9" and python_version < "3.12" +jsonschema-specifications==2023.7.1 ; python_version >= "3.9" and python_version < "3.12" +jsonschema==4.19.0 ; python_version >= "3.9" and python_version < "3.12" +jsonschema[format-nongpl]==4.19.0 ; python_version >= "3.9" and python_version < "3.12" +jupyter-client==8.3.0 ; python_version >= "3.9" and python_version < "3.12" +jupyter-console==6.6.3 ; python_version >= "3.9" and python_version < "3.12" +jupyter-core==5.3.1 ; python_version >= "3.9" and python_version < "3.12" +jupyter-events==0.7.0 ; python_version >= "3.9" and python_version < "3.12" +jupyter-lsp==2.2.0 ; python_version >= "3.9" and python_version < "3.12" +jupyter-server-terminals==0.4.4 ; python_version >= "3.9" and python_version < "3.12" +jupyter-server==2.7.2 ; python_version >= "3.9" and python_version < "3.12" +jupyter==1.0.0 ; python_version >= "3.9" and python_version < "3.12" +jupyterlab-pygments==0.2.2 ; python_version >= "3.9" and python_version < "3.12" +jupyterlab-server==2.24.0 ; python_version >= "3.9" and python_version < "3.12" +jupyterlab-widgets==3.0.8 ; python_version >= "3.9" and python_version < "3.12" +jupyterlab==4.0.5 ; python_version >= "3.9" and python_version < "3.12" +keyring==24.2.0 ; python_version >= "3.9" and python_version < "3.12" +kiwisolver==1.4.5 ; python_version >= "3.9" and python_version < "3.12" +latexcodec==2.0.1 ; python_version >= "3.9" and python_version < "3.12" +markdown-it-py==3.0.0 ; python_version >= "3.9" and python_version < "3.12" +markupsafe==2.1.3 ; python_version >= "3.9" and python_version < "3.12" +matplotlib-inline==0.1.6 ; python_version >= "3.9" and python_version < "3.12" +matplotlib==3.7.2 ; python_version >= "3.9" and python_version < "3.12" +mdurl==0.1.2 ; python_version >= "3.9" and python_version < "3.12" +mistune==3.0.1 ; python_version >= "3.9" and python_version < "3.12" +more-itertools==10.1.0 ; python_version >= "3.9" and python_version < "3.12" +mypy-extensions==1.0.0 ; python_version >= "3.9" and python_version < "3.12" +nbclient==0.8.0 ; python_version >= "3.9" and python_version < "3.12" +nbconvert==7.7.4 ; python_version >= "3.9" and python_version < "3.12" +nbformat==5.9.2 ; python_version >= "3.9" and python_version < "3.12" +nest-asyncio==1.5.7 ; python_version >= "3.9" and python_version < "3.12" +nodeenv==1.8.0 ; python_version >= "3.9" and python_version < "3.12" +notebook-shim==0.2.3 ; python_version >= "3.9" and python_version < "3.12" +notebook==7.0.2 ; python_version >= "3.9" and python_version < "3.12" +numpy==1.25.2 ; python_version >= "3.9" and python_version < "3.12" +overrides==7.4.0 ; python_version >= "3.9" and python_version < "3.12" +packaging==23.1 ; python_version >= "3.9" and python_version < "3.12" +pandocfilters==1.5.0 ; python_version >= "3.9" and python_version < "3.12" +parso==0.8.3 ; python_version >= "3.9" and python_version < "3.12" +pathspec==0.11.2 ; python_version >= "3.9" and python_version < "3.12" +pexpect==4.8.0 ; python_version >= "3.9" and python_version < "3.12" and sys_platform != "win32" +pickleshare==0.7.5 ; python_version >= "3.9" and python_version < "3.12" +pillow==10.0.0 ; python_version >= "3.9" and python_version < "3.12" +pkginfo==1.9.6 ; python_version >= "3.9" and python_version < "3.12" +platformdirs==3.10.0 ; python_version >= "3.9" and python_version < "3.12" +pluggy==1.3.0 ; python_version >= "3.9" and python_version < "3.12" +pre-commit==3.3.3 ; python_version >= "3.9" and python_version < "3.12" +prometheus-client==0.17.1 ; python_version >= "3.9" and python_version < "3.12" +prompt-toolkit==3.0.39 ; python_version >= "3.9" and python_version < "3.12" +psutil==5.9.5 ; python_version >= "3.9" and python_version < "3.12" +ptyprocess==0.7.0 ; python_version >= "3.9" and python_version < "3.12" and (sys_platform != "win32" or os_name != "nt") +pure-eval==0.2.2 ; python_version >= "3.9" and python_version < "3.12" +pybtex-docutils==1.0.3 ; python_version >= "3.9" and python_version < "3.12" +pybtex==0.24.0 ; python_version >= "3.9" and python_version < "3.12" +pycparser==2.21 ; python_version >= "3.9" and python_version < "3.12" +pydata-sphinx-theme==0.13.3 ; python_version >= "3.9" and python_version < "3.12" +pygments==2.16.1 ; python_version >= "3.9" and python_version < "3.12" +pyparsing==3.0.9 ; python_version >= "3.9" and python_version < "3.12" +pyright==1.1.324 ; python_version >= "3.9" and python_version < "3.12" +pytest-cov==4.1.0 ; python_version >= "3.9" and python_version < "3.12" +pytest-xdist==3.3.1 ; python_version >= "3.9" and python_version < "3.12" +pytest==7.4.0 ; python_version >= "3.9" and python_version < "3.12" +python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "3.12" +python-json-logger==2.0.7 ; python_version >= "3.9" and python_version < "3.12" +pywin32-ctypes==0.2.2 ; python_version >= "3.9" and python_version < "3.12" and sys_platform == "win32" +pywin32==306 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.9" and python_version < "3.12" +pywinpty==2.0.11 ; python_version >= "3.9" and python_version < "3.12" and os_name == "nt" +pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "3.12" +pyzmq==25.1.1 ; python_version >= "3.9" and python_version < "3.12" +qtconsole==5.4.3 ; python_version >= "3.9" and python_version < "3.12" +qtpy==2.3.1 ; python_version >= "3.9" and python_version < "3.12" +readme-renderer==41.0 ; python_version >= "3.9" and python_version < "3.12" +referencing==0.30.2 ; python_version >= "3.9" and python_version < "3.12" +requests-toolbelt==1.0.0 ; python_version >= "3.9" and python_version < "3.12" +requests==2.31.0 ; python_version >= "3.9" and python_version < "3.12" +restructuredtext-lint==1.4.0 ; python_version >= "3.9" and python_version < "3.12" +rfc3339-validator==0.1.4 ; python_version >= "3.9" and python_version < "3.12" +rfc3986-validator==0.1.1 ; python_version >= "3.9" and python_version < "3.12" +rfc3986==2.0.0 ; python_version >= "3.9" and python_version < "3.12" +rich==13.5.2 ; python_version >= "3.9" and python_version < "3.12" +rpds-py==0.9.2 ; python_version >= "3.9" and python_version < "3.12" +ruff==0.0.286 ; python_version >= "3.9" and python_version < "3.12" +scipy==1.11.2 ; python_version >= "3.9" and python_version < "3.12" +secretstorage==3.3.3 ; python_version >= "3.9" and python_version < "3.12" and sys_platform == "linux" +send2trash==1.8.2 ; python_version >= "3.9" and python_version < "3.12" +setuptools==68.1.2 ; python_version >= "3.9" and python_version < "3.12" +six==1.16.0 ; python_version >= "3.9" and python_version < "3.12" +sniffio==1.3.0 ; python_version >= "3.9" and python_version < "3.12" +snowballstemmer==2.2.0 ; python_version >= "3.9" and python_version < "3.12" +soupsieve==2.4.1 ; python_version >= "3.9" and python_version < "3.12" +sphinx==4.5.0 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-applehelp==1.0.4 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-bibtex==2.6.0 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-devhelp==1.0.2 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-htmlhelp==2.0.1 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-jsmath==1.0.1 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-qthelp==1.0.3 ; python_version >= "3.9" and python_version < "3.12" +sphinxcontrib-serializinghtml==1.1.5 ; python_version >= "3.9" and python_version < "3.12" +stack-data==0.6.2 ; python_version >= "3.9" and python_version < "3.12" +terminado==0.17.1 ; python_version >= "3.9" and python_version < "3.12" +tinycss2==1.2.1 ; python_version >= "3.9" and python_version < "3.12" +toml==0.10.2 ; python_version >= "3.9" and python_version < "3.12" +tomli==2.0.1 ; python_version >= "3.9" and python_version < "3.12" +tornado==6.3.3 ; python_version >= "3.9" and python_version < "3.12" +traitlets==5.9.0 ; python_version >= "3.9" and python_version < "3.12" +twine==4.0.2 ; python_version >= "3.9" and python_version < "3.12" +typing-extensions==4.7.1 ; python_version >= "3.9" and python_version < "3.12" +uri-template==1.3.0 ; python_version >= "3.9" and python_version < "3.12" +urllib3==2.0.4 ; python_version >= "3.9" and python_version < "3.12" +virtualenv==20.24.3 ; python_version >= "3.9" and python_version < "3.12" +wcwidth==0.2.6 ; python_version >= "3.9" and python_version < "3.12" +webcolors==1.13 ; python_version >= "3.9" and python_version < "3.12" +webencodings==0.5.1 ; python_version >= "3.9" and python_version < "3.12" +websocket-client==1.6.2 ; python_version >= "3.9" and python_version < "3.12" +widgetsnbextension==4.0.8 ; python_version >= "3.9" and python_version < "3.12" +zipp==3.16.2 ; python_version >= "3.9" and python_version < "3.12" diff --git a/setup.py b/setup.py deleted file mode 100644 index 42bb43c7..00000000 --- a/setup.py +++ /dev/null @@ -1,100 +0,0 @@ -""" -Colour - HDRI - Setup -===================== -""" - -import codecs -from setuptools import setup - -packages = [ - "colour_hdri", - "colour_hdri.calibration", - "colour_hdri.calibration.tests", - "colour_hdri.distortion", - "colour_hdri.distortion.tests", - "colour_hdri.exposure", - "colour_hdri.exposure.tests", - "colour_hdri.generation", - "colour_hdri.generation.tests", - "colour_hdri.models", - "colour_hdri.models.datasets", - "colour_hdri.models.tests", - "colour_hdri.plotting", - "colour_hdri.process", - "colour_hdri.process.tests", - "colour_hdri.recovery", - "colour_hdri.recovery.tests", - "colour_hdri.sampling", - "colour_hdri.sampling.tests", - "colour_hdri.tonemapping", - "colour_hdri.tonemapping.global_operators", - "colour_hdri.tonemapping.global_operators.tests", - "colour_hdri.utilities", - "colour_hdri.utilities.tests", -] - -package_data = { - "": ["*"], - "colour_hdri": [ - "examples/*", - "resources/colour-hdri-tests-datasets/*", - "resources/colour-hdri-tests-datasets/colour_hdri/distortion/*", - ], -} - -install_requires = [ - "colour-science>=0.4.2", - "imageio>=2,<3", - "numpy>=1.20,<2", - "scipy>=1.7,<2", - "typing-extensions>=4,<5", -] - -extras_require = { - "development": [ - "biblib-simple", - "black", - "blackdoc", - "coverage!=6.3", - "coveralls", - "flake8", - "flynt", - "invoke", - "jupyter", - "mypy", - "pre-commit", - "pydata-sphinx-theme", - "pydocstyle", - "pytest", - "pytest-cov", - "restructuredtext-lint", - "sphinx>=4,<5", - "sphinxcontrib-bibtex", - "toml", - "twine", - ], - "optional": ["colour-demosaicing>=0.2.3"], - "plotting": ["matplotlib>=3.5,!=3.5.0,!=3.5.1"], - "read-the-docs": [ - "matplotlib>=3.5,!=3.5.0,!=3.5.1", - "pydata-sphinx-theme", - "sphinxcontrib-bibtex", - ], -} - -setup( - name="colour-hdri", - version="0.2.1", - description="HDRI processing algorithms for Python", - long_description=codecs.open("README.rst", encoding="utf8").read(), - author="Colour Developers", - author_email="colour-developers@colour-science.org", - maintainer="Colour Developers", - maintainer_email="colour-developers@colour-science.org", - url="https://www.colour-science.org/", - packages=packages, - package_data=package_data, - install_requires=install_requires, - extras_require=extras_require, - python_requires=">=3.9,<3.12", -) diff --git a/tasks.py b/tasks.py index 91fea4d6..262ed526 100644 --- a/tasks.py +++ b/tasks.py @@ -6,26 +6,26 @@ from __future__ import annotations import biblib.bib +import contextlib import fnmatch import os import re import uuid -from colour.hints import Boolean - import colour_hdri from colour.utilities import message_box import inspect if not hasattr(inspect, "getargspec"): - inspect.getargspec = inspect.getfullargspec + inspect.getargspec = inspect.getfullargspec # pyright: ignore -from invoke import Context, task +from invoke.tasks import task +from invoke.context import Context __author__ = "Colour Developers" __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -69,10 +69,9 @@ @task def clean( ctx: Context, - docs: Boolean = True, - bytecode: Boolean = False, - mypy: Boolean = True, - pytest: Boolean = True, + docs: bool = True, + bytecode: bool = False, + pytest: bool = True, ): """ Clean the project. @@ -85,8 +84,6 @@ def clean( Whether to clean the *docs* directory. bytecode Whether to clean the bytecode files, e.g. *.pyc* files. - mypy - Whether to clean the *Mypy* cache directory. pytest Whether to clean the *Pytest* cache directory. """ @@ -103,9 +100,6 @@ def clean( patterns.append("**/__pycache__") patterns.append("**/*.pyc") - if mypy: - patterns.append(".mypy_cache") - if pytest: patterns.append(".pytest_cache") @@ -116,8 +110,8 @@ def clean( @task def formatting( ctx: Context, - asciify: Boolean = True, - bibtex: Boolean = True, + asciify: bool = True, + bibtex: bool = True, ): """ Convert unicode characters to ASCII and cleanup the *BibTeX* file. @@ -146,10 +140,8 @@ def formatting( ) for entry in sorted(entries.values(), key=lambda x: x.key): - try: + with contextlib.suppress(KeyError): del entry["file"] - except KeyError: - pass for key, value in entry.items(): entry[key] = re.sub("(? requirements.txt" + "poetry export -f requirements.txt " + "--without-hashes " + "--with dev,docs,optional " + "--output requirements.txt" + ) + + message_box('Exporting "docs/requirements.txt" file...') + ctx.run( + "poetry export -f requirements.txt " + "--without-hashes " + "--with docs,optional " + "--output docs/requirements.txt" ) @@ -347,68 +338,11 @@ def build(ctx: Context): message_box("Building...") ctx.run("poetry build") - - with ctx.cd("dist"): - ctx.run(f"tar -xvf {PYPI_ARCHIVE_NAME}-{APPLICATION_VERSION}.tar.gz") - ctx.run(f"cp {PYPI_ARCHIVE_NAME}-{APPLICATION_VERSION}/setup.py ../") - - ctx.run(f"rm -rf {PYPI_ARCHIVE_NAME}-{APPLICATION_VERSION}") - - with open("setup.py") as setup_file: - source = setup_file.read() - - setup_kwargs = [] - - def sub_callable(match): - setup_kwargs.append(match) - - return "" - - template = """ -setup({0} -) -""" - - source = re.sub( - "from setuptools import setup", - ( - '"""\n' - "Colour - HDRI - Setup\n" - "=====================\n" - '"""\n\n' - "import codecs\n" - "from setuptools import setup" - ), - source, - ) - source = re.sub( - "setup_kwargs = {(.*)}.*setup\\(\\*\\*setup_kwargs\\)", - sub_callable, - source, - flags=re.DOTALL, - )[:-2] - setup_kwargs = setup_kwargs[0].group(1).splitlines() - for i, line in enumerate(setup_kwargs): - setup_kwargs[i] = re.sub("^\\s*('(\\w+)':\\s?)", " \\2=", line) - if setup_kwargs[i].strip().startswith("long_description"): - setup_kwargs[i] = ( - " long_description=" - "codecs.open('README.rst', encoding='utf8')" - ".read()," - ) - - source += template.format("\n".join(setup_kwargs)) - - with open("setup.py", "w") as setup_file: - setup_file.write(source) - - ctx.run("poetry run pre-commit run --files setup.py || true") - ctx.run("twine check dist/*") @task -def virtualise(ctx: Context, tests: Boolean = True): +def virtualise(ctx: Context, tests: bool = True): """ Create a virtual environment for the project build. @@ -432,7 +366,7 @@ def virtualise(ctx: Context, tests: Boolean = True): ) with ctx.cd(unique_name): - ctx.run('poetry install --extras "optional plotting"') + ctx.run("poetry install") ctx.run("source $(poetry env info -p)/bin/activate") ctx.run( 'python -c "import imageio;' @@ -441,7 +375,6 @@ def virtualise(ctx: Context, tests: Boolean = True): if tests: ctx.run( "poetry run pytest " - "--disable-warnings " "--doctest-modules " f"--ignore={PYTHON_PACKAGE_NAME}/examples " f"{PYTHON_PACKAGE_NAME}", @@ -462,42 +395,42 @@ def tag(ctx: Context): message_box("Tagging...") result = ctx.run("git rev-parse --abbrev-ref HEAD", hide="both") - assert ( - result.stdout.strip() == "develop" - ), "Are you still on a feature or master branch?" + if result.stdout.strip() != "develop": # pyright: ignore + raise RuntimeError("Are you still on a feature or master branch?") with open(os.path.join(PYTHON_PACKAGE_NAME, "__init__.py")) as file_handle: file_content = file_handle.read() major_version = re.search( '__major_version__\\s+=\\s+"(.*)"', file_content - ).group( # type: ignore[union-attr] + ).group( # pyright: ignore 1 ) minor_version = re.search( '__minor_version__\\s+=\\s+"(.*)"', file_content - ).group( # type: ignore[union-attr] + ).group( # pyright: ignore 1 ) change_version = re.search( '__change_version__\\s+=\\s+"(.*)"', file_content - ).group( # type: ignore[union-attr] + ).group( # pyright: ignore 1 ) version = ".".join((major_version, minor_version, change_version)) result = ctx.run("git ls-remote --tags upstream", hide="both") - remote_tags = result.stdout.strip().split("\n") + remote_tags = result.stdout.strip().split("\n") # pyright: ignore tags = set() for remote_tag in remote_tags: tags.add( remote_tag.split("refs/tags/")[1].replace("refs/tags/", "^{}") ) - tags = sorted(list(tags)) - assert f"v{version}" not in tags, ( - f'A "{PYTHON_PACKAGE_NAME}" "v{version}" tag already exists in ' - f"remote repository!" - ) + version_tags = sorted(tags) + if f"v{version}" in version_tags: + raise RuntimeError( + f'A "{PYTHON_PACKAGE_NAME}" "v{version}" tag already exists in ' + f"remote repository!" + ) ctx.run(f"git flow release start v{version}") ctx.run(f"git flow release finish v{version}") diff --git a/utilities/export_todo.py b/utilities/export_todo.py index ae0eb290..901bd305 100755 --- a/utilities/export_todo.py +++ b/utilities/export_todo.py @@ -10,7 +10,7 @@ import os __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -34,9 +34,9 @@ ----- | **Colour - HDRI** by Colour Developers -| Copyright 2015 Colour Developers – \ +| Copyright 2015 Colour Developers - \ `colour-developers@colour-science.org `__ -| This software is released under terms of New BSD License: \ +| This software is released under terms of BSD-3-Clause: \ https://opensource.org/licenses/BSD-3-Clause | `https://github.com/colour-science/colour-hdri \ `__ @@ -66,7 +66,7 @@ def extract_todo_items(root_directory: str) -> dict: if not filename.endswith(".py"): continue - filename = os.path.join(root, filename) + filename = os.path.join(root, filename) # noqa: PLW2901 with codecs.open(filename, encoding="utf8") as file_handle: content = file_handle.readlines() @@ -74,7 +74,7 @@ def extract_todo_items(root_directory: str) -> dict: line_number = 1 todo_item = [] for i, line in enumerate(content): - line = line.strip() + line = line.strip() # noqa: PLW2901 if line.startswith("# TODO:"): in_todo = True line_number = i + 1 @@ -108,9 +108,9 @@ def export_todo_items(todo_items: dict, file_path: str): """ todo_rst = [] - for module, todo_items in todo_items.items(): + for module, module_todo_items in todo_items.items(): todo_rst.append(f"- {module}\n") - for line_numer, todo_item in todo_items: + for line_numer, todo_item in module_todo_items: todo_rst.append(f" - Line {line_numer} : {todo_item}") todo_rst.append("\n") @@ -120,6 +120,8 @@ def export_todo_items(todo_items: dict, file_path: str): if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + export_todo_items( extract_todo_items(os.path.join("..", "colour_hdri")), os.path.join("..", "TODO.rst"), diff --git a/utilities/unicode_to_ascii.py b/utilities/unicode_to_ascii.py index 0e48f124..aab5dbe4 100755 --- a/utilities/unicode_to_ascii.py +++ b/utilities/unicode_to_ascii.py @@ -11,7 +11,7 @@ import unicodedata __copyright__ = "Copyright 2015 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" __maintainer__ = "Colour Developers" __email__ = "colour-developers@colour-science.org" __status__ = "Production" @@ -55,7 +55,7 @@ def unicode_to_ascii(root_directory: str): if filename == "unicode_to_ascii.py": continue - filename = os.path.join(root, filename) + filename = os.path.join(root, filename) # noqa: PLW2901 with codecs.open(filename, encoding="utf8") as file_handle: content = file_handle.read() @@ -69,4 +69,6 @@ def unicode_to_ascii(root_directory: str): if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + unicode_to_ascii(os.path.join("..", "colour_hdri"))