prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Disk queues don't preserve Request class
  When a Request subclass (e.g. FormRequest) is sent to a disk queue a bare Request is what you get back. 
  
  This is inconvenient for scrapy-splash: Splash requests all have Splash URL as request.url, but for logging it is nice to display the requested URL, not only Splash URL. In scrapy-splash this is implemented by changing `__repr__` in a Request subclass, but it works only when request is kept in memory.
  
  
  </issue>
  <code>
  [start of scrapy/utils/reqser.py]
  1 """
  2 Helper functions for serializing (and deserializing) requests.
  3 """
  4 import six
  5 
  6 from scrapy.http import Request
  7 from scrapy.utils.python import to_unicode, to_native_str
  8 
  9 
  10 def request_to_dict(request, spider=None):
  11     """Convert Request object to a dict.
  12 
  13     If a spider is given, it will try to find out the name of the spider method
  14     used in the callback and store that as the callback.
  15     """
  16     cb = request.callback
  17     if callable(cb):
  18         cb = _find_method(spider, cb)
  19     eb = request.errback
  20     if callable(eb):
  21         eb = _find_method(spider, eb)
  22     d = {
  23         'url': to_unicode(request.url),  # urls should be safe (safe_string_url)
  24         'callback': cb,
  25         'errback': eb,
  26         'method': request.method,
  27         'headers': dict(request.headers),
  28         'body': request.body,
  29         'cookies': request.cookies,
  30         'meta': request.meta,
  31         '_encoding': request._encoding,
  32         'priority': request.priority,
  33         'dont_filter': request.dont_filter,
  34     }
  35     return d
  36 
  37 
  38 def request_from_dict(d, spider=None):
  39     """Create Request object from a dict.
  40 
  41     If a spider is given, it will try to resolve the callbacks looking at the
  42     spider for methods with the same name.
  43     """
  44     cb = d['callback']
  45     if cb and spider:
  46         cb = _get_method(spider, cb)
  47     eb = d['errback']
  48     if eb and spider:
  49         eb = _get_method(spider, eb)
  50     return Request(
  51         url=to_native_str(d['url']),
  52         callback=cb,
  53         errback=eb,
  54         method=d['method'],
  55         headers=d['headers'],
  56         body=d['body'],
  57         cookies=d['cookies'],
  58         meta=d['meta'],
  59         encoding=d['_encoding'],
  60         priority=d['priority'],
  61         dont_filter=d['dont_filter'])
  62 
  63 
  64 def _find_method(obj, func):
  65     if obj:
  66         try:
  67             func_self = six.get_method_self(func)
  68         except AttributeError:  # func has no __self__
  69             pass
  70         else:
  71             if func_self is obj:
  72                 return six.get_method_function(func).__name__
  73     raise ValueError("Function %s is not a method of: %s" % (func, obj))
  74 
  75 
  76 def _get_method(obj, name):
  77     name = str(name)
  78     try:
  79         return getattr(obj, name)
  80     except AttributeError:
  81         raise ValueError("Method %r not found in: %s" % (name, obj))
  82
  [end of scrapy/utils/reqser.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/utils/reqser.py b/scrapy/utils/reqser.py
  --- a/scrapy/utils/reqser.py
  +++ b/scrapy/utils/reqser.py
  @@ -5,6 +5,7 @@
   
   from scrapy.http import Request
   from scrapy.utils.python import to_unicode, to_native_str
  +from scrapy.utils.misc import load_object
   
   
   def request_to_dict(request, spider=None):
  @@ -32,6 +33,8 @@
           'priority': request.priority,
           'dont_filter': request.dont_filter,
       }
  +    if type(request) is not Request:
  +        d['_class'] = request.__module__ + '.' + request.__class__.__name__
       return d
   
   
  @@ -47,7 +50,8 @@
       eb = d['errback']
       if eb and spider:
           eb = _get_method(spider, eb)
  -    return Request(
  +    request_cls = load_object(d['_class']) if '_class' in d else Request
  +    return request_cls(
           url=to_native_str(d['url']),
           callback=cb,
           errback=eb,
  
verification_info: {"golden_diff": "diff --git a/scrapy/utils/reqser.py b/scrapy/utils/reqser.py\n--- a/scrapy/utils/reqser.py\n+++ b/scrapy/utils/reqser.py\n@@ -5,6 +5,7 @@\n \n from scrapy.http import Request\n from scrapy.utils.python import to_unicode, to_native_str\n+from scrapy.utils.misc import load_object\n \n \n def request_to_dict(request, spider=None):\n@@ -32,6 +33,8 @@\n         'priority': request.priority,\n         'dont_filter': request.dont_filter,\n     }\n+    if type(request) is not Request:\n+        d['_class'] = request.__module__ + '.' + request.__class__.__name__\n     return d\n \n \n@@ -47,7 +50,8 @@\n     eb = d['errback']\n     if eb and spider:\n         eb = _get_method(spider, eb)\n-    return Request(\n+    request_cls = load_object(d['_class']) if '_class' in d else Request\n+    return request_cls(\n         url=to_native_str(d['url']),\n         callback=cb,\n         errback=eb,\n", "issue": "Disk queues don't preserve Request class\nWhen a Request subclass (e.g. FormRequest) is sent to a disk queue a bare Request is what you get back. \n\nThis is inconvenient for scrapy-splash: Splash requests all have Splash URL as request.url, but for logging it is nice to display the requested URL, not only Splash URL. In scrapy-splash this is implemented by changing `__repr__` in a Request subclass, but it works only when request is kept in memory.\n\n", "before_files": [{"content": "\"\"\"\nHelper functions for serializing (and deserializing) requests.\n\"\"\"\nimport six\n\nfrom scrapy.http import Request\nfrom scrapy.utils.python import to_unicode, to_native_str\n\n\ndef request_to_dict(request, spider=None):\n    \"\"\"Convert Request object to a dict.\n\n    If a spider is given, it will try to find out the name of the spider method\n    used in the callback and store that as the callback.\n    \"\"\"\n    cb = request.callback\n    if callable(cb):\n        cb = _find_method(spider, cb)\n    eb = request.errback\n    if callable(eb):\n        eb = _find_method(spider, eb)\n    d = {\n        'url': to_unicode(request.url),  # urls should be safe (safe_string_url)\n        'callback': cb,\n        'errback': eb,\n        'method': request.method,\n        'headers': dict(request.headers),\n        'body': request.body,\n        'cookies': request.cookies,\n        'meta': request.meta,\n        '_encoding': request._encoding,\n        'priority': request.priority,\n        'dont_filter': request.dont_filter,\n    }\n    return d\n\n\ndef request_from_dict(d, spider=None):\n    \"\"\"Create Request object from a dict.\n\n    If a spider is given, it will try to resolve the callbacks looking at the\n    spider for methods with the same name.\n    \"\"\"\n    cb = d['callback']\n    if cb and spider:\n        cb = _get_method(spider, cb)\n    eb = d['errback']\n    if eb and spider:\n        eb = _get_method(spider, eb)\n    return Request(\n        url=to_native_str(d['url']),\n        callback=cb,\n        errback=eb,\n        method=d['method'],\n        headers=d['headers'],\n        body=d['body'],\n        cookies=d['cookies'],\n        meta=d['meta'],\n        encoding=d['_encoding'],\n        priority=d['priority'],\n        dont_filter=d['dont_filter'])\n\n\ndef _find_method(obj, func):\n    if obj:\n        try:\n            func_self = six.get_method_self(func)\n        except AttributeError:  # func has no __self__\n            pass\n        else:\n            if func_self is obj:\n                return six.get_method_function(func).__name__\n    raise ValueError(\"Function %s is not a method of: %s\" % (func, obj))\n\n\ndef _get_method(obj, name):\n    name = str(name)\n    try:\n        return getattr(obj, name)\n    except AttributeError:\n        raise ValueError(\"Method %r not found in: %s\" % (name, obj))\n", "path": "scrapy/utils/reqser.py"}]}