We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
web: broken header behavior
Yes, I know its deprecated, I'm going to fix it anyways.

headers bleed between web requests because we're using `update` on `default_headers`.

``` python
web.get('http://google.com/')
# Headers: User-Agent: Sopel/6.3.1 (http://sopel.chat)
web.get('http://google.com/', headers={'some-header': 'value'})
# Headers: User-Agent: Sopel/6.3.1 (http://sopel.chat), some-header: value
web.get('http://google.com/')
# Headers: User-Agent: Sopel/6.3.1 (http://sopel.chat), some-header: value
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sopel/web.py`
Content:
```
1 # coding=utf-8
2 """
3 *Availability: 3+, depreacted in 6.2.0*
4 
5 The web class contains essential web-related functions for interaction with web
6 applications or websites in your modules.  It supports HTTP GET, HTTP POST and
7 HTTP HEAD.
8 """
9 # Copyright © 2008, Sean B. Palmer, inamidst.com
10 # Copyright © 2009, Michael Yanovich <yanovich.1@osu.edu>
11 # Copyright © 2012, Dimitri Molenaars, Tyrope.nl.
12 # Copyright © 2012-2013, Elad Alfassa, <elad@fedoraproject.org>
13 # Licensed under the Eiffel Forum License 2.
14 
15 from __future__ import unicode_literals, absolute_import, print_function, division
16 
17 import re
18 import sys
19 import urllib
20 import os.path
21 import requests
22 
23 from sopel import __version__
24 from sopel.tools import deprecated
25 
26 if sys.version_info.major < 3:
27     import httplib
28     from htmlentitydefs import name2codepoint
29     from urlparse import urlparse
30     from urlparse import urlunparse
31 else:
32     import http.client as httplib
33     from html.entities import name2codepoint
34     from urllib.parse import urlparse
35     from urllib.parse import urlunparse
36     unichr = chr
37     unicode = str
38 
39 try:
40     import ssl
41     if not hasattr(ssl, 'match_hostname'):
42         # Attempt to import ssl_match_hostname from python-backports
43         import backports.ssl_match_hostname
44         ssl.match_hostname = backports.ssl_match_hostname.match_hostname
45         ssl.CertificateError = backports.ssl_match_hostname.CertificateError
46     has_ssl = True
47 except ImportError:
48     has_ssl = False
49 
50 USER_AGENT = 'Sopel/{} (http://sopel.chat)'.format(__version__)
51 default_headers = {'User-Agent': USER_AGENT}
52 ca_certs = None  # Will be overriden when config loads. This is for an edge case.
53 
54 
55 class MockHttpResponse(httplib.HTTPResponse):
56     "Mock HTTPResponse with data that comes from requests."
57     def __init__(self, response):
58         self.headers = response.headers
59         self.status = response.status_code
60         self.reason = response.reason
61         self.close = response.close
62         self.read = response.raw.read
63         self.url = response.url
64 
65     def geturl(self):
66         return self.url
67 
68 
69 # HTTP GET
70 @deprecated
71 def get(uri, timeout=20, headers=None, return_headers=False,
72         limit_bytes=None, verify_ssl=True, dont_decode=False):
73     """Execute an HTTP GET query on `uri`, and return the result. Deprecated.
74 
75     `timeout` is an optional argument, which represents how much time we should
76     wait before throwing a timeout exception. It defaults to 20, but can be set
77     to higher values if you are communicating with a slow web application.
78     `headers` is a dict of HTTP headers to send with the request.  If
79     `return_headers` is True, return a tuple of (bytes, headers)
80 
81     `limit_bytes` is ignored.
82 
83     """
84     if not uri.startswith('http'):
85         uri = "http://" + uri
86     if headers is None:
87         headers = default_headers
88     else:
89         headers = default_headers.update(headers)
90     u = requests.get(uri, timeout=timeout, headers=headers, verify=verify_ssl)
91     bytes = u.content
92     u.close()
93     headers = u.headers
94     if not dont_decode:
95         bytes = u.text
96     if not return_headers:
97         return bytes
98     else:
99         headers['_http_status'] = u.status_code
100         return (bytes, headers)
101 
102 
103 # Get HTTP headers
104 @deprecated
105 def head(uri, timeout=20, headers=None, verify_ssl=True):
106     """Execute an HTTP GET query on `uri`, and return the headers. Deprecated.
107 
108     `timeout` is an optional argument, which represents how much time we should
109     wait before throwing a timeout exception. It defaults to 20, but can be set
110     to higher values if you are communicating with a slow web application.
111 
112     """
113     if not uri.startswith('http'):
114         uri = "http://" + uri
115     if headers is None:
116         headers = default_headers
117     else:
118         headers = default_headers.update(headers)
119     u = requests.get(uri, timeout=timeout, headers=headers, verify=verify_ssl)
120     info = u.headers
121     u.close()
122     return info
123 
124 
125 # HTTP POST
126 @deprecated
127 def post(uri, query, limit_bytes=None, timeout=20, verify_ssl=True, return_headers=False):
128     """Execute an HTTP POST query. Deprecated.
129 
130     `uri` is the target URI, and `query` is the POST data. `headers` is a dict
131     of HTTP headers to send with the request.
132 
133     `limit_bytes` is ignored.
134 
135     """
136     if not uri.startswith('http'):
137         uri = "http://" + uri
138     u = requests.post(uri, timeout=timeout, verify=verify_ssl, data=query)
139     bytes = u.raw.read(limit_bytes)
140     headers = u.headers
141     u.close()
142     if not return_headers:
143         return bytes
144     else:
145         headers['_http_status'] = u.status_code
146         return (bytes, headers)
147 
148 r_entity = re.compile(r'&([^;\s]+);')
149 
150 
151 def entity(match):
152     value = match.group(1).lower()
153     if value.startswith('#x'):
154         return unichr(int(value[2:], 16))
155     elif value.startswith('#'):
156         return unichr(int(value[1:]))
157     elif value in name2codepoint:
158         return unichr(name2codepoint[value])
159     return '[' + value + ']'
160 
161 
162 def decode(html):
163     return r_entity.sub(entity, html)
164 
165 
166 # For internal use in web.py, (modules can use this if they need a urllib
167 # object they can execute read() on) Both handles redirects and makes sure
168 # input URI is UTF-8
169 @deprecated
170 def get_urllib_object(uri, timeout, headers=None, verify_ssl=True, data=None):
171     """Return an HTTPResponse object for `uri` and `timeout` and `headers`. Deprecated
172 
173     """
174 
175     if headers is None:
176         headers = default_headers
177     else:
178         headers = default_headers.update(headers)
179     if data is not None:
180         response = requests.post(uri, timeout=timeout, verify=verify_ssl,
181                                  data=data, headers=headers)
182     else:
183         response = requests.get(uri, timeout=timeout, verify=verify_ssl,
184                                 headers=headers)
185     return MockHttpResponse(response)
186 
187 
188 # Identical to urllib2.quote
189 def quote(string, safe='/'):
190     """Like urllib2.quote but handles unicode properly."""
191     if sys.version_info.major < 3:
192         if isinstance(string, unicode):
193             string = string.encode('utf8')
194         string = urllib.quote(string, safe.encode('utf8'))
195     else:
196         string = urllib.parse.quote(str(string), safe)
197     return string
198 
199 
200 def quote_query(string):
201     """Quotes the query parameters."""
202     parsed = urlparse(string)
203     string = string.replace(parsed.query, quote(parsed.query, "/=&"), 1)
204     return string
205 
206 
207 # Functions for international domain name magic
208 
209 def urlencode_non_ascii(b):
210     regex = '[\x80-\xFF]'
211     if sys.version_info.major > 2:
212         regex = b'[\x80-\xFF]'
213     return re.sub(regex, lambda c: '%%%02x' % ord(c.group(0)), b)
214 
215 
216 def iri_to_uri(iri):
217     parts = urlparse(iri)
218     parts_seq = (part.encode('idna') if parti == 1 else urlencode_non_ascii(part.encode('utf-8')) for parti, part in enumerate(parts))
219     if sys.version_info.major > 2:
220         parts_seq = list(parts_seq)
221 
222     parsed = urlunparse(parts_seq)
223     if sys.version_info.major > 2:
224         return parsed.decode()
225     else:
226         return parsed
227 
228 
229 if sys.version_info.major < 3:
230     urlencode = urllib.urlencode
231 else:
232     urlencode = urllib.parse.urlencode
233
```
--- 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/sopel/web.py b/sopel/web.py
--- a/sopel/web.py
+++ b/sopel/web.py
@@ -86,7 +86,8 @@
     if headers is None:
         headers = default_headers
     else:
