We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Remove Python 2 code from WrappedRequest
[The WrappedRequest class](https://github.com/scrapy/scrapy/blob/06f3d12c1208c380f9f1a16cb36ba2dfa3c244c5/scrapy/http/cookies.py#L148) has methods that can be removed, as [they were only used in Python 3.3 and earlier](https://docs.python.org/3/library/http.cookiejar.html#http.cookiejar.CookieJar.extract_cookies).

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scrapy/http/cookies.py`
Content:
```
1 import re
2 import time
3 from http.cookiejar import CookieJar as _CookieJar, DefaultCookiePolicy
4 
5 from scrapy.utils.httpobj import urlparse_cached
6 from scrapy.utils.python import to_unicode
7 
8 
9 # Defined in the http.cookiejar module, but undocumented:
10 # https://github.com/python/cpython/blob/v3.9.0/Lib/http/cookiejar.py#L527
11 IPV4_RE = re.compile(r"\.\d+$", re.ASCII)
12 
13 
14 class CookieJar:
15     def __init__(self, policy=None, check_expired_frequency=10000):
16         self.policy = policy or DefaultCookiePolicy()
17         self.jar = _CookieJar(self.policy)
18         self.jar._cookies_lock = _DummyLock()
19         self.check_expired_frequency = check_expired_frequency
20         self.processed = 0
21 
22     def extract_cookies(self, response, request):
23         wreq = WrappedRequest(request)
24         wrsp = WrappedResponse(response)
25         return self.jar.extract_cookies(wrsp, wreq)
26 
27     def add_cookie_header(self, request):
28         wreq = WrappedRequest(request)
29         self.policy._now = self.jar._now = int(time.time())
30 
31         # the cookiejar implementation iterates through all domains
32         # instead we restrict to potential matches on the domain
33         req_host = urlparse_cached(request).hostname
34         if not req_host:
35             return
36 
37         if not IPV4_RE.search(req_host):
38             hosts = potential_domain_matches(req_host)
39             if '.' not in req_host:
40                 hosts += [req_host + ".local"]
41         else:
42             hosts = [req_host]
43 
44         cookies = []
45         for host in hosts:
46             if host in self.jar._cookies:
47                 cookies += self.jar._cookies_for_domain(host, wreq)
48 
49         attrs = self.jar._cookie_attrs(cookies)
50         if attrs:
51             if not wreq.has_header("Cookie"):
52                 wreq.add_unredirected_header("Cookie", "; ".join(attrs))
53 
54         self.processed += 1
55         if self.processed % self.check_expired_frequency == 0:
56             # This is still quite inefficient for large number of cookies
57             self.jar.clear_expired_cookies()
58 
59     @property
60     def _cookies(self):
61         return self.jar._cookies
62 
63     def clear_session_cookies(self, *args, **kwargs):
64         return self.jar.clear_session_cookies(*args, **kwargs)
65 
66     def clear(self, domain=None, path=None, name=None):
67         return self.jar.clear(domain, path, name)
68 
69     def __iter__(self):
70         return iter(self.jar)
71 
72     def __len__(self):
73         return len(self.jar)
74 
75     def set_policy(self, pol):
76         return self.jar.set_policy(pol)
77 
78     def make_cookies(self, response, request):
79         wreq = WrappedRequest(request)
80         wrsp = WrappedResponse(response)
81         return self.jar.make_cookies(wrsp, wreq)
82 
83     def set_cookie(self, cookie):
84         self.jar.set_cookie(cookie)
85 
86     def set_cookie_if_ok(self, cookie, request):
87         self.jar.set_cookie_if_ok(cookie, WrappedRequest(request))
88 
89 
90 def potential_domain_matches(domain):
91     """Potential domain matches for a cookie
92 
93     >>> potential_domain_matches('www.example.com')
94     ['www.example.com', 'example.com', '.www.example.com', '.example.com']
95 
96     """
97     matches = [domain]
98     try:
99         start = domain.index('.') + 1
100         end = domain.rindex('.')
101         while start < end:
102             matches.append(domain[start:])
103             start = domain.index('.', start) + 1
104     except ValueError:
105         pass
106     return matches + ['.' + d for d in matches]
107 
108 
109 class _DummyLock:
110     def acquire(self):
111         pass
112 
113     def release(self):
114         pass
115 
116 
117 class WrappedRequest:
118     """Wraps a scrapy Request class with methods defined by urllib2.Request class to interact with CookieJar class
119 
120     see http://docs.python.org/library/urllib2.html#urllib2.Request
121     """
122 
123     def __init__(self, request):
124         self.request = request
125 
126     def get_full_url(self):
127         return self.request.url
128 
129     def get_host(self):
130         return urlparse_cached(self.request).netloc
131 
132     def get_type(self):
133         return urlparse_cached(self.request).scheme
134 
135     def is_unverifiable(self):
136         """Unverifiable should indicate whether the request is unverifiable, as defined by RFC 2965.
137 
138         It defaults to False. An unverifiable request is one whose URL the user did not have the
139         option to approve. For example, if the request is for an image in an
140         HTML document, and the user had no option to approve the automatic
141         fetching of the image, this should be true.
142         """
143         return self.request.meta.get('is_unverifiable', False)
144 
145     def get_origin_req_host(self):
146         return urlparse_cached(self.request).hostname
147 
148     # python3 uses attributes instead of methods
149     @property
150     def full_url(self):
151         return self.get_full_url()
152 
153     @property
154     def host(self):
155         return self.get_host()
156 
157     @property
158     def type(self):
159         return self.get_type()
160 
161     @property
162     def unverifiable(self):
163         return self.is_unverifiable()
164 
165     @property
166     def origin_req_host(self):
167         return self.get_origin_req_host()
168 
169     def has_header(self, name):
170         return name in self.request.headers
171 
172     def get_header(self, name, default=None):
173         return to_unicode(self.request.headers.get(name, default),
174                           errors='replace')
175 
176     def header_items(self):
177         return [
178             (to_unicode(k, errors='replace'),
179              [to_unicode(x, errors='replace') for x in v])
180             for k, v in self.request.headers.items()
181         ]
182 
183     def add_unredirected_header(self, name, value):
184         self.request.headers.appendlist(name, value)
185 
186 
187 class WrappedResponse:
188 
189     def __init__(self, response):
190         self.response = response
191 
192     def info(self):
193         return self
194 
195     def get_all(self, name, default=None):
196         return [to_unicode(v, errors='replace')
197                 for v in self.response.headers.getlist(name)]
198
```
--- 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/scrapy/http/cookies.py b/scrapy/http/cookies.py
--- a/scrapy/http/cookies.py
+++ b/scrapy/http/cookies.py
@@ -142,10 +142,6 @@
         """
         return self.request.meta.get('is_unverifiable', False)
 
-    def get_origin_req_host(self):
-        return urlparse_cached(self.request).hostname
-
-    # python3 uses attributes instead of methods
     @property
     def full_url(self):
         return self.get_full_url()
@@ -164,7 +160,7 @@
 
     @property
     def origin_req_host(self):
-        return self.get_origin_req_host()
+        return urlparse_cached(self.request).hostname
 
     def has_header(self, name):
         return name in self.request.headers

{"golden_diff": "diff --git a/scrapy/http/cookies.py b/scrapy/http/cookies.py\n--- a/scrapy/http/cookies.py\n+++ b/scrapy/http/cookies.py\n@@ -142,10 +142,6 @@\n         \"\"\"\n         return self.request.meta.get('is_unverifiable', False)\n \n-    def get_origin_req_host(self):\n-        return urlparse_cached(self.request).hostname\n-\n-    # python3 uses attributes instead of methods\n     @property\n     def full_url(self):\n         return self.get_full_url()\n@@ -164,7 +160,7 @@\n \n     @property\n     def origin_req_host(self):\n-        return self.get_origin_req_host()\n+        return urlparse_cached(self.request).hostname\n \n     def has_header(self, name):\n         return name in self.request.headers\n", "issue": "Remove Python 2 code from WrappedRequest\n[The WrappedRequest class](https://github.com/scrapy/scrapy/blob/06f3d12c1208c380f9f1a16cb36ba2dfa3c244c5/scrapy/http/cookies.py#L148) has methods that can be removed, as [they were only used in Python 3.3 and earlier](https://docs.python.org/3/library/http.cookiejar.html#http.cookiejar.CookieJar.extract_cookies).\n", "before_files": [{"content": "import re\nimport time\nfrom http.cookiejar import CookieJar as _CookieJar, DefaultCookiePolicy\n\nfrom scrapy.utils.httpobj import urlparse_cached\nfrom scrapy.utils.python import to_unicode\n\n\n# Defined in the http.cookiejar module, but undocumented:\n# https://github.com/python/cpython/blob/v3.9.0/Lib/http/cookiejar.py#L527\nIPV4_RE = re.compile(r\"\\.\\d+$\", re.ASCII)\n\n\nclass CookieJar:\n    def __init__(self, policy=None, check_expired_frequency=10000):\n        self.policy = policy or DefaultCookiePolicy()\n        self.jar = _CookieJar(self.policy)\n        self.jar._cookies_lock = _DummyLock()\n        self.check_expired_frequency = check_expired_frequency\n        self.processed = 0\n\n    def extract_cookies(self, response, request):\n        wreq = WrappedRequest(request)\n        wrsp = WrappedResponse(response)\n        return self.jar.extract_cookies(wrsp, wreq)\n\n    def add_cookie_header(self, request):\n        wreq = WrappedRequest(request)\n        self.policy._now = self.jar._now = int(time.time())\n\n        # the cookiejar implementation iterates through all domains\n        # instead we restrict to potential matches on the domain\n        req_host = urlparse_cached(request).hostname\n        if not req_host:\n            return\n\n        if not IPV4_RE.search(req_host):\n            hosts = potential_domain_matches(req_host)\n            if '.' not in req_host:\n                hosts += [req_host + \".local\"]\n        else:\n            hosts = [req_host]\n\n        cookies = []\n        for host in hosts:\n            if host in self.jar._cookies:\n                cookies += self.jar._cookies_for_domain(host, wreq)\n\n        attrs = self.jar._cookie_attrs(cookies)\n        if attrs:\n            if not wreq.has_header(\"Cookie\"):\n                wreq.add_unredirected_header(\"Cookie\", \"; \".join(attrs))\n\n        self.processed += 1\n        if self.processed % self.check_expired_frequency == 0:\n            # This is still quite inefficient for large number of cookies\n            self.jar.clear_expired_cookies()\n\n    @property\n    def _cookies(self):\n        return self.jar._cookies\n\n    def clear_session_cookies(self, *args, **kwargs):\n        return self.jar.clear_session_cookies(*args, **kwargs)\n\n    def clear(self, domain=None, path=None, name=None):\n        return self.jar.clear(domain, path, name)\n\n    def __iter__(self):\n        return iter(self.jar)\n\n    def __len__(self):\n        return len(self.jar)\n\n    def set_policy(self, pol):\n        return self.jar.set_policy(pol)\n\n    def make_cookies(self, response, request):\n        wreq = WrappedRequest(request)\n        wrsp = WrappedResponse(response)\n        return self.jar.make_cookies(wrsp, wreq)\n\n    def set_cookie(self, cookie):\n        self.jar.set_cookie(cookie)\n\n    def set_cookie_if_ok(self, cookie, request):\n        self.jar.set_cookie_if_ok(cookie, WrappedRequest(request))\n\n\ndef potential_domain_matches(domain):\n    \"\"\"Potential domain matches for a cookie\n\n    >>> potential_domain_matches('www.example.com')\n    ['www.example.com', 'example.com', '.www.example.com', '.example.com']\n\n    \"\"\"\n    matches = [domain]\n    try:\n        start = domain.index('.') + 1\n        end = domain.rindex('.')\n        while start < end:\n            matches.append(domain[start:])\n            start = domain.index('.', start) + 1\n    except ValueError:\n        pass\n    return matches + ['.' + d for d in matches]\n\n\nclass _DummyLock:\n    def acquire(self):\n        pass\n\n    def release(self):\n        pass\n\n\nclass WrappedRequest:\n    \"\"\"Wraps a scrapy Request class with methods defined by urllib2.Request class to interact with CookieJar class\n\n    see http://docs.python.org/library/urllib2.html#urllib2.Request\n    \"\"\"\n\n    def __init__(self, request):\n        self.request = request\n\n    def get_full_url(self):\n        return self.request.url\n\n    def get_host(self):\n        return urlparse_cached(self.request).netloc\n\n    def get_type(self):\n        return urlparse_cached(self.request).scheme\n\n    def is_unverifiable(self):\n        \"\"\"Unverifiable should indicate whether the request is unverifiable, as defined by RFC 2965.\n\n        It defaults to False. An unverifiable request is one whose URL the user did not have the\n        option to approve. For example, if the request is for an image in an\n        HTML document, and the user had no option to approve the automatic\n        fetching of the image, this should be true.\n        \"\"\"\n        return self.request.meta.get('is_unverifiable', False)\n\n    def get_origin_req_host(self):\n        return urlparse_cached(self.request).hostname\n\n    # python3 uses attributes instead of methods\n    @property\n    def full_url(self):\n        return self.get_full_url()\n\n    @property\n    def host(self):\n        return self.get_host()\n\n    @property\n    def type(self):\n        return self.get_type()\n\n    @property\n    def unverifiable(self):\n        return self.is_unverifiable()\n\n    @property\n    def origin_req_host(self):\n        return self.get_origin_req_host()\n\n    def has_header(self, name):\n        return name in self.request.headers\n\n    def get_header(self, name, default=None):\n        return to_unicode(self.request.headers.get(name, default),\n                          errors='replace')\n\n    def header_items(self):\n        return [\n            (to_unicode(k, errors='replace'),\n             [to_unicode(x, errors='replace') for x in v])\n            for k, v in self.request.headers.items()\n        ]\n\n    def add_unredirected_header(self, name, value):\n        self.request.headers.appendlist(name, value)\n\n\nclass WrappedResponse:\n\n    def __init__(self, response):\n        self.response = response\n\n    def info(self):\n        return self\n\n    def get_all(self, name, default=None):\n        return [to_unicode(v, errors='replace')\n                for v in self.response.headers.getlist(name)]\n", "path": "scrapy/http/cookies.py"}], "after_files": [{"content": "import re\nimport time\nfrom http.cookiejar import CookieJar as _CookieJar, DefaultCookiePolicy\n\nfrom scrapy.utils.httpobj import urlparse_cached\nfrom scrapy.utils.python import to_unicode\n\n\n# Defined in the http.cookiejar module, but undocumented:\n# https://github.com/python/cpython/blob/v3.9.0/Lib/http/cookiejar.py#L527\nIPV4_RE = re.compile(r\"\\.\\d+$\", re.ASCII)\n\n\nclass CookieJar:\n    def __init__(self, policy=None, check_expired_frequency=10000):\n        self.policy = policy or DefaultCookiePolicy()\n        self.jar = _CookieJar(self.policy)\n        self.jar._cookies_lock = _DummyLock()\n        self.check_expired_frequency = check_expired_frequency\n        self.processed = 0\n\n    def extract_cookies(self, response, request):\n        wreq = WrappedRequest(request)\n        wrsp = WrappedResponse(response)\n        return self.jar.extract_cookies(wrsp, wreq)\n\n    def add_cookie_header(self, request):\n        wreq = WrappedRequest(request)\n        self.policy._now = self.jar._now = int(time.time())\n\n        # the cookiejar implementation iterates through all domains\n        # instead we restrict to potential matches on the domain\n        req_host = urlparse_cached(request).hostname\n        if not req_host:\n            return\n\n        if not IPV4_RE.search(req_host):\n            hosts = potential_domain_matches(req_host)\n            if '.' not in req_host:\n                hosts += [req_host + \".local\"]\n        else:\n            hosts = [req_host]\n\n        cookies = []\n        for host in hosts:\n            if host in self.jar._cookies:\n                cookies += self.jar._cookies_for_domain(host, wreq)\n\n        attrs = self.jar._cookie_attrs(cookies)\n        if attrs:\n            if not wreq.has_header(\"Cookie\"):\n                wreq.add_unredirected_header(\"Cookie\", \"; \".join(attrs))\n\n        self.processed += 1\n        if self.processed % self.check_expired_frequency == 0:\n            # This is still quite inefficient for large number of cookies\n            self.jar.clear_expired_cookies()\n\n    @property\n    def _cookies(self):\n        return self.jar._cookies\n\n    def clear_session_cookies(self, *args, **kwargs):\n        return self.jar.clear_session_cookies(*args, **kwargs)\n\n    def clear(self, domain=None, path=None, name=None):\n        return self.jar.clear(domain, path, name)\n\n    def __iter__(self):\n        return iter(self.jar)\n\n    def __len__(self):\n        return len(self.jar)\n\n    def set_policy(self, pol):\n        return self.jar.set_policy(pol)\n\n    def make_cookies(self, response, request):\n        wreq = WrappedRequest(request)\n        wrsp = WrappedResponse(response)\n        return self.jar.make_cookies(wrsp, wreq)\n\n    def set_cookie(self, cookie):\n        self.jar.set_cookie(cookie)\n\n    def set_cookie_if_ok(self, cookie, request):\n        self.jar.set_cookie_if_ok(cookie, WrappedRequest(request))\n\n\ndef potential_domain_matches(domain):\n    \"\"\"Potential domain matches for a cookie\n\n    >>> potential_domain_matches('www.example.com')\n    ['www.example.com', 'example.com', '.www.example.com', '.example.com']\n\n    \"\"\"\n    matches = [domain]\n    try:\n        start = domain.index('.') + 1\n        end = domain.rindex('.')\n        while start < end:\n            matches.append(domain[start:])\n            start = domain.index('.', start) + 1\n    except ValueError:\n        pass\n    return matches + ['.' + d for d in matches]\n\n\nclass _DummyLock:\n    def acquire(self):\n        pass\n\n    def release(self):\n        pass\n\n\nclass WrappedRequest:\n    \"\"\"Wraps a scrapy Request class with methods defined by urllib2.Request class to interact with CookieJar class\n\n    see http://docs.python.org/library/urllib2.html#urllib2.Request\n    \"\"\"\n\n    def __init__(self, request):\n        self.request = request\n\n    def get_full_url(self):\n        return self.request.url\n\n    def get_host(self):\n        return urlparse_cached(self.request).netloc\n\n    def get_type(self):\n        return urlparse_cached(self.request).scheme\n\n    def is_unverifiable(self):\n        \"\"\"Unverifiable should indicate whether the request is unverifiable, as defined by RFC 2965.\n\n        It defaults to False. An unverifiable request is one whose URL the user did not have the\n        option to approve. For example, if the request is for an image in an\n        HTML document, and the user had no option to approve the automatic\n        fetching of the image, this should be true.\n        \"\"\"\n        return self.request.meta.get('is_unverifiable', False)\n\n    @property\n    def full_url(self):\n        return self.get_full_url()\n\n    @property\n    def host(self):\n        return self.get_host()\n\n    @property\n    def type(self):\n        return self.get_type()\n\n    @property\n    def unverifiable(self):\n        return self.is_unverifiable()\n\n    @property\n    def origin_req_host(self):\n        return urlparse_cached(self.request).hostname\n\n    def has_header(self, name):\n        return name in self.request.headers\n\n    def get_header(self, name, default=None):\n        return to_unicode(self.request.headers.get(name, default),\n                          errors='replace')\n\n    def header_items(self):\n        return [\n            (to_unicode(k, errors='replace'),\n             [to_unicode(x, errors='replace') for x in v])\n            for k, v in self.request.headers.items()\n        ]\n\n    def add_unredirected_header(self, name, value):\n        self.request.headers.appendlist(name, value)\n\n\nclass WrappedResponse:\n\n    def __init__(self, response):\n        self.response = response\n\n    def info(self):\n        return self\n\n    def get_all(self, name, default=None):\n        return [to_unicode(v, errors='replace')\n                for v in self.response.headers.getlist(name)]\n", "path": "scrapy/http/cookies.py"}]}