prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Idea: warn users when trying to use TextResponse functionality with plain Response
  Currently, if we try to use TextResponse functionality like response.text or css()/xpath() methods with a plain Response (e.g. in case of binary content), we get an AttributeError:
  
  ```
  >>> response.css
  ---------------------------------------------------------------------------
  AttributeError                            Traceback (most recent call last)
  <ipython-input-1-7d6e256164d4> in <module>()
  ----> 1 response.css
  
  AttributeError: 'Response' object has no attribute 'css'
  >>> response.xpath
  ---------------------------------------------------------------------------
  AttributeError                            Traceback (most recent call last)
  <ipython-input-2-4f61f6e9fc6e> in <module>()
  ----> 1 response.xpath
  
  AttributeError: 'Response' object has no attribute 'xpath'
  >>> response.text
  ---------------------------------------------------------------------------
  AttributeError                            Traceback (most recent call last)
  <ipython-input-3-be6a4a00df5e> in <module>()
  ----> 1 response.text
  
  AttributeError: 'Response' object has no attribute 'text'
  ```
  
  Would it make sense to add a few methods/properties to explain what's going on for new users?
  
  I was thinking instead of AttributeError, a better behavior could be a ValueError with a message giving a bit more context.
  
  So, in plain `Response`, we could have:
  
  ```
  def css(self, *args, **kw):
      raise ValueError('Response content is not text')
  
  def xpath(self, *args, **kw):
      raise ValueError('Response content is not text')
  
  @property
  def text(self, *args, **kw):
      raise ValueError('Response content is not text')
  ```
  
  This would be nice, because we'd had to explain fewer things when teaching people about responses and also about using `.css` and `.xpath` methods.
  
  What do you think?
  
  
  </issue>
  <code>
  [start of scrapy/http/response/__init__.py]
  1 """
  2 This module implements the Response class which is used to represent HTTP
  3 responses in Scrapy.
  4 
  5 See documentation in docs/topics/request-response.rst
  6 """
  7 from six.moves.urllib.parse import urljoin
  8 
  9 from scrapy.http.headers import Headers
  10 from scrapy.utils.trackref import object_ref
  11 from scrapy.http.common import obsolete_setter
  12 
  13 class Response(object_ref):
  14 
  15     def __init__(self, url, status=200, headers=None, body=b'', flags=None, request=None):
  16         self.headers = Headers(headers or {})
  17         self.status = int(status)
  18         self._set_body(body)
  19         self._set_url(url)
  20         self.request = request
  21         self.flags = [] if flags is None else list(flags)
  22 
  23     @property
  24     def meta(self):
  25         try:
  26             return self.request.meta
  27         except AttributeError:
  28             raise AttributeError(
  29                 "Response.meta not available, this response "
  30                 "is not tied to any request"
  31             )
  32 
  33     def _get_url(self):
  34         return self._url
  35 
  36     def _set_url(self, url):
  37         if isinstance(url, str):
  38             self._url = url
  39         else:
  40             raise TypeError('%s url must be str, got %s:' % (type(self).__name__,
  41                 type(url).__name__))
  42 
  43     url = property(_get_url, obsolete_setter(_set_url, 'url'))
  44 
  45     def _get_body(self):
  46         return self._body
  47 
  48     def _set_body(self, body):
  49         if body is None:
  50             self._body = b''
  51         elif not isinstance(body, bytes):
  52             raise TypeError(
  53                 "Response body must be bytes. "
  54                 "If you want to pass unicode body use TextResponse "
  55                 "or HtmlResponse.")
  56         else:
  57             self._body = body
  58 
  59     body = property(_get_body, obsolete_setter(_set_body, 'body'))
  60 
  61     def __str__(self):
  62         return "<%d %s>" % (self.status, self.url)
  63 
  64     __repr__ = __str__
  65 
  66     def copy(self):
  67         """Return a copy of this Response"""
  68         return self.replace()
  69 
  70     def replace(self, *args, **kwargs):
  71         """Create a new Response with the same attributes except for those
  72         given new values.
  73         """
  74         for x in ['url', 'status', 'headers', 'body', 'request', 'flags']:
  75             kwargs.setdefault(x, getattr(self, x))
  76         cls = kwargs.pop('cls', self.__class__)
  77         return cls(*args, **kwargs)
  78 
  79     def urljoin(self, url):
  80         """Join this Response's url with a possible relative url to form an
  81         absolute interpretation of the latter."""
  82         return urljoin(self.url, url)
  83
  [end of scrapy/http/response/__init__.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/scrapy/http/response/__init__.py b/scrapy/http/response/__init__.py
  --- a/scrapy/http/response/__init__.py
  +++ b/scrapy/http/response/__init__.py
  @@ -9,6 +9,8 @@
   from scrapy.http.headers import Headers
   from scrapy.utils.trackref import object_ref
   from scrapy.http.common import obsolete_setter
  +from scrapy.exceptions import NotSupported
  +
   
   class Response(object_ref):
   
  @@ -80,3 +82,22 @@
           """Join this Response's url with a possible relative url to form an
           absolute interpretation of the latter."""
           return urljoin(self.url, url)
  +
  +    @property
  +    def text(self):
  +        """For subclasses of TextResponse, this will return the body
  +        as text (unicode object in Python 2 and str in Python 3)
  +        """
  +        raise AttributeError("Response content isn't text")
  +
  +    def css(self, *a, **kw):
  +        """Shortcut method implemented only by responses whose content
  +        is text (subclasses of TextResponse).
  +        """
  +        raise NotSupported("Response content isn't text")
  +
  +    def xpath(self, *a, **kw):
  +        """Shortcut method implemented only by responses whose content
  +        is text (subclasses of TextResponse).
  +        """
  +        raise NotSupported("Response content isn't text")
  
verification_info: {"golden_diff": "diff --git a/scrapy/http/response/__init__.py b/scrapy/http/response/__init__.py\n--- a/scrapy/http/response/__init__.py\n+++ b/scrapy/http/response/__init__.py\n@@ -9,6 +9,8 @@\n from scrapy.http.headers import Headers\n from scrapy.utils.trackref import object_ref\n from scrapy.http.common import obsolete_setter\n+from scrapy.exceptions import NotSupported\n+\n \n class Response(object_ref):\n \n@@ -80,3 +82,22 @@\n         \"\"\"Join this Response's url with a possible relative url to form an\n         absolute interpretation of the latter.\"\"\"\n         return urljoin(self.url, url)\n+\n+    @property\n+    def text(self):\n+        \"\"\"For subclasses of TextResponse, this will return the body\n+        as text (unicode object in Python 2 and str in Python 3)\n+        \"\"\"\n+        raise AttributeError(\"Response content isn't text\")\n+\n+    def css(self, *a, **kw):\n+        \"\"\"Shortcut method implemented only by responses whose content\n+        is text (subclasses of TextResponse).\n+        \"\"\"\n+        raise NotSupported(\"Response content isn't text\")\n+\n+    def xpath(self, *a, **kw):\n+        \"\"\"Shortcut method implemented only by responses whose content\n+        is text (subclasses of TextResponse).\n+        \"\"\"\n+        raise NotSupported(\"Response content isn't text\")\n", "issue": "Idea: warn users when trying to use TextResponse functionality with plain Response\nCurrently, if we try to use TextResponse functionality like response.text or css()/xpath() methods with a plain Response (e.g. in case of binary content), we get an AttributeError:\n\n```\n>>> response.css\n---------------------------------------------------------------------------\nAttributeError                            Traceback (most recent call last)\n<ipython-input-1-7d6e256164d4> in <module>()\n----> 1 response.css\n\nAttributeError: 'Response' object has no attribute 'css'\n>>> response.xpath\n---------------------------------------------------------------------------\nAttributeError                            Traceback (most recent call last)\n<ipython-input-2-4f61f6e9fc6e> in <module>()\n----> 1 response.xpath\n\nAttributeError: 'Response' object has no attribute 'xpath'\n>>> response.text\n---------------------------------------------------------------------------\nAttributeError                            Traceback (most recent call last)\n<ipython-input-3-be6a4a00df5e> in <module>()\n----> 1 response.text\n\nAttributeError: 'Response' object has no attribute 'text'\n```\n\nWould it make sense to add a few methods/properties to explain what's going on for new users?\n\nI was thinking instead of AttributeError, a better behavior could be a ValueError with a message giving a bit more context.\n\nSo, in plain `Response`, we could have:\n\n```\ndef css(self, *args, **kw):\n    raise ValueError('Response content is not text')\n\ndef xpath(self, *args, **kw):\n    raise ValueError('Response content is not text')\n\n@property\ndef text(self, *args, **kw):\n    raise ValueError('Response content is not text')\n```\n\nThis would be nice, because we'd had to explain fewer things when teaching people about responses and also about using `.css` and `.xpath` methods.\n\nWhat do you think?\n\n", "before_files": [{"content": "\"\"\"\nThis module implements the Response class which is used to represent HTTP\nresponses in Scrapy.\n\nSee documentation in docs/topics/request-response.rst\n\"\"\"\nfrom six.moves.urllib.parse import urljoin\n\nfrom scrapy.http.headers import Headers\nfrom scrapy.utils.trackref import object_ref\nfrom scrapy.http.common import obsolete_setter\n\nclass Response(object_ref):\n\n    def __init__(self, url, status=200, headers=None, body=b'', flags=None, request=None):\n        self.headers = Headers(headers or {})\n        self.status = int(status)\n        self._set_body(body)\n        self._set_url(url)\n        self.request = request\n        self.flags = [] if flags is None else list(flags)\n\n    @property\n    def meta(self):\n        try:\n            return self.request.meta\n        except AttributeError:\n            raise AttributeError(\n                \"Response.meta not available, this response \"\n                \"is not tied to any request\"\n            )\n\n    def _get_url(self):\n        return self._url\n\n    def _set_url(self, url):\n        if isinstance(url, str):\n            self._url = url\n        else:\n            raise TypeError('%s url must be str, got %s:' % (type(self).__name__,\n                type(url).__name__))\n\n    url = property(_get_url, obsolete_setter(_set_url, 'url'))\n\n    def _get_body(self):\n        return self._body\n\n    def _set_body(self, body):\n        if body is None:\n            self._body = b''\n        elif not isinstance(body, bytes):\n            raise TypeError(\n                \"Response body must be bytes. \"\n                \"If you want to pass unicode body use TextResponse \"\n                \"or HtmlResponse.\")\n        else:\n            self._body = body\n\n    body = property(_get_body, obsolete_setter(_set_body, 'body'))\n\n    def __str__(self):\n        return \"<%d %s>\" % (self.status, self.url)\n\n    __repr__ = __str__\n\n    def copy(self):\n        \"\"\"Return a copy of this Response\"\"\"\n        return self.replace()\n\n    def replace(self, *args, **kwargs):\n        \"\"\"Create a new Response with the same attributes except for those\n        given new values.\n        \"\"\"\n        for x in ['url', 'status', 'headers', 'body', 'request', 'flags']:\n            kwargs.setdefault(x, getattr(self, x))\n        cls = kwargs.pop('cls', self.__class__)\n        return cls(*args, **kwargs)\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(self.url, url)\n", "path": "scrapy/http/response/__init__.py"}]}