-        headers = default_headers.update(headers)
+        tmp = default_headers.copy()
+        headers = tmp.update(headers)
     u = requests.get(uri, timeout=timeout, headers=headers, verify=verify_ssl)
     bytes = u.content
     u.close()
@@ -115,7 +116,8 @@
     if headers is None:
         headers = default_headers
     else:
-        headers = default_headers.update(headers)
+        tmp = default_headers.copy()
+        headers = tmp.update(headers)
     u = requests.get(uri, timeout=timeout, headers=headers, verify=verify_ssl)
     info = u.headers
     u.close()
@@ -175,7 +177,8 @@
     if headers is None:
         headers = default_headers
     else:
-        headers = default_headers.update(headers)
+        tmp = default_headers.copy()
+        headers = tmp.update(headers)
     if data is not None:
         response = requests.post(uri, timeout=timeout, verify=verify_ssl,
                                  data=data, headers=headers)

{"golden_diff": "diff --git a/sopel/web.py b/sopel/web.py\n--- a/sopel/web.py\n+++ b/sopel/web.py\n@@ -86,7 +86,8 @@\n     if headers is None:\n         headers = default_headers\n     else:\n-        headers = default_headers.update(headers)\n+        tmp = default_headers.copy()\n+        headers = tmp.update(headers)\n     u = requests.get(uri, timeout=timeout, headers=headers, verify=verify_ssl)\n     bytes = u.content\n     u.close()\n@@ -115,7 +116,8 @@\n     if headers is None:\n         headers = default_headers\n     else:\n-        headers = default_headers.update(headers)\n+        tmp = default_headers.copy()\n+        headers = tmp.update(headers)\n     u = requests.get(uri, timeout=timeout, headers=headers, verify=verify_ssl)\n     info = u.headers\n     u.close()\n@@ -175,7 +177,8 @@\n     if headers is None:\n         headers = default_headers\n     else:\n-        headers = default_headers.update(headers)\n+        tmp = default_headers.copy()\n+        headers = tmp.update(headers)\n     if data is not None:\n         response = requests.post(uri, timeout=timeout, verify=verify_ssl,\n                                  data=data, headers=headers)\n", "issue": "web: broken header behavior\nYes, I know its deprecated, I'm going to fix it anyways.\n\nheaders bleed between web requests because we're using `update` on `default_headers`.\n\n``` python\nweb.get('http://google.com/')\n# Headers: User-Agent: Sopel/6.3.1 (http://sopel.chat)\nweb.get('http://google.com/', headers={'some-header': 'value'})\n# Headers: User-Agent: Sopel/6.3.1 (http://sopel.chat), some-header: value\nweb.get('http://google.com/')\n# Headers: User-Agent: Sopel/6.3.1 (http://sopel.chat), some-header: value\n```\n\n", "before_files": [{"content": "# coding=utf-8\n\"\"\"\n*Availability: 3+, depreacted in 6.2.0*\n\nThe web class contains essential web-related functions for interaction with web\napplications or websites in your modules.  It supports HTTP GET, HTTP POST and\nHTTP HEAD.\n\"\"\"\n# Copyright \u00a9 2008, Sean B. Palmer, inamidst.com\n# Copyright \u00a9 2009, Michael Yanovich <yanovich.1@osu.edu>\n# Copyright \u00a9 2012, Dimitri Molenaars, Tyrope.nl.\n# Copyright \u00a9 2012-2013, Elad Alfassa, <elad@fedoraproject.org>\n# Licensed under the Eiffel Forum License 2.\n\nfrom __future__ import unicode_literals, absolute_import, print_function, division\n\nimport re\nimport sys\nimport urllib\nimport os.path\nimport requests\n\nfrom sopel import __version__\nfrom sopel.tools import deprecated\n\nif sys.version_info.major < 3:\n    import httplib\n    from htmlentitydefs import name2codepoint\n    from urlparse import urlparse\n    from urlparse import urlunparse\nelse:\n    import http.client as httplib\n    from html.entities import name2codepoint\n    from urllib.parse import urlparse\n    from urllib.parse import urlunparse\n    unichr = chr\n    unicode = str\n\ntry:\n    import ssl\n    if not hasattr(ssl, 'match_hostname'):\n        # Attempt to import ssl_match_hostname from python-backports\n        import backports.ssl_match_hostname\n        ssl.match_hostname = backports.ssl_match_hostname.match_hostname\n        ssl.CertificateError = backports.ssl_match_hostname.CertificateError\n    has_ssl = True\nexcept ImportError:\n    has_ssl = False\n\nUSER_AGENT = 'Sopel/{} (http://sopel.chat)'.format(__version__)\ndefault_headers = {'User-Agent': USER_AGENT}\nca_certs = None  # Will be overriden when config loads. This is for an edge case.\n\n\nclass MockHttpResponse(httplib.HTTPResponse):\n    \"Mock HTTPResponse with data that comes from requests.\"\n    def __init__(self, response):\n        self.headers = response.headers\n        self.status = response.status_code\n        self.reason = response.reason\n        self.close = response.close\n        self.read = response.raw.read\n        self.url = response.url\n\n    def geturl(self):\n        return self.url\n\n\n# HTTP GET\n@deprecated\ndef get(uri, timeout=20, headers=None, return_headers=False,\n        limit_bytes=None, verify_ssl=True, dont_decode=False):\n    \"\"\"Execute an HTTP GET query on `uri`, and return the result. Deprecated.\n\n    `timeout` is an optional argument, which represents how much time we should\n    wait before throwing a timeout exception. It defaults to 20, but can be set\n    to higher values if you are communicating with a slow web application.\n    `headers` is a dict of HTTP headers to send with the request.  If\n    `return_headers` is True, return a tuple of (bytes, headers)\n\n    `limit_bytes` is ignored.\n\n    \"\"\"\n    if not uri.startswith('http'):\n        uri = \"http://\" + uri\n    if headers is None:\n        headers = default_headers\n    else:\n        headers = default_headers.update(headers)\n    u = requests.get(uri, timeout=timeout, headers=headers, verify=verify_ssl)\n    bytes = u.content\n    u.close()\n    headers = u.headers\n    if not dont_decode:\n        bytes = u.text\n    if not return_headers:\n        return bytes\n    else:\n        headers['_http_status'] = u.status_code\n        return (bytes, headers)\n\n\n# Get HTTP headers\n@deprecated\ndef head(uri, timeout=20, headers=None, verify_ssl=True):\n    \"\"\"Execute an HTTP GET query on `uri`, and return the headers. Deprecated.\n\n    `timeout` is an optional argument, which represents how much time we should\n    wait before throwing a timeout exception. It defaults to 20, but can be set\n    to higher values if you are communicating with a slow web application.\n\n    \"\"\"\n    if not uri.startswith('http'):\n        uri = \"http://\" + uri\n    if headers is None:\n        headers = default_headers\n    else:\n        headers = default_headers.update(headers)\n    u = requests.get(uri, timeout=timeout, headers=headers, verify=verify_ssl)\n    info = u.headers\n    u.close()\n    return info\n\n\n# HTTP POST\n@deprecated\ndef post(uri, query, limit_bytes=None, timeout=20, verify_ssl=True, return_headers=False):\n    \"\"\"Execute an HTTP POST query. Deprecated.\n\n    `uri` is the target URI, and `query` is the POST data. `headers` is a dict\n    of HTTP headers to send with the request.\n\n    `limit_bytes` is ignored.\n\n    \"\"\"\n    if not uri.startswith('http'):\n        uri = \"http://\" + uri\n    u = requests.post(uri, timeout=timeout, verify=verify_ssl, data=query)\n    bytes = u.raw.read(limit_bytes)\n    headers = u.headers\n    u.close()\n    if not return_headers:\n        return bytes\n    else:\n        headers['_http_status'] = u.status_code\n        return (bytes, headers)\n\nr_entity = re.compile(r'&([^;\\s]+);')\n\n\ndef entity(match):\n    value = match.group(1).lower()\n    if value.startswith('#x'):\n        return unichr(int(value[2:], 16))\n    elif value.startswith('#'):\n        return unichr(int(value[1:]))\n    elif value in name2codepoint:\n        return unichr(name2codepoint[value])\n    return '[' + value + ']'\n\n\ndef decode(html):\n    return r_entity.sub(entity, html)\n\n\n# For internal use in web.py, (modules can use this if they need a urllib\n# object they can execute read() on) Both handles redirects and makes sure\n# input URI is UTF-8\n@deprecated\ndef get_urllib_object(uri, timeout, headers=None, verify_ssl=True, data=None):\n    \"\"\"Return an HTTPResponse object for `uri` and `timeout` and `headers`. Deprecated\n\n    \"\"\"\n\n    if headers is None:\n        headers = default_headers\n    else:\n        headers = default_headers.update(headers)\n    if data is not None:\n        response = requests.post(uri, timeout=timeout, verify=verify_ssl,\n                                 data=data, headers=headers)\n    else:\n        response = requests.get(uri, timeout=timeout, verify=verify_ssl,\n                                headers=headers)\n    return MockHttpResponse(response)\n\n\n# Identical to urllib2.quote\ndef quote(string, safe='/'):\n    \"\"\"Like urllib2.quote but handles unicode properly.\"\"\"\n    if sys.version_info.major < 3:\n        if isinstance(string, unicode):\n            string = string.encode('utf8')\n        string = urllib.quote(string, safe.encode('utf8'))\n    else:\n        string = urllib.parse.quote(str(string), safe)\n    return string\n\n\ndef quote_query(string):\n    \"\"\"Quotes the query parameters.\"\"\"\n    parsed = urlparse(string)\n    string = string.replace(parsed.query, quote(parsed.query, \"/=&\"), 1)\n    return string\n\n\n# Functions for international domain name magic\n\ndef urlencode_non_ascii(b):\n    regex = '[\\x80-\\xFF]'\n    if sys.version_info.major > 2:\n        regex = b'[\\x80-\\xFF]'\n    return re.sub(regex, lambda c: '%%%02x' % ord(c.group(0)), b)\n\n\ndef iri_to_uri(iri):\n    parts = urlparse(iri)\n    parts_seq = (part.encode('idna') if parti == 1 else urlencode_non_ascii(part.encode('utf-8')) for parti, part in enumerate(parts))\n    if sys.version_info.major > 2:\n        parts_seq = list(parts_seq)\n\n    parsed = urlunparse(parts_seq)\n    if sys.version_info.major > 2:\n        return parsed.decode()\n    else:\n        return parsed\n\n\nif sys.version_info.major < 3:\n    urlencode = urllib.urlencode\nelse:\n    urlencode = urllib.parse.urlencode\n", "path": "sopel/web.py"}], "after_files": [{"content": "# coding=utf-8\n\"\"\"\n*Availability: 3+, depreacted in 6.2.0*\n\nThe web class contains essential web-related functions for interaction with web\napplications or websites in your modules.  It supports HTTP GET, HTTP POST and\nHTTP HEAD.\n\"\"\"\n# Copyright \u00a9 2008, Sean B. Palmer, inamidst.com\n# Copyright \u00a9 2009, Michael Yanovich <yanovich.1@osu.edu>\n# Copyright \u00a9 2012, Dimitri Molenaars, Tyrope.nl.\n# Copyright \u00a9 2012-2013, Elad Alfassa, <elad@fedoraproject.org>\n# Licensed under the Eiffel Forum License 2.\n\nfrom __future__ import unicode_literals, absolute_import, print_function, division\n\nimport re\nimport sys\nimport urllib\nimport os.path\nimport requests\n\nfrom sopel import __version__\nfrom sopel.tools import deprecated\n\nif sys.version_info.major < 3:\n    import httplib\n    from htmlentitydefs import name2codepoint\n    from urlparse import urlparse\n    from urlparse import urlunparse\nelse:\n    import http.client as httplib\n    from html.entities import name2codepoint\n    from urllib.parse import urlparse\n    from urllib.parse import urlunparse\n    unichr = chr\n    unicode = str\n\ntry:\n    import ssl\n    if not hasattr(ssl, 'match_hostname'):\n        # Attempt to import ssl_match_hostname from python-backports\n        import backports.ssl_match_hostname\n        ssl.match_hostname = backports.ssl_match_hostname.match_hostname\n        ssl.CertificateError = backports.ssl_match_hostname.CertificateError\n    has_ssl = True\nexcept ImportError:\n    has_ssl = False\n\nUSER_AGENT = 'Sopel/{} (http://sopel.chat)'.format(__version__)\ndefault_headers = {'User-Agent': USER_AGENT}\nca_certs = None  # Will be overriden when config loads. This is for an edge case.\n\n\nclass MockHttpResponse(httplib.HTTPResponse):\n    \"Mock HTTPResponse with data that comes from requests.\"\n    def __init__(self, response):\n        self.headers = response.headers\n        self.status = response.status_code\n        self.reason = response.reason\n        self.close = response.close\n        self.read = response.raw.read\n        self.url = response.url\n\n    def geturl(self):\n        return self.url\n\n\n# HTTP GET\n@deprecated\ndef get(uri, timeout=20, headers=None, return_headers=False,\n        limit_bytes=None, verify_ssl=True, dont_decode=False):\n    \"\"\"Execute an HTTP GET query on `uri`, and return the result. Deprecated.\n\n    `timeout` is an optional argument, which represents how much time we should\n    wait before throwing a timeout exception. It defaults to 20, but can be set\n    to higher values if you are communicating with a slow web application.\n    `headers` is a dict of HTTP headers to send with the request.  If\n    `return_headers` is True, return a tuple of (bytes, headers)\n\n    `limit_bytes` is ignored.\n\n    \"\"\"\n    if not uri.startswith('http'):\n        uri = \"http://\" + uri\n    if headers is None:\n        headers = default_headers\n    else:\n        tmp = default_headers.copy()\n        headers = tmp.update(headers)\n    u = requests.get(uri, timeout=timeout, headers=headers, verify=verify_ssl)\n    bytes = u.content\n    u.close()\n    headers = u.headers\n    if not dont_decode:\n        bytes = u.text\n    if not return_headers:\n        return bytes\n    else:\n        headers['_http_status'] = u.status_code\n        return (bytes, headers)\n\n\n# Get HTTP headers\n@deprecated\ndef head(uri, timeout=20, headers=None, verify_ssl=True):\n    \"\"\"Execute an HTTP GET query on `uri`, and return the headers. Deprecated.\n\n    `timeout` is an optional argument, which represents how much time we should\n    wait before throwing a timeout exception. It defaults to 20, but can be set\n    to higher values if you are communicating with a slow web application.\n\n    \"\"\"\n    if not uri.startswith('http'):\n        uri = \"http://\" + uri\n    if headers is None:\n        headers = default_headers\n    else:\n        tmp = default_headers.copy()\n        headers = tmp.update(headers)\n    u = requests.get(uri, timeout=timeout, headers=headers, verify=verify_ssl)\n    info = u.headers\n    u.close()\n    return info\n\n\n# HTTP POST\n@deprecated\ndef post(uri, query, limit_bytes=None, timeout=20, verify_ssl=True, return_headers=False):\n    \"\"\"Execute an HTTP POST query. Deprecated.\n\n    `uri` is the target URI, and `query` is the POST data. `headers` is a dict\n    of HTTP headers to send with the request.\n\n    `limit_bytes` is ignored.\n\n    \"\"\"\n    if not uri.startswith('http'):\n        uri = \"http://\" + uri\n    u = requests.post(uri, timeout=timeout, verify=verify_ssl, data=query)\n    bytes = u.raw.read(limit_bytes)\n    headers = u.headers\n    u.close()\n    if not return_headers:\n        return bytes\n    else:\n        headers['_http_status'] = u.status_code\n        return (bytes, headers)\n\nr_entity = re.compile(r'&([^;\\s]+);')\n\n\ndef entity(match):\n    value = match.group(1).lower()\n    if value.startswith('#x'):\n        return unichr(int(value[2:], 16))\n    elif value.startswith('#'):\n        return unichr(int(value[1:]))\n    elif value in name2codepoint:\n        return unichr(name2codepoint[value])\n    return '[' + value + ']'\n\n\ndef decode(html):\n    return r_entity.sub(entity, html)\n\n\n# For internal use in web.py, (modules can use this if they need a urllib\n# object they can execute read() on) Both handles redirects and makes sure\n# input URI is UTF-8\n@deprecated\ndef get_urllib_object(uri, timeout, headers=None, verify_ssl=True, data=None):\n    \"\"\"Return an HTTPResponse object for `uri` and `timeout` and `headers`. Deprecated\n\n    \"\"\"\n\n    if headers is None:\n        headers = default_headers\n    else:\n        tmp = default_headers.copy()\n        headers = tmp.update(headers)\n    if data is not None:\n        response = requests.post(uri, timeout=timeout, verify=verify_ssl,\n                                 data=data, headers=headers)\n    else:\n        response = requests.get(uri, timeout=timeout, verify=verify_ssl,\n                                headers=headers)\n    return MockHttpResponse(response)\n\n\n# Identical to urllib2.quote\ndef quote(string, safe='/'):\n    \"\"\"Like urllib2.quote but handles unicode properly.\"\"\"\n    if sys.version_info.major < 3:\n        if isinstance(string, unicode):\n            string = string.encode('utf8')\n        string = urllib.quote(string, safe.encode('utf8'))\n    else:\n        string = urllib.parse.quote(str(string), safe)\n    return string\n\n\ndef quote_query(string):\n    \"\"\"Quotes the query parameters.\"\"\"\n    parsed = urlparse(string)\n    string = string.replace(parsed.query, quote(parsed.query, \"/=&\"), 1)\n    return string\n\n\n# Functions for international domain name magic\n\ndef urlencode_non_ascii(b):\n    regex = '[\\x80-\\xFF]'\n    if sys.version_info.major > 2:\n        regex = b'[\\x80-\\xFF]'\n    return re.sub(regex, lambda c: '%%%02x' % ord(c.group(0)), b)\n\n\ndef iri_to_uri(iri):\n    parts = urlparse(iri)\n    parts_seq = (part.encode('idna') if parti == 1 else urlencode_non_ascii(part.encode('utf-8')) for parti, part in enumerate(parts))\n    if sys.version_info.major > 2:\n        parts_seq = list(parts_seq)\n\n    parsed = urlunparse(parts_seq)\n    if sys.version_info.major > 2:\n        return parsed.decode()\n    else:\n        return parsed\n\n\nif sys.version_info.major < 3:\n    urlencode = urllib.urlencode\nelse:\n    urlencode = urllib.parse.urlencode\n", "path": "sopel/web.py"}]}