We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ValueError when using IPCProvider
* Version: 4.2.1
* Python: 2.7/3.4/3.5
* OS: osx/linux/win


### What was wrong?

When using IPCProvider sometimes ValueError is encountered if the response is incomplete. Looks like in this pull request https://github.com/ethereum/web3.py/pull/785/files the author forgot to add `except ValueError` to IPCProvider  https://github.com/ethereum/web3.py/blob/master/web3/providers/ipc.py#L176

### How can it be fixed?

Add `except ValueError` to IPCProvider.make_request https://github.com/ethereum/web3.py/blob/master/web3/providers/ipc.py#L176


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `web3/utils/encoding.py`
Content:
```
1 # String encodings and numeric representations
2 import json
3 import re
4 
5 from eth_utils import (
6     add_0x_prefix,
7     big_endian_to_int,
8     decode_hex,
9     encode_hex,
10     int_to_big_endian,
11     is_boolean,
12     is_bytes,
13     is_hex,
14     is_integer,
15     is_list_like,
16     remove_0x_prefix,
17     to_hex,
18 )
19 
20 from web3.utils.abi import (
21     is_address_type,
22     is_array_type,
23     is_bool_type,
24     is_bytes_type,
25     is_int_type,
26     is_string_type,
27     is_uint_type,
28     size_of_type,
29     sub_type_of_array_type,
30 )
31 from web3.utils.toolz import (
32     curry,
33 )
34 from web3.utils.validation import (
35     assert_one_val,
36     validate_abi_type,
37     validate_abi_value,
38 )
39 
40 
41 def hex_encode_abi_type(abi_type, value, force_size=None):
42     """
43     Encodes value into a hex string in format of abi_type
44     """
45     validate_abi_type(abi_type)
46     validate_abi_value(abi_type, value)
47 
48     data_size = force_size or size_of_type(abi_type)
49     if is_array_type(abi_type):
50         sub_type = sub_type_of_array_type(abi_type)
51         return "".join([remove_0x_prefix(hex_encode_abi_type(sub_type, v, 256)) for v in value])
52     elif is_bool_type(abi_type):
53         return to_hex_with_size(value, data_size)
54     elif is_uint_type(abi_type):
55         return to_hex_with_size(value, data_size)
56     elif is_int_type(abi_type):
57         return to_hex_twos_compliment(value, data_size)
58     elif is_address_type(abi_type):
59         return pad_hex(value, data_size)
60     elif is_bytes_type(abi_type):
61         if is_bytes(value):
62             return encode_hex(value)
63         else:
64             return value
65     elif is_string_type(abi_type):
66         return to_hex(text=value)
67     else:
68         raise ValueError(
69             "Unsupported ABI type: {0}".format(abi_type)
70         )
71 
72 
73 def to_hex_twos_compliment(value, bit_size):
74     """
75     Converts integer value to twos compliment hex representation with given bit_size
76     """
77     if value >= 0:
78         return to_hex_with_size(value, bit_size)
79 
80     value = (1 << bit_size) + value
81     hex_value = hex(value)
82     hex_value = hex_value.rstrip("L")
83     return hex_value
84 
85 
86 def to_hex_with_size(value, bit_size):
87     """
88     Converts a value to hex with given bit_size:
89     """
90     return pad_hex(to_hex(value), bit_size)
91 
92 
93 def pad_hex(value, bit_size):
94     """
95     Pads a hex string up to the given bit_size
96     """
97     value = remove_0x_prefix(value)
98     return add_0x_prefix(value.zfill(int(bit_size / 4)))
99 
100 
101 def trim_hex(hexstr):
102     if hexstr.startswith('0x0'):
103         hexstr = re.sub('^0x0+', '0x', hexstr)
104         if hexstr == '0x':
105             hexstr = '0x0'
106     return hexstr
107 
108 
109 def to_int(value=None, hexstr=None, text=None):
110     """
111     Converts value to it's integer representation.
112 
113     Values are converted this way:
114 
115      * value:
116        * bytes: big-endian integer
117        * bool: True => 1, False => 0
118      * hexstr: interpret hex as integer
119      * text: interpret as string of digits, like '12' => 12
120     """
121     assert_one_val(value, hexstr=hexstr, text=text)
122 
123     if hexstr is not None:
124         return int(hexstr, 16)
125     elif text is not None:
126         return int(text)
127     elif isinstance(value, bytes):
128         return big_endian_to_int(value)
129     elif isinstance(value, str):
130         raise TypeError("Pass in strings with keyword hexstr or text")
131     else:
132         return int(value)
133 
134 
135 @curry
136 def pad_bytes(fill_with, num_bytes, unpadded):
137     return unpadded.rjust(num_bytes, fill_with)
138 
139 
140 zpad_bytes = pad_bytes(b'\0')
141 
142 
143 def to_bytes(primitive=None, hexstr=None, text=None):
144     assert_one_val(primitive, hexstr=hexstr, text=text)
145 
146     if is_boolean(primitive):
147         return b'\x01' if primitive else b'\x00'
148     elif isinstance(primitive, bytes):
149         return primitive
150     elif is_integer(primitive):
151         return to_bytes(hexstr=to_hex(primitive))
152     elif hexstr is not None:
153         if len(hexstr) % 2:
154             hexstr = '0x0' + remove_0x_prefix(hexstr)
155         return decode_hex(hexstr)
156     elif text is not None:
157         return text.encode('utf-8')
158     raise TypeError("expected an int in first arg, or keyword of hexstr or text")
159 
160 
161 def to_text(primitive=None, hexstr=None, text=None):
162     assert_one_val(primitive, hexstr=hexstr, text=text)
163 
164     if hexstr is not None:
165         return to_bytes(hexstr=hexstr).decode('utf-8')
166     elif text is not None:
167         return text
168     elif isinstance(primitive, str):
169         return to_text(hexstr=primitive)
170     elif isinstance(primitive, bytes):
171         return primitive.decode('utf-8')
172     elif is_integer(primitive):
173         byte_encoding = int_to_big_endian(primitive)
174         return to_text(byte_encoding)
175     raise TypeError("Expected an int, bytes or hexstr.")
176 
177 
178 @curry
179 def text_if_str(to_type, text_or_primitive):
180     '''
181     Convert to a type, assuming that strings can be only unicode text (not a hexstr)
182 
183     @param to_type is a function that takes the arguments (primitive, hexstr=hexstr, text=text),
184         eg~ to_bytes, to_text, to_hex, to_int, etc
185     @param hexstr_or_primitive in bytes, str, or int.
186     '''
187     if isinstance(text_or_primitive, str):
188         (primitive, text) = (None, text_or_primitive)
189     else:
190         (primitive, text) = (text_or_primitive, None)
191     return to_type(primitive, text=text)
192 
193 
194 @curry
195 def hexstr_if_str(to_type, hexstr_or_primitive):
196     '''
197     Convert to a type, assuming that strings can be only hexstr (not unicode text)
198 
199     @param to_type is a function that takes the arguments (primitive, hexstr=hexstr, text=text),
200         eg~ to_bytes, to_text, to_hex, to_int, etc
201     @param text_or_primitive in bytes, str, or int.
202     '''
203     if isinstance(hexstr_or_primitive, str):
204         (primitive, hexstr) = (None, hexstr_or_primitive)
205         if remove_0x_prefix(hexstr) and not is_hex(hexstr):
206             raise ValueError(
207                 "when sending a str, it must be a hex string. Got: {0!r}".format(
208                     hexstr_or_primitive,
209                 )
210             )
211     else:
212         (primitive, hexstr) = (hexstr_or_primitive, None)
213     return to_type(primitive, hexstr=hexstr)
214 
215 
216 class FriendlyJsonSerde:
217     '''
218     Friendly JSON serializer & deserializer
219 
220     When encoding or decoding fails, this class collects
221     information on which fields failed, to show more
222     helpful information in the raised error messages.
223     '''
224     def _json_mapping_errors(self, mapping):
225         for key, val in mapping.items():
226             try:
227                 self._friendly_json_encode(val)
228             except TypeError as exc:
229                 yield "%r: because (%s)" % (key, exc)
230 
231     def _json_list_errors(self, iterable):
232         for index, element in enumerate(iterable):
233             try:
234                 self._friendly_json_encode(element)
235             except TypeError as exc:
236                 yield "%d: because (%s)" % (index, exc)
237 
238     def _friendly_json_encode(self, obj):
239         try:
240             encoded = json.dumps(obj)
241             return encoded
242         except TypeError as full_exception:
243             if hasattr(obj, 'items'):
244                 item_errors = '; '.join(self._json_mapping_errors(obj))
245                 raise TypeError("dict had unencodable value at keys: {{{}}}".format(item_errors))
246             elif is_list_like(obj):
247                 element_errors = '; '.join(self._json_list_errors(obj))
248                 raise TypeError("list had unencodable value at index: [{}]".format(element_errors))
249             else:
250                 raise full_exception
251 
252     def json_decode(self, json_str):
253         try:
254             decoded = json.loads(json_str)
255             return decoded
256         except json.decoder.JSONDecodeError as exc:
257             err_msg = 'Could not decode {} because of {}.'.format(repr(json_str), exc)
258             raise ValueError(err_msg)
259 
260     def json_encode(self, obj):
261         try:
262             return self._friendly_json_encode(obj)
263         except TypeError as exc:
264             raise TypeError("Could not encode to JSON: {}".format(exc))
265 
266 
267 def to_4byte_hex(hex_or_str_or_bytes):
268     size_of_4bytes = 4 * 8
269     byte_str = hexstr_if_str(to_bytes, hex_or_str_or_bytes)
270     if len(byte_str) > 4:
271         raise ValueError(
272             'expected value of size 4 bytes. Got: %d bytes' % len(byte_str)
273         )
274     hex_str = encode_hex(byte_str)
275     return pad_hex(hex_str, size_of_4bytes)
276
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/web3/utils/encoding.py b/web3/utils/encoding.py
--- a/web3/utils/encoding.py
+++ b/web3/utils/encoding.py
@@ -255,7 +255,9 @@
             return decoded
         except json.decoder.JSONDecodeError as exc:
             err_msg = 'Could not decode {} because of {}.'.format(repr(json_str), exc)
-            raise ValueError(err_msg)
+            # Calling code may rely on catching JSONDecodeError to recognize bad json
+            # so we have to re-raise the same type.
+            raise json.decoder.JSONDecodeError(err_msg, exc.doc, exc.pos)
 
     def json_encode(self, obj):
         try:

{"golden_diff": "diff --git a/web3/utils/encoding.py b/web3/utils/encoding.py\n--- a/web3/utils/encoding.py\n+++ b/web3/utils/encoding.py\n@@ -255,7 +255,9 @@\n             return decoded\n         except json.decoder.JSONDecodeError as exc:\n             err_msg = 'Could not decode {} because of {}.'.format(repr(json_str), exc)\n-            raise ValueError(err_msg)\n+            # Calling code may rely on catching JSONDecodeError to recognize bad json\n+            # so we have to re-raise the same type.\n+            raise json.decoder.JSONDecodeError(err_msg, exc.doc, exc.pos)\n \n     def json_encode(self, obj):\n         try:\n", "issue": "ValueError when using IPCProvider\n* Version: 4.2.1\r\n* Python: 2.7/3.4/3.5\r\n* OS: osx/linux/win\r\n\r\n\r\n### What was wrong?\r\n\r\nWhen using IPCProvider sometimes ValueError is encountered if the response is incomplete. Looks like in this pull request https://github.com/ethereum/web3.py/pull/785/files the author forgot to add `except ValueError` to IPCProvider  https://github.com/ethereum/web3.py/blob/master/web3/providers/ipc.py#L176\r\n\r\n### How can it be fixed?\r\n\r\nAdd `except ValueError` to IPCProvider.make_request https://github.com/ethereum/web3.py/blob/master/web3/providers/ipc.py#L176\r\n\n", "before_files": [{"content": "# String encodings and numeric representations\nimport json\nimport re\n\nfrom eth_utils import (\n    add_0x_prefix,\n    big_endian_to_int,\n    decode_hex,\n    encode_hex,\n    int_to_big_endian,\n    is_boolean,\n    is_bytes,\n    is_hex,\n    is_integer,\n    is_list_like,\n    remove_0x_prefix,\n    to_hex,\n)\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_string_type,\n    is_uint_type,\n    size_of_type,\n    sub_type_of_array_type,\n)\nfrom web3.utils.toolz import (\n    curry,\n)\nfrom web3.utils.validation import (\n    assert_one_val,\n    validate_abi_type,\n    validate_abi_value,\n)\n\n\ndef hex_encode_abi_type(abi_type, value, force_size=None):\n    \"\"\"\n    Encodes value into a hex string in format of abi_type\n    \"\"\"\n    validate_abi_type(abi_type)\n    validate_abi_value(abi_type, value)\n\n    data_size = force_size or size_of_type(abi_type)\n    if is_array_type(abi_type):\n        sub_type = sub_type_of_array_type(abi_type)\n        return \"\".join([remove_0x_prefix(hex_encode_abi_type(sub_type, v, 256)) for v in value])\n    elif is_bool_type(abi_type):\n        return to_hex_with_size(value, data_size)\n    elif is_uint_type(abi_type):\n        return to_hex_with_size(value, data_size)\n    elif is_int_type(abi_type):\n        return to_hex_twos_compliment(value, data_size)\n    elif is_address_type(abi_type):\n        return pad_hex(value, data_size)\n    elif is_bytes_type(abi_type):\n        if is_bytes(value):\n            return encode_hex(value)\n        else:\n            return value\n    elif is_string_type(abi_type):\n        return to_hex(text=value)\n    else:\n        raise ValueError(\n            \"Unsupported ABI type: {0}\".format(abi_type)\n        )\n\n\ndef to_hex_twos_compliment(value, bit_size):\n    \"\"\"\n    Converts integer value to twos compliment hex representation with given bit_size\n    \"\"\"\n    if value >= 0:\n        return to_hex_with_size(value, bit_size)\n\n    value = (1 << bit_size) + value\n    hex_value = hex(value)\n    hex_value = hex_value.rstrip(\"L\")\n    return hex_value\n\n\ndef to_hex_with_size(value, bit_size):\n    \"\"\"\n    Converts a value to hex with given bit_size:\n    \"\"\"\n    return pad_hex(to_hex(value), bit_size)\n\n\ndef pad_hex(value, bit_size):\n    \"\"\"\n    Pads a hex string up to the given bit_size\n    \"\"\"\n    value = remove_0x_prefix(value)\n    return add_0x_prefix(value.zfill(int(bit_size / 4)))\n\n\ndef trim_hex(hexstr):\n    if hexstr.startswith('0x0'):\n        hexstr = re.sub('^0x0+', '0x', hexstr)\n        if hexstr == '0x':\n            hexstr = '0x0'\n    return hexstr\n\n\ndef to_int(value=None, hexstr=None, text=None):\n    \"\"\"\n    Converts value to it's integer representation.\n\n    Values are converted this way:\n\n     * value:\n       * bytes: big-endian integer\n       * bool: True => 1, False => 0\n     * hexstr: interpret hex as integer\n     * text: interpret as string of digits, like '12' => 12\n    \"\"\"\n    assert_one_val(value, hexstr=hexstr, text=text)\n\n    if hexstr is not None:\n        return int(hexstr, 16)\n    elif text is not None:\n        return int(text)\n    elif isinstance(value, bytes):\n        return big_endian_to_int(value)\n    elif isinstance(value, str):\n        raise TypeError(\"Pass in strings with keyword hexstr or text\")\n    else:\n        return int(value)\n\n\n@curry\ndef pad_bytes(fill_with, num_bytes, unpadded):\n    return unpadded.rjust(num_bytes, fill_with)\n\n\nzpad_bytes = pad_bytes(b'\\0')\n\n\ndef to_bytes(primitive=None, hexstr=None, text=None):\n    assert_one_val(primitive, hexstr=hexstr, text=text)\n\n    if is_boolean(primitive):\n        return b'\\x01' if primitive else b'\\x00'\n    elif isinstance(primitive, bytes):\n        return primitive\n    elif is_integer(primitive):\n        return to_bytes(hexstr=to_hex(primitive))\n    elif hexstr is not None:\n        if len(hexstr) % 2:\n            hexstr = '0x0' + remove_0x_prefix(hexstr)\n        return decode_hex(hexstr)\n    elif text is not None:\n        return text.encode('utf-8')\n    raise TypeError(\"expected an int in first arg, or keyword of hexstr or text\")\n\n\ndef to_text(primitive=None, hexstr=None, text=None):\n    assert_one_val(primitive, hexstr=hexstr, text=text)\n\n    if hexstr is not None:\n        return to_bytes(hexstr=hexstr).decode('utf-8')\n    elif text is not None:\n        return text\n    elif isinstance(primitive, str):\n        return to_text(hexstr=primitive)\n    elif isinstance(primitive, bytes):\n        return primitive.decode('utf-8')\n    elif is_integer(primitive):\n        byte_encoding = int_to_big_endian(primitive)\n        return to_text(byte_encoding)\n    raise TypeError(\"Expected an int, bytes or hexstr.\")\n\n\n@curry\ndef text_if_str(to_type, text_or_primitive):\n    '''\n    Convert to a type, assuming that strings can be only unicode text (not a hexstr)\n\n    @param to_type is a function that takes the arguments (primitive, hexstr=hexstr, text=text),\n        eg~ to_bytes, to_text, to_hex, to_int, etc\n    @param hexstr_or_primitive in bytes, str, or int.\n    '''\n    if isinstance(text_or_primitive, str):\n        (primitive, text) = (None, text_or_primitive)\n    else:\n        (primitive, text) = (text_or_primitive, None)\n    return to_type(primitive, text=text)\n\n\n@curry\ndef hexstr_if_str(to_type, hexstr_or_primitive):\n    '''\n    Convert to a type, assuming that strings can be only hexstr (not unicode text)\n\n    @param to_type is a function that takes the arguments (primitive, hexstr=hexstr, text=text),\n        eg~ to_bytes, to_text, to_hex, to_int, etc\n    @param text_or_primitive in bytes, str, or int.\n    '''\n    if isinstance(hexstr_or_primitive, str):\n        (primitive, hexstr) = (None, hexstr_or_primitive)\n        if remove_0x_prefix(hexstr) and not is_hex(hexstr):\n            raise ValueError(\n                \"when sending a str, it must be a hex string. Got: {0!r}\".format(\n                    hexstr_or_primitive,\n                )\n            )\n    else:\n        (primitive, hexstr) = (hexstr_or_primitive, None)\n    return to_type(primitive, hexstr=hexstr)\n\n\nclass FriendlyJsonSerde:\n    '''\n    Friendly JSON serializer & deserializer\n\n    When encoding or decoding fails, this class collects\n    information on which fields failed, to show more\n    helpful information in the raised error messages.\n    '''\n    def _json_mapping_errors(self, mapping):\n        for key, val in mapping.items():\n            try:\n                self._friendly_json_encode(val)\n            except TypeError as exc:\n                yield \"%r: because (%s)\" % (key, exc)\n\n    def _json_list_errors(self, iterable):\n        for index, element in enumerate(iterable):\n            try:\n                self._friendly_json_encode(element)\n            except TypeError as exc:\n                yield \"%d: because (%s)\" % (index, exc)\n\n    def _friendly_json_encode(self, obj):\n        try:\n            encoded = json.dumps(obj)\n            return encoded\n        except TypeError as full_exception:\n            if hasattr(obj, 'items'):\n                item_errors = '; '.join(self._json_mapping_errors(obj))\n                raise TypeError(\"dict had unencodable value at keys: {{{}}}\".format(item_errors))\n            elif is_list_like(obj):\n                element_errors = '; '.join(self._json_list_errors(obj))\n                raise TypeError(\"list had unencodable value at index: [{}]\".format(element_errors))\n            else:\n                raise full_exception\n\n    def json_decode(self, json_str):\n        try:\n            decoded = json.loads(json_str)\n            return decoded\n        except json.decoder.JSONDecodeError as exc:\n            err_msg = 'Could not decode {} because of {}.'.format(repr(json_str), exc)\n            raise ValueError(err_msg)\n\n    def json_encode(self, obj):\n        try:\n            return self._friendly_json_encode(obj)\n        except TypeError as exc:\n            raise TypeError(\"Could not encode to JSON: {}\".format(exc))\n\n\ndef to_4byte_hex(hex_or_str_or_bytes):\n    size_of_4bytes = 4 * 8\n    byte_str = hexstr_if_str(to_bytes, hex_or_str_or_bytes)\n    if len(byte_str) > 4:\n        raise ValueError(\n            'expected value of size 4 bytes. Got: %d bytes' % len(byte_str)\n        )\n    hex_str = encode_hex(byte_str)\n    return pad_hex(hex_str, size_of_4bytes)\n", "path": "web3/utils/encoding.py"}], "after_files": [{"content": "# String encodings and numeric representations\nimport json\nimport re\n\nfrom eth_utils import (\n    add_0x_prefix,\n    big_endian_to_int,\n    decode_hex,\n    encode_hex,\n    int_to_big_endian,\n    is_boolean,\n    is_bytes,\n    is_hex,\n    is_integer,\n    is_list_like,\n    remove_0x_prefix,\n    to_hex,\n)\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_string_type,\n    is_uint_type,\n    size_of_type,\n    sub_type_of_array_type,\n)\nfrom web3.utils.toolz import (\n    curry,\n)\nfrom web3.utils.validation import (\n    assert_one_val,\n    validate_abi_type,\n    validate_abi_value,\n)\n\n\ndef hex_encode_abi_type(abi_type, value, force_size=None):\n    \"\"\"\n    Encodes value into a hex string in format of abi_type\n    \"\"\"\n    validate_abi_type(abi_type)\n    validate_abi_value(abi_type, value)\n\n    data_size = force_size or size_of_type(abi_type)\n    if is_array_type(abi_type):\n        sub_type = sub_type_of_array_type(abi_type)\n        return \"\".join([remove_0x_prefix(hex_encode_abi_type(sub_type, v, 256)) for v in value])\n    elif is_bool_type(abi_type):\n        return to_hex_with_size(value, data_size)\n    elif is_uint_type(abi_type):\n        return to_hex_with_size(value, data_size)\n    elif is_int_type(abi_type):\n        return to_hex_twos_compliment(value, data_size)\n    elif is_address_type(abi_type):\n        return pad_hex(value, data_size)\n    elif is_bytes_type(abi_type):\n        if is_bytes(value):\n            return encode_hex(value)\n        else:\n            return value\n    elif is_string_type(abi_type):\n        return to_hex(text=value)\n    else:\n        raise ValueError(\n            \"Unsupported ABI type: {0}\".format(abi_type)\n        )\n\n\ndef to_hex_twos_compliment(value, bit_size):\n    \"\"\"\n    Converts integer value to twos compliment hex representation with given bit_size\n    \"\"\"\n    if value >= 0:\n        return to_hex_with_size(value, bit_size)\n\n    value = (1 << bit_size) + value\n    hex_value = hex(value)\n    hex_value = hex_value.rstrip(\"L\")\n    return hex_value\n\n\ndef to_hex_with_size(value, bit_size):\n    \"\"\"\n    Converts a value to hex with given bit_size:\n    \"\"\"\n    return pad_hex(to_hex(value), bit_size)\n\n\ndef pad_hex(value, bit_size):\n    \"\"\"\n    Pads a hex string up to the given bit_size\n    \"\"\"\n    value = remove_0x_prefix(value)\n    return add_0x_prefix(value.zfill(int(bit_size / 4)))\n\n\ndef trim_hex(hexstr):\n    if hexstr.startswith('0x0'):\n        hexstr = re.sub('^0x0+', '0x', hexstr)\n        if hexstr == '0x':\n            hexstr = '0x0'\n    return hexstr\n\n\ndef to_int(value=None, hexstr=None, text=None):\n    \"\"\"\n    Converts value to it's integer representation.\n\n    Values are converted this way:\n\n     * value:\n       * bytes: big-endian integer\n       * bool: True => 1, False => 0\n     * hexstr: interpret hex as integer\n     * text: interpret as string of digits, like '12' => 12\n    \"\"\"\n    assert_one_val(value, hexstr=hexstr, text=text)\n\n    if hexstr is not None:\n        return int(hexstr, 16)\n    elif text is not None:\n        return int(text)\n    elif isinstance(value, bytes):\n        return big_endian_to_int(value)\n    elif isinstance(value, str):\n        raise TypeError(\"Pass in strings with keyword hexstr or text\")\n    else:\n        return int(value)\n\n\n@curry\ndef pad_bytes(fill_with, num_bytes, unpadded):\n    return unpadded.rjust(num_bytes, fill_with)\n\n\nzpad_bytes = pad_bytes(b'\\0')\n\n\ndef to_bytes(primitive=None, hexstr=None, text=None):\n    assert_one_val(primitive, hexstr=hexstr, text=text)\n\n    if is_boolean(primitive):\n        return b'\\x01' if primitive else b'\\x00'\n    elif isinstance(primitive, bytes):\n        return primitive\n    elif is_integer(primitive):\n        return to_bytes(hexstr=to_hex(primitive))\n    elif hexstr is not None:\n        if len(hexstr) % 2:\n            hexstr = '0x0' + remove_0x_prefix(hexstr)\n        return decode_hex(hexstr)\n    elif text is not None:\n        return text.encode('utf-8')\n    raise TypeError(\"expected an int in first arg, or keyword of hexstr or text\")\n\n\ndef to_text(primitive=None, hexstr=None, text=None):\n    assert_one_val(primitive, hexstr=hexstr, text=text)\n\n    if hexstr is not None:\n        return to_bytes(hexstr=hexstr).decode('utf-8')\n    elif text is not None:\n        return text\n    elif isinstance(primitive, str):\n        return to_text(hexstr=primitive)\n    elif isinstance(primitive, bytes):\n        return primitive.decode('utf-8')\n    elif is_integer(primitive):\n        byte_encoding = int_to_big_endian(primitive)\n        return to_text(byte_encoding)\n    raise TypeError(\"Expected an int, bytes or hexstr.\")\n\n\n@curry\ndef text_if_str(to_type, text_or_primitive):\n    '''\n    Convert to a type, assuming that strings can be only unicode text (not a hexstr)\n\n    @param to_type is a function that takes the arguments (primitive, hexstr=hexstr, text=text),\n        eg~ to_bytes, to_text, to_hex, to_int, etc\n    @param hexstr_or_primitive in bytes, str, or int.\n    '''\n    if isinstance(text_or_primitive, str):\n        (primitive, text) = (None, text_or_primitive)\n    else:\n        (primitive, text) = (text_or_primitive, None)\n    return to_type(primitive, text=text)\n\n\n@curry\ndef hexstr_if_str(to_type, hexstr_or_primitive):\n    '''\n    Convert to a type, assuming that strings can be only hexstr (not unicode text)\n\n    @param to_type is a function that takes the arguments (primitive, hexstr=hexstr, text=text),\n        eg~ to_bytes, to_text, to_hex, to_int, etc\n    @param text_or_primitive in bytes, str, or int.\n    '''\n    if isinstance(hexstr_or_primitive, str):\n        (primitive, hexstr) = (None, hexstr_or_primitive)\n        if remove_0x_prefix(hexstr) and not is_hex(hexstr):\n            raise ValueError(\n                \"when sending a str, it must be a hex string. Got: {0!r}\".format(\n                    hexstr_or_primitive,\n                )\n            )\n    else:\n        (primitive, hexstr) = (hexstr_or_primitive, None)\n    return to_type(primitive, hexstr=hexstr)\n\n\nclass FriendlyJsonSerde:\n    '''\n    Friendly JSON serializer & deserializer\n\n    When encoding or decoding fails, this class collects\n    information on which fields failed, to show more\n    helpful information in the raised error messages.\n    '''\n    def _json_mapping_errors(self, mapping):\n        for key, val in mapping.items():\n            try:\n                self._friendly_json_encode(val)\n            except TypeError as exc:\n                yield \"%r: because (%s)\" % (key, exc)\n\n    def _json_list_errors(self, iterable):\n        for index, element in enumerate(iterable):\n            try:\n                self._friendly_json_encode(element)\n            except TypeError as exc:\n                yield \"%d: because (%s)\" % (index, exc)\n\n    def _friendly_json_encode(self, obj):\n        try:\n            encoded = json.dumps(obj)\n            return encoded\n        except TypeError as full_exception:\n            if hasattr(obj, 'items'):\n                item_errors = '; '.join(self._json_mapping_errors(obj))\n                raise TypeError(\"dict had unencodable value at keys: {{{}}}\".format(item_errors))\n            elif is_list_like(obj):\n                element_errors = '; '.join(self._json_list_errors(obj))\n                raise TypeError(\"list had unencodable value at index: [{}]\".format(element_errors))\n            else:\n                raise full_exception\n\n    def json_decode(self, json_str):\n        try:\n            decoded = json.loads(json_str)\n            return decoded\n        except json.decoder.JSONDecodeError as exc:\n            err_msg = 'Could not decode {} because of {}.'.format(repr(json_str), exc)\n            # Calling code may rely on catching JSONDecodeError to recognize bad json\n            # so we have to re-raise the same type.\n            raise json.decoder.JSONDecodeError(err_msg, exc.doc, exc.pos)\n\n    def json_encode(self, obj):\n        try:\n            return self._friendly_json_encode(obj)\n        except TypeError as exc:\n            raise TypeError(\"Could not encode to JSON: {}\".format(exc))\n\n\ndef to_4byte_hex(hex_or_str_or_bytes):\n    size_of_4bytes = 4 * 8\n    byte_str = hexstr_if_str(to_bytes, hex_or_str_or_bytes)\n    if len(byte_str) > 4:\n        raise ValueError(\n            'expected value of size 4 bytes. Got: %d bytes' % len(byte_str)\n        )\n    hex_str = encode_hex(byte_str)\n    return pad_hex(hex_str, size_of_4bytes)\n", "path": "web3/utils/encoding.py"}]}