from typing import Optional


class CaseInsensitiveEnumMixin:
    """Mixin for str Enums that accepts values in any case.

    When combined with ``str`` and ``Enum``, allows instantiation with
    case-insensitive values.  For example, ``MetricSource("human_evaluation")``
    will resolve to ``MetricSource.HUMAN_EVALUATION``.
    """

    @classmethod
    def _missing_(cls, value: object) -> Optional["CaseInsensitiveEnumMixin"]:
        if isinstance(value, str):
            upper_value = value.upper()
            for member in cls:
                if member.value.upper() == upper_value:
                    return member
        return None
