prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  100% Test coverage
  Let's get the test coverage up to 100%, and then force-pin it.
  
  Any contributions towards this are welcome.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `httpcore/concurrency.py`
  Content:
  ```
  1 """
  2 The `Reader` and `Writer` classes here provide a lightweight layer over
  3 `asyncio.StreamReader` and `asyncio.StreamWriter`.
  4 
  5 Similarly `PoolSemaphore` is a lightweight layer over `BoundedSemaphore`.
  6 
  7 These classes help encapsulate the timeout logic, make it easier to unit-test
  8 protocols, and help keep the rest of the package more `async`/`await`
  9 based, and less strictly `asyncio`-specific.
  10 """
  11 import asyncio
  12 import ssl
  13 import typing
  14 
  15 from .config import DEFAULT_TIMEOUT_CONFIG, PoolLimits, TimeoutConfig
  16 from .exceptions import ConnectTimeout, PoolTimeout, ReadTimeout, WriteTimeout
  17 from .interfaces import (
  18     BasePoolSemaphore,
  19     BaseReader,
  20     BaseWriter,
  21     ConcurrencyBackend,
  22     Protocol,
  23 )
  24 
  25 OptionalTimeout = typing.Optional[TimeoutConfig]
  26 
  27 
  28 SSL_MONKEY_PATCH_APPLIED = False
  29 
  30 
  31 def ssl_monkey_patch() -> None:
  32     """
  33     Monky-patch for https://bugs.python.org/issue36709
  34 
  35     This prevents console errors when outstanding HTTPS connections
  36     still exist at the point of exiting.
  37 
  38     Clients which have been opened using a `with` block, or which have
  39     had `close()` closed, will not exhibit this issue in the first place.
  40     """
  41     MonkeyPatch = asyncio.selector_events._SelectorSocketTransport  # type: ignore
  42 
  43     _write = MonkeyPatch.write
  44 
  45     def _fixed_write(self, data: bytes) -> None:  # type: ignore
  46         if not self._loop.is_closed():
  47             _write(self, data)
  48 
  49     MonkeyPatch.write = _fixed_write
  50 
  51 
  52 class Reader(BaseReader):
  53     def __init__(
  54         self, stream_reader: asyncio.StreamReader, timeout: TimeoutConfig
  55     ) -> None:
  56         self.stream_reader = stream_reader
  57         self.timeout = timeout
  58 
  59     async def read(self, n: int, timeout: OptionalTimeout = None) -> bytes:
  60         if timeout is None:
  61             timeout = self.timeout
  62 
  63         try:
  64             data = await asyncio.wait_for(
  65                 self.stream_reader.read(n), timeout.read_timeout
  66             )
  67         except asyncio.TimeoutError:
  68             raise ReadTimeout()
  69 
  70         return data
  71 
  72 
  73 class Writer(BaseWriter):
  74     def __init__(self, stream_writer: asyncio.StreamWriter, timeout: TimeoutConfig):
  75         self.stream_writer = stream_writer
  76         self.timeout = timeout
  77 
  78     def write_no_block(self, data: bytes) -> None:
  79         self.stream_writer.write(data)
  80 
  81     async def write(self, data: bytes, timeout: OptionalTimeout = None) -> None:
  82         if not data:
  83             return
  84 
  85         if timeout is None:
  86             timeout = self.timeout
  87 
  88         self.stream_writer.write(data)
  89         try:
  90             await asyncio.wait_for(  # type: ignore
  91                 self.stream_writer.drain(), timeout.write_timeout
  92             )
  93         except asyncio.TimeoutError:
  94             raise WriteTimeout()
  95 
  96     async def close(self) -> None:
  97         self.stream_writer.close()
  98 
  99 
  100 class PoolSemaphore(BasePoolSemaphore):
  101     def __init__(self, pool_limits: PoolLimits):
  102         self.pool_limits = pool_limits
  103 
  104     @property
  105     def semaphore(self) -> typing.Optional[asyncio.BoundedSemaphore]:
  106         if not hasattr(self, "_semaphore"):
  107             max_connections = self.pool_limits.hard_limit
  108             if max_connections is None:
  109                 self._semaphore = None
  110             else:
  111                 self._semaphore = asyncio.BoundedSemaphore(value=max_connections)
  112         return self._semaphore
  113 
  114     async def acquire(self) -> None:
  115         if self.semaphore is None:
  116             return
  117 
  118         timeout = self.pool_limits.pool_timeout
  119         try:
  120             await asyncio.wait_for(self.semaphore.acquire(), timeout)
  121         except asyncio.TimeoutError:
  122             raise PoolTimeout()
  123 
  124     def release(self) -> None:
  125         if self.semaphore is None:
  126             return
  127 
  128         self.semaphore.release()
  129 
  130 
  131 class AsyncioBackend(ConcurrencyBackend):
  132     def __init__(self) -> None:
  133         global SSL_MONKEY_PATCH_APPLIED
  134 
  135         if not SSL_MONKEY_PATCH_APPLIED:
  136             ssl_monkey_patch()
  137         SSL_MONKEY_PATCH_APPLIED = True
  138 
  139     async def connect(
  140         self,
  141         hostname: str,
  142         port: int,
  143         ssl_context: typing.Optional[ssl.SSLContext],
  144         timeout: TimeoutConfig,
  145     ) -> typing.Tuple[BaseReader, BaseWriter, Protocol]:
  146         try:
  147             stream_reader, stream_writer = await asyncio.wait_for(  # type: ignore
  148                 asyncio.open_connection(hostname, port, ssl=ssl_context),
  149                 timeout.connect_timeout,
  150             )
  151         except asyncio.TimeoutError:
  152             raise ConnectTimeout()
  153 
  154         ssl_object = stream_writer.get_extra_info("ssl_object")
  155         if ssl_object is None:
  156             ident = "http/1.1"
  157         else:
  158             ident = ssl_object.selected_alpn_protocol()
  159             if ident is None:
  160                 ident = ssl_object.selected_npn_protocol()
  161 
  162         reader = Reader(stream_reader=stream_reader, timeout=timeout)
  163         writer = Writer(stream_writer=stream_writer, timeout=timeout)
  164         protocol = Protocol.HTTP_2 if ident == "h2" else Protocol.HTTP_11
  165 
  166         return (reader, writer, protocol)
  167 
  168     def get_semaphore(self, limits: PoolLimits) -> BasePoolSemaphore:
  169         return PoolSemaphore(limits)
  170
  ```
  --- 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/httpcore/concurrency.py b/httpcore/concurrency.py
  --- a/httpcore/concurrency.py
  +++ b/httpcore/concurrency.py
  @@ -76,7 +76,7 @@
           self.timeout = timeout
   
       def write_no_block(self, data: bytes) -> None:
  -        self.stream_writer.write(data)
  +        self.stream_writer.write(data)  # pragma: nocover
   
       async def write(self, data: bytes, timeout: OptionalTimeout = None) -> None:
           if not data:
  
