def pow(val: Any, exponent: Any, default: Any = RaiseTypeErrorIfNotProvided) -> Any:
    """Returns `val**factor` of the given value, if defined.

    Values define an extrapolation by defining a __pow__(self, exponent) method.
    Note that the method may return NotImplemented to indicate a particular
    extrapolation can't be done.

    Args:
        val: The value or iterable of values to invert.
        exponent: The extrapolation factor. For example, if this is 0.5 and val
            is a gate then the caller is asking for a square root of the gate.
        default: Determines the fallback behavior when `val` doesn't have
            an extrapolation defined. If `default` is not set and that occurs,
            a TypeError is raised instead.

    Returns:
        If `val` has a __pow__ method that returns something besides
        NotImplemented, that result is returned. Otherwise, if a default value
        was specified, the default value is returned.

    Raises:
        TypeError: `val` doesn't have a __pow__ method (or that method returned
            NotImplemented) and no `default` value was specified.
    """
    raiser: Callable | None = getattr(val, '__pow__', None)
    result = NotImplemented if raiser is None else raiser(exponent)
    if result is not NotImplemented:
        return result

    if default is not RaiseTypeErrorIfNotProvided:
        return default
    if raiser is None:
        raise TypeError(f"object of type '{type(val)}' has no __pow__ method.")
    raise TypeError(
        f"object of type '{type(val)}' does have a __pow__ method, but it returned NotImplemented."
    )
Returns `val**factor` of the given value, if defined.

    Values define an extrapolation by defining a __pow__(self, exponent) method.
    Note that the method may return NotImplemented to indicate a particular
    extrapolation can't be done.

    Args:
        val: The value or iterable of values to invert.
        exponent: The extrapolation factor. For example, if this is 0.5 and val
            is a gate then the caller is asking for a square root of the gate.
        default: Determines the fallback behavior when `val` doesn't have
            an extrapolation defined. If `default` is not set and that occurs,
            a TypeError is raised instead.

    Returns:
        If `val` has a __pow__ method that returns something besides
        NotImplemented, that result is returned. Otherwise, if a default value
        was specified, the default value is returned.

    Raises:
        TypeError: `val` doesn't have a __pow__ method (or that method returned
            NotImplemented) and no `default` value was specified.
    
cirq-core/cirq/protocols/pow_protocol.py