<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def recover( data: bytes, signature: Signature, hasher: Callable[[bytes], bytes] = eth_sign_sha3, ) -> Address: """ eth_recover address from data hash and signature """

    _hash = hasher(data)

    # ecdsa_recover accepts only standard [0,1] v's so we add support also for [27,28] here
    # anything else will raise BadSignature
    if signature[-1] >= 27:  # support (0,1,27,28) v values
        signature = Signature(signature[:-1] + bytes([signature[-1] - 27]))

    try:
        sig = keys.Signature(signature_bytes=signature)
        public_key = keys.ecdsa_recover(message_hash=_hash, signature=sig)
    except BadSignature as e:
        raise InvalidSignature from e
    return public_key.to_canonical_address()