prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Lifespan scope is missing asgi dict
  the lifespan scope (https://asgi.readthedocs.io/en/latest/specs/lifespan.html#scope) is missing the asgi dict
  
  prompted by
  
  _Originally posted by @florimondmanca in https://github.com/encode/uvicorn/pull/751_
  
  </issue>
  <code>
  [start of uvicorn/lifespan/on.py]
  1 import asyncio
  2 import logging
  3 
  4 STATE_TRANSITION_ERROR = "Got invalid state transition on lifespan protocol."
  5 
  6 
  7 class LifespanOn:
  8     def __init__(self, config):
  9         if not config.loaded:
  10             config.load()
  11 
  12         self.config = config
  13         self.logger = logging.getLogger("uvicorn.error")
  14         self.startup_event = asyncio.Event()
  15         self.shutdown_event = asyncio.Event()
  16         self.receive_queue = asyncio.Queue()
  17         self.error_occured = False
  18         self.startup_failed = False
  19         self.should_exit = False
  20 
  21     async def startup(self):
  22         self.logger.info("Waiting for application startup.")
  23 
  24         loop = asyncio.get_event_loop()
  25         loop.create_task(self.main())
  26 
  27         await self.receive_queue.put({"type": "lifespan.startup"})
  28         await self.startup_event.wait()
  29 
  30         if self.startup_failed or (self.error_occured and self.config.lifespan == "on"):
  31             self.logger.error("Application startup failed. Exiting.")
  32             self.should_exit = True
  33         else:
  34             self.logger.info("Application startup complete.")
  35 
  36     async def shutdown(self):
  37         if self.error_occured:
  38             return
  39         self.logger.info("Waiting for application shutdown.")
  40         await self.receive_queue.put({"type": "lifespan.shutdown"})
  41         await self.shutdown_event.wait()
  42         self.logger.info("Application shutdown complete.")
  43 
  44     async def main(self):
  45         try:
  46             app = self.config.loaded_app
  47             scope = {"type": "lifespan"}
  48             await app(scope, self.receive, self.send)
  49         except BaseException as exc:
  50             self.asgi = None
  51             self.error_occured = True
  52             if self.startup_failed:
  53                 return
  54             if self.config.lifespan == "auto":
  55                 msg = "ASGI 'lifespan' protocol appears unsupported."
  56                 self.logger.info(msg)
  57             else:
  58                 msg = "Exception in 'lifespan' protocol\n"
  59                 self.logger.error(msg, exc_info=exc)
  60         finally:
  61             self.startup_event.set()
  62             self.shutdown_event.set()
  63 
  64     async def send(self, message):
  65         assert message["type"] in (
  66             "lifespan.startup.complete",
  67             "lifespan.startup.failed",
  68             "lifespan.shutdown.complete",
  69         )
  70 
  71         if message["type"] == "lifespan.startup.complete":
  72             assert not self.startup_event.is_set(), STATE_TRANSITION_ERROR
  73             assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR
  74             self.startup_event.set()
  75 
  76         elif message["type"] == "lifespan.startup.failed":
  77             assert not self.startup_event.is_set(), STATE_TRANSITION_ERROR
  78             assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR
  79             self.startup_event.set()
  80             self.startup_failed = True
  81             if message.get("message"):
  82                 self.logger.error(message["message"])
  83 
  84         elif message["type"] == "lifespan.shutdown.complete":
  85             assert self.startup_event.is_set(), STATE_TRANSITION_ERROR
  86             assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR
  87             self.shutdown_event.set()
  88 
  89     async def receive(self):
  90         return await self.receive_queue.get()
  91
  [end of uvicorn/lifespan/on.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/uvicorn/lifespan/on.py b/uvicorn/lifespan/on.py
  --- a/uvicorn/lifespan/on.py
  +++ b/uvicorn/lifespan/on.py
  @@ -44,7 +44,10 @@
       async def main(self):
           try:
               app = self.config.loaded_app
  -            scope = {"type": "lifespan"}
  +            scope = {
  +                "type": "lifespan",
  +                "asgi": {"version": self.config.asgi_version, "spec_version": "2.0"},
  +            }
               await app(scope, self.receive, self.send)
           except BaseException as exc:
               self.asgi = None
  
verification_info: {"golden_diff": "diff --git a/uvicorn/lifespan/on.py b/uvicorn/lifespan/on.py\n--- a/uvicorn/lifespan/on.py\n+++ b/uvicorn/lifespan/on.py\n@@ -44,7 +44,10 @@\n     async def main(self):\n         try:\n             app = self.config.loaded_app\n-            scope = {\"type\": \"lifespan\"}\n+            scope = {\n+                \"type\": \"lifespan\",\n+                \"asgi\": {\"version\": self.config.asgi_version, \"spec_version\": \"2.0\"},\n+            }\n             await app(scope, self.receive, self.send)\n         except BaseException as exc:\n             self.asgi = None\n", "issue": "Lifespan scope is missing asgi dict\nthe lifespan scope (https://asgi.readthedocs.io/en/latest/specs/lifespan.html#scope) is missing the asgi dict\r\n\r\nprompted by\r\n\r\n_Originally posted by @florimondmanca in https://github.com/encode/uvicorn/pull/751_\n", "before_files": [{"content": "import asyncio\nimport logging\n\nSTATE_TRANSITION_ERROR = \"Got invalid state transition on lifespan protocol.\"\n\n\nclass LifespanOn:\n    def __init__(self, config):\n        if not config.loaded:\n            config.load()\n\n        self.config = config\n        self.logger = logging.getLogger(\"uvicorn.error\")\n        self.startup_event = asyncio.Event()\n        self.shutdown_event = asyncio.Event()\n        self.receive_queue = asyncio.Queue()\n        self.error_occured = False\n        self.startup_failed = False\n        self.should_exit = False\n\n    async def startup(self):\n        self.logger.info(\"Waiting for application startup.\")\n\n        loop = asyncio.get_event_loop()\n        loop.create_task(self.main())\n\n        await self.receive_queue.put({\"type\": \"lifespan.startup\"})\n        await self.startup_event.wait()\n\n        if self.startup_failed or (self.error_occured and self.config.lifespan == \"on\"):\n            self.logger.error(\"Application startup failed. Exiting.\")\n            self.should_exit = True\n        else:\n            self.logger.info(\"Application startup complete.\")\n\n    async def shutdown(self):\n        if self.error_occured:\n            return\n        self.logger.info(\"Waiting for application shutdown.\")\n        await self.receive_queue.put({\"type\": \"lifespan.shutdown\"})\n        await self.shutdown_event.wait()\n        self.logger.info(\"Application shutdown complete.\")\n\n    async def main(self):\n        try:\n            app = self.config.loaded_app\n            scope = {\"type\": \"lifespan\"}\n            await app(scope, self.receive, self.send)\n        except BaseException as exc:\n            self.asgi = None\n            self.error_occured = True\n            if self.startup_failed:\n                return\n            if self.config.lifespan == \"auto\":\n                msg = \"ASGI 'lifespan' protocol appears unsupported.\"\n                self.logger.info(msg)\n            else:\n                msg = \"Exception in 'lifespan' protocol\\n\"\n                self.logger.error(msg, exc_info=exc)\n        finally:\n            self.startup_event.set()\n            self.shutdown_event.set()\n\n    async def send(self, message):\n        assert message[\"type\"] in (\n            \"lifespan.startup.complete\",\n            \"lifespan.startup.failed\",\n            \"lifespan.shutdown.complete\",\n        )\n\n        if message[\"type\"] == \"lifespan.startup.complete\":\n            assert not self.startup_event.is_set(), STATE_TRANSITION_ERROR\n            assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR\n            self.startup_event.set()\n\n        elif message[\"type\"] == \"lifespan.startup.failed\":\n            assert not self.startup_event.is_set(), STATE_TRANSITION_ERROR\n            assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR\n            self.startup_event.set()\n            self.startup_failed = True\n            if message.get(\"message\"):\n                self.logger.error(message[\"message\"])\n\n        elif message[\"type\"] == \"lifespan.shutdown.complete\":\n            assert self.startup_event.is_set(), STATE_TRANSITION_ERROR\n            assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR\n            self.shutdown_event.set()\n\n    async def receive(self):\n        return await self.receive_queue.get()\n", "path": "uvicorn/lifespan/on.py"}]}