prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Contracts for FormRequest
  At the moment there's no way to create a contract for a callback that is passed a response from `FormRequest`.
  
  How about something simple like this (`ContractsManager.from_method`):
  ```python
  request = FormRequest(**kwargs) if 'formdata' in kwargs else Request(**kwargs)
  ```
  
  --- 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/contracts/__init__.py`
  Content:
  ```
  1 import sys
  2 import re
  3 from functools import wraps
  4 from inspect import getmembers
  5 from unittest import TestCase
  6 
  7 from scrapy.http import Request
  8 from scrapy.utils.spider import iterate_spider_output
  9 from scrapy.utils.python import get_spec
  10 
  11 
  12 class ContractsManager(object):
  13     contracts = {}
  14 
  15     def __init__(self, contracts):
  16         for contract in contracts:
  17             self.contracts[contract.name] = contract
  18 
  19     def tested_methods_from_spidercls(self, spidercls):
  20         methods = []
  21         for key, value in getmembers(spidercls):
  22             if (callable(value) and value.__doc__ and
  23                     re.search(r'^\s*@', value.__doc__, re.MULTILINE)):
  24                 methods.append(key)
  25 
  26         return methods
  27 
  28     def extract_contracts(self, method):
  29         contracts = []
  30         for line in method.__doc__.split('\n'):
  31             line = line.strip()
  32 
  33             if line.startswith('@'):
  34                 name, args = re.match(r'@(\w+)\s*(.*)', line).groups()
  35                 args = re.split(r'\s+', args)
  36 
  37                 contracts.append(self.contracts[name](method, *args))
  38 
  39         return contracts
  40 
  41     def from_spider(self, spider, results):
  42         requests = []
  43         for method in self.tested_methods_from_spidercls(type(spider)):
  44             bound_method = spider.__getattribute__(method)
  45             requests.append(self.from_method(bound_method, results))
  46 
  47         return requests
  48 
  49     def from_method(self, method, results):
  50         contracts = self.extract_contracts(method)
  51         if contracts:
  52             # calculate request args
  53             args, kwargs = get_spec(Request.__init__)
  54             kwargs['callback'] = method
  55             for contract in contracts:
  56                 kwargs = contract.adjust_request_args(kwargs)
  57 
  58             # create and prepare request
  59             args.remove('self')
  60             if set(args).issubset(set(kwargs)):
  61                 request = Request(**kwargs)
  62 
  63                 # execute pre and post hooks in order
  64                 for contract in reversed(contracts):
  65                     request = contract.add_pre_hook(request, results)
  66                 for contract in contracts:
  67                     request = contract.add_post_hook(request, results)
  68 
  69                 self._clean_req(request, method, results)
  70                 return request
  71 
  72     def _clean_req(self, request, method, results):
  73         """ stop the request from returning objects and records any errors """
  74 
  75         cb = request.callback
  76 
  77         @wraps(cb)
  78         def cb_wrapper(response):
  79             try:
  80                 output = cb(response)
  81                 output = list(iterate_spider_output(output))
  82             except:
  83                 case = _create_testcase(method, 'callback')
  84                 results.addError(case, sys.exc_info())
  85 
  86         def eb_wrapper(failure):
  87             case = _create_testcase(method, 'errback')
  88             exc_info = failure.type, failure.value, failure.getTracebackObject()
  89             results.addError(case, exc_info)
  90 
  91         request.callback = cb_wrapper
  92         request.errback = eb_wrapper
  93 
  94 
  95 class Contract(object):
  96     """ Abstract class for contracts """
  97 
  98     def __init__(self, method, *args):
  99         self.testcase_pre = _create_testcase(method, '@%s pre-hook' % self.name)
  100         self.testcase_post = _create_testcase(method, '@%s post-hook' % self.name)
  101         self.args = args
  102 
  103     def add_pre_hook(self, request, results):
  104         if hasattr(self, 'pre_process'):
  105             cb = request.callback
  106 
  107             @wraps(cb)
  108             def wrapper(response):
  109                 try:
  110                     results.startTest(self.testcase_pre)
  111                     self.pre_process(response)
  112                     results.stopTest(self.testcase_pre)
  113                 except AssertionError:
  114                     results.addFailure(self.testcase_pre, sys.exc_info())
  115                 except Exception:
  116                     results.addError(self.testcase_pre, sys.exc_info())
  117                 else:
  118                     results.addSuccess(self.testcase_pre)
  119                 finally:
  120                     return list(iterate_spider_output(cb(response)))
  121 
  122             request.callback = wrapper
  123 
  124         return request
  125 
  126     def add_post_hook(self, request, results):
  127         if hasattr(self, 'post_process'):
  128             cb = request.callback
  129 
  130             @wraps(cb)
  131             def wrapper(response):
  132                 output = list(iterate_spider_output(cb(response)))
  133                 try:
  134                     results.startTest(self.testcase_post)
  135                     self.post_process(output)
  136                     results.stopTest(self.testcase_post)
  137                 except AssertionError:
  138                     results.addFailure(self.testcase_post, sys.exc_info())
  139                 except Exception:
  140                     results.addError(self.testcase_post, sys.exc_info())
  141                 else:
  142                     results.addSuccess(self.testcase_post)
  143                 finally:
  144                     return output
  145 
  146             request.callback = wrapper
  147 
  148         return request
  149 
  150     def adjust_request_args(self, args):
  151         return args
  152 
  153 
  154 def _create_testcase(method, desc):
  155     spider = method.__self__.name
  156 
  157     class ContractTestCase(TestCase):
  158         def __str__(_self):
  159             return "[%s] %s (%s)" % (spider, method.__name__, desc)
  160 
  161     name = '%s_%s' % (spider, method.__name__)
  162     setattr(ContractTestCase, name, lambda x: x)
  163     return ContractTestCase(name)
  164
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/scrapy/contracts/__init__.py b/scrapy/contracts/__init__.py
  --- a/scrapy/contracts/__init__.py
  +++ b/scrapy/contracts/__init__.py
  @@ -49,16 +49,22 @@
       def from_method(self, method, results):
           contracts = self.extract_contracts(method)
           if contracts:
  +            request_cls = Request
  +            for contract in contracts:
  +                if contract.request_cls is not None:
  +                    request_cls = contract.request_cls
  +
               # calculate request args
  -            args, kwargs = get_spec(Request.__init__)
  +            args, kwargs = get_spec(request_cls.__init__)
               kwargs['callback'] = method
               for contract in contracts:
                   kwargs = contract.adjust_request_args(kwargs)
   
  -            # create and prepare request
               args.remove('self')
  +
  +            # check if all positional arguments are defined in kwargs
               if set(args).issubset(set(kwargs)):
  -                request = Request(**kwargs)
  +                request = request_cls(**kwargs)
   
                   # execute pre and post hooks in order
                   for contract in reversed(contracts):
  @@ -94,6 +100,7 @@
   
   class Contract(object):
       """ Abstract class for contracts """
  +    request_cls = None
   
       def __init__(self, method, *args):
           self.testcase_pre = _create_testcase(method, '@%s pre-hook' % self.name)
  
