"""Utility functions.""" from operator import itemgetter from typing import Callable, Collection, Hashable, TypeVar, cast __all__ = ['has_duplicates'] T = TypeVar('T') def has_duplicates(items: Collection[T], key: str | Callable[[T], Hashable] | None = None) -> bool: """Check if a collection contains any duplicate elements based on a key. Args: items: A collection of elements. key: The key to use for finding duplicates. It Can be a string (for dict-like objects), a callable, or None (to use the item itself). Returns: True if the collection contains duplicates, False otherwise. """ key_func: Callable[[T], Hashable] if key is not None: if isinstance(key, str): # Use `cast` to tell mypy that we know itemgetter is a valid # callable for this context. This resolves the error. key_func = cast(Callable[[T], Hashable], itemgetter(key)) else: key_func = key else: # If no key, the item itself is used. It must be hashable. key_func = lambda o: cast(Hashable, o) # noqa: E731 seen: set[Hashable] = set() for item in items: key_item = key_func(item) if key_item in seen: return True seen.add(key_item) return False