Skip to content

Commit

Permalink
Add "colour.utilities.int_digest" definition.
Browse files Browse the repository at this point in the history
  • Loading branch information
KelSolaar committed May 5, 2023
1 parent d383bdb commit dedee5f
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 1 deletion.
2 changes: 2 additions & 0 deletions colour/utilities/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
validate_method,
optional,
slugify,
int_digest,
)
from .verbose import (
ColourWarning,
Expand Down Expand Up @@ -167,6 +168,7 @@
"validate_method",
"optional",
"slugify",
"int_digest",
]
__all__ += [
"ColourWarning",
Expand Down
78 changes: 78 additions & 0 deletions colour/utilities/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"is_pandas_installed",
"is_tqdm_installed",
"is_trimesh_installed",
"is_xxhash_installed",
"required",
"is_iterable",
"is_string",
Expand All @@ -86,6 +87,7 @@
"validate_method",
"optional",
"slugify",
"int_digest",
]


Expand Down Expand Up @@ -894,6 +896,42 @@ def is_trimesh_installed(raise_exception: bool = False) -> bool:
return False


def is_xxhash_installed(raise_exception: bool = False) -> bool:
"""
Return whether *xxhash* is installed and available.
Parameters
----------
raise_exception
Whether to raise an exception if *xxhash* is unavailable.
Returns
-------
:class:`bool`
Whether *xxhash* is installed.
Raises
------
:class:`ImportError`
If *xxhash* is not installed.
"""

try: # pragma: no cover
# pylint: disable=W0611
import xxhash # noqa: F401

return True
except ImportError as error: # pragma: no cover
if raise_exception:
raise ImportError(
'"xxhash" related API features are not available: '
f'"{error}".\nSee the installation guide for more information: '
"https://www.colour-science.org/installation-guide/"
) from error

return False


_REQUIREMENTS_TO_CALLABLE: CanonicalMapping = CanonicalMapping(
{
"ctlrender": is_ctlrender_installed,
Expand All @@ -905,6 +943,7 @@ def is_trimesh_installed(raise_exception: bool = False) -> bool:
"Pandas": is_pandas_installed,
"tqdm": is_tqdm_installed,
"trimesh": is_trimesh_installed,
"xxhash": is_xxhash_installed,
}
)
"""
Expand All @@ -923,6 +962,7 @@ def required(
"Pandas",
"tqdm",
"trimesh",
"xxhash",
]
) -> Callable:
"""
Expand Down Expand Up @@ -1427,3 +1467,41 @@ def slugify(object_: Any, allow_unicode: bool = False) -> str:
value = re.sub(r"[^\w\s-]", "", value.lower())

return re.sub(r"[-\s]+", "-", value).strip("-_")


if is_xxhash_installed():
import xxhash
from colour.utilities.documentation import is_documentation_building

int_digest = xxhash.xxh3_64_intdigest

if is_documentation_building():
import array

def int_digest(
args: str # noqa: ARG001
| bytes
| bytearray
| memoryview
| array.ArrayType[int],
seed: int = None, # noqa: ARG001
) -> int:
"""
Generate an integer digest for given argument using *xxhash* if
available or falling back to :func:`hash` if not.
Parameters
----------
args
Argument to generate the int digest of.
seed
Seed used to alter result predictably.
Returns
-------
:class:`int`
Integer digest.
"""

else:
int_digest = hash
19 changes: 19 additions & 0 deletions colour/utilities/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
validate_method,
optional,
slugify,
int_digest,
)

__author__ = "Colour Developers"
Expand Down Expand Up @@ -536,5 +537,23 @@ def test_slugify(self):
self.assertEqual(slugify(123), "123")


class TestIntDigest(unittest.TestCase):
"""
Define :func:`colour.utilities.common.int_digest` definition unit tests
methods.
"""

def test_int_digest(self):
"""Test :func:`colour.utilities.common.int_digest` definition."""

self.assertEqual(int_digest("Foo"), 7467386374397815550)

self.assertEqual(
int_digest(np.array([1, 2, 3]).tobytes()), 8964613590703056768
)

self.assertEqual(int_digest(repr((1, 2, 3))), 5069958125469218295)


if __name__ == "__main__":
unittest.main()
2 changes: 2 additions & 0 deletions docs/colour.utilities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Common
is_pandas_installed
is_tqdm_installed
is_trimesh_installed
is_xxhash_installed
required
is_iterable
is_string
Expand All @@ -81,6 +82,7 @@ Common
validate_method
optional
slugify
int_digest

Array
-----
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pandas = { version = ">= 1.3, < 2", optional = true }
pygraphviz = { version = ">= 1, < 2", optional = true }
tqdm = { version = ">= 4, < 5", optional = true }
trimesh = { version = ">= 3, < 4", optional = true }
xxhash = { version = ">= 3.2, < 4", optional = true }

biblib-simple = { version = "*", optional = true } # Development dependency.
black = { version = "*", optional = true } # Development dependency.
Expand Down Expand Up @@ -124,7 +125,7 @@ development = [
]
graphviz = [ "pygraphviz" ]
meshing = [ "trimesh" ]
optional = [ "networkx", "pandas", "scikit-learn", "tqdm" ]
optional = [ "networkx", "pandas", "scikit-learn", "tqdm", "xxhash" ]
plotting = [ "matplotlib" ]
read-the-docs = [
"matplotlib",
Expand Down

0 comments on commit dedee5f

Please sign in to comment.