We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
prequest does not support PUT
Title says it all.  Give me the green light and I can whip up a patch (no pun intended).


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pyramid/scripts/prequest.py`
Content:
```
1 import optparse
2 import sys
3 import textwrap
4 
5 from pyramid.compat import url_unquote
6 from pyramid.request import Request
7 from pyramid.paster import get_app
8 from pyramid.scripts.common import parse_vars
9 
10 def main(argv=sys.argv, quiet=False):
11     command = PRequestCommand(argv, quiet)
12     return command.run()
13 
14 class PRequestCommand(object):
15     description = """\
16     Run a request for the described application.
17 
18     This command makes an artifical request to a web application that uses a
19     PasteDeploy (.ini) configuration file for the server and application.
20 
21     Use "prequest config.ini /path" to request "/path".  Use "prequest
22     --method=POST config.ini /path < data" to do a POST with the given
23     request body.
24 
25     If the path is relative (doesn't begin with "/") it is interpreted as
26     relative to "/".  The path passed to this script should be URL-quoted.
27     The path can be succeeded with a query string (e.g. `/path?a=1&=b2').
28 
29     The variable "environ['paste.command_request']" will be set to "True" in
30     the request's WSGI environment, so your application can distinguish these
31     calls from normal requests.
32     """
33     usage = "usage: %prog config_uri path_info [args/options]"
34     parser = optparse.OptionParser(
35         usage=usage,
36         description=textwrap.dedent(description)
37         )
38     parser.add_option(
39         '-n', '--app-name',
40         dest='app_name',
41         metavar= 'NAME',
42         help="Load the named application from the config file (default 'main')",
43         type="string",
44         )
45     parser.add_option(
46         '--header',
47         dest='headers',
48         metavar='NAME:VALUE',
49         type='string',
50         action='append',
51         help="Header to add to request (you can use this option multiple times)"
52         )
53     parser.add_option(
54         '-d', '--display-headers',
55         dest='display_headers',
56         action='store_true',
57         help='Display status and headers before the response body'
58         )
59     parser.add_option(
60         '-m', '--method',
61         dest='method',
62         choices=['GET', 'HEAD', 'POST', 'DELETE'],
63         type='choice',
64         help='Request method type (GET, POST, DELETE)',
65         )
66 
67     get_app = staticmethod(get_app)
68     stdin = sys.stdin
69 
70     def __init__(self, argv, quiet=False):
71         self.quiet = quiet
72         self.options, self.args = self.parser.parse_args(argv[1:])
73 
74     def out(self, msg): # pragma: no cover
75         if not self.quiet:
76             print(msg)
77 
78     def run(self):
79         if not len(self.args) >= 2:
80             self.out('You must provide at least two arguments')
81             return 2
82         app_spec = self.args[0]
83         path = self.args[1]
84         if not path.startswith('/'):
85             path = '/' + path
86 
87         try:
88             path, qs = path.split('?', 1)
89         except ValueError:
90             qs = ''
91 
92         path = url_unquote(path)
93 
94         headers = {}
95         if self.options.headers:
96             for item in self.options.headers:
97                 if ':' not in item:
98                     self.out(
99                         "Bad --header=%s option, value must be in the form "
100                         "'name:value'" % item)
101                     return 2
102                 name, value = item.split(':', 1)
103                 headers[name] = value.strip()
104 
105         app = self.get_app(app_spec, self.options.app_name,
106                 options=parse_vars(self.args[2:]))
107 
108         request_method = (self.options.method or 'GET').upper()
109 
110         environ = {
111             'REQUEST_METHOD': request_method,
112             'SCRIPT_NAME': '',           # may be empty if app is at the root
113             'PATH_INFO': path,           
114             'SERVER_NAME': 'localhost',  # always mandatory
115             'SERVER_PORT': '80',         # always mandatory 
116             'SERVER_PROTOCOL': 'HTTP/1.0',
117             'CONTENT_TYPE': 'text/plain',
118             'REMOTE_ADDR':'127.0.0.1',
119             'wsgi.run_once': True,
120             'wsgi.multithread': False,
121             'wsgi.multiprocess': False,
122             'wsgi.errors': sys.stderr,
123             'wsgi.url_scheme': 'http',
124             'wsgi.version': (1, 0),
125             'QUERY_STRING': qs,
126             'HTTP_ACCEPT': 'text/plain;q=1.0, */*;q=0.1',
127             'paste.command_request': True,
128             }
129 
130         if request_method == 'POST':
131             environ['wsgi.input'] = self.stdin
132             environ['CONTENT_LENGTH'] = '-1'
133 
134         for name, value in headers.items():
135             if name.lower() == 'content-type':
136                 name = 'CONTENT_TYPE'
137             else:
138                 name = 'HTTP_'+name.upper().replace('-', '_')
139             environ[name] = value
140 
141         request = Request.blank(path, environ=environ)
142         response = request.get_response(app)
143         if self.options.display_headers:
144             self.out(response.status)
145             for name, value in response.headerlist:
146                 self.out('%s: %s' % (name, value))
147         if response.charset:
148             self.out(response.ubody)
149         else:
150             self.out(response.body)
151         return 0
152
```
--- 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/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py
--- a/pyramid/scripts/prequest.py
+++ b/pyramid/scripts/prequest.py
@@ -59,9 +59,9 @@
     parser.add_option(
         '-m', '--method',
         dest='method',
-        choices=['GET', 'HEAD', 'POST', 'DELETE'],
+        choices=['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'],
         type='choice',
-        help='Request method type (GET, POST, DELETE)',
+        help='Request method type',
         )
 
     get_app = staticmethod(get_app)
@@ -127,7 +127,7 @@
             'paste.command_request': True,
             }
 
-        if request_method == 'POST':
+        if request_method in ('POST', 'PUT', 'PATCH'):
             environ['wsgi.input'] = self.stdin
             environ['CONTENT_LENGTH'] = '-1'

{"golden_diff": "diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py\n--- a/pyramid/scripts/prequest.py\n+++ b/pyramid/scripts/prequest.py\n@@ -59,9 +59,9 @@\n     parser.add_option(\n         '-m', '--method',\n         dest='method',\n-        choices=['GET', 'HEAD', 'POST', 'DELETE'],\n+        choices=['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'],\n         type='choice',\n-        help='Request method type (GET, POST, DELETE)',\n+        help='Request method type',\n         )\n \n     get_app = staticmethod(get_app)\n@@ -127,7 +127,7 @@\n             'paste.command_request': True,\n             }\n \n-        if request_method == 'POST':\n+        if request_method in ('POST', 'PUT', 'PATCH'):\n             environ['wsgi.input'] = self.stdin\n             environ['CONTENT_LENGTH'] = '-1'\n", "issue": "prequest does not support PUT\nTitle says it all.  Give me the green light and I can whip up a patch (no pun intended).\n\n", "before_files": [{"content": "import optparse\nimport sys\nimport textwrap\n\nfrom pyramid.compat import url_unquote\nfrom pyramid.request import Request\nfrom pyramid.paster import get_app\nfrom pyramid.scripts.common import parse_vars\n\ndef main(argv=sys.argv, quiet=False):\n    command = PRequestCommand(argv, quiet)\n    return command.run()\n\nclass PRequestCommand(object):\n    description = \"\"\"\\\n    Run a request for the described application.\n\n    This command makes an artifical request to a web application that uses a\n    PasteDeploy (.ini) configuration file for the server and application.\n\n    Use \"prequest config.ini /path\" to request \"/path\".  Use \"prequest\n    --method=POST config.ini /path < data\" to do a POST with the given\n    request body.\n\n    If the path is relative (doesn't begin with \"/\") it is interpreted as\n    relative to \"/\".  The path passed to this script should be URL-quoted.\n    The path can be succeeded with a query string (e.g. `/path?a=1&=b2').\n\n    The variable \"environ['paste.command_request']\" will be set to \"True\" in\n    the request's WSGI environment, so your application can distinguish these\n    calls from normal requests.\n    \"\"\"\n    usage = \"usage: %prog config_uri path_info [args/options]\"\n    parser = optparse.OptionParser(\n        usage=usage,\n        description=textwrap.dedent(description)\n        )\n    parser.add_option(\n        '-n', '--app-name',\n        dest='app_name',\n        metavar= 'NAME',\n        help=\"Load the named application from the config file (default 'main')\",\n        type=\"string\",\n        )\n    parser.add_option(\n        '--header',\n        dest='headers',\n        metavar='NAME:VALUE',\n        type='string',\n        action='append',\n        help=\"Header to add to request (you can use this option multiple times)\"\n        )\n    parser.add_option(\n        '-d', '--display-headers',\n        dest='display_headers',\n        action='store_true',\n        help='Display status and headers before the response body'\n        )\n    parser.add_option(\n        '-m', '--method',\n        dest='method',\n        choices=['GET', 'HEAD', 'POST', 'DELETE'],\n        type='choice',\n        help='Request method type (GET, POST, DELETE)',\n        )\n\n    get_app = staticmethod(get_app)\n    stdin = sys.stdin\n\n    def __init__(self, argv, quiet=False):\n        self.quiet = quiet\n        self.options, self.args = self.parser.parse_args(argv[1:])\n\n    def out(self, msg): # pragma: no cover\n        if not self.quiet:\n            print(msg)\n\n    def run(self):\n        if not len(self.args) >= 2:\n            self.out('You must provide at least two arguments')\n            return 2\n        app_spec = self.args[0]\n        path = self.args[1]\n        if not path.startswith('/'):\n            path = '/' + path\n\n        try:\n            path, qs = path.split('?', 1)\n        except ValueError:\n            qs = ''\n\n        path = url_unquote(path)\n\n        headers = {}\n        if self.options.headers:\n            for item in self.options.headers:\n                if ':' not in item:\n                    self.out(\n                        \"Bad --header=%s option, value must be in the form \"\n                        \"'name:value'\" % item)\n                    return 2\n                name, value = item.split(':', 1)\n                headers[name] = value.strip()\n\n        app = self.get_app(app_spec, self.options.app_name,\n                options=parse_vars(self.args[2:]))\n\n        request_method = (self.options.method or 'GET').upper()\n\n        environ = {\n            'REQUEST_METHOD': request_method,\n            'SCRIPT_NAME': '',           # may be empty if app is at the root\n            'PATH_INFO': path,           \n            'SERVER_NAME': 'localhost',  # always mandatory\n            'SERVER_PORT': '80',         # always mandatory \n            'SERVER_PROTOCOL': 'HTTP/1.0',\n            'CONTENT_TYPE': 'text/plain',\n            'REMOTE_ADDR':'127.0.0.1',\n            'wsgi.run_once': True,\n            'wsgi.multithread': False,\n            'wsgi.multiprocess': False,\n            'wsgi.errors': sys.stderr,\n            'wsgi.url_scheme': 'http',\n            'wsgi.version': (1, 0),\n            'QUERY_STRING': qs,\n            'HTTP_ACCEPT': 'text/plain;q=1.0, */*;q=0.1',\n            'paste.command_request': True,\n            }\n\n        if request_method == 'POST':\n            environ['wsgi.input'] = self.stdin\n            environ['CONTENT_LENGTH'] = '-1'\n\n        for name, value in headers.items():\n            if name.lower() == 'content-type':\n                name = 'CONTENT_TYPE'\n            else:\n                name = 'HTTP_'+name.upper().replace('-', '_')\n            environ[name] = value\n\n        request = Request.blank(path, environ=environ)\n        response = request.get_response(app)\n        if self.options.display_headers:\n            self.out(response.status)\n            for name, value in response.headerlist:\n                self.out('%s: %s' % (name, value))\n        if response.charset:\n            self.out(response.ubody)\n        else:\n            self.out(response.body)\n        return 0\n", "path": "pyramid/scripts/prequest.py"}], "after_files": [{"content": "import optparse\nimport sys\nimport textwrap\n\nfrom pyramid.compat import url_unquote\nfrom pyramid.request import Request\nfrom pyramid.paster import get_app\nfrom pyramid.scripts.common import parse_vars\n\ndef main(argv=sys.argv, quiet=False):\n    command = PRequestCommand(argv, quiet)\n    return command.run()\n\nclass PRequestCommand(object):\n    description = \"\"\"\\\n    Run a request for the described application.\n\n    This command makes an artifical request to a web application that uses a\n    PasteDeploy (.ini) configuration file for the server and application.\n\n    Use \"prequest config.ini /path\" to request \"/path\".  Use \"prequest\n    --method=POST config.ini /path < data\" to do a POST with the given\n    request body.\n\n    If the path is relative (doesn't begin with \"/\") it is interpreted as\n    relative to \"/\".  The path passed to this script should be URL-quoted.\n    The path can be succeeded with a query string (e.g. `/path?a=1&=b2').\n\n    The variable \"environ['paste.command_request']\" will be set to \"True\" in\n    the request's WSGI environment, so your application can distinguish these\n    calls from normal requests.\n    \"\"\"\n    usage = \"usage: %prog config_uri path_info [args/options]\"\n    parser = optparse.OptionParser(\n        usage=usage,\n        description=textwrap.dedent(description)\n        )\n    parser.add_option(\n        '-n', '--app-name',\n        dest='app_name',\n        metavar= 'NAME',\n        help=\"Load the named application from the config file (default 'main')\",\n        type=\"string\",\n        )\n    parser.add_option(\n        '--header',\n        dest='headers',\n        metavar='NAME:VALUE',\n        type='string',\n        action='append',\n        help=\"Header to add to request (you can use this option multiple times)\"\n        )\n    parser.add_option(\n        '-d', '--display-headers',\n        dest='display_headers',\n        action='store_true',\n        help='Display status and headers before the response body'\n        )\n    parser.add_option(\n        '-m', '--method',\n        dest='method',\n        choices=['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'],\n        type='choice',\n        help='Request method type',\n        )\n\n    get_app = staticmethod(get_app)\n    stdin = sys.stdin\n\n    def __init__(self, argv, quiet=False):\n        self.quiet = quiet\n        self.options, self.args = self.parser.parse_args(argv[1:])\n\n    def out(self, msg): # pragma: no cover\n        if not self.quiet:\n            print(msg)\n\n    def run(self):\n        if not len(self.args) >= 2:\n            self.out('You must provide at least two arguments')\n            return 2\n        app_spec = self.args[0]\n        path = self.args[1]\n        if not path.startswith('/'):\n            path = '/' + path\n\n        try:\n            path, qs = path.split('?', 1)\n        except ValueError:\n            qs = ''\n\n        path = url_unquote(path)\n\n        headers = {}\n        if self.options.headers:\n            for item in self.options.headers:\n                if ':' not in item:\n                    self.out(\n                        \"Bad --header=%s option, value must be in the form \"\n                        \"'name:value'\" % item)\n                    return 2\n                name, value = item.split(':', 1)\n                headers[name] = value.strip()\n\n        app = self.get_app(app_spec, self.options.app_name,\n                options=parse_vars(self.args[2:]))\n\n        request_method = (self.options.method or 'GET').upper()\n\n        environ = {\n            'REQUEST_METHOD': request_method,\n            'SCRIPT_NAME': '',           # may be empty if app is at the root\n            'PATH_INFO': path,           \n            'SERVER_NAME': 'localhost',  # always mandatory\n            'SERVER_PORT': '80',         # always mandatory \n            'SERVER_PROTOCOL': 'HTTP/1.0',\n            'CONTENT_TYPE': 'text/plain',\n            'REMOTE_ADDR':'127.0.0.1',\n            'wsgi.run_once': True,\n            'wsgi.multithread': False,\n            'wsgi.multiprocess': False,\n            'wsgi.errors': sys.stderr,\n            'wsgi.url_scheme': 'http',\n            'wsgi.version': (1, 0),\n            'QUERY_STRING': qs,\n            'HTTP_ACCEPT': 'text/plain;q=1.0, */*;q=0.1',\n            'paste.command_request': True,\n            }\n\n        if request_method in ('POST', 'PUT', 'PATCH'):\n            environ['wsgi.input'] = self.stdin\n            environ['CONTENT_LENGTH'] = '-1'\n\n        for name, value in headers.items():\n            if name.lower() == 'content-type':\n                name = 'CONTENT_TYPE'\n            else:\n                name = 'HTTP_'+name.upper().replace('-', '_')\n            environ[name] = value\n\n        request = Request.blank(path, environ=environ)\n        response = request.get_response(app)\n        if self.options.display_headers:\n            self.out(response.status)\n            for name, value in response.headerlist:\n                self.out('%s: %s' % (name, value))\n        if response.charset:\n            self.out(response.ubody)\n        else:\n            self.out(response.body)\n        return 0\n", "path": "pyramid/scripts/prequest.py"}]}