prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Improve warning on failed address checksum
  * Version: 4
  
  ### What was wrong?
  
  Error message about checksum failure isn't clear enough, especially when the address is supplied as all-lower-case.
  
  ### How can it be fixed?
  
  Special-case the warning, so that an all-lower-case address gives a specific warning, along the lines of: "web3py only accepts checksummed addresses. Please report it as a bug on any project that does not provide you checksummed addresses. In the meantime, you can force an address into checksummed state with `valid_address = w3.toChecksumAddress(questionable_address)` after double-checking that there are no errors in the address. Alternatively, you can use an ENS name in its place."
  
  But, you know, not a paragraph...
  
  </issue>
  <code>
  [start of web3/utils/validation.py]
  1 import itertools
  2 
  3 from eth_utils import (
  4     is_0x_prefixed,
  5     is_boolean,
  6     is_bytes,
  7     is_checksum_address,
  8     is_dict,
  9     is_hex_address,
  10     is_integer,
  11     is_list_like,
  12     is_string,
  13 )
  14 
  15 from web3.exceptions import (
  16     InvalidAddress,
  17 )
  18 from web3.utils.abi import (
  19     is_address_type,
  20     is_array_type,
  21     is_bool_type,
  22     is_bytes_type,
  23     is_int_type,
  24     is_recognized_type,
  25     is_string_type,
  26     is_uint_type,
  27     length_of_array_type,
  28     sub_type_of_array_type,
  29 )
  30 
  31 
  32 def validate_abi(abi):
  33     """
  34     Helper function for validating an ABI
  35     """
  36     if not is_list_like(abi):
  37         raise ValueError("'abi' is not a list")
  38     for e in abi:
  39         if not is_dict(e):
  40             raise ValueError("The elements of 'abi' are not all dictionaries")
  41 
  42 
  43 def validate_abi_type(abi_type):
  44     """
  45     Helper function for validating an abi_type
  46     """
  47     if not is_recognized_type(abi_type):
  48         raise ValueError("Unrecognized abi_type: {abi_type}".format(abi_type=abi_type))
  49 
  50 
  51 def validate_abi_value(abi_type, value):
  52     """
  53     Helper function for validating a value against the expected abi_type
  54     Note: abi_type 'bytes' must either be python3 'bytes' object or ''
  55     """
  56     if is_array_type(abi_type) and is_list_like(value):
  57         # validate length
  58         specified_length = length_of_array_type(abi_type)
  59         if specified_length is not None:
  60             if specified_length < 1:
  61                 raise TypeError(
  62                     "Invalid abi-type: {abi_type}. Length of fixed sized arrays"
  63                     "must be greater than 0."
  64                     .format(abi_type=abi_type)
  65                 )
  66             if specified_length != len(value):
  67                 raise TypeError(
  68                     "The following array length does not the length specified"
  69                     "by the abi-type, {abi_type}: {value}"
  70                     .format(abi_type=abi_type, value=value)
  71                 )
  72 
  73         # validate sub_types
  74         sub_type = sub_type_of_array_type(abi_type)
  75         for v in value:
  76             validate_abi_value(sub_type, v)
  77         return
  78     elif is_bool_type(abi_type) and is_boolean(value):
  79         return
  80     elif is_uint_type(abi_type) and is_integer(value) and value >= 0:
  81         return
  82     elif is_int_type(abi_type) and is_integer(value):
  83         return
  84     elif is_address_type(abi_type):
  85         validate_address(value)
  86         return
  87     elif is_bytes_type(abi_type):
  88         if is_bytes(value):
  89             return
  90         elif is_string(value):
  91             if is_0x_prefixed(value):
  92                 return
  93             else:
  94                 raise TypeError(
  95                     "ABI values of abi-type 'bytes' must be either"
  96                     "a python3 'bytes' object or an '0x' prefixed string."
  97                 )
  98     elif is_string_type(abi_type) and is_string(value):
  99         return
  100 
  101     raise TypeError(
  102         "The following abi value is not a '{abi_type}': {value}"
  103         .format(abi_type=abi_type, value=value)
  104     )
  105 
  106 
  107 def validate_address(value):
  108     """
  109     Helper function for validating an address
  110     """
  111     if not isinstance(value, str):
  112         raise TypeError('Address {} must be provided as a string'.format(value))
  113     if not is_hex_address(value):
  114         raise InvalidAddress("Address must be 20 bytes, as a hex string with a 0x prefix", value)
  115     if not is_checksum_address(value):
  116         raise InvalidAddress("Address has an invalid EIP checksum", value)
  117 
  118 
  119 def has_one_val(*args, **kwargs):
  120     vals = itertools.chain(args, kwargs.values())
  121     not_nones = list(filter(lambda val: val is not None, vals))
  122     return len(not_nones) == 1
  123 
  124 
  125 def assert_one_val(*args, **kwargs):
  126     if not has_one_val(*args, **kwargs):
  127         raise TypeError(
  128             "Exactly one of the passed values can be specified. "
  129             "Instead, values were: %r, %r" % (args, kwargs)
  130         )
  131
  [end of web3/utils/validation.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/web3/utils/validation.py b/web3/utils/validation.py
  --- a/web3/utils/validation.py
  +++ b/web3/utils/validation.py
  @@ -113,7 +113,21 @@
       if not is_hex_address(value):
           raise InvalidAddress("Address must be 20 bytes, as a hex string with a 0x prefix", value)
       if not is_checksum_address(value):
  -        raise InvalidAddress("Address has an invalid EIP checksum", value)
  +        if value == value.lower():
  +            raise InvalidAddress(
  +                "Web3.py only accepts checksum addresses. "
  +                "The software that gave you this non-checksum address should be considered unsafe, "
  +                "please file it as a bug on their platform. "
  +                "Try using an ENS name instead. Or, if you must accept lower safety, "
  +                "use Web3.toChecksumAddress(lower_case_address).",
  +                value,
  +            )
  +        else:
  +            raise InvalidAddress(
  +                "Address has an invalid EIP-55 checksum. "
  +                "After looking up the address from the original source, try again.",
  +                value,
  +            )
   
   
   def has_one_val(*args, **kwargs):
  
verification_info: {"golden_diff": "diff --git a/web3/utils/validation.py b/web3/utils/validation.py\n--- a/web3/utils/validation.py\n+++ b/web3/utils/validation.py\n@@ -113,7 +113,21 @@\n     if not is_hex_address(value):\n         raise InvalidAddress(\"Address must be 20 bytes, as a hex string with a 0x prefix\", value)\n     if not is_checksum_address(value):\n-        raise InvalidAddress(\"Address has an invalid EIP checksum\", value)\n+        if value == value.lower():\n+            raise InvalidAddress(\n+                \"Web3.py only accepts checksum addresses. \"\n+                \"The software that gave you this non-checksum address should be considered unsafe, \"\n+                \"please file it as a bug on their platform. \"\n+                \"Try using an ENS name instead. Or, if you must accept lower safety, \"\n+                \"use Web3.toChecksumAddress(lower_case_address).\",\n+                value,\n+            )\n+        else:\n+            raise InvalidAddress(\n+                \"Address has an invalid EIP-55 checksum. \"\n+                \"After looking up the address from the original source, try again.\",\n+                value,\n+            )\n \n \n def has_one_val(*args, **kwargs):\n", "issue": "Improve warning on failed address checksum\n* Version: 4\r\n\r\n### What was wrong?\r\n\r\nError message about checksum failure isn't clear enough, especially when the address is supplied as all-lower-case.\r\n\r\n### How can it be fixed?\r\n\r\nSpecial-case the warning, so that an all-lower-case address gives a specific warning, along the lines of: \"web3py only accepts checksummed addresses. Please report it as a bug on any project that does not provide you checksummed addresses. In the meantime, you can force an address into checksummed state with `valid_address = w3.toChecksumAddress(questionable_address)` after double-checking that there are no errors in the address. Alternatively, you can use an ENS name in its place.\"\r\n\r\nBut, you know, not a paragraph...\n", "before_files": [{"content": "import itertools\n\nfrom eth_utils import (\n    is_0x_prefixed,\n    is_boolean,\n    is_bytes,\n    is_checksum_address,\n    is_dict,\n    is_hex_address,\n    is_integer,\n    is_list_like,\n    is_string,\n)\n\nfrom web3.exceptions import (\n    InvalidAddress,\n)\nfrom web3.utils.abi import (\n    is_address_type,\n    is_array_type,\n    is_bool_type,\n    is_bytes_type,\n    is_int_type,\n    is_recognized_type,\n    is_string_type,\n    is_uint_type,\n    length_of_array_type,\n    sub_type_of_array_type,\n)\n\n\ndef validate_abi(abi):\n    \"\"\"\n    Helper function for validating an ABI\n    \"\"\"\n    if not is_list_like(abi):\n        raise ValueError(\"'abi' is not a list\")\n    for e in abi:\n        if not is_dict(e):\n            raise ValueError(\"The elements of 'abi' are not all dictionaries\")\n\n\ndef validate_abi_type(abi_type):\n    \"\"\"\n    Helper function for validating an abi_type\n    \"\"\"\n    if not is_recognized_type(abi_type):\n        raise ValueError(\"Unrecognized abi_type: {abi_type}\".format(abi_type=abi_type))\n\n\ndef validate_abi_value(abi_type, value):\n    \"\"\"\n    Helper function for validating a value against the expected abi_type\n    Note: abi_type 'bytes' must either be python3 'bytes' object or ''\n    \"\"\"\n    if is_array_type(abi_type) and is_list_like(value):\n        # validate length\n        specified_length = length_of_array_type(abi_type)\n        if specified_length is not None:\n            if specified_length < 1:\n                raise TypeError(\n                    \"Invalid abi-type: {abi_type}. Length of fixed sized arrays\"\n                    \"must be greater than 0.\"\n                    .format(abi_type=abi_type)\n                )\n            if specified_length != len(value):\n                raise TypeError(\n                    \"The following array length does not the length specified\"\n                    \"by the abi-type, {abi_type}: {value}\"\n                    .format(abi_type=abi_type, value=value)\n                )\n\n        # validate sub_types\n        sub_type = sub_type_of_array_type(abi_type)\n        for v in value:\n            validate_abi_value(sub_type, v)\n        return\n    elif is_bool_type(abi_type) and is_boolean(value):\n        return\n    elif is_uint_type(abi_type) and is_integer(value) and value >= 0:\n        return\n    elif is_int_type(abi_type) and is_integer(value):\n        return\n    elif is_address_type(abi_type):\n        validate_address(value)\n        return\n    elif is_bytes_type(abi_type):\n        if is_bytes(value):\n            return\n        elif is_string(value):\n            if is_0x_prefixed(value):\n                return\n            else:\n                raise TypeError(\n                    \"ABI values of abi-type 'bytes' must be either\"\n                    \"a python3 'bytes' object or an '0x' prefixed string.\"\n                )\n    elif is_string_type(abi_type) and is_string(value):\n        return\n\n    raise TypeError(\n        \"The following abi value is not a '{abi_type}': {value}\"\n        .format(abi_type=abi_type, value=value)\n    )\n\n\ndef validate_address(value):\n    \"\"\"\n    Helper function for validating an address\n    \"\"\"\n    if not isinstance(value, str):\n        raise TypeError('Address {} must be provided as a string'.format(value))\n    if not is_hex_address(value):\n        raise InvalidAddress(\"Address must be 20 bytes, as a hex string with a 0x prefix\", value)\n    if not is_checksum_address(value):\n        raise InvalidAddress(\"Address has an invalid EIP checksum\", value)\n\n\ndef has_one_val(*args, **kwargs):\n    vals = itertools.chain(args, kwargs.values())\n    not_nones = list(filter(lambda val: val is not None, vals))\n    return len(not_nones) == 1\n\n\ndef assert_one_val(*args, **kwargs):\n    if not has_one_val(*args, **kwargs):\n        raise TypeError(\n            \"Exactly one of the passed values can be specified. \"\n            \"Instead, values were: %r, %r\" % (args, kwargs)\n        )\n", "path": "web3/utils/validation.py"}]}