prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Request should present a scope-like interface
  The `Request` class should present a dict-like interface so that it can be used in the same way as `scope`. Should also allow it to be instantiated without a `receive` channel being set initially.
  
  </issue>
  <code>
  [start of starlette/request.py]
  1 from starlette.datastructures import URL, Headers, QueryParams
  2 import json
  3 
  4 
  5 class Request:
  6     def __init__(self, scope, receive):
  7         self._scope = scope
  8         self._receive = receive
  9         self._stream_consumed = False
  10 
  11     @property
  12     def method(self):
  13         return self._scope["method"]
  14 
  15     @property
  16     def url(self):
  17         if not hasattr(self, "_url"):
  18             scheme = self._scope["scheme"]
  19             host, port = self._scope["server"]
  20             path = self._scope["path"]
  21             query_string = self._scope["query_string"]
  22 
  23             if (scheme == "http" and port != 80) or (scheme == "https" and port != 443):
  24                 url = "%s://%s:%s%s" % (scheme, host, port, path)
  25             else:
  26                 url = "%s://%s%s" % (scheme, host, path)
  27 
  28             if query_string:
  29                 url += "?" + query_string.decode()
  30 
  31             self._url = URL(url)
  32         return self._url
  33 
  34     @property
  35     def headers(self):
  36         if not hasattr(self, "_headers"):
  37             self._headers = Headers(
  38                 [
  39                     (key.decode(), value.decode())
  40                     for key, value in self._scope["headers"]
  41                 ]
  42             )
  43         return self._headers
  44 
  45     @property
  46     def query_params(self):
  47         if not hasattr(self, "_query_params"):
  48             query_string = self._scope["query_string"].decode()
  49             self._query_params = QueryParams(query_string)
  50         return self._query_params
  51 
  52     async def stream(self):
  53         if hasattr(self, "_body"):
  54             yield self._body
  55             return
  56 
  57         if self._stream_consumed:
  58             raise RuntimeError("Stream consumed")
  59 
  60         self._stream_consumed = True
  61         while True:
  62             message = await self._receive()
  63             if message["type"] == "http.request":
  64                 yield message.get("body", b"")
  65                 if not message.get("more_body", False):
  66                     break
  67 
  68     async def body(self):
  69         if not hasattr(self, "_body"):
  70             body = b""
  71             async for chunk in self.stream():
  72                 body += chunk
  73             self._body = body
  74         return self._body
  75 
  76     async def json(self):
  77         if not hasattr(self, "_json"):
  78             body = await self.body()
  79             self._json = json.loads(body)
  80         return self._json
  81
  [end of starlette/request.py]
  [start of starlette/decorators.py]
  1 from starlette.request import Request
  2 from starlette.response import Response
  3 from starlette.types import ASGIInstance, Receive, Send, Scope
  4 
  5 
  6 def asgi_application(func):
  7     def app(scope: Scope) -> ASGIInstance:
  8         async def awaitable(receive: Receive, send: Send) -> None:
  9             request = Request(scope, receive)
  10             response = func(request)
  11             await response(receive, send)
  12 
  13         return awaitable
  14 
  15     return app
  16
  [end of starlette/decorators.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/starlette/decorators.py b/starlette/decorators.py
  --- a/starlette/decorators.py
  +++ b/starlette/decorators.py
  @@ -5,8 +5,10 @@
   
   def asgi_application(func):
       def app(scope: Scope) -> ASGIInstance:
  +        request = Request(scope)
  +
           async def awaitable(receive: Receive, send: Send) -> None:
  -            request = Request(scope, receive)
  +            request.set_receive_channel(receive)
               response = func(request)
               await response(receive, send)
   
  diff --git a/starlette/request.py b/starlette/request.py
  --- a/starlette/request.py
  +++ b/starlette/request.py
  @@ -1,19 +1,33 @@
   from starlette.datastructures import URL, Headers, QueryParams
  +from collections.abc import Mapping
   import json
  +import typing
   
   
  -class Request:
  -    def __init__(self, scope, receive):
  +class Request(Mapping):
  +    def __init__(self, scope, receive=None):
           self._scope = scope
           self._receive = receive
           self._stream_consumed = False
   
  +    def __getitem__(self, key):
  +        return self._scope[key]
  +
  +    def __iter__(self):
  +        return iter(self._scope)
  +
  +    def __len__(self):
  +        return len(self._scope)
  +
  +    def set_receive_channel(self, receive):
  +        self._receive = receive
  +
       @property
  -    def method(self):
  +    def method(self) -> str:
           return self._scope["method"]
   
       @property
  -    def url(self):
  +    def url(self) -> URL:
           if not hasattr(self, "_url"):
               scheme = self._scope["scheme"]
               host, port = self._scope["server"]
  @@ -32,7 +46,7 @@
           return self._url
   
       @property
  -    def headers(self):
  +    def headers(self) -> Headers:
           if not hasattr(self, "_headers"):
               self._headers = Headers(
                   [
  @@ -43,7 +57,7 @@
           return self._headers
   
       @property
  -    def query_params(self):
  +    def query_params(self) -> QueryParams:
           if not hasattr(self, "_query_params"):
               query_string = self._scope["query_string"].decode()
               self._query_params = QueryParams(query_string)
  @@ -57,6 +71,9 @@
           if self._stream_consumed:
               raise RuntimeError("Stream consumed")
   
  +        if self._receive is None:
  +            raise RuntimeError("Receive channel has not been made available")
  +
           self._stream_consumed = True
           while True:
               message = await self._receive()
  
verification_info: {"golden_diff": "diff --git a/starlette/decorators.py b/starlette/decorators.py\n--- a/starlette/decorators.py\n+++ b/starlette/decorators.py\n@@ -5,8 +5,10 @@\n \n def asgi_application(func):\n     def app(scope: Scope) -> ASGIInstance:\n+        request = Request(scope)\n+\n         async def awaitable(receive: Receive, send: Send) -> None:\n-            request = Request(scope, receive)\n+            request.set_receive_channel(receive)\n             response = func(request)\n             await response(receive, send)\n \ndiff --git a/starlette/request.py b/starlette/request.py\n--- a/starlette/request.py\n+++ b/starlette/request.py\n@@ -1,19 +1,33 @@\n from starlette.datastructures import URL, Headers, QueryParams\n+from collections.abc import Mapping\n import json\n+import typing\n \n \n-class Request:\n-    def __init__(self, scope, receive):\n+class Request(Mapping):\n+    def __init__(self, scope, receive=None):\n         self._scope = scope\n         self._receive = receive\n         self._stream_consumed = False\n \n+    def __getitem__(self, key):\n+        return self._scope[key]\n+\n+    def __iter__(self):\n+        return iter(self._scope)\n+\n+    def __len__(self):\n+        return len(self._scope)\n+\n+    def set_receive_channel(self, receive):\n+        self._receive = receive\n+\n     @property\n-    def method(self):\n+    def method(self) -> str:\n         return self._scope[\"method\"]\n \n     @property\n-    def url(self):\n+    def url(self) -> URL:\n         if not hasattr(self, \"_url\"):\n             scheme = self._scope[\"scheme\"]\n             host, port = self._scope[\"server\"]\n@@ -32,7 +46,7 @@\n         return self._url\n \n     @property\n-    def headers(self):\n+    def headers(self) -> Headers:\n         if not hasattr(self, \"_headers\"):\n             self._headers = Headers(\n                 [\n@@ -43,7 +57,7 @@\n         return self._headers\n \n     @property\n-    def query_params(self):\n+    def query_params(self) -> QueryParams:\n         if not hasattr(self, \"_query_params\"):\n             query_string = self._scope[\"query_string\"].decode()\n             self._query_params = QueryParams(query_string)\n@@ -57,6 +71,9 @@\n         if self._stream_consumed:\n             raise RuntimeError(\"Stream consumed\")\n \n+        if self._receive is None:\n+            raise RuntimeError(\"Receive channel has not been made available\")\n+\n         self._stream_consumed = True\n         while True:\n             message = await self._receive()\n", "issue": "Request should present a scope-like interface\nThe `Request` class should present a dict-like interface so that it can be used in the same way as `scope`. Should also allow it to be instantiated without a `receive` channel being set initially.\n", "before_files": [{"content": "from starlette.datastructures import URL, Headers, QueryParams\nimport json\n\n\nclass Request:\n    def __init__(self, scope, receive):\n        self._scope = scope\n        self._receive = receive\n        self._stream_consumed = False\n\n    @property\n    def method(self):\n        return self._scope[\"method\"]\n\n    @property\n    def url(self):\n        if not hasattr(self, \"_url\"):\n            scheme = self._scope[\"scheme\"]\n            host, port = self._scope[\"server\"]\n            path = self._scope[\"path\"]\n            query_string = self._scope[\"query_string\"]\n\n            if (scheme == \"http\" and port != 80) or (scheme == \"https\" and port != 443):\n                url = \"%s://%s:%s%s\" % (scheme, host, port, path)\n            else:\n                url = \"%s://%s%s\" % (scheme, host, path)\n\n            if query_string:\n                url += \"?\" + query_string.decode()\n\n            self._url = URL(url)\n        return self._url\n\n    @property\n    def headers(self):\n        if not hasattr(self, \"_headers\"):\n            self._headers = Headers(\n                [\n                    (key.decode(), value.decode())\n                    for key, value in self._scope[\"headers\"]\n                ]\n            )\n        return self._headers\n\n    @property\n    def query_params(self):\n        if not hasattr(self, \"_query_params\"):\n            query_string = self._scope[\"query_string\"].decode()\n            self._query_params = QueryParams(query_string)\n        return self._query_params\n\n    async def stream(self):\n        if hasattr(self, \"_body\"):\n            yield self._body\n            return\n\n        if self._stream_consumed:\n            raise RuntimeError(\"Stream consumed\")\n\n        self._stream_consumed = True\n        while True:\n            message = await self._receive()\n            if message[\"type\"] == \"http.request\":\n                yield message.get(\"body\", b\"\")\n                if not message.get(\"more_body\", False):\n                    break\n\n    async def body(self):\n        if not hasattr(self, \"_body\"):\n            body = b\"\"\n            async for chunk in self.stream():\n                body += chunk\n            self._body = body\n        return self._body\n\n    async def json(self):\n        if not hasattr(self, \"_json\"):\n            body = await self.body()\n            self._json = json.loads(body)\n        return self._json\n", "path": "starlette/request.py"}, {"content": "from starlette.request import Request\nfrom starlette.response import Response\nfrom starlette.types import ASGIInstance, Receive, Send, Scope\n\n\ndef asgi_application(func):\n    def app(scope: Scope) -> ASGIInstance:\n        async def awaitable(receive: Receive, send: Send) -> None:\n            request = Request(scope, receive)\n            response = func(request)\n            await response(receive, send)\n\n        return awaitable\n\n    return app\n", "path": "starlette/decorators.py"}]}