We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Deprecate Response.body_as_unicode


--- 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/response/text.py`
Content:
```
1 """
2 This module implements the TextResponse class which adds encoding handling and
3 discovering (through HTTP headers) to base Response class.
4 
5 See documentation in docs/topics/request-response.rst
6 """
7 
8 from contextlib import suppress
9 from typing import Generator
10 from urllib.parse import urljoin
11 
12 import parsel
13 from w3lib.encoding import (html_body_declared_encoding, html_to_unicode,
14                             http_content_type_encoding, resolve_encoding)
15 from w3lib.html import strip_html5_whitespace
16 
17 from scrapy.http import Request
18 from scrapy.http.response import Response
19 from scrapy.utils.python import memoizemethod_noargs, to_unicode
20 from scrapy.utils.response import get_base_url
21 
22 
23 class TextResponse(Response):
24 
25     _DEFAULT_ENCODING = 'ascii'
26 
27     def __init__(self, *args, **kwargs):
28         self._encoding = kwargs.pop('encoding', None)
29         self._cached_benc = None
30         self._cached_ubody = None
31         self._cached_selector = None
32         super(TextResponse, self).__init__(*args, **kwargs)
33 
34     def _set_url(self, url):
35         if isinstance(url, str):
36             self._url = to_unicode(url, self.encoding)
37         else:
38             super(TextResponse, self)._set_url(url)
39 
40     def _set_body(self, body):
41         self._body = b''  # used by encoding detection
42         if isinstance(body, str):
43             if self._encoding is None:
44                 raise TypeError('Cannot convert unicode body - %s has no encoding' %
45                                 type(self).__name__)
46             self._body = body.encode(self._encoding)
47         else:
48             super(TextResponse, self)._set_body(body)
49 
50     def replace(self, *args, **kwargs):
51         kwargs.setdefault('encoding', self.encoding)
52         return Response.replace(self, *args, **kwargs)
53 
54     @property
55     def encoding(self):
56         return self._declared_encoding() or self._body_inferred_encoding()
57 
58     def _declared_encoding(self):
59         return self._encoding or self._headers_encoding() \
60             or self._body_declared_encoding()
61 
62     def body_as_unicode(self):
63         """Return body as unicode"""
64         return self.text
65 
66     @property
67     def text(self):
68         """ Body as unicode """
69         # access self.encoding before _cached_ubody to make sure
70         # _body_inferred_encoding is called
71         benc = self.encoding
72         if self._cached_ubody is None:
73             charset = 'charset=%s' % benc
74             self._cached_ubody = html_to_unicode(charset, self.body)[1]
75         return self._cached_ubody
76 
77     def urljoin(self, url):
78         """Join this Response's url with a possible relative url to form an
79         absolute interpretation of the latter."""
80         return urljoin(get_base_url(self), url)
81 
82     @memoizemethod_noargs
83     def _headers_encoding(self):
84         content_type = self.headers.get(b'Content-Type', b'')
85         return http_content_type_encoding(to_unicode(content_type))
86 
87     def _body_inferred_encoding(self):
88         if self._cached_benc is None:
89             content_type = to_unicode(self.headers.get(b'Content-Type', b''))
90             benc, ubody = html_to_unicode(content_type, self.body,
91                                           auto_detect_fun=self._auto_detect_fun,
92                                           default_encoding=self._DEFAULT_ENCODING)
93             self._cached_benc = benc
94             self._cached_ubody = ubody
95         return self._cached_benc
96 
97     def _auto_detect_fun(self, text):
98         for enc in (self._DEFAULT_ENCODING, 'utf-8', 'cp1252'):
99             try:
100                 text.decode(enc)
101             except UnicodeError:
102                 continue
103             return resolve_encoding(enc)
104 
105     @memoizemethod_noargs
106     def _body_declared_encoding(self):
107         return html_body_declared_encoding(self.body)
108 
109     @property
110     def selector(self):
111         from scrapy.selector import Selector
112         if self._cached_selector is None:
113             self._cached_selector = Selector(self)
114         return self._cached_selector
115 
116     def xpath(self, query, **kwargs):
117         return self.selector.xpath(query, **kwargs)
118 
119     def css(self, query):
120         return self.selector.css(query)
121 
122     def follow(self, url, callback=None, method='GET', headers=None, body=None,
123                cookies=None, meta=None, encoding=None, priority=0,
124                dont_filter=False, errback=None, cb_kwargs=None, flags=None):
125         # type: (...) -> Request
126         """
127         Return a :class:`~.Request` instance to follow a link ``url``.
128         It accepts the same arguments as ``Request.__init__`` method,
129         but ``url`` can be not only an absolute URL, but also
130 
131         * a relative URL
132         * a :class:`~scrapy.link.Link` object, e.g. the result of
133           :ref:`topics-link-extractors`
134         * a :class:`~scrapy.selector.Selector` object for a ``<link>`` or ``<a>`` element, e.g.
135           ``response.css('a.my_link')[0]``
136         * an attribute :class:`~scrapy.selector.Selector` (not SelectorList), e.g.
137           ``response.css('a::attr(href)')[0]`` or
138           ``response.xpath('//img/@src')[0]``
139 
140         See :ref:`response-follow-example` for usage examples.
141         """
142         if isinstance(url, parsel.Selector):
143             url = _url_from_selector(url)
144         elif isinstance(url, parsel.SelectorList):
145             raise ValueError("SelectorList is not supported")
146         encoding = self.encoding if encoding is None else encoding
147         return super(TextResponse, self).follow(
148             url=url,
149             callback=callback,
150             method=method,
151             headers=headers,
152             body=body,
153             cookies=cookies,
154             meta=meta,
155             encoding=encoding,
156             priority=priority,
157             dont_filter=dont_filter,
158             errback=errback,
159             cb_kwargs=cb_kwargs,
160             flags=flags,
161         )
162 
163     def follow_all(self, urls=None, callback=None, method='GET', headers=None, body=None,
164                    cookies=None, meta=None, encoding=None, priority=0,
165                    dont_filter=False, errback=None, cb_kwargs=None, flags=None,
166                    css=None, xpath=None):
167         # type: (...) -> Generator[Request, None, None]
168         """
169         A generator that produces :class:`~.Request` instances to follow all
170         links in ``urls``. It accepts the same arguments as the :class:`~.Request`'s
171         ``__init__`` method, except that each ``urls`` element does not need to be
172         an absolute URL, it can be any of the following:
173 
174         * a relative URL
175         * a :class:`~scrapy.link.Link` object, e.g. the result of
176           :ref:`topics-link-extractors`
177         * a :class:`~scrapy.selector.Selector` object for a ``<link>`` or ``<a>`` element, e.g.
178           ``response.css('a.my_link')[0]``
179         * an attribute :class:`~scrapy.selector.Selector` (not SelectorList), e.g.
180           ``response.css('a::attr(href)')[0]`` or
181           ``response.xpath('//img/@src')[0]``
182 
183         In addition, ``css`` and ``xpath`` arguments are accepted to perform the link extraction
184         within the ``follow_all`` method (only one of ``urls``, ``css`` and ``xpath`` is accepted).
185 
186         Note that when passing a ``SelectorList`` as argument for the ``urls`` parameter or
187         using the ``css`` or ``xpath`` parameters, this method will not produce requests for
188         selectors from which links cannot be obtained (for instance, anchor tags without an
189         ``href`` attribute)
190         """
191         arguments = [x for x in (urls, css, xpath) if x is not None]
192         if len(arguments) != 1:
193             raise ValueError(
194                 "Please supply exactly one of the following arguments: urls, css, xpath"
195             )
196         if not urls:
197             if css:
198                 urls = self.css(css)
199             if xpath:
200                 urls = self.xpath(xpath)
201         if isinstance(urls, parsel.SelectorList):
202             selectors = urls
203             urls = []
204             for sel in selectors:
205                 with suppress(_InvalidSelector):
206                     urls.append(_url_from_selector(sel))
207         return super(TextResponse, self).follow_all(
208             urls=urls,
209             callback=callback,
210             method=method,
211             headers=headers,
212             body=body,
213             cookies=cookies,
214             meta=meta,
215             encoding=encoding,
216             priority=priority,
217             dont_filter=dont_filter,
218             errback=errback,
219             cb_kwargs=cb_kwargs,
220             flags=flags,
221         )
222 
223 
224 class _InvalidSelector(ValueError):
225     """
226     Raised when a URL cannot be obtained from a Selector
227     """
228 
229 
230 def _url_from_selector(sel):
231     # type: (parsel.Selector) -> str
232     if isinstance(sel.root, str):
233         # e.g. ::attr(href) result
234         return strip_html5_whitespace(sel.root)
235     if not hasattr(sel.root, 'tag'):
236         raise _InvalidSelector("Unsupported selector: %s" % sel)
237     if sel.root.tag not in ('a', 'link'):
238         raise _InvalidSelector("Only <a> and <link> elements are supported; got <%s>" %
239                                sel.root.tag)
240     href = sel.root.get('href')
241     if href is None:
242         raise _InvalidSelector("<%s> element has no href attribute: %s" %
243                                (sel.root.tag, sel))
244     return strip_html5_whitespace(href)
245
```
--- 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/response/text.py b/scrapy/http/response/text.py
--- a/scrapy/http/response/text.py
+++ b/scrapy/http/response/text.py
@@ -5,6 +5,7 @@
 See documentation in docs/topics/request-response.rst
 """
 
+import warnings
 from contextlib import suppress
 from typing import Generator
 from urllib.parse import urljoin
@@ -14,6 +15,7 @@
                             http_content_type_encoding, resolve_encoding)
 from w3lib.html import strip_html5_whitespace
 
+from scrapy.exceptions import ScrapyDeprecationWarning
 from scrapy.http import Request
 from scrapy.http.response import Response
 from scrapy.utils.python import memoizemethod_noargs, to_unicode
@@ -61,6 +63,9 @@
 
     def body_as_unicode(self):
         """Return body as unicode"""
+        warnings.warn('Response.body_as_unicode() is deprecated, '
+                      'please use Response.text instead.',
+                      ScrapyDeprecationWarning)
         return self.text
 
     @property

{"golden_diff": "diff --git a/scrapy/http/response/text.py b/scrapy/http/response/text.py\n--- a/scrapy/http/response/text.py\n+++ b/scrapy/http/response/text.py\n@@ -5,6 +5,7 @@\n See documentation in docs/topics/request-response.rst\n \"\"\"\n \n+import warnings\n from contextlib import suppress\n from typing import Generator\n from urllib.parse import urljoin\n@@ -14,6 +15,7 @@\n                             http_content_type_encoding, resolve_encoding)\n from w3lib.html import strip_html5_whitespace\n \n+from scrapy.exceptions import ScrapyDeprecationWarning\n from scrapy.http import Request\n from scrapy.http.response import Response\n from scrapy.utils.python import memoizemethod_noargs, to_unicode\n@@ -61,6 +63,9 @@\n \n     def body_as_unicode(self):\n         \"\"\"Return body as unicode\"\"\"\n+        warnings.warn('Response.body_as_unicode() is deprecated, '\n+                      'please use Response.text instead.',\n+                      ScrapyDeprecationWarning)\n         return self.text\n \n     @property\n", "issue": "Deprecate Response.body_as_unicode\n\n", "before_files": [{"content": "\"\"\"\nThis module implements the TextResponse class which adds encoding handling and\ndiscovering (through HTTP headers) to base Response class.\n\nSee documentation in docs/topics/request-response.rst\n\"\"\"\n\nfrom contextlib import suppress\nfrom typing import Generator\nfrom urllib.parse import urljoin\n\nimport parsel\nfrom w3lib.encoding import (html_body_declared_encoding, html_to_unicode,\n                            http_content_type_encoding, resolve_encoding)\nfrom w3lib.html import strip_html5_whitespace\n\nfrom scrapy.http import Request\nfrom scrapy.http.response import Response\nfrom scrapy.utils.python import memoizemethod_noargs, to_unicode\nfrom scrapy.utils.response import get_base_url\n\n\nclass TextResponse(Response):\n\n    _DEFAULT_ENCODING = 'ascii'\n\n    def __init__(self, *args, **kwargs):\n        self._encoding = kwargs.pop('encoding', None)\n        self._cached_benc = None\n        self._cached_ubody = None\n        self._cached_selector = None\n        super(TextResponse, self).__init__(*args, **kwargs)\n\n    def _set_url(self, url):\n        if isinstance(url, str):\n            self._url = to_unicode(url, self.encoding)\n        else:\n            super(TextResponse, self)._set_url(url)\n\n    def _set_body(self, body):\n        self._body = b''  # used by encoding detection\n        if isinstance(body, str):\n            if self._encoding is None:\n                raise TypeError('Cannot convert unicode body - %s has no encoding' %\n                                type(self).__name__)\n            self._body = body.encode(self._encoding)\n        else:\n            super(TextResponse, self)._set_body(body)\n\n    def replace(self, *args, **kwargs):\n        kwargs.setdefault('encoding', self.encoding)\n        return Response.replace(self, *args, **kwargs)\n\n    @property\n    def encoding(self):\n        return self._declared_encoding() or self._body_inferred_encoding()\n\n    def _declared_encoding(self):\n        return self._encoding or self._headers_encoding() \\\n            or self._body_declared_encoding()\n\n    def body_as_unicode(self):\n        \"\"\"Return body as unicode\"\"\"\n        return self.text\n\n    @property\n    def text(self):\n        \"\"\" Body as unicode \"\"\"\n        # access self.encoding before _cached_ubody to make sure\n        # _body_inferred_encoding is called\n        benc = self.encoding\n        if self._cached_ubody is None:\n            charset = 'charset=%s' % benc\n            self._cached_ubody = html_to_unicode(charset, self.body)[1]\n        return self._cached_ubody\n\n    def urljoin(self, url):\n        \"\"\"Join this Response's url with a possible relative url to form an\n        absolute interpretation of the latter.\"\"\"\n        return urljoin(get_base_url(self), url)\n\n    @memoizemethod_noargs\n    def _headers_encoding(self):\n        content_type = self.headers.get(b'Content-Type', b'')\n        return http_content_type_encoding(to_unicode(content_type))\n\n    def _body_inferred_encoding(self):\n        if self._cached_benc is None:\n            content_type = to_unicode(self.headers.get(b'Content-Type', b''))\n            benc, ubody = html_to_unicode(content_type, self.body,\n                                          auto_detect_fun=self._auto_detect_fun,\n                                          default_encoding=self._DEFAULT_ENCODING)\n            self._cached_benc = benc\n            self._cached_ubody = ubody\n        return self._cached_benc\n\n    def _auto_detect_fun(self, text):\n        for enc in (self._DEFAULT_ENCODING, 'utf-8', 'cp1252'):\n            try:\n                text.decode(enc)\n            except UnicodeError:\n                continue\n            return resolve_encoding(enc)\n\n    @memoizemethod_noargs\n    def _body_declared_encoding(self):\n        return html_body_declared_encoding(self.body)\n\n    @property\n    def selector(self):\n        from scrapy.selector import Selector\n        if self._cached_selector is None:\n            self._cached_selector = Selector(self)\n        return self._cached_selector\n\n    def xpath(self, query, **kwargs):\n        return self.selector.xpath(query, **kwargs)\n\n    def css(self, query):\n        return self.selector.css(query)\n\n    def follow(self, url, callback=None, method='GET', headers=None, body=None,\n               cookies=None, meta=None, encoding=None, priority=0,\n               dont_filter=False, errback=None, cb_kwargs=None, flags=None):\n        # type: (...) -> Request\n        \"\"\"\n        Return a :class:`~.Request` instance to follow a link ``url``.\n        It accepts the same arguments as ``Request.__init__`` method,\n        but ``url`` can be not only an absolute URL, but also\n\n        * a relative URL\n        * a :class:`~scrapy.link.Link` object, e.g. the result of\n          :ref:`topics-link-extractors`\n        * a :class:`~scrapy.selector.Selector` object for a ``<link>`` or ``<a>`` element, e.g.\n          ``response.css('a.my_link')[0]``\n        * an attribute :class:`~scrapy.selector.Selector` (not SelectorList), e.g.\n          ``response.css('a::attr(href)')[0]`` or\n          ``response.xpath('//img/@src')[0]``\n\n        See :ref:`response-follow-example` for usage examples.\n        \"\"\"\n        if isinstance(url, parsel.Selector):\n            url = _url_from_selector(url)\n        elif isinstance(url, parsel.SelectorList):\n            raise ValueError(\"SelectorList is not supported\")\n        encoding = self.encoding if encoding is None else encoding\n        return super(TextResponse, self).follow(\n            url=url,\n            callback=callback,\n            method=method,\n            headers=headers,\n            body=body,\n            cookies=cookies,\n            meta=meta,\n            encoding=encoding,\n            priority=priority,\n            dont_filter=dont_filter,\n            errback=errback,\n            cb_kwargs=cb_kwargs,\n            flags=flags,\n        )\n\n    def follow_all(self, urls=None, callback=None, method='GET', headers=None, body=None,\n                   cookies=None, meta=None, encoding=None, priority=0,\n                   dont_filter=False, errback=None, cb_kwargs=None, flags=None,\n                   css=None, xpath=None):\n        # type: (...) -> Generator[Request, None, None]\n        \"\"\"\n        A generator that produces :class:`~.Request` instances to follow all\n        links in ``urls``. It accepts the same arguments as the :class:`~.Request`'s\n        ``__init__`` method, except that each ``urls`` element does not need to be\n        an absolute URL, it can be any of the following:\n\n        * a relative URL\n        * a :class:`~scrapy.link.Link` object, e.g. the result of\n          :ref:`topics-link-extractors`\n        * a :class:`~scrapy.selector.Selector` object for a ``<link>`` or ``<a>`` element, e.g.\n          ``response.css('a.my_link')[0]``\n        * an attribute :class:`~scrapy.selector.Selector` (not SelectorList), e.g.\n          ``response.css('a::attr(href)')[0]`` or\n          ``response.xpath('//img/@src')[0]``\n\n        In addition, ``css`` and ``xpath`` arguments are accepted to perform the link extraction\n        within the ``follow_all`` method (only one of ``urls``, ``css`` and ``xpath`` is accepted).\n\n        Note that when passing a ``SelectorList`` as argument for the ``urls`` parameter or\n        using the ``css`` or ``xpath`` parameters, this method will not produce requests for\n        selectors from which links cannot be obtained (for instance, anchor tags without an\n        ``href`` attribute)\n        \"\"\"\n        arguments = [x for x in (urls, css, xpath) if x is not None]\n        if len(arguments) != 1:\n            raise ValueError(\n                \"Please supply exactly one of the following arguments: urls, css, xpath\"\n            )\n        if not urls:\n            if css:\n                urls = self.css(css)\n            if xpath:\n                urls = self.xpath(xpath)\n        if isinstance(urls, parsel.SelectorList):\n            selectors = urls\n            urls = []\n            for sel in selectors:\n                with suppress(_InvalidSelector):\n                    urls.append(_url_from_selector(sel))\n        return super(TextResponse, self).follow_all(\n            urls=urls,\n            callback=callback,\n            method=method,\n            headers=headers,\n            body=body,\n            cookies=cookies,\n            meta=meta,\n            encoding=encoding,\n            priority=priority,\n            dont_filter=dont_filter,\n            errback=errback,\n            cb_kwargs=cb_kwargs,\n            flags=flags,\n        )\n\n\nclass _InvalidSelector(ValueError):\n    \"\"\"\n    Raised when a URL cannot be obtained from a Selector\n    \"\"\"\n\n\ndef _url_from_selector(sel):\n    # type: (parsel.Selector) -> str\n    if isinstance(sel.root, str):\n        # e.g. ::attr(href) result\n        return strip_html5_whitespace(sel.root)\n    if not hasattr(sel.root, 'tag'):\n        raise _InvalidSelector(\"Unsupported selector: %s\" % sel)\n    if sel.root.tag not in ('a', 'link'):\n        raise _InvalidSelector(\"Only <a> and <link> elements are supported; got <%s>\" %\n                               sel.root.tag)\n    href = sel.root.get('href')\n    if href is None:\n        raise _InvalidSelector(\"<%s> element has no href attribute: %s\" %\n                               (sel.root.tag, sel))\n    return strip_html5_whitespace(href)\n", "path": "scrapy/http/response/text.py"}], "after_files": [{"content": "\"\"\"\nThis module implements the TextResponse class which adds encoding handling and\ndiscovering (through HTTP headers) to base Response class.\n\nSee documentation in docs/topics/request-response.rst\n\"\"\"\n\nimport warnings\nfrom contextlib import suppress\nfrom typing import Generator\nfrom urllib.parse import urljoin\n\nimport parsel\nfrom w3lib.encoding import (html_body_declared_encoding, html_to_unicode,\n                            http_content_type_encoding, resolve_encoding)\nfrom w3lib.html import strip_html5_whitespace\n\nfrom scrapy.exceptions import ScrapyDeprecationWarning\nfrom scrapy.http import Request\nfrom scrapy.http.response import Response\nfrom scrapy.utils.python import memoizemethod_noargs, to_unicode\nfrom scrapy.utils.response import get_base_url\n\n\nclass TextResponse(Response):\n\n    _DEFAULT_ENCODING = 'ascii'\n\n    def __init__(self, *args, **kwargs):\n        self._encoding = kwargs.pop('encoding', None)\n        self._cached_benc = None\n        self._cached_ubody = None\n        self._cached_selector = None\n        super(TextResponse, self).__init__(*args, **kwargs)\n\n    def _set_url(self, url):\n        if isinstance(url, str):\n            self._url = to_unicode(url, self.encoding)\n        else:\n            super(TextResponse, self)._set_url(url)\n\n    def _set_body(self, body):\n        self._body = b''  # used by encoding detection\n        if isinstance(body, str):\n            if self._encoding is None:\n                raise TypeError('Cannot convert unicode body - %s has no encoding' %\n                                type(self).__name__)\n            self._body = body.encode(self._encoding)\n        else:\n            super(TextResponse, self)._set_body(body)\n\n    def replace(self, *args, **kwargs):\n        kwargs.setdefault('encoding', self.encoding)\n        return Response.replace(self, *args, **kwargs)\n\n    @property\n    def encoding(self):\n        return self._declared_encoding() or self._body_inferred_encoding()\n\n    def _declared_encoding(self):\n        return self._encoding or self._headers_encoding() \\\n            or self._body_declared_encoding()\n\n    def body_as_unicode(self):\n        \"\"\"Return body as unicode\"\"\"\n        warnings.warn('Response.body_as_unicode() is deprecated, '\n                      'please use Response.text instead.',\n                      ScrapyDeprecationWarning)\n        return self.text\n\n    @property\n    def text(self):\n        \"\"\" Body as unicode \"\"\"\n        # access self.encoding before _cached_ubody to make sure\n        # _body_inferred_encoding is called\n        benc = self.encoding\n        if self._cached_ubody is None:\n            charset = 'charset=%s' % benc\n            self._cached_ubody = html_to_unicode(charset, self.body)[1]\n        return self._cached_ubody\n\n    def urljoin(self, url):\n        \"\"\"Join this Response's url with a possible relative url to form an\n        absolute interpretation of the latter.\"\"\"\n        return urljoin(get_base_url(self), url)\n\n    @memoizemethod_noargs\n    def _headers_encoding(self):\n        content_type = self.headers.get(b'Content-Type', b'')\n        return http_content_type_encoding(to_unicode(content_type))\n\n    def _body_inferred_encoding(self):\n        if self._cached_benc is None:\n            content_type = to_unicode(self.headers.get(b'Content-Type', b''))\n            benc, ubody = html_to_unicode(content_type, self.body,\n                                          auto_detect_fun=self._auto_detect_fun,\n                                          default_encoding=self._DEFAULT_ENCODING)\n            self._cached_benc = benc\n            self._cached_ubody = ubody\n        return self._cached_benc\n\n    def _auto_detect_fun(self, text):\n        for enc in (self._DEFAULT_ENCODING, 'utf-8', 'cp1252'):\n            try:\n                text.decode(enc)\n            except UnicodeError:\n                continue\n            return resolve_encoding(enc)\n\n    @memoizemethod_noargs\n    def _body_declared_encoding(self):\n        return html_body_declared_encoding(self.body)\n\n    @property\n    def selector(self):\n        from scrapy.selector import Selector\n        if self._cached_selector is None:\n            self._cached_selector = Selector(self)\n        return self._cached_selector\n\n    def xpath(self, query, **kwargs):\n        return self.selector.xpath(query, **kwargs)\n\n    def css(self, query):\n        return self.selector.css(query)\n\n    def follow(self, url, callback=None, method='GET', headers=None, body=None,\n               cookies=None, meta=None, encoding=None, priority=0,\n               dont_filter=False, errback=None, cb_kwargs=None, flags=None):\n        # type: (...) -> Request\n        \"\"\"\n        Return a :class:`~.Request` instance to follow a link ``url``.\n        It accepts the same arguments as ``Request.__init__`` method,\n        but ``url`` can be not only an absolute URL, but also\n\n        * a relative URL\n        * a :class:`~scrapy.link.Link` object, e.g. the result of\n          :ref:`topics-link-extractors`\n        * a :class:`~scrapy.selector.Selector` object for a ``<link>`` or ``<a>`` element, e.g.\n          ``response.css('a.my_link')[0]``\n        * an attribute :class:`~scrapy.selector.Selector` (not SelectorList), e.g.\n          ``response.css('a::attr(href)')[0]`` or\n          ``response.xpath('//img/@src')[0]``\n\n        See :ref:`response-follow-example` for usage examples.\n        \"\"\"\n        if isinstance(url, parsel.Selector):\n            url = _url_from_selector(url)\n        elif isinstance(url, parsel.SelectorList):\n            raise ValueError(\"SelectorList is not supported\")\n        encoding = self.encoding if encoding is None else encoding\n        return super(TextResponse, self).follow(\n            url=url,\n            callback=callback,\n            method=method,\n            headers=headers,\n            body=body,\n            cookies=cookies,\n            meta=meta,\n            encoding=encoding,\n            priority=priority,\n            dont_filter=dont_filter,\n            errback=errback,\n            cb_kwargs=cb_kwargs,\n            flags=flags,\n        )\n\n    def follow_all(self, urls=None, callback=None, method='GET', headers=None, body=None,\n                   cookies=None, meta=None, encoding=None, priority=0,\n                   dont_filter=False, errback=None, cb_kwargs=None, flags=None,\n                   css=None, xpath=None):\n        # type: (...) -> Generator[Request, None, None]\n        \"\"\"\n        A generator that produces :class:`~.Request` instances to follow all\n        links in ``urls``. It accepts the same arguments as the :class:`~.Request`'s\n        ``__init__`` method, except that each ``urls`` element does not need to be\n        an absolute URL, it can be any of the following:\n\n        * a relative URL\n        * a :class:`~scrapy.link.Link` object, e.g. the result of\n          :ref:`topics-link-extractors`\n        * a :class:`~scrapy.selector.Selector` object for a ``<link>`` or ``<a>`` element, e.g.\n          ``response.css('a.my_link')[0]``\n        * an attribute :class:`~scrapy.selector.Selector` (not SelectorList), e.g.\n          ``response.css('a::attr(href)')[0]`` or\n          ``response.xpath('//img/@src')[0]``\n\n        In addition, ``css`` and ``xpath`` arguments are accepted to perform the link extraction\n        within the ``follow_all`` method (only one of ``urls``, ``css`` and ``xpath`` is accepted).\n\n        Note that when passing a ``SelectorList`` as argument for the ``urls`` parameter or\n        using the ``css`` or ``xpath`` parameters, this method will not produce requests for\n        selectors from which links cannot be obtained (for instance, anchor tags without an\n        ``href`` attribute)\n        \"\"\"\n        arguments = [x for x in (urls, css, xpath) if x is not None]\n        if len(arguments) != 1:\n            raise ValueError(\n                \"Please supply exactly one of the following arguments: urls, css, xpath\"\n            )\n        if not urls:\n            if css:\n                urls = self.css(css)\n            if xpath:\n                urls = self.xpath(xpath)\n        if isinstance(urls, parsel.SelectorList):\n            selectors = urls\n            urls = []\n            for sel in selectors:\n                with suppress(_InvalidSelector):\n                    urls.append(_url_from_selector(sel))\n        return super(TextResponse, self).follow_all(\n            urls=urls,\n            callback=callback,\n            method=method,\n            headers=headers,\n            body=body,\n            cookies=cookies,\n            meta=meta,\n            encoding=encoding,\n            priority=priority,\n            dont_filter=dont_filter,\n            errback=errback,\n            cb_kwargs=cb_kwargs,\n            flags=flags,\n        )\n\n\nclass _InvalidSelector(ValueError):\n    \"\"\"\n    Raised when a URL cannot be obtained from a Selector\n    \"\"\"\n\n\ndef _url_from_selector(sel):\n    # type: (parsel.Selector) -> str\n    if isinstance(sel.root, str):\n        # e.g. ::attr(href) result\n        return strip_html5_whitespace(sel.root)\n    if not hasattr(sel.root, 'tag'):\n        raise _InvalidSelector(\"Unsupported selector: %s\" % sel)\n    if sel.root.tag not in ('a', 'link'):\n        raise _InvalidSelector(\"Only <a> and <link> elements are supported; got <%s>\" %\n                               sel.root.tag)\n    href = sel.root.get('href')\n    if href is None:\n        raise _InvalidSelector(\"<%s> element has no href attribute: %s\" %\n                               (sel.root.tag, sel))\n    return strip_html5_whitespace(href)\n", "path": "scrapy/http/response/text.py"}]}