verification_info: {"golden_diff": "diff --git a/scrapy/contracts/__init__.py b/scrapy/contracts/__init__.py\n--- a/scrapy/contracts/__init__.py\n+++ b/scrapy/contracts/__init__.py\n@@ -49,16 +49,22 @@\n     def from_method(self, method, results):\n         contracts = self.extract_contracts(method)\n         if contracts:\n+            request_cls = Request\n+            for contract in contracts:\n+                if contract.request_cls is not None:\n+                    request_cls = contract.request_cls\n+\n             # calculate request args\n-            args, kwargs = get_spec(Request.__init__)\n+            args, kwargs = get_spec(request_cls.__init__)\n             kwargs['callback'] = method\n             for contract in contracts:\n                 kwargs = contract.adjust_request_args(kwargs)\n \n-            # create and prepare request\n             args.remove('self')\n+\n+            # check if all positional arguments are defined in kwargs\n             if set(args).issubset(set(kwargs)):\n-                request = Request(**kwargs)\n+                request = request_cls(**kwargs)\n \n                 # execute pre and post hooks in order\n                 for contract in reversed(contracts):\n@@ -94,6 +100,7 @@\n \n class Contract(object):\n     \"\"\" Abstract class for contracts \"\"\"\n+    request_cls = None\n \n     def __init__(self, method, *args):\n         self.testcase_pre = _create_testcase(method, '@%s pre-hook' % self.name)\n", "issue": "Contracts for FormRequest\nAt the moment there's no way to create a contract for a callback that is passed a response from `FormRequest`.\r\n\r\nHow about something simple like this (`ContractsManager.from_method`):\r\n```python\r\nrequest = FormRequest(**kwargs) if 'formdata' in kwargs else Request(**kwargs)\r\n```\n", "before_files": [{"content": "import sys\nimport re\nfrom functools import wraps\nfrom inspect import getmembers\nfrom unittest import TestCase\n\nfrom scrapy.http import Request\nfrom scrapy.utils.spider import iterate_spider_output\nfrom scrapy.utils.python import get_spec\n\n\nclass ContractsManager(object):\n    contracts = {}\n\n    def __init__(self, contracts):\n        for contract in contracts:\n            self.contracts[contract.name] = contract\n\n    def tested_methods_from_spidercls(self, spidercls):\n        methods = []\n        for key, value in getmembers(spidercls):\n            if (callable(value) and value.__doc__ and\n                    re.search(r'^\\s*@', value.__doc__, re.MULTILINE)):\n                methods.append(key)\n\n        return methods\n\n    def extract_contracts(self, method):\n        contracts = []\n        for line in method.__doc__.split('\\n'):\n            line = line.strip()\n\n            if line.startswith('@'):\n                name, args = re.match(r'@(\\w+)\\s*(.*)', line).groups()\n                args = re.split(r'\\s+', args)\n\n                contracts.append(self.contracts[name](method, *args))\n\n        return contracts\n\n    def from_spider(self, spider, results):\n        requests = []\n        for method in self.tested_methods_from_spidercls(type(spider)):\n            bound_method = spider.__getattribute__(method)\n            requests.append(self.from_method(bound_method, results))\n\n        return requests\n\n    def from_method(self, method, results):\n        contracts = self.extract_contracts(method)\n        if contracts:\n            # calculate request args\n            args, kwargs = get_spec(Request.__init__)\n            kwargs['callback'] = method\n            for contract in contracts:\n                kwargs = contract.adjust_request_args(kwargs)\n\n            # create and prepare request\n            args.remove('self')\n            if set(args).issubset(set(kwargs)):\n                request = Request(**kwargs)\n\n                # execute pre and post hooks in order\n                for contract in reversed(contracts):\n                    request = contract.add_pre_hook(request, results)\n                for contract in contracts:\n                    request = contract.add_post_hook(request, results)\n\n                self._clean_req(request, method, results)\n                return request\n\n    def _clean_req(self, request, method, results):\n        \"\"\" stop the request from returning objects and records any errors \"\"\"\n\n        cb = request.callback\n\n        @wraps(cb)\n        def cb_wrapper(response):\n            try:\n                output = cb(response)\n                output = list(iterate_spider_output(output))\n            except:\n                case = _create_testcase(method, 'callback')\n                results.addError(case, sys.exc_info())\n\n        def eb_wrapper(failure):\n            case = _create_testcase(method, 'errback')\n            exc_info = failure.type, failure.value, failure.getTracebackObject()\n            results.addError(case, exc_info)\n\n        request.callback = cb_wrapper\n        request.errback = eb_wrapper\n\n\nclass Contract(object):\n    \"\"\" Abstract class for contracts \"\"\"\n\n    def __init__(self, method, *args):\n        self.testcase_pre = _create_testcase(method, '@%s pre-hook' % self.name)\n        self.testcase_post = _create_testcase(method, '@%s post-hook' % self.name)\n        self.args = args\n\n    def add_pre_hook(self, request, results):\n        if hasattr(self, 'pre_process'):\n            cb = request.callback\n\n            @wraps(cb)\n            def wrapper(response):\n                try:\n                    results.startTest(self.testcase_pre)\n                    self.pre_process(response)\n                    results.stopTest(self.testcase_pre)\n                except AssertionError:\n                    results.addFailure(self.testcase_pre, sys.exc_info())\n                except Exception:\n                    results.addError(self.testcase_pre, sys.exc_info())\n                else:\n                    results.addSuccess(self.testcase_pre)\n                finally:\n                    return list(iterate_spider_output(cb(response)))\n\n            request.callback = wrapper\n\n        return request\n\n    def add_post_hook(self, request, results):\n        if hasattr(self, 'post_process'):\n            cb = request.callback\n\n            @wraps(cb)\n            def wrapper(response):\n                output = list(iterate_spider_output(cb(response)))\n                try:\n                    results.startTest(self.testcase_post)\n                    self.post_process(output)\n                    results.stopTest(self.testcase_post)\n                except AssertionError:\n                    results.addFailure(self.testcase_post, sys.exc_info())\n                except Exception:\n                    results.addError(self.testcase_post, sys.exc_info())\n                else:\n                    results.addSuccess(self.testcase_post)\n                finally:\n                    return output\n\n            request.callback = wrapper\n\n        return request\n\n    def adjust_request_args(self, args):\n        return args\n\n\ndef _create_testcase(method, desc):\n    spider = method.__self__.name\n\n    class ContractTestCase(TestCase):\n        def __str__(_self):\n            return \"[%s] %s (%s)\" % (spider, method.__name__, desc)\n\n    name = '%s_%s' % (spider, method.__name__)\n    setattr(ContractTestCase, name, lambda x: x)\n    return ContractTestCase(name)\n", "path": "scrapy/contracts/__init__.py"}], "after_files": [{"content": "import sys\nimport re\nfrom functools import wraps\nfrom inspect import getmembers\nfrom unittest import TestCase\n\nfrom scrapy.http import Request\nfrom scrapy.utils.spider import iterate_spider_output\nfrom scrapy.utils.python import get_spec\n\n\nclass ContractsManager(object):\n    contracts = {}\n\n    def __init__(self, contracts):\n        for contract in contracts:\n            self.contracts[contract.name] = contract\n\n    def tested_methods_from_spidercls(self, spidercls):\n        methods = []\n        for key, value in getmembers(spidercls):\n            if (callable(value) and value.__doc__ and\n                    re.search(r'^\\s*@', value.__doc__, re.MULTILINE)):\n                methods.append(key)\n\n        return methods\n\n    def extract_contracts(self, method):\n        contracts = []\n        for line in method.__doc__.split('\\n'):\n            line = line.strip()\n\n            if line.startswith('@'):\n                name, args = re.match(r'@(\\w+)\\s*(.*)', line).groups()\n                args = re.split(r'\\s+', args)\n\n                contracts.append(self.contracts[name](method, *args))\n\n        return contracts\n\n    def from_spider(self, spider, results):\n        requests = []\n        for method in self.tested_methods_from_spidercls(type(spider)):\n            bound_method = spider.__getattribute__(method)\n            requests.append(self.from_method(bound_method, results))\n\n        return requests\n\n    def from_method(self, method, results):\n        contracts = self.extract_contracts(method)\n        if contracts:\n            request_cls = Request\n            for contract in contracts:\n                if contract.request_cls is not None:\n                    request_cls = contract.request_cls\n\n            # calculate request args\n            args, kwargs = get_spec(request_cls.__init__)\n            kwargs['callback'] = method\n            for contract in contracts:\n                kwargs = contract.adjust_request_args(kwargs)\n\n            args.remove('self')\n\n            # check if all positional arguments are defined in kwargs\n            if set(args).issubset(set(kwargs)):\n                request = request_cls(**kwargs)\n\n                # execute pre and post hooks in order\n                for contract in reversed(contracts):\n                    request = contract.add_pre_hook(request, results)\n                for contract in contracts:\n                    request = contract.add_post_hook(request, results)\n\n                self._clean_req(request, method, results)\n                return request\n\n    def _clean_req(self, request, method, results):\n        \"\"\" stop the request from returning objects and records any errors \"\"\"\n\n        cb = request.callback\n\n        @wraps(cb)\n        def cb_wrapper(response):\n            try:\n                output = cb(response)\n                output = list(iterate_spider_output(output))\n            except:\n                case = _create_testcase(method, 'callback')\n                results.addError(case, sys.exc_info())\n\n        def eb_wrapper(failure):\n            case = _create_testcase(method, 'errback')\n            exc_info = failure.type, failure.value, failure.getTracebackObject()\n            results.addError(case, exc_info)\n\n        request.callback = cb_wrapper\n        request.errback = eb_wrapper\n\n\nclass Contract(object):\n    \"\"\" Abstract class for contracts \"\"\"\n    request_cls = None\n\n    def __init__(self, method, *args):\n        self.testcase_pre = _create_testcase(method, '@%s pre-hook' % self.name)\n        self.testcase_post = _create_testcase(method, '@%s post-hook' % self.name)\n        self.args = args\n\n    def add_pre_hook(self, request, results):\n        if hasattr(self, 'pre_process'):\n            cb = request.callback\n\n            @wraps(cb)\n            def wrapper(response):\n                try:\n                    results.startTest(self.testcase_pre)\n                    self.pre_process(response)\n                    results.stopTest(self.testcase_pre)\n                except AssertionError:\n                    results.addFailure(self.testcase_pre, sys.exc_info())\n                except Exception:\n                    results.addError(self.testcase_pre, sys.exc_info())\n                else:\n                    results.addSuccess(self.testcase_pre)\n                finally:\n                    return list(iterate_spider_output(cb(response)))\n\n            request.callback = wrapper\n\n        return request\n\n    def add_post_hook(self, request, results):\n        if hasattr(self, 'post_process'):\n            cb = request.callback\n\n            @wraps(cb)\n            def wrapper(response):\n                output = list(iterate_spider_output(cb(response)))\n                try:\n                    results.startTest(self.testcase_post)\n                    self.post_process(output)\n                    results.stopTest(self.testcase_post)\n                except AssertionError:\n                    results.addFailure(self.testcase_post, sys.exc_info())\n                except Exception:\n                    results.addError(self.testcase_post, sys.exc_info())\n                else:\n                    results.addSuccess(self.testcase_post)\n                finally:\n                    return output\n\n            request.callback = wrapper\n\n        return request\n\n    def adjust_request_args(self, args):\n        return args\n\n\ndef _create_testcase(method, desc):\n    spider = method.__self__.name\n\n    class ContractTestCase(TestCase):\n        def __str__(_self):\n            return \"[%s] %s (%s)\" % (spider, method.__name__, desc)\n\n    name = '%s_%s' % (spider, method.__name__)\n    setattr(ContractTestCase, name, lambda x: x)\n    return ContractTestCase(name)\n", "path": "scrapy/contracts/__init__.py"}]}