verification_info: {"golden_diff": "diff --git a/httpcore/concurrency.py b/httpcore/concurrency.py\n--- a/httpcore/concurrency.py\n+++ b/httpcore/concurrency.py\n@@ -76,7 +76,7 @@\n         self.timeout = timeout\n \n     def write_no_block(self, data: bytes) -> None:\n-        self.stream_writer.write(data)\n+        self.stream_writer.write(data)  # pragma: nocover\n \n     async def write(self, data: bytes, timeout: OptionalTimeout = None) -> None:\n         if not data:\n", "issue": "100% Test coverage\nLet's get the test coverage up to 100%, and then force-pin it.\r\n\r\nAny contributions towards this are welcome.\n", "before_files": [{"content": "\"\"\"\nThe `Reader` and `Writer` classes here provide a lightweight layer over\n`asyncio.StreamReader` and `asyncio.StreamWriter`.\n\nSimilarly `PoolSemaphore` is a lightweight layer over `BoundedSemaphore`.\n\nThese classes help encapsulate the timeout logic, make it easier to unit-test\nprotocols, and help keep the rest of the package more `async`/`await`\nbased, and less strictly `asyncio`-specific.\n\"\"\"\nimport asyncio\nimport ssl\nimport typing\n\nfrom .config import DEFAULT_TIMEOUT_CONFIG, PoolLimits, TimeoutConfig\nfrom .exceptions import ConnectTimeout, PoolTimeout, ReadTimeout, WriteTimeout\nfrom .interfaces import (\n    BasePoolSemaphore,\n    BaseReader,\n    BaseWriter,\n    ConcurrencyBackend,\n    Protocol,\n)\n\nOptionalTimeout = typing.Optional[TimeoutConfig]\n\n\nSSL_MONKEY_PATCH_APPLIED = False\n\n\ndef ssl_monkey_patch() -> None:\n    \"\"\"\n    Monky-patch for https://bugs.python.org/issue36709\n\n    This prevents console errors when outstanding HTTPS connections\n    still exist at the point of exiting.\n\n    Clients which have been opened using a `with` block, or which have\n    had `close()` closed, will not exhibit this issue in the first place.\n    \"\"\"\n    MonkeyPatch = asyncio.selector_events._SelectorSocketTransport  # type: ignore\n\n    _write = MonkeyPatch.write\n\n    def _fixed_write(self, data: bytes) -> None:  # type: ignore\n        if not self._loop.is_closed():\n            _write(self, data)\n\n    MonkeyPatch.write = _fixed_write\n\n\nclass Reader(BaseReader):\n    def __init__(\n        self, stream_reader: asyncio.StreamReader, timeout: TimeoutConfig\n    ) -> None:\n        self.stream_reader = stream_reader\n        self.timeout = timeout\n\n    async def read(self, n: int, timeout: OptionalTimeout = None) -> bytes:\n        if timeout is None:\n            timeout = self.timeout\n\n        try:\n            data = await asyncio.wait_for(\n                self.stream_reader.read(n), timeout.read_timeout\n            )\n        except asyncio.TimeoutError:\n            raise ReadTimeout()\n\n        return data\n\n\nclass Writer(BaseWriter):\n    def __init__(self, stream_writer: asyncio.StreamWriter, timeout: TimeoutConfig):\n        self.stream_writer = stream_writer\n        self.timeout = timeout\n\n    def write_no_block(self, data: bytes) -> None:\n        self.stream_writer.write(data)\n\n    async def write(self, data: bytes, timeout: OptionalTimeout = None) -> None:\n        if not data:\n            return\n\n        if timeout is None:\n            timeout = self.timeout\n\n        self.stream_writer.write(data)\n        try:\n            await asyncio.wait_for(  # type: ignore\n                self.stream_writer.drain(), timeout.write_timeout\n            )\n        except asyncio.TimeoutError:\n            raise WriteTimeout()\n\n    async def close(self) -> None:\n        self.stream_writer.close()\n\n\nclass PoolSemaphore(BasePoolSemaphore):\n    def __init__(self, pool_limits: PoolLimits):\n        self.pool_limits = pool_limits\n\n    @property\n    def semaphore(self) -> typing.Optional[asyncio.BoundedSemaphore]:\n        if not hasattr(self, \"_semaphore\"):\n            max_connections = self.pool_limits.hard_limit\n            if max_connections is None:\n                self._semaphore = None\n            else:\n                self._semaphore = asyncio.BoundedSemaphore(value=max_connections)\n        return self._semaphore\n\n    async def acquire(self) -> None:\n        if self.semaphore is None:\n            return\n\n        timeout = self.pool_limits.pool_timeout\n        try:\n            await asyncio.wait_for(self.semaphore.acquire(), timeout)\n        except asyncio.TimeoutError:\n            raise PoolTimeout()\n\n    def release(self) -> None:\n        if self.semaphore is None:\n            return\n\n        self.semaphore.release()\n\n\nclass AsyncioBackend(ConcurrencyBackend):\n    def __init__(self) -> None:\n        global SSL_MONKEY_PATCH_APPLIED\n\n        if not SSL_MONKEY_PATCH_APPLIED:\n            ssl_monkey_patch()\n        SSL_MONKEY_PATCH_APPLIED = True\n\n    async def connect(\n        self,\n        hostname: str,\n        port: int,\n        ssl_context: typing.Optional[ssl.SSLContext],\n        timeout: TimeoutConfig,\n    ) -> typing.Tuple[BaseReader, BaseWriter, Protocol]:\n        try:\n            stream_reader, stream_writer = await asyncio.wait_for(  # type: ignore\n                asyncio.open_connection(hostname, port, ssl=ssl_context),\n                timeout.connect_timeout,\n            )\n        except asyncio.TimeoutError:\n            raise ConnectTimeout()\n\n        ssl_object = stream_writer.get_extra_info(\"ssl_object\")\n        if ssl_object is None:\n            ident = \"http/1.1\"\n        else:\n            ident = ssl_object.selected_alpn_protocol()\n            if ident is None:\n                ident = ssl_object.selected_npn_protocol()\n\n        reader = Reader(stream_reader=stream_reader, timeout=timeout)\n        writer = Writer(stream_writer=stream_writer, timeout=timeout)\n        protocol = Protocol.HTTP_2 if ident == \"h2\" else Protocol.HTTP_11\n\n        return (reader, writer, protocol)\n\n    def get_semaphore(self, limits: PoolLimits) -> BasePoolSemaphore:\n        return PoolSemaphore(limits)\n", "path": "httpcore/concurrency.py"}], "after_files": [{"content": "\"\"\"\nThe `Reader` and `Writer` classes here provide a lightweight layer over\n`asyncio.StreamReader` and `asyncio.StreamWriter`.\n\nSimilarly `PoolSemaphore` is a lightweight layer over `BoundedSemaphore`.\n\nThese classes help encapsulate the timeout logic, make it easier to unit-test\nprotocols, and help keep the rest of the package more `async`/`await`\nbased, and less strictly `asyncio`-specific.\n\"\"\"\nimport asyncio\nimport ssl\nimport typing\n\nfrom .config import DEFAULT_TIMEOUT_CONFIG, PoolLimits, TimeoutConfig\nfrom .exceptions import ConnectTimeout, PoolTimeout, ReadTimeout, WriteTimeout\nfrom .interfaces import (\n    BasePoolSemaphore,\n    BaseReader,\n    BaseWriter,\n    ConcurrencyBackend,\n    Protocol,\n)\n\nOptionalTimeout = typing.Optional[TimeoutConfig]\n\n\nSSL_MONKEY_PATCH_APPLIED = False\n\n\ndef ssl_monkey_patch() -> None:\n    \"\"\"\n    Monky-patch for https://bugs.python.org/issue36709\n\n    This prevents console errors when outstanding HTTPS connections\n    still exist at the point of exiting.\n\n    Clients which have been opened using a `with` block, or which have\n    had `close()` closed, will not exhibit this issue in the first place.\n    \"\"\"\n    MonkeyPatch = asyncio.selector_events._SelectorSocketTransport  # type: ignore\n\n    _write = MonkeyPatch.write\n\n    def _fixed_write(self, data: bytes) -> None:  # type: ignore\n        if not self._loop.is_closed():\n            _write(self, data)\n\n    MonkeyPatch.write = _fixed_write\n\n\nclass Reader(BaseReader):\n    def __init__(\n        self, stream_reader: asyncio.StreamReader, timeout: TimeoutConfig\n    ) -> None:\n        self.stream_reader = stream_reader\n        self.timeout = timeout\n\n    async def read(self, n: int, timeout: OptionalTimeout = None) -> bytes:\n        if timeout is None:\n            timeout = self.timeout\n\n        try:\n            data = await asyncio.wait_for(\n                self.stream_reader.read(n), timeout.read_timeout\n            )\n        except asyncio.TimeoutError:\n            raise ReadTimeout()\n\n        return data\n\n\nclass Writer(BaseWriter):\n    def __init__(self, stream_writer: asyncio.StreamWriter, timeout: TimeoutConfig):\n        self.stream_writer = stream_writer\n        self.timeout = timeout\n\n    def write_no_block(self, data: bytes) -> None:\n        self.stream_writer.write(data)  # pragma: nocover\n\n    async def write(self, data: bytes, timeout: OptionalTimeout = None) -> None:\n        if not data:\n            return\n\n        if timeout is None:\n            timeout = self.timeout\n\n        self.stream_writer.write(data)\n        try:\n            await asyncio.wait_for(  # type: ignore\n                self.stream_writer.drain(), timeout.write_timeout\n            )\n        except asyncio.TimeoutError:\n            raise WriteTimeout()\n\n    async def close(self) -> None:\n        self.stream_writer.close()\n\n\nclass PoolSemaphore(BasePoolSemaphore):\n    def __init__(self, pool_limits: PoolLimits):\n        self.pool_limits = pool_limits\n\n    @property\n    def semaphore(self) -> typing.Optional[asyncio.BoundedSemaphore]:\n        if not hasattr(self, \"_semaphore\"):\n            max_connections = self.pool_limits.hard_limit\n            if max_connections is None:\n                self._semaphore = None\n            else:\n                self._semaphore = asyncio.BoundedSemaphore(value=max_connections)\n        return self._semaphore\n\n    async def acquire(self) -> None:\n        if self.semaphore is None:\n            return\n\n        timeout = self.pool_limits.pool_timeout\n        try:\n            await asyncio.wait_for(self.semaphore.acquire(), timeout)\n        except asyncio.TimeoutError:\n            raise PoolTimeout()\n\n    def release(self) -> None:\n        if self.semaphore is None:\n            return\n\n        self.semaphore.release()\n\n\nclass AsyncioBackend(ConcurrencyBackend):\n    def __init__(self) -> None:\n        global SSL_MONKEY_PATCH_APPLIED\n\n        if not SSL_MONKEY_PATCH_APPLIED:\n            ssl_monkey_patch()\n        SSL_MONKEY_PATCH_APPLIED = True\n\n    async def connect(\n        self,\n        hostname: str,\n        port: int,\n        ssl_context: typing.Optional[ssl.SSLContext],\n        timeout: TimeoutConfig,\n    ) -> typing.Tuple[BaseReader, BaseWriter, Protocol]:\n        try:\n            stream_reader, stream_writer = await asyncio.wait_for(  # type: ignore\n                asyncio.open_connection(hostname, port, ssl=ssl_context),\n                timeout.connect_timeout,\n            )\n        except asyncio.TimeoutError:\n            raise ConnectTimeout()\n\n        ssl_object = stream_writer.get_extra_info(\"ssl_object\")\n        if ssl_object is None:\n            ident = \"http/1.1\"\n        else:\n            ident = ssl_object.selected_alpn_protocol()\n            if ident is None:\n                ident = ssl_object.selected_npn_protocol()\n\n        reader = Reader(stream_reader=stream_reader, timeout=timeout)\n        writer = Writer(stream_writer=stream_writer, timeout=timeout)\n        protocol = Protocol.HTTP_2 if ident == \"h2\" else Protocol.HTTP_11\n\n        return (reader, writer, protocol)\n\n    def get_semaphore(self, limits: PoolLimits) -> BasePoolSemaphore:\n        return PoolSemaphore(limits)\n", "path": "httpcore/concurrency.py"